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