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