Merge branch 'experimental' of git.opendreambox.org:/git/enigma2 into experimental
[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_CURRENT_SKIN
45 from Components.config import config, configfile, ConfigText, ConfigYesNo, ConfigInteger, NoSave
46 InitFallbackFiles()
47
48 profile("ReloadProfiles")
49 eDVBDB.getInstance().reloadBouquets()
50
51 config.misc.radiopic = ConfigText(default = resolveFilename(SCOPE_CURRENT_SKIN, "radio.mvi"))
52 config.misc.isNextRecordTimerAfterEventActionAuto = ConfigYesNo(default=False)
53 config.misc.useTransponderTime = ConfigYesNo(default=True)
54 config.misc.startCounter = ConfigInteger(default=0) # number of e2 starts...
55 config.misc.standbyCounter = NoSave(ConfigInteger(default=0)) # number of standby
56
57 #demo code for use of standby enter leave callbacks
58 #def leaveStandby():
59 #       print "!!!!!!!!!!!!!!!!!leave standby"
60
61 #def standbyCountChanged(configElement):
62 #       print "!!!!!!!!!!!!!!!!!enter standby num", configElement.value
63 #       from Screens.Standby import inStandby
64 #       inStandby.onClose.append(leaveStandby)
65
66 #config.misc.standbyCounter.addNotifier(standbyCountChanged, initial_call = False)
67 ####################################################
68
69 def useTransponderTimeChanged(configElement):
70         enigma.eDVBLocalTimeHandler.getInstance().setUseDVBTime(configElement.value)
71 config.misc.useTransponderTime.addNotifier(useTransponderTimeChanged)
72
73 profile("Twisted")
74 try:
75         import twisted.python.runtime
76         twisted.python.runtime.platform.supportsThreads = lambda: False
77
78         import e2reactor
79         e2reactor.install()
80
81         from twisted.internet import reactor
82
83         def runReactor():
84                 reactor.run(installSignalHandlers=False)
85 except ImportError:
86         print "twisted not available"
87         def runReactor():
88                 runMainloop()
89
90 profile("LOAD:Plugin")
91
92 # initialize autorun plugins and plugin menu entries
93 from Components.PluginComponent import plugins
94
95 profile("LOAD:Wizard")
96 from Screens.Wizard import wizardManager
97 from Screens.DefaultWizard import *
98 from Screens.StartWizard import *
99 from Screens.TutorialWizard import *
100 import Screens.Rc
101 from Tools.BoundFunction import boundFunction
102 from Plugins.Plugin import PluginDescriptor
103
104 profile("misc")
105 had = dict()
106
107 def dump(dir, p = ""):
108         if isinstance(dir, dict):
109                 for (entry, val) in dir.items():
110                         dump(val, p + "(dict)/" + entry)
111         if hasattr(dir, "__dict__"):
112                 for name, value in dir.__dict__.items():
113                         if not had.has_key(str(value)):
114                                 had[str(value)] = 1
115                                 dump(value, p + "/" + str(name))
116                         else:
117                                 print p + "/" + str(name) + ":" + str(dir.__class__) + "(cycle)"
118         else:
119                 print p + ":" + str(dir)
120
121 # + ":" + str(dir.__class__)
122
123 # display
124
125 profile("LOAD:ScreenGlobals")
126 from Screens.Globals import Globals
127 from Screens.SessionGlobals import SessionGlobals
128 from Screens.Screen import Screen
129
130 profile("Screen")
131 Screen.global_screen = Globals()
132
133 # Session.open:
134 # * push current active dialog ('current_dialog') onto stack
135 # * call execEnd for this dialog
136 #   * clear in_exec flag
137 #   * hide screen
138 # * instantiate new dialog into 'current_dialog'
139 #   * create screens, components
140 #   * read, apply skin
141 #   * create GUI for screen
142 # * call execBegin for new dialog
143 #   * set in_exec
144 #   * show gui screen
145 #   * call components' / screen's onExecBegin
146 # ... screen is active, until it calls 'close'...
147 # Session.close:
148 # * assert in_exec
149 # * save return value
150 # * start deferred close handler ('onClose')
151 # * execEnd
152 #   * clear in_exec
153 #   * hide screen
154 # .. a moment later:
155 # Session.doClose:
156 # * destroy screen
157
158 class Session:
159         def __init__(self, desktop = None, summary_desktop = None, navigation = None):
160                 self.desktop = desktop
161                 self.summary_desktop = summary_desktop
162                 self.nav = navigation
163                 self.delay_timer = eTimer()
164                 self.delay_timer.callback.append(self.processDelay)
165
166                 self.current_dialog = None
167
168                 self.dialog_stack = [ ]
169                 self.summary_stack = [ ]
170                 self.summary = None
171
172                 self.in_exec = False
173
174                 self.screen = SessionGlobals(self)
175
176                 for p in plugins.getPlugins(PluginDescriptor.WHERE_SESSIONSTART):
177                         p(reason=0, session=self)
178
179         def processDelay(self):
180                 callback = self.current_dialog.callback
181
182                 retval = self.current_dialog.returnValue
183
184                 if self.current_dialog.isTmp:
185                         self.current_dialog.doClose()
186 #                       dump(self.current_dialog)
187                         del self.current_dialog
188                 else:
189                         del self.current_dialog.callback
190
191                 self.popCurrent()
192                 if callback is not None:
193                         callback(*retval)
194
195         def execBegin(self, first=True, do_show = True):
196                 assert not self.in_exec 
197                 self.in_exec = True
198                 c = self.current_dialog
199
200                 # when this is an execbegin after a execend of a "higher" dialog,
201                 # popSummary already did the right thing.
202                 if first:
203                         self.pushSummary()
204                         summary = c.createSummary() or SimpleSummary
205                         self.summary = self.instantiateSummaryDialog(summary, c)
206                         self.summary.show()
207                         c.addSummary(self.summary)
208
209                 c.execBegin()
210
211                 # when execBegin opened a new dialog, don't bother showing the old one.
212                 if c == self.current_dialog and do_show:
213                         c.show()
214
215         def execEnd(self, last=True):
216                 assert self.in_exec
217                 self.in_exec = False
218
219                 self.current_dialog.execEnd()
220                 self.current_dialog.hide()
221
222                 if last:
223                         self.current_dialog.removeSummary(self.summary)
224                         self.popSummary()
225
226         def create(self, screen, arguments, **kwargs):
227                 # creates an instance of 'screen' (which is a class)
228                 try:
229                         return screen(self, *arguments, **kwargs)
230                 except:
231                         errstr = "Screen %s(%s, %s): %s" % (str(screen), str(arguments), str(kwargs), exc_info()[0])
232                         print errstr
233                         print_exc(file=stdout)
234                         quitMainloop(5)
235
236         def instantiateDialog(self, screen, *arguments, **kwargs):
237                 return self.doInstantiateDialog(screen, arguments, kwargs, self.desktop)
238
239         def deleteDialog(self, screen):
240                 screen.hide()
241                 screen.doClose()
242
243         def instantiateSummaryDialog(self, screen, *arguments, **kwargs):
244                 return self.doInstantiateDialog(screen, arguments, kwargs, self.summary_desktop)
245
246         def doInstantiateDialog(self, screen, arguments, kwargs, desktop):
247                 # create dialog
248
249                 try:
250                         dlg = self.create(screen, arguments, **kwargs)
251                 except:
252                         print 'EXCEPTION IN DIALOG INIT CODE, ABORTING:'
253                         print '-'*60
254                         print_exc(file=stdout)
255                         quitMainloop(5)
256                         print '-'*60
257
258                 if dlg is None:
259                         return
260
261                 # read skin data
262                 readSkin(dlg, None, dlg.skinName, desktop)
263
264                 # create GUI view of this dialog
265                 assert desktop is not None
266
267                 dlg.setDesktop(desktop)
268                 dlg.applySkin()
269
270                 return dlg
271
272         def pushCurrent(self):
273                 if self.current_dialog is not None:
274                         self.dialog_stack.append((self.current_dialog, self.current_dialog.shown))
275                         self.execEnd(last=False)
276
277         def popCurrent(self):
278                 if self.dialog_stack:
279                         (self.current_dialog, do_show) = self.dialog_stack.pop()
280                         self.execBegin(first=False, do_show=do_show)
281                 else:
282                         self.current_dialog = None
283
284         def execDialog(self, dialog):
285                 self.pushCurrent()
286                 self.current_dialog = dialog
287                 self.current_dialog.isTmp = False
288                 self.current_dialog.callback = None # would cause re-entrancy problems.
289                 self.execBegin()
290
291         def openWithCallback(self, callback, screen, *arguments, **kwargs):
292                 dlg = self.open(screen, *arguments, **kwargs)
293                 dlg.callback = callback
294                 return dlg
295
296         def open(self, screen, *arguments, **kwargs):
297                 if self.dialog_stack and not self.in_exec:
298                         raise RuntimeError("modal open are allowed only from a screen which is modal!")
299                         # ...unless it's the very first screen.
300
301                 self.pushCurrent()
302                 dlg = self.current_dialog = self.instantiateDialog(screen, *arguments, **kwargs)
303                 dlg.isTmp = True
304                 dlg.callback = None
305                 self.execBegin()
306                 return dlg
307
308         def close(self, screen, *retval):
309                 if not self.in_exec:
310                         print "close after exec!"
311                         return
312
313                 # be sure that the close is for the right dialog!
314                 # if it's not, you probably closed after another dialog
315                 # was opened. this can happen if you open a dialog
316                 # onExecBegin, and forget to do this only once.
317                 # after close of the top dialog, the underlying will
318                 # gain focus again (for a short time), thus triggering
319                 # the onExec, which opens the dialog again, closing the loop.
320                 assert screen == self.current_dialog
321
322                 self.current_dialog.returnValue = retval
323                 self.delay_timer.start(0, 1)
324                 self.execEnd()
325
326         def pushSummary(self):
327                 if self.summary is not None:
328                         self.summary.hide()
329                 self.summary_stack.append(self.summary)
330                 self.summary = None
331
332         def popSummary(self):
333                 if self.summary is not None:
334                         self.summary.doClose()
335                 self.summary = self.summary_stack.pop()
336                 if self.summary is not None:
337                         self.summary.show()
338
339 profile("Standby,PowerKey")
340 import Screens.Standby
341 from Screens.Menu import MainMenu, mdom
342 from GlobalActions import globalActionMap
343
344 class PowerKey:
345         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
346
347         def __init__(self, session):
348                 self.session = session
349                 globalActionMap.actions["power_down"]=self.powerdown
350                 globalActionMap.actions["power_up"]=self.powerup
351                 globalActionMap.actions["power_long"]=self.powerlong
352                 globalActionMap.actions["deepstandby"]=self.shutdown # frontpanel long power button press
353                 self.standbyblocked = 1
354
355         def MenuClosed(self, *val):
356                 self.session.infobar = None
357
358         def shutdown(self):
359                 print "PowerOff - Now!"
360                 if not Screens.Standby.inTryQuitMainloop and self.session.current_dialog and self.session.current_dialog.ALLOW_SUSPEND:
361                         self.session.open(Screens.Standby.TryQuitMainloop, 1)
362
363         def powerlong(self):
364                 if Screens.Standby.inTryQuitMainloop or (self.session.current_dialog and not self.session.current_dialog.ALLOW_SUSPEND):
365                         return
366                 self.doAction(action = config.usage.on_long_powerpress.value)
367
368         def doAction(self, action):
369                 self.standbyblocked = 1
370                 if action == "shutdown":
371                         self.shutdown()
372                 elif action == "show_menu":
373                         print "Show shutdown Menu"
374                         root = mdom.getroot()
375                         for x in root.findall("menu"):
376                                 y = x.find("id")
377                                 if y is not None:
378                                         id = y.get("val")
379                                         if id and id == "shutdown":
380                                                 self.session.infobar = self
381                                                 menu_screen = self.session.openWithCallback(self.MenuClosed, MainMenu, x)
382                                                 menu_screen.setTitle(_("Standby / Restart"))
383                                                 return
384                 elif action == "standby":
385                         self.standby()
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