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