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