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