ChannelSelection.py: small fix for bug #420
[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
367                 self.standbyblocked = 1
368                 action = config.usage.on_long_powerpress.value
369                 if action == "shutdown":
370                         self.shutdown()
371                 elif action == "show_menu":
372                         print "Show shutdown Menu"
373                         root = mdom.getroot()
374                         for x in root.findall("menu"):
375                                 y = x.find("id")
376                                 if y is not None:
377                                         id = y.get("val")
378                                         if id and id == "shutdown":
379                                                 self.session.infobar = self
380                                                 menu_screen = self.session.openWithCallback(self.MenuClosed, MainMenu, x)
381                                                 menu_screen.setTitle(_("Standby / Restart"))
382                                                 return
383
384         def powerdown(self):
385                 self.standbyblocked = 0
386
387         def powerup(self):
388                 if self.standbyblocked == 0:
389                         self.standbyblocked = 1
390                         self.standby()
391
392         def standby(self):
393                 if not Screens.Standby.inStandby and self.session.current_dialog and self.session.current_dialog.ALLOW_SUSPEND and self.session.in_exec:
394                         self.session.open(Screens.Standby.Standby)
395
396 profile("Scart")
397 from Screens.Scart import Scart
398
399 class AutoScartControl:
400         def __init__(self, session):
401                 self.force = False
402                 self.current_vcr_sb = eAVSwitch.getInstance().getVCRSlowBlanking()
403                 if self.current_vcr_sb and config.av.vcrswitch.value:
404                         self.scartDialog = session.instantiateDialog(Scart, True)
405                 else:
406                         self.scartDialog = session.instantiateDialog(Scart, False)
407                 config.av.vcrswitch.addNotifier(self.recheckVCRSb)
408                 eAVSwitch.getInstance().vcr_sb_notifier.get().append(self.VCRSbChanged)
409
410         def recheckVCRSb(self, configElement):
411                 self.VCRSbChanged(self.current_vcr_sb)
412
413         def VCRSbChanged(self, value):
414                 #print "vcr sb changed to", value
415                 self.current_vcr_sb = value
416                 if config.av.vcrswitch.value or value > 2:
417                         if value:
418                                 self.scartDialog.showMessageBox()
419                         else:
420                                 self.scartDialog.switchToTV()
421
422 profile("Load:CI")
423 from enigma import eDVBCIInterfaces
424 from Screens.Ci import CiHandler
425
426 profile("Load:VolumeControl")
427 from Components.VolumeControl import VolumeControl
428
429 def runScreenTest():
430         config.misc.startCounter.value += 1
431
432         profile("readPluginList")
433         plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
434
435         profile("Init:Session")
436         nav = Navigation(config.misc.isNextRecordTimerAfterEventActionAuto.value)
437         session = Session(desktop = getDesktop(0), summary_desktop = getDesktop(1), navigation = nav)
438
439         CiHandler.setSession(session)
440
441         screensToRun = [ p.__call__ for p in plugins.getPlugins(PluginDescriptor.WHERE_WIZARD) ]
442
443         profile("wizards")
444         screensToRun += wizardManager.getWizards()
445
446         screensToRun.append((100, Screens.InfoBar.InfoBar))
447
448         screensToRun.sort()
449
450         ePythonConfigQuery.setQueryFunc(configfile.getResolvedKey)
451
452 #       eDVBCIInterfaces.getInstance().setDescrambleRules(0 # Slot Number
453 #               ,(      ["1:0:1:24:4:85:C00000:0:0:0:"], #service_list
454 #                       ["PREMIERE"], #provider_list,
455 #                       [] #caid_list
456 #               ));
457
458         def runNextScreen(session, screensToRun, *result):
459                 if result:
460                         quitMainloop(*result)
461                         return
462
463                 screen = screensToRun[0][1]
464                 args = screensToRun[0][2:]
465
466                 if screensToRun:
467                         session.openWithCallback(boundFunction(runNextScreen, session, screensToRun[1:]), screen, *args)
468                 else:
469                         session.open(screen, *args)
470
471         runNextScreen(session, screensToRun)
472
473         profile("Init:VolumeControl")
474         vol = VolumeControl(session)
475         profile("Init:PowerKey")
476         power = PowerKey(session)
477
478         # we need session.scart to access it from within menu.xml
479         session.scart = AutoScartControl(session)
480
481         profile("RunReactor")
482         profile_final()
483         runReactor()
484
485         config.misc.startCounter.save()
486
487         profile("wakeup")
488         from time import time, strftime, localtime
489         from Tools.DreamboxHardware import setFPWakeuptime, getFPWakeuptime, setRTCtime
490         #get currentTime
491         nowTime = time()
492         wakeupList = [
493                 x for x in ((session.nav.RecordTimer.getNextRecordingTime(), 0, session.nav.RecordTimer.isNextRecordAfterEventActionAuto()),
494                                         (session.nav.RecordTimer.getNextZapTime(), 1),
495                                         (plugins.getNextWakeupTime(), 2))
496                 if x[0] != -1
497         ]
498         wakeupList.sort()
499         recordTimerWakeupAuto = False
500         if wakeupList:
501                 from time import strftime
502                 startTime = wakeupList[0]
503                 if (startTime[0] - nowTime) < 270: # no time to switch box back on
504                         wptime = nowTime + 30  # so switch back on in 30 seconds
505                 else:
506                         wptime = startTime[0] - 240
507                 if not config.misc.useTransponderTime.value:
508                         print "dvb time sync disabled... so set RTC now to current linux time!", strftime("%Y/%m/%d %H:%M", localtime(nowTime))
509                         setRTCtime(nowTime)
510                 print "set wakeup time to", strftime("%Y/%m/%d %H:%M", localtime(wptime))
511                 setFPWakeuptime(wptime)
512                 recordTimerWakeupAuto = startTime[1] == 0 and startTime[2]
513         config.misc.isNextRecordTimerAfterEventActionAuto.value = recordTimerWakeupAuto
514         config.misc.isNextRecordTimerAfterEventActionAuto.save()
515
516         profile("stopService")
517         session.nav.stopService()
518         profile("nav shutdown")
519         session.nav.shutdown()
520
521         profile("configfile.save")
522         configfile.save()
523
524         return 0
525
526 profile("Init:skin")
527 import skin
528 skin.loadSkinData(getDesktop(0))
529
530 profile("InputDevice")
531 import Components.InputDevice
532 Components.InputDevice.InitInputDevices()
533
534 profile("AVSwitch")
535 import Components.AVSwitch
536 Components.AVSwitch.InitAVSwitch()
537
538 profile("RecordingConfig")
539 import Components.RecordingConfig
540 Components.RecordingConfig.InitRecordingConfig()
541
542 profile("UsageConfig")
543 import Components.UsageConfig
544 Components.UsageConfig.InitUsageConfig()
545
546 profile("keymapparser")
547 import keymapparser
548 keymapparser.readKeymap(config.usage.keymap.value)
549
550 profile("Network")
551 import Components.Network
552 Components.Network.InitNetwork()
553
554 profile("LCD")
555 import Components.Lcd
556 Components.Lcd.InitLcd()
557
558 profile("SetupDevices")
559 import Components.SetupDevices
560 Components.SetupDevices.InitSetupDevices()
561
562 profile("RFMod")
563 import Components.RFmod
564 Components.RFmod.InitRFmod()
565
566 profile("Init:CI")
567 import Screens.Ci
568 Screens.Ci.InitCiConfig()
569
570 #from enigma import dump_malloc_stats
571 #t = eTimer()
572 #t.callback.append(dump_malloc_stats)
573 #t.start(1000)
574
575 # first, setup a screen
576 try:
577         runScreenTest()
578
579         plugins.shutdown()
580
581         from Components.ParentalControl import parentalControl
582         parentalControl.save()
583 except:
584         print 'EXCEPTION IN PYTHON STARTUP CODE:'
585         print '-'*60
586         print_exc(file=stdout)
587         quitMainloop(5)
588         print '-'*60