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