simplify enabling the sleep timer by defaulting the action of the sleep
[enigma2.git] / mytest.py
1 import eBaseImpl
2 import enigma
3 enigma.eTimer = eBaseImpl.eTimer
4 enigma.eSocketNotifier = eBaseImpl.eSocketNotifier
5
6 from Tools.Profile import profile, profile_final
7
8 profile("PYTHON_START")
9
10 from enigma import runMainloop, eDVBDB, eTimer, quitMainloop, \
11         getDesktop, ePythonConfigQuery, eAVSwitch, eServiceEvent
12 from tools import *
13
14 profile("LANGUAGE")
15
16 from Components.Language import language
17
18 def setEPGLanguage():
19         print "language set to", language.getLanguage()
20         eServiceEvent.setEPGLanguage(language.getLanguage())
21
22 language.addCallback(setEPGLanguage)
23
24 from traceback import print_exc
25 profile("LOAD:InfoBar")
26 import Screens.InfoBar
27 from Screens.SimpleSummary import SimpleSummary
28
29 from sys import stdout, exc_info
30
31 profile("ParentalControl")
32 from Components.ParentalControl import InitParentalControl
33 InitParentalControl()
34
35 profile("LOAD:Navigation")
36 from Navigation import Navigation
37
38 profile("LOAD:skin")
39 from skin import readSkin, applyAllAttributes
40
41 profile("LOAD:Tools")
42 from Tools.Directories import InitFallbackFiles, resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
43 from Components.config import config, configfile, ConfigText, ConfigSubsection, ConfigInteger
44 InitFallbackFiles()
45
46 profile("ReloadProfiles")
47 eDVBDB.getInstance().reloadBouquets()
48
49 config.misc.radiopic = ConfigText(default = resolveFilename(SCOPE_SKIN_IMAGE)+"radio.mvi")
50
51 profile("Twisted")
52 try:
53         import twisted.python.runtime
54         twisted.python.runtime.platform.supportsThreads = lambda: False
55
56         import e2reactor
57         e2reactor.install()
58
59         from twisted.internet import reactor
60
61         def runReactor():
62                 reactor.run()
63 except ImportError:
64         print "twisted not available"
65         def runReactor():
66                 runMainloop()
67
68 profile("LOAD:Plugin")
69
70 # initialize autorun plugins and plugin menu entries
71 from Components.PluginComponent import plugins
72
73 profile("LOAD:Wizard")
74 from Screens.Wizard import wizardManager
75 from Screens.ImageWizard import *
76 from Screens.StartWizard import *
77 from Screens.DefaultWizard import *
78 from Screens.TutorialWizard import *
79 from Tools.BoundFunction import boundFunction
80 from Plugins.Plugin import PluginDescriptor
81
82 profile("misc")
83 had = dict()
84
85 def dump(dir, p = ""):
86         if isinstance(dir, dict):
87                 for (entry, val) in dir.items():
88                         dump(val, p + "(dict)/" + entry)
89         if hasattr(dir, "__dict__"):
90                 for name, value in dir.__dict__.items():
91                         if not had.has_key(str(value)):
92                                 had[str(value)] = 1
93                                 dump(value, p + "/" + str(name))
94                         else:
95                                 print p + "/" + str(name) + ":" + str(dir.__class__) + "(cycle)"
96         else:
97                 print p + ":" + str(dir)
98
99 # + ":" + str(dir.__class__)
100
101 # display
102
103 profile("LOAD:ScreenGlobals")
104 from Screens.Globals import Globals
105 from Screens.SessionGlobals import SessionGlobals
106 from Screens.Screen import Screen
107
108 profile("Screen")
109 Screen.global_screen = Globals()
110
111 # Session.open:
112 # * push current active dialog ('current_dialog') onto stack
113 # * call execEnd for this dialog
114 #   * clear in_exec flag
115 #   * hide screen
116 # * instantiate new dialog into 'current_dialog'
117 #   * create screens, components
118 #   * read, apply skin
119 #   * create GUI for screen
120 # * call execBegin for new dialog
121 #   * set in_exec
122 #   * show gui screen
123 #   * call components' / screen's onExecBegin
124 # ... screen is active, until it calls 'close'...
125 # Session.close:
126 # * assert in_exec
127 # * save return value
128 # * start deferred close handler ('onClose')
129 # * execEnd
130 #   * clear in_exec
131 #   * hide screen
132 # .. a moment later:
133 # Session.doClose:
134 # * destroy screen
135
136 class Session:
137         def __init__(self, desktop = None, summary_desktop = None, navigation = None):
138                 self.desktop = desktop
139                 self.summary_desktop = summary_desktop
140                 self.nav = navigation
141                 self.delay_timer = eTimer()
142                 self.delay_timer.callback.append(self.processDelay)
143
144                 self.current_dialog = None
145
146                 self.dialog_stack = [ ]
147                 self.summary_stack = [ ]
148                 self.summary = None
149
150                 self.in_exec = False
151
152                 self.screen = SessionGlobals(self)
153
154                 for p in plugins.getPlugins(PluginDescriptor.WHERE_SESSIONSTART):
155                         p(reason=0, session=self)
156
157         def processDelay(self):
158                 callback = self.current_dialog.callback
159
160                 retval = self.current_dialog.returnValue
161
162                 if self.current_dialog.isTmp:
163                         self.current_dialog.doClose()
164 #                       dump(self.current_dialog)
165                         del self.current_dialog
166                 else:
167                         del self.current_dialog.callback
168
169                 self.popCurrent()
170                 if callback is not None:
171                         callback(*retval)
172
173         def execBegin(self, first=True, do_show = True):
174                 assert not self.in_exec 
175                 self.in_exec = True
176                 c = self.current_dialog
177
178                 # when this is an execbegin after a execend of a "higher" dialog,
179                 # popSummary already did the right thing.
180                 if first:
181                         self.pushSummary()
182                         summary = c.createSummary() or SimpleSummary
183                         self.summary = self.instantiateSummaryDialog(summary, c)
184                         self.summary.show()
185                         c.addSummary(self.summary)
186
187                 c.execBegin()
188
189                 # when execBegin opened a new dialog, don't bother showing the old one.
190                 if c == self.current_dialog and do_show:
191                         c.show()
192
193         def execEnd(self, last=True):
194                 assert self.in_exec
195                 self.in_exec = False
196
197                 self.current_dialog.execEnd()
198                 self.current_dialog.hide()
199
200                 if last:
201                         self.current_dialog.removeSummary(self.summary)
202                         self.popSummary()
203
204         def create(self, screen, arguments, **kwargs):
205                 # creates an instance of 'screen' (which is a class)
206                 try:
207                         return screen(self, *arguments, **kwargs)
208                 except:
209                         errstr = "Screen %s(%s, %s): %s" % (str(screen), str(arguments), str(kwargs), exc_info()[0])
210                         print errstr
211                         print_exc(file=stdout)
212                         quitMainloop(5)
213
214         def instantiateDialog(self, screen, *arguments, **kwargs):
215                 return self.doInstantiateDialog(screen, arguments, kwargs, self.desktop)
216
217         def deleteDialog(self, screen):
218                 screen.hide()
219                 screen.doClose()
220
221         def instantiateSummaryDialog(self, screen, *arguments, **kwargs):
222                 return self.doInstantiateDialog(screen, arguments, kwargs, self.summary_desktop)
223
224         def doInstantiateDialog(self, screen, arguments, kwargs, desktop):
225                 # create dialog
226
227                 try:
228                         dlg = self.create(screen, arguments, **kwargs)
229                 except:
230                         print 'EXCEPTION IN DIALOG INIT CODE, ABORTING:'
231                         print '-'*60
232                         print_exc(file=stdout)
233                         quitMainloop(5)
234                         print '-'*60
235
236                 if dlg is None:
237                         return
238
239                 # read skin data
240                 readSkin(dlg, None, dlg.skinName, desktop)
241
242                 # create GUI view of this dialog
243                 assert desktop is not None
244
245                 dlg.setDesktop(desktop)
246                 dlg.applySkin()
247
248                 return dlg
249
250         def pushCurrent(self):
251                 if self.current_dialog is not None:
252                         self.dialog_stack.append((self.current_dialog, self.current_dialog.shown))
253                         self.execEnd(last=False)
254
255         def popCurrent(self):
256                 if len(self.dialog_stack):
257                         (self.current_dialog, do_show) = self.dialog_stack.pop()
258                         self.execBegin(first=False, do_show=do_show)
259                 else:
260                         self.current_dialog = None
261
262         def execDialog(self, dialog):
263                 self.pushCurrent()
264                 self.current_dialog = dialog
265                 self.current_dialog.isTmp = False
266                 self.current_dialog.callback = None # would cause re-entrancy problems.
267                 self.execBegin()
268
269         def openWithCallback(self, callback, screen, *arguments, **kwargs):
270                 dlg = self.open(screen, *arguments, **kwargs)
271                 dlg.callback = callback
272                 return dlg
273
274         def open(self, screen, *arguments, **kwargs):
275                 if len(self.dialog_stack) and not self.in_exec:
276                         raise "modal open are allowed only from a screen which is modal!"
277                         # ...unless it's the very first screen.
278
279                 self.pushCurrent()
280                 dlg = self.current_dialog = self.instantiateDialog(screen, *arguments, **kwargs)
281                 dlg.isTmp = True
282                 dlg.callback = None
283                 self.execBegin()
284                 return dlg
285
286         def close(self, screen, *retval):
287                 if not self.in_exec:
288                         print "close after exec!"
289                         return
290
291                 # be sure that the close is for the right dialog!
292                 # if it's not, you probably closed after another dialog
293                 # was opened. this can happen if you open a dialog
294                 # onExecBegin, and forget to do this only once.
295                 # after close of the top dialog, the underlying will
296                 # gain focus again (for a short time), thus triggering
297                 # the onExec, which opens the dialog again, closing the loop.
298                 assert screen == self.current_dialog
299
300                 self.current_dialog.returnValue = retval
301                 self.delay_timer.start(0, 1)
302                 self.execEnd()
303
304         def pushSummary(self):
305                 if self.summary is not None:
306                         self.summary.hide()
307                 self.summary_stack.append(self.summary)
308                 self.summary = None
309
310         def popSummary(self):
311                 if self.summary is not None:
312                         self.summary.doClose()
313                 self.summary = self.summary_stack.pop()
314                 if self.summary is not None:
315                         self.summary.show()
316
317 profile("Standby,PowerKey")
318 import Screens.Standby
319 from Screens.Menu import MainMenu, mdom
320 import xml.dom.minidom
321 from GlobalActions import globalActionMap
322
323 class PowerKey:
324         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
325
326         def __init__(self, session):
327                 self.session = session
328                 globalActionMap.actions["power_down"]=self.powerdown
329                 globalActionMap.actions["power_up"]=self.powerup
330                 globalActionMap.actions["power_long"]=self.powerlong
331                 globalActionMap.actions["deepstandby"]=self.shutdown # frontpanel long power button press
332                 self.standbyblocked = 1
333
334         def MenuClosed(self, *val):
335                 self.session.infobar = None
336
337         def shutdown(self):
338                 print "PowerOff - Now!"
339                 if not Screens.Standby.inTryQuitMainloop and self.session.current_dialog and self.session.current_dialog.ALLOW_SUSPEND:
340                         self.session.open(Screens.Standby.TryQuitMainloop, 1)
341
342         def powerlong(self):
343                 self.standbyblocked = 1
344                 action = config.usage.on_long_powerpress.value
345                 if action == "shutdown":
346                         self.shutdown()
347                 elif action == "show_menu":
348                         print "Show shutdown Menu"
349                         menu = mdom.childNodes[0]
350                         for x in menu.childNodes:
351                                 if x.nodeType != xml.dom.minidom.Element.nodeType:
352                                     continue
353                                 elif x.tagName == 'menu':
354                                         for y in x.childNodes:
355                                                 if y.nodeType != xml.dom.minidom.Element.nodeType:
356                                                         continue
357                                                 elif y.tagName == 'id':
358                                                         id = y.getAttribute("val")
359                                                         if id and id == "shutdown":
360                                                                 self.session.infobar = self
361                                                                 menu_screen = self.session.openWithCallback(self.MenuClosed, MainMenu, x, x.childNodes)
362                                                                 menu_screen.setTitle(_("Standby / Restart"))
363                                                                 return
364
365         def powerdown(self):
366                 self.standbyblocked = 0
367
368         def powerup(self):
369                 if self.standbyblocked == 0:
370                         self.standbyblocked = 1
371                         self.standby()
372
373         def standby(self):
374                 if not Screens.Standby.inStandby and self.session.current_dialog and self.session.current_dialog.ALLOW_SUSPEND:
375                         self.session.open(Screens.Standby.Standby)
376
377 profile("Scart")
378 from Screens.Scart import Scart
379
380 class AutoScartControl:
381         def __init__(self, session):
382                 self.force = False
383                 self.current_vcr_sb = eAVSwitch.getInstance().getVCRSlowBlanking()
384                 if self.current_vcr_sb and config.av.vcrswitch.value:
385                         self.scartDialog = session.instantiateDialog(Scart, True)
386                 else:
387                         self.scartDialog = session.instantiateDialog(Scart, False)
388                 config.av.vcrswitch.addNotifier(self.recheckVCRSb)
389                 eAVSwitch.getInstance().vcr_sb_notifier.get().append(self.VCRSbChanged)
390
391         def recheckVCRSb(self, configElement):
392                 self.VCRSbChanged(self.current_vcr_sb)
393
394         def VCRSbChanged(self, value):
395                 #print "vcr sb changed to", value
396                 self.current_vcr_sb = value
397                 if config.av.vcrswitch.value or value > 2:
398                         if value:
399                                 self.scartDialog.showMessageBox()
400                         else:
401                                 self.scartDialog.switchToTV()
402
403 profile("Load:CI")
404 from enigma import eDVBCIInterfaces
405 from Screens.Ci import CiHandler
406
407 profile("Load:VolumeControl")
408 from Components.VolumeControl import VolumeControl
409
410 def runScreenTest():
411         profile("readPluginList")
412         plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
413
414         profile("Init:Session")
415         session = Session(desktop = getDesktop(0), summary_desktop = getDesktop(1), navigation = Navigation())
416
417         CiHandler.setSession(session)
418
419         screensToRun = [ ]
420
421         for p in plugins.getPlugins(PluginDescriptor.WHERE_WIZARD):
422                 screensToRun.append(p.__call__)
423
424         profile("wizards")
425         screensToRun += wizardManager.getWizards()
426
427         screensToRun.append((100, Screens.InfoBar.InfoBar))
428
429         screensToRun.sort()
430
431         ePythonConfigQuery.setQueryFunc(configfile.getResolvedKey)
432
433 #       eDVBCIInterfaces.getInstance().setDescrambleRules(0 # Slot Number
434 #               ,(      ["1:0:1:24:4:85:C00000:0:0:0:"], #service_list
435 #                       ["PREMIERE"], #provider_list,
436 #                       [] #caid_list
437 #               ));
438
439         def runNextScreen(session, screensToRun, *result):
440                 if result:
441                         quitMainloop(*result)
442                         return
443
444                 screen = screensToRun[0][1]
445
446                 if len(screensToRun):
447                         session.openWithCallback(boundFunction(runNextScreen, session, screensToRun[1:]), screen)
448                 else:
449                         session.open(screen)
450
451         runNextScreen(session, screensToRun)
452
453         profile("Init:VolumeControl")
454         vol = VolumeControl(session)
455         profile("Init:PowerKey")
456         power = PowerKey(session)
457
458         # we need session.scart to access it from within menu.xml
459         session.scart = AutoScartControl(session)
460
461         profile("RunReactor")
462         profile_final()
463         runReactor()
464         profile("configfile.save")
465         configfile.save()
466
467         profile("wakeup")
468         from time import time
469         from Tools.DreamboxHardware import setFPWakeuptime
470         #get currentTime
471         nowTime = time()
472         wakeupList = [
473                 x for x in
474                                 [session.nav.RecordTimer.getNextRecordingTime(),
475                                 session.nav.RecordTimer.getNextZapTime(),
476                                 plugins.getNextWakeupTime()]
477                 if x != -1
478         ]
479         wakeupList.sort()
480         if len(wakeupList):
481                 startTime = wakeupList.pop(0)
482                 if (startTime - nowTime < 330): # no time to switch box back on
483                         setFPWakeuptime(nowTime + 30) # so switch back on in 30 seconds
484                 else:
485                         setFPWakeuptime(startTime - 300)
486         profile("stopService")
487         session.nav.stopService()
488         profile("nav shutdown")
489         session.nav.shutdown()
490
491         return 0
492
493 profile("Init:skin")
494 import skin
495 skin.loadSkinData(getDesktop(0))
496
497 profile("InputDevice")
498 import Components.InputDevice
499 Components.InputDevice.InitInputDevices()
500
501 profile("AVSwitch")
502 import Components.AVSwitch
503 Components.AVSwitch.InitAVSwitch()
504
505 profile("RecordingConfig")
506 import Components.RecordingConfig
507 Components.RecordingConfig.InitRecordingConfig()
508
509 profile("UsageConfig")
510 import Components.UsageConfig
511 Components.UsageConfig.InitUsageConfig()
512
513 profile("keymapparser")
514 import keymapparser
515 keymapparser.readKeymap(config.usage.keymap.value)
516
517 profile("Network")
518 import Components.Network
519 Components.Network.InitNetwork()
520
521 profile("LCD")
522 import Components.Lcd
523 Components.Lcd.InitLcd()
524
525 profile("SetupDevices")
526 import Components.SetupDevices
527 Components.SetupDevices.InitSetupDevices()
528
529 profile("RFMod")
530 import Components.RFmod
531 Components.RFmod.InitRFmod()
532
533 profile("Init:CI")
534 import Screens.Ci
535 Screens.Ci.InitCiConfig()
536
537 #from enigma import dump_malloc_stats
538 #t = eTimer()
539 #t.callback.append(dump_malloc_stats)
540 #t.start(1000)
541
542 # first, setup a screen
543 try:
544         runScreenTest()
545
546         plugins.shutdown()
547
548         from Components.ParentalControl import parentalControl
549         parentalControl.save()
550 except:
551         print 'EXCEPTION IN PYTHON STARTUP CODE:'
552         print '-'*60
553         print_exc(file=stdout)
554         quitMainloop(5)
555         print '-'*60