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