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