more flexible way of adding new playlist types
[enigma2.git] / mytest.py
1 from Tools import RedirectOutput
2 from enigma import *
3 from tools import *
4
5 from Components.Language import language
6
7 def setEPGLanguage():
8         print "language set to", language.getLanguage()
9         eServiceEvent.setEPGLanguage(language.getLanguage())
10         
11 language.addCallback(setEPGLanguage)
12
13 import traceback
14 import Screens.InfoBar
15 from Screens.SimpleSummary import SimpleSummary
16
17 import sys
18 import time
19
20 import ServiceReference
21
22 from Navigation import Navigation
23
24 from skin import readSkin, applyAllAttributes
25
26 from Components.config import configfile
27 from Tools.Directories import InitFallbackFiles, resolveFilename, SCOPE_PLUGINS
28 InitFallbackFiles()
29 eDVBDB.getInstance().reloadBouquets()
30
31 try:
32         import e2reactor
33         e2reactor.install()
34         
35         from twisted.internet import reactor
36         
37         def runReactor():
38                 reactor.run()
39 except ImportError:
40         print "twisted not available"
41         def runReactor():
42                 runMainloop()
43
44 # initialize autorun plugins and plugin menu entries
45 from Components.PluginComponent import plugins
46
47 from Screens.Wizard import wizardManager
48 from Screens.ImageWizard import *
49 from Screens.StartWizard import *
50 from Screens.TutorialWizard import *
51 from Tools.BoundFunction import boundFunction
52 from Plugins.Plugin import PluginDescriptor
53
54 had = dict()
55
56 def dump(dir, p = ""):
57         if isinstance(dir, dict):
58                 for (entry, val) in dir.items():
59                         dump(val, p + "(dict)/" + entry)
60         if hasattr(dir, "__dict__"):
61                 for name, value in dir.__dict__.items():
62                         if not had.has_key(str(value)):
63                                 had[str(value)] = 1
64                                 dump(value, p + "/" + str(name))
65                         else:
66                                 print p + "/" + str(name) + ":" + str(dir.__class__) + "(cycle)"
67         else:
68                 print p + ":" + str(dir)
69
70 # + ":" + str(dir.__class__)
71
72 # display
73
74 class OutputDevice:
75         def create(self, screen): pass
76
77 # display: HTML
78
79 class HTMLOutputDevice(OutputDevice):
80         def create(self, comp):
81                 print comp.produceHTML()
82
83 html = HTMLOutputDevice()
84
85 class GUIOutputDevice(OutputDevice):
86         parent = None
87         def create(self, comp, desktop):
88                 comp.createGUIScreen(self.parent, desktop)
89
90 # Session.open:
91 # * push current active dialog ('current_dialog') onto stack
92 # * call execEnd for this dialog
93 #   * clear in_exec flag
94 #   * hide screen
95 # * instantiate new dialog into 'current_dialog'
96 #   * create screens, components
97 #   * read, apply skin
98 #   * create GUI for screen
99 # * call execBegin for new dialog
100 #   * set in_exec
101 #   * show gui screen
102 #   * call components' / screen's onExecBegin
103 # ... screen is active, until it calls 'close'...
104 # Session.close:
105 # * assert in_exec
106 # * save return value
107 # * start deferred close handler ('onClose')
108 # * execEnd
109 #   * clear in_exec
110 #   * hide screen
111 # .. a moment later:
112 # Session.doClose:
113 # * destroy screen
114
115 class Session:
116         def __init__(self, desktop = None, summary_desktop = None, navigation = None):
117                 self.desktop = desktop
118                 self.summary_desktop = summary_desktop
119                 self.nav = navigation
120                 self.delay_timer = eTimer()
121                 self.delay_timer.timeout.get().append(self.processDelay)
122                 
123                 self.current_dialog = None
124                 
125                 self.dialog_stack = [ ]
126                 self.summary_stack = [ ]
127                 self.summary = None
128                 
129                 self.in_exec = False
130                 
131                 for p in plugins.getPlugins(PluginDescriptor.WHERE_SESSIONSTART):
132                         p(reason=0, session=self)
133         
134         def processDelay(self):
135                 callback = self.current_dialog.callback
136
137                 retval = self.current_dialog.returnValue
138
139                 if self.current_dialog.isTmp:
140                         self.current_dialog.doClose()
141 #                       dump(self.current_dialog)
142                         del self.current_dialog
143                 else:
144                         del self.current_dialog.callback
145                 
146                 self.popCurrent()
147                 if callback is not None:
148                         callback(*retval)
149
150         def execBegin(self, first=True):
151                 assert not self.in_exec 
152                 self.in_exec = True
153                 c = self.current_dialog
154                 
155                 # when this is an execbegin after a execend of a "higher" dialog,
156                 # popSummary already did the right thing.
157                 if first:
158                         self.pushSummary()
159                         summary = c.createSummary() or SimpleSummary
160                         self.summary = self.instantiateSummaryDialog(summary, c)
161                         self.summary.show()
162                         c.addSummary(self.summary)
163
164                 c.execBegin()
165
166                 # when execBegin opened a new dialog, don't bother showing the old one.
167                 if c == self.current_dialog:
168                         c.show()
169                 
170         def execEnd(self, last=True):
171                 assert self.in_exec
172                 self.in_exec = False
173
174                 self.current_dialog.execEnd()
175                 self.current_dialog.hide()
176                 
177                 if last:
178                         self.current_dialog.removeSummary(self.summary)
179                         self.popSummary()
180         
181         def create(self, screen, arguments, **kwargs):
182                 # creates an instance of 'screen' (which is a class)
183                 try:
184                         return screen(self, *arguments, **kwargs)
185                 except:
186                         errstr = "Screen %s(%s, %s): %s" % (str(screen), str(arguments), str(kwargs), sys.exc_info()[0])
187                         print errstr
188                         traceback.print_exc(file=sys.stdout)
189                         quitMainloop(5)
190         
191         def instantiateDialog(self, screen, *arguments, **kwargs):
192                 return self.doInstantiateDialog(screen, arguments, kwargs, self.desktop)
193         
194         def instantiateSummaryDialog(self, screen, *arguments, **kwargs):
195                 return self.doInstantiateDialog(screen, arguments, kwargs, self.summary_desktop)
196         
197         def doInstantiateDialog(self, screen, arguments, kwargs, desktop):
198                 # create dialog
199                 
200                 try:
201                         dlg = self.create(screen, arguments, **kwargs)
202                 except:
203                         print 'EXCEPTION IN DIALOG INIT CODE, ABORTING:'
204                         print '-'*60
205                         traceback.print_exc(file=sys.stdout)
206                         quitMainloop(5)
207                         print '-'*60
208                 
209                 if dlg is None:
210                         return
211
212                 # read skin data
213                 readSkin(dlg, None, dlg.skinName, desktop)
214
215                 # create GUI view of this dialog
216                 assert desktop is not None
217                 
218                 z = 0
219                 title = ""
220                 for (key, value) in dlg.skinAttributes:
221                         if key == "zPosition":
222                                 z = int(value)
223                         elif key == "title":
224                                 title = value
225                 
226                 dlg.instance = eWindow(desktop, z)
227                 dlg.title = title
228                 applyAllAttributes(dlg.instance, desktop, dlg.skinAttributes)
229                 gui = GUIOutputDevice()
230                 gui.parent = dlg.instance
231                 gui.create(dlg, desktop)
232                 
233                 return dlg
234          
235         def pushCurrent(self):
236                 if self.current_dialog is not None:
237                         self.dialog_stack.append(self.current_dialog)
238                         self.execEnd(last=False)
239         
240         def popCurrent(self):
241                 if len(self.dialog_stack):
242                         self.current_dialog = self.dialog_stack.pop()
243                         self.execBegin(first=False)
244                 else:
245                         self.current_dialog = None
246
247         def execDialog(self, dialog):
248                 self.pushCurrent()
249                 self.current_dialog = dialog
250                 self.current_dialog.isTmp = False
251                 self.current_dialog.callback = None # would cause re-entrancy problems.
252                 self.execBegin()
253
254         def openWithCallback(self, callback, screen, *arguments, **kwargs):
255                 dlg = self.open(screen, *arguments, **kwargs)
256                 dlg.callback = callback
257                 return dlg
258
259         def open(self, screen, *arguments, **kwargs):
260                 if len(self.dialog_stack) and not self.in_exec:
261                         raise "modal open are allowed only from a screen which is modal!"
262                         # ...unless it's the very first screen.
263                 
264                 self.pushCurrent()
265                 dlg = self.current_dialog = self.instantiateDialog(screen, *arguments, **kwargs)
266                 dlg.isTmp = True
267                 dlg.callback = None
268                 self.execBegin()
269                 return dlg
270
271         def close(self, screen, *retval):
272                 if not self.in_exec:
273                         print "close after exec!"
274                         return
275                 
276                 # be sure that the close is for the right dialog!
277                 # if it's not, you probably closed after another dialog
278                 # was opened. this can happen if you open a dialog
279                 # onExecBegin, and forget to do this only once.
280                 # after close of the top dialog, the underlying will
281                 # gain focus again (for a short time), thus triggering
282                 # the onExec, which opens the dialog again, closing the loop.
283                 assert screen == self.current_dialog
284                 
285                 self.current_dialog.returnValue = retval
286                 self.delay_timer.start(0, 1)
287                 self.execEnd()
288
289         def pushSummary(self):
290                 if self.summary is not None:
291                         self.summary.hide()
292                 self.summary_stack.append(self.summary)
293                 self.summary = None
294
295         def popSummary(self):
296                 if self.summary is not None:
297                         self.summary.doClose()
298                 self.summary = self.summary_stack.pop()
299                 if self.summary is not None:
300                         self.summary.show()
301
302 from Screens.Volume import Volume
303 from Screens.Mute import Mute
304 from GlobalActions import globalActionMap
305 from Components.config import ConfigSubsection, configSequence, configElement, configsequencearg
306
307 #TODO .. move this to a own .py file
308 class VolumeControl:
309         """Volume control, handles volUp, volDown, volMute actions and display
310         a corresponding dialog"""
311         def __init__(self, session):
312                 global globalActionMap
313                 globalActionMap.actions["volumeUp"]=self.volUp
314                 globalActionMap.actions["volumeDown"]=self.volDown
315                 globalActionMap.actions["volumeMute"]=self.volMute
316
317                 config.audio = ConfigSubsection()
318                 config.audio.volume = configElement("config.audio.volume", configSequence, [100], configsequencearg.get("INTEGER", (0, 100)))
319
320                 self.volumeDialog = session.instantiateDialog(Volume)
321                 self.muteDialog = session.instantiateDialog(Mute)
322
323                 self.hideVolTimer = eTimer()
324                 self.hideVolTimer.timeout.get().append(self.volHide)
325
326                 vol = config.audio.volume.value[0]
327                 self.volumeDialog.setValue(vol)
328                 eDVBVolumecontrol.getInstance().setVolume(vol, vol)
329
330         def volSave(self):
331                 config.audio.volume.value = eDVBVolumecontrol.getInstance().getVolume()
332                 config.audio.volume.save()
333
334         def     volUp(self):
335                 if (eDVBVolumecontrol.getInstance().isMuted()):
336                         self.volMute()
337                 eDVBVolumecontrol.getInstance().volumeUp()
338                 self.volumeDialog.show()
339                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
340                 self.volSave()
341                 self.hideVolTimer.start(3000, True)
342
343         def     volDown(self):
344                 if (eDVBVolumecontrol.getInstance().isMuted()):
345                         self.volMute()
346                 eDVBVolumecontrol.getInstance().volumeDown()
347                 self.volumeDialog.show()
348                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
349                 self.volSave()
350                 self.hideVolTimer.start(3000, True)
351
352         def volHide(self):
353                 self.volumeDialog.hide()
354
355         def     volMute(self):
356                 eDVBVolumecontrol.getInstance().volumeToggleMute()
357                 self.volumeDialog.setValue(eDVBVolumecontrol.getInstance().getVolume())
358
359                 if (eDVBVolumecontrol.getInstance().isMuted()):
360                         self.muteDialog.show()
361                 else:
362                         self.muteDialog.hide()
363
364 from Screens.Standby import Standby
365
366 class PowerKey:
367         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
368         
369         def __init__(self, session):
370                 self.session = session
371                 self.powerKeyTimer = eTimer()
372                 self.powerKeyTimer.timeout.get().append(self.powertimer)
373                 globalActionMap.actions["powerdown"]=self.powerdown
374                 globalActionMap.actions["powerup"]=self.powerup
375                 self.standbyblocked = 0
376 #               self["PowerKeyActions"] = HelpableActionMap(self, "PowerKeyActions",
377                         #{
378                                 #"powerdown": self.powerdown,
379                                 #"powerup": self.powerup,
380                                 #"discreteStandby": (self.standby, "Go standby"),
381                                 #"discretePowerOff": (self.quit, "Go to deep standby"),
382                         #})
383
384         def powertimer(self):   
385                 print "PowerOff - Now!"
386                 self.quit()
387         
388         def powerdown(self):
389                 self.standbyblocked = 0
390                 self.powerKeyTimer.start(3000, True)
391
392         def powerup(self):
393                 self.powerKeyTimer.stop()
394                 if self.standbyblocked == 0:
395                         self.standbyblocked = 1
396                         self.standby()
397
398         def standby(self):
399                 self.session.open(Standby, self)
400
401         def quit(self):
402                 # halt
403                 quitMainloop(1)
404
405 def runScreenTest():
406         plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
407
408         session = Session(desktop = getDesktop(0), summary_desktop = getDesktop(1), navigation = Navigation())
409         
410         screensToRun = [ ]
411         
412         for p in plugins.getPlugins(PluginDescriptor.WHERE_WIZARD):
413                 screensToRun.append(p.__call__)
414         
415         screensToRun += wizardManager.getWizards()
416         
417         screensToRun.append(Screens.InfoBar.InfoBar)
418
419         ePythonConfigQuery.setQueryFunc(configfile.getResolvedKey)
420
421         def runNextScreen(session, screensToRun, *result):
422                 if result:
423                         quitMainloop(*result)
424                         return
425         
426                 screen = screensToRun[0]
427                 
428                 if len(screensToRun):
429                         session.openWithCallback(boundFunction(runNextScreen, session, screensToRun[1:]), screen)
430                 else:
431                         session.open(screen)
432         
433         runNextScreen(session, screensToRun)
434         
435         vol = VolumeControl(session)
436         power = PowerKey(session)
437         
438         runReactor()
439         
440         configfile.save()
441         
442         from Tools.DreamboxHardware import setFPWakeuptime
443         from time import time
444         nextRecordingTime = session.nav.RecordTimer.getNextRecordingTime()
445         if nextRecordingTime != -1:
446                 if (nextRecordingTime - time() < 330): # no time to switch box back on
447                         setFPWakeuptime(time() + 30) # so switch back on in 30 seconds
448                 else:
449                         setFPWakeuptime(nextRecordingTime - (300))
450         
451         session.nav.shutdown()
452         
453         return 0
454
455 import keymapparser
456 keymapparser.readKeymap()
457 import skin
458 skin.loadSkinData(getDesktop(0))
459
460 import Components.InputDevice
461 Components.InputDevice.InitInputDevices()
462
463 import Components.AVSwitch
464 Components.AVSwitch.InitAVSwitch()
465
466 import Components.RecordingConfig
467 Components.RecordingConfig.InitRecordingConfig()
468
469 import Components.UsageConfig
470 Components.UsageConfig.InitUsageConfig()
471
472 import Components.Network
473 Components.Network.InitNetwork()
474
475 import Components.Lcd
476 Components.Lcd.InitLcd()
477
478 import Components.SetupDevices
479 Components.SetupDevices.InitSetupDevices()
480
481 import Components.RFmod
482 Components.RFmod.InitRFmod()
483
484 import Components.NimManager
485
486 # first, setup a screen
487 try:
488         runScreenTest()
489
490         plugins.shutdown()
491 except:
492         print 'EXCEPTION IN PYTHON STARTUP CODE:'
493         print '-'*60
494         traceback.print_exc(file=sys.stdout)
495         quitMainloop(5)
496         print '-'*60