4.5.0r6
[enigma2.git] / usr / lib / enigma2 / python / mytest.py
1 from __future__ import division
2 from __future__ import print_function
3
4 try:
5         import twisted.python.runtime
6         twisted.python.runtime.platform.supportsThreads = lambda: True
7
8         import e2reactor
9         e2reactor.install()
10 except:
11         pass
12
13 import enigma
14
15 from enigma import ePythonConfigQuery
16 from Components.config import configfile
17 from Screens.SetupGuide import SetupGuide
18 queryFunc_conn = ePythonConfigQuery.getQueryFuncSignal().connect(configfile.getResolvedKey)
19
20 def gPixmapPtr_deref(self):
21         print("gPixmapPtr.__deref__() is deprecated please completely remove the \".__deref__()\" call!")
22         import traceback
23         traceback.print_stack(limit = 2)
24         return self
25
26 enigma.gPixmapPtr.__deref__ = gPixmapPtr_deref
27
28 # allow None as pixmap parameter for setPixmap
29 ePixmap_setPixmap_org = enigma.ePixmap.setPixmap
30 def ePixmap_setPixmap(self, pixmap):
31         if pixmap is None:
32                 print("ePixmap.setPixmap(None) is deprecated please use ePixmap.setPixmap(enigma.gPixmapPtr())!")
33                 import traceback
34                 traceback.print_stack(limit = 2)
35                 pm = enigma.gPixmapPtr()
36                 ePixmap_setPixmap_org(self, pm)
37         else:
38                 ePixmap_setPixmap_org(self, pixmap)
39 enigma.ePixmap.setPixmap = ePixmap_setPixmap
40
41 # allow None as pixmap parameter for setPixmap
42 eSlider_setPixmap_org = enigma.eSlider.setPixmap
43 def eSlider_setPixmap(self, pixmap):
44         if pixmap is None:
45                 print("eSlider.setPixmap(None) is deprecated please use eSlider.setPixmap(enigma.gPixmapPtr())!")
46                 import traceback
47                 traceback.print_stack(limit = 2)
48                 pm = enigma.gPixmapPtr()
49                 eSlider_setPixmap_org(self, pm)
50         else:
51                 eSlider_setPixmap_org(self, pixmap)
52 enigma.eSlider.setPixmap = eSlider_setPixmap
53
54 # allow None as pixmap parameter for setBackgroundPixmap
55 eSlider_setBackgroundPixmap_org = enigma.eSlider.setBackgroundPixmap
56 def eSlider_setBackgroundPixmap(self, pixmap):
57         if pixmap is None:
58                 print("eSlider.setBackgroundPixmap(None) is deprecated please use eSlider.setBackgroundPixmap(enigma.gPixmapPtr())!")
59                 import traceback
60                 traceback.print_stack(limit = 2)
61                 pm = enigma.gPixmapPtr()
62                 eSlider_setBackgroundPixmap_org(self, pm)
63         else:
64                 eSlider_setBackgroundPixmap_org(self, pixmap)
65 enigma.eSlider.setBackgroundPixmap = eSlider_setBackgroundPixmap
66
67 # allow None as pixmap parameter for setPointer
68 ePositionGauge_setPointer_org = enigma.ePositionGauge.setPointer
69 def ePositionGauge_setPointer(self, which, pixmap, center):
70         if pixmap is None:
71                 print("ePositionGauge.setPointer(which, None, center) is deprecated please use ePositionGauge.setPointer(which, enigma.gPixmapPtr(), center)!")
72                 import traceback
73                 traceback.print_stack(limit = 2)
74                 pm = enigma.gPixmapPtr()
75                 ePositionGauge_setPointer_org(self, which, pm, center)
76         else:
77                 ePositionGauge_setPointer_org(self, which, pixmap, center)
78 enigma.ePositionGauge.setPointer = ePositionGauge_setPointer
79
80 def iUriService_ptrValid(self):
81         return True
82 enigma.iUriService.ptrValid = iUriService_ptrValid
83
84 from Tools.Profile import profile, profile_final
85
86 profile("PYTHON_START")
87
88 from enigma import runMainloop, eDVBDB, eTimer, quitMainloop, \
89         getDesktop, eAVSwitch, eServiceEvent, \
90         eEPGCache
91
92 profile("LOAD:resourcemanager")
93 from Components.ResourceManager import resourcemanager
94
95 profile("LOAD:api")
96 from API import api
97
98 profile("ImageDefaults")
99 from Components.DreamInfoHandler import ImageDefaultInstaller
100 ImageDefaultInstaller()
101
102 profile("LOAD:harddiskmanager")
103 from Components.Harddisk import harddiskmanager
104
105 profile("LANGUAGE")
106 from Components.Language import language
107
108 def setEPGLanguage():
109         print("language set to", language.getLanguage())
110         eServiceEvent.setEPGLanguage(language.getLanguage())
111
112 language.addCallback(setEPGLanguage)
113
114 from traceback import print_exc
115
116 profile("LOAD:InfoBar")
117 import Screens.InfoBar
118 from Screens.SimpleSummary import SimpleSummary
119
120 from sys import stdout, exc_info
121
122 profile("Bouquets")
123 eDVBDB.getInstance().reloadBouquets()
124
125 profile("ParentalControl")
126 from Components.ParentalControl import InitParentalControl
127 InitParentalControl()
128
129 profile("LOAD:Navigation")
130 from Navigation import Navigation
131
132 profile("LOAD:skin")
133 from skin import readSkin, SkinError
134
135 profile("LOAD:Tools")
136 from Tools.Directories import InitFallbackFiles, resolveFilename, SCOPE_CURRENT_SKIN, SCOPE_PLUGINS, SCOPE_CONFIG
137 from Components.config import config, configfile, ConfigText, ConfigYesNo, ConfigInteger, ConfigSelection, NoSave, ConfigSubsection
138 InitFallbackFiles()
139
140 profile("config.misc")
141
142 config.misc.radiopic = ConfigText(default = resolveFilename(SCOPE_CURRENT_SKIN, "radio.mvi"))
143 config.misc.isNextRecordTimerAfterEventActionAuto = ConfigYesNo(default=False)
144 config.misc.useTransponderTime = ConfigYesNo(default=True)
145 config.misc.startCounter = ConfigInteger(default=0) # number of e2 starts...
146 config.misc.standbyCounter = NoSave(ConfigInteger(default=0)) # number of standby
147 config.misc.epgcache_filename = ConfigText(default = resolveFilename(SCOPE_CONFIG, "epg.db"))
148 config.misc.epgcache_timespan = ConfigSelection(default = "28", choices = [("7", _("7 days")), ("14", _("14 days")), ("21", _("21 days")), ("28", _("28 days"))])
149 config.misc.epgcache_outdated_timespan = ConfigInteger(default = 0, limits=(0,96))
150 config.misc.record_io_buffer = ConfigInteger(default=192512*5)
151 config.misc.record_dmx_buffer = ConfigInteger(default=1024*1024)
152 config.misc.prev_wakeup_time = ConfigInteger(default=0)
153 #config.misc.prev_wakeup_time_type is only valid when wakeup_time is not 0
154 config.misc.prev_wakeup_time_type = ConfigInteger(default=0) # 0 = RecordTimer, 1 = SleepTimer, 2 = Plugin
155 config.misc.use_legacy_virtual_subservices_detection = ConfigYesNo(default=False)
156 config.misc.recording_allowed = ConfigYesNo(default=True)
157 config.misc.fileWatchVerboseDebug = ConfigYesNo(default=False)
158
159 #gstreamer User-Agent settings (used by servicemp3)
160 config.mediaplayer = ConfigSubsection()
161 config.mediaplayer.useAlternateUserAgent = NoSave(ConfigYesNo(default=False))
162 config.mediaplayer.alternateUserAgent = ConfigText(default="")
163
164 def setEPGCachePath(configElement):
165         eEPGCache.getInstance().setCacheFile(configElement.value)
166
167 def setEPGCacheTimespan(configElement):
168         eEPGCache.getInstance().setCacheTimespan(int(configElement.value))
169
170 def setOutdatedEPGTimespan(configElement):
171         eEPGCache.getInstance().setOutdatedEPGTimespan(configElement.value)
172
173 #demo code for use of standby enter leave callbacks
174 #def leaveStandby():
175 #       print "!!!!!!!!!!!!!!!!!leave standby"
176
177 #def standbyCountChanged(configElement):
178 #       print "!!!!!!!!!!!!!!!!!enter standby num", configElement.value
179 #       from Screens.Standby import inStandby
180 #       inStandby.onClose.append(leaveStandby)
181
182 #config.misc.standbyCounter.addNotifier(standbyCountChanged, initial_call = False)
183 ####################################################
184
185 def useTransponderTimeChanged(configElement):
186         enigma.eDVBLocalTimeHandler.getInstance().setUseDVBTime(configElement.value)
187 config.misc.useTransponderTime.addNotifier(useTransponderTimeChanged)
188
189 def debugAccelMemoryUsageChanged(configElement):
190         if configElement.value == 'nothing':
191                 enigma.cvar.debug_accel_memory_usage = 0
192         elif configElement.value == 'all':
193                 enigma.cvar.debug_accel_memory_usage = 3
194         elif configElement.value == 'alloc':
195                 enigma.cvar.debug_accel_memory_usage = 1
196         elif configElement.value == 'dealloc':
197                 enigma.cvar.debug_accel_memory_usage = 2
198 config.misc.debug_accel_memory_usage = ConfigSelection(default = "nothing", 
199         choices = [("nothing", _("nothing")), ("alloc", _("allocations")), ("dealloc", _("deallocations")), ("all", _("all"))])
200 config.misc.debug_accel_memory_usage.addNotifier(debugAccelMemoryUsageChanged) 
201
202 def fileWatchVerboseDebugChanged(configElement):
203         enigma.eFileWatch.setVerboseDebug(configElement.value)
204 config.misc.fileWatchVerboseDebug.addNotifier(fileWatchVerboseDebugChanged)
205
206 profile("Twisted")
207 try:
208         from twisted.internet import reactor
209         def runReactor():
210                 reactor.run(installSignalHandlers=False)
211                 reactor.stop()
212                 reactor.doShutdown()
213
214 except ImportError:
215         print("twisted not available")
216         def runReactor():
217                 runMainloop()
218
219 profile("LOAD:API")
220 from API import registerAPIs
221 registerAPIs()
222
223 profile("LOAD:Plugin")
224 # initialize autorun plugins and plugin menu entries
225 from Components.PluginComponent import plugins
226 from Plugins.Plugin import PluginDescriptor
227 plugins.runEarlyPlugins(resolveFilename(SCOPE_PLUGINS))
228
229 profile("LOAD:Wizard")
230 from Screens.Wizard import wizardManager
231 from Screens.DefaultWizard import *
232 from Screens.StartWizard import *
233 from Screens.TutorialWizard import *
234 import Screens.Rc
235 from Tools.BoundFunction import boundFunction
236
237 profile("misc")
238 had = dict()
239
240 def dump(dir, p = ""):
241         if isinstance(dir, dict):
242                 for (entry, val) in dir.items():
243                         dump(val, p + "(dict)/" + entry)
244         if hasattr(dir, "__dict__"):
245                 for name, value in dir.__dict__.items():
246                         if str(value) not in had:
247                                 had[str(value)] = 1
248                                 dump(value, p + "/" + str(name))
249                         else:
250                                 print(p + "/" + str(name) + ":" + str(dir.__class__) + "(cycle)")
251         else:
252                 print(p + ":" + str(dir))
253
254 # + ":" + str(dir.__class__)
255
256 # display
257
258 profile("LOAD:ScreenGlobals")
259 from Screens.SessionGlobals import SessionGlobals
260 from Screens.Screen import Screen
261 profile("Screen")
262
263 # Session.open:
264 # * push current active dialog ('current_dialog') onto stack
265 # * call execEnd for this dialog
266 #   * clear in_exec flag
267 #   * hide screen
268 # * instantiate new dialog into 'current_dialog'
269 #   * create screens, components
270 #   * read, apply skin
271 #   * create GUI for screen
272 # * call execBegin for new dialog
273 #   * set in_exec
274 #   * show gui screen
275 #   * call components' / screen's onExecBegin
276 # ... screen is active, until it calls 'close'...
277 # Session.close:
278 # * assert in_exec
279 # * save return value
280 # * start deferred close handler ('onClose')
281 # * execEnd
282 #   * clear in_exec
283 #   * hide screen
284 # .. a moment later:
285 # Session.doClose:
286 # * destroy screen
287
288 class Session:
289         instance = None
290         @staticmethod
291         def get():
292                 return Session.instance
293
294         def __init__(self, desktop = None, summary_desktop = None, navigation = None):
295                 Session.instance = self
296                 self.desktop = desktop
297                 self.summary_desktop = summary_desktop
298                 self.nav = navigation
299                 self.delay_timer = eTimer()
300                 self.delay_timer_conn = self.delay_timer.timeout.connect(self.processDelay)
301
302                 self.current_player = None
303                 self.current_dialog = None
304                 self.next_dialog = None
305
306                 self.dialog_stack = [ ]
307                 self.fading_dialogs = [ ]
308                 self.summary_stack = [ ]
309                 self.summary = None
310
311                 self.in_exec = False
312
313                 self.screen = SessionGlobals(self)
314
315                 self.shutdown = False
316                 from Components.FrontPanelLed import frontPanelLed
317                 frontPanelLed.init(self)
318                 for p in plugins.getPlugins(PluginDescriptor.WHERE_SESSIONSTART):
319                         p(reason=0, session=self)
320
321         def processDelay(self):
322                 callback = self.current_dialog.callback
323
324                 retval = self.current_dialog.returnValue
325
326                 self.fading_dialogs.append(self.current_dialog)
327                 if self.current_dialog.isTmp:
328                         self.current_dialog._Screen__doClose()
329                 else:
330                         del self.current_dialog.callback
331
332                 self.popCurrent()
333                 if callback is not None:
334                         callback(*retval)
335
336                 if self.next_dialog:
337                         dlg = self.next_dialog
338                         self.next_dialog = None
339                         self.pushCurrent()
340                         self.current_dialog = dlg
341                         self.execBegin()
342
343         def execBegin(self, first=True, do_show=True):
344                 assert not self.in_exec
345                 self.in_exec = True
346                 c = self.current_dialog
347
348                 # when this is an execbegin after a execend of a "higher" dialog,
349                 # popSummary already did the right thing.
350                 if first:
351                         self.pushSummary()
352                         summary = c.createSummary() or SimpleSummary
353                         self.summary = self.instantiateSummaryDialog(summary, c)
354                         if self.summary:
355                                 self.summary.neverAnimate()
356                                 self.summary.show()
357                                 c.addSummary(self.summary)
358
359                 c.saveKeyboardMode()
360                 c.enable(do_show) # we must pass the "do_show" boolean to enable because "show" also can be called from within the enable function
361                 c.execBegin()
362
363                 # when execBegin opened a new dialog, don't bother showing the old one.
364                 if c == self.current_dialog and do_show:
365                         c.show()
366
367         def execEnd(self, last=True, is_dialog=False):
368                 assert self.in_exec
369                 self.in_exec = False
370
371                 self.current_dialog.execEnd()
372                 self.current_dialog.restoreKeyboardMode()
373                 if is_dialog:
374                         self.current_dialog.disable()
375                 else:
376                         self.current_dialog.hide()
377
378                 if last and self.summary:
379                         self.current_dialog.removeSummary(self.summary)
380                         self.popSummary()
381
382         def create(self, screen, arguments, **kwargs):
383                 # creates an instance of 'screen' (which is a class)
384                 try:
385                         return screen(self, *arguments, **kwargs)
386                 except:
387                         errstr = "Screen %s(%s, %s): %s" % (str(screen), str(arguments), str(kwargs), exc_info()[0])
388                         print(errstr)
389                         print_exc(file=stdout)
390                         quitMainloop(5)
391
392         def instantiateDialog(self, screen, *arguments, **kwargs):
393                 return self.doInstantiateDialog(screen, arguments, kwargs, self.desktop)
394
395         def deleteDialog(self, screen):
396                 screen._Screen__doClose(immediate=True)
397
398         def instantiateSummaryDialog(self, screen, *arguments, **kwargs):
399                 if not self.summary_desktop:
400                         return None
401                 return self.doInstantiateDialog(screen, arguments, kwargs, self.summary_desktop)
402
403         def doInstantiateDialog(self, screen, arguments, kwargs, desktop):
404                 # create dialog
405                 z = None
406                 if "zPosition" in kwargs:
407                         z = kwargs["zPosition"]
408                         del kwargs["zPosition"]
409                 try:
410                         dlg = self.create(screen, arguments, **kwargs)
411                 except Exception as e:
412                         print('EXCEPTION IN DIALOG INIT CODE, ABORTING:')
413                         print('-'*60)
414                         print_exc(file=stdout)
415                         if isinstance(e, SkinError):
416                                 print("SKIN ERROR", e)
417                                 print("defaulting to standard skin...")
418                                 config.skin.primary_skin.value = "skin.xml"
419                                 config.skin.primary_skin.save()
420                                 configfile.save()
421                         quitMainloop(5)
422                         print('-'*60)
423
424                 if dlg is None:
425                         return
426
427                 # read skin data
428                 readSkin(dlg, None, dlg.skinName, desktop)
429
430                 # create GUI view of this dialog
431                 assert desktop is not None
432                 if z != None:
433                         dlg.setZPosition(z)
434                 dlg.setDesktop(desktop)
435                 dlg.applySkin()
436
437                 return dlg
438
439         def pushCurrent(self, is_dialog=False):
440                 if self.current_dialog is not None:
441                         self.dialog_stack.append((self.current_dialog, self.current_dialog.shown))
442                         self.execEnd(last=False, is_dialog=is_dialog)
443
444         def popCurrent(self):
445                 if self.dialog_stack:
446                         (self.current_dialog, do_show) = self.dialog_stack.pop()
447                         self.execBegin(first=False, do_show=do_show)
448                 else:
449                         self.current_dialog = None
450
451         def execDialog(self, dialog):
452                 dialog.isTmp = False
453                 dialog.callback = None # would cause re-entrancy problems.
454
455                 if self.delay_timer.isActive():
456                         assert not self.next_dialog
457                         self.next_dialog = dialog
458                 else:
459                         self.pushCurrent()
460                         self.current_dialog = dialog
461                         self.execBegin()
462
463         def openWithCallback(self, callback, screen, *arguments, **kwargs):
464                 dlg = self.open(screen, *arguments, **kwargs)
465                 dlg.callback = callback
466                 return dlg
467
468         def open(self, screen, *arguments, **kwargs):
469                 if self.dialog_stack and not self.in_exec:
470                         raise RuntimeError("modal open are allowed only from a screen which is modal!")
471                         # ...unless it's the very first screen.
472                 is_dialog = False
473                 if self.desktop.isDimmable():
474                         try:
475                                 is_dialog = screen.IS_DIALOG
476                         except:
477                                 pass
478
479                         if "is_dialog" in kwargs:
480                                 is_dialog = kwargs["is_dialog"]
481                                 del kwargs["is_dialog"]
482                 else:
483                         if "is_dialog" in kwargs:
484                                 del kwargs["is_dialog"]
485
486                 custom_animation = None
487                 if "custom_animation" in kwargs:
488                         custom_animation = kwargs["custom_animation"]
489                         del kwargs["custom_animation"]
490
491                 self.pushCurrent(is_dialog=is_dialog)
492                 dlg = self.current_dialog = self.instantiateDialog(screen, *arguments, **kwargs)
493
494                 dlg.isTmp = True
495                 dlg.callback = None
496                 if custom_animation:
497                         dlg.setShowHideAnimation(custom_animation)
498
499                 self.execBegin()
500                 return dlg
501
502         def close(self, screen, *retval):
503                 if not self.in_exec:
504                         print("close after exec!")
505                         return
506
507                 # be sure that the close is for the right dialog!
508                 # if it's not, you probably closed after another dialog
509                 # was opened. this can happen if you open a dialog
510                 # onExecBegin, and forget to do this only once.
511                 # after close of the top dialog, the underlying will
512                 # gain focus again (for a short time), thus triggering
513                 # the onExec, which opens the dialog again, closing the loop.
514                 assert screen == self.current_dialog
515
516                 self.current_dialog.returnValue = retval
517                 self.delay_timer.start(0, 1)
518                 self.execEnd()
519
520         def pushSummary(self):
521                 if self.summary is not None:
522                         self.summary.hide()
523                 self.summary_stack.append(self.summary)
524                 self.summary = None
525
526         def popSummary(self):
527                 if self.summary is not None:
528                         self.summary._Screen__doClose(immediate=True)
529                 self.summary = self.summary_stack.pop()
530                 if self.summary is not None:
531                         self.summary.show()
532
533 profile("Standby,PowerKey")
534 import Screens.Standby
535 from Screens.Menu import MainMenu, mdom
536 from GlobalActions import globalActionMap
537
538 class PowerKey:
539         """ PowerKey stuff - handles the powerkey press and powerkey release actions"""
540
541         def __init__(self, session):
542                 self.session = session
543                 globalActionMap.actions["power_down"]=self.powerdown
544                 globalActionMap.actions["power_up"]=self.powerup
545                 globalActionMap.actions["power_long"]=self.powerlong
546                 globalActionMap.actions["deepstandby"]=self.shutdown # frontpanel long power button press
547                 self.standbyblocked = 1
548
549         def MenuClosed(self, *val):
550                 self.session.infobar = None
551
552         def shutdown(self):
553                 print("PowerOff - Now!")
554                 if not Screens.Standby.inTryQuitMainloop and self.session.current_dialog and self.session.current_dialog.ALLOW_SUSPEND:
555                         self.session.open(Screens.Standby.TryQuitMainloop, 1)
556
557         def powerlong(self):
558                 if Screens.Standby.inTryQuitMainloop or (self.session.current_dialog and not self.session.current_dialog.ALLOW_SUSPEND):
559                         return
560                 self.doAction(action = config.usage.on_long_powerpress.value)
561
562         def doAction(self, action):
563                 self.standbyblocked = 1
564                 if action == "shutdown":
565                         self.shutdown()
566                 elif action == "show_menu":
567                         print("Show shutdown Menu")
568                         root = mdom.getroot()
569                         for x in root.findall("menu"):
570                                 y = x.find("id")
571                                 if y is not None:
572                                         id = y.get("val")
573                                         if id and id == "shutdown":
574                                                 self.session.infobar = self
575                                                 menu_screen = self.session.openWithCallback(self.MenuClosed, MainMenu, x)
576                                                 menu_screen.setTitle(_("Standby / Restart"))
577                                                 return
578                 elif action == "standby":
579                         self.standby()
580
581         def powerdown(self):
582                 self.standbyblocked = 0
583
584         def powerup(self):
585                 if self.standbyblocked == 0:
586                         self.doAction(action = config.usage.on_short_powerpress.value)
587
588         def standby(self):
589                 if not Screens.Standby.inStandby and self.session.current_dialog and self.session.current_dialog.ALLOW_SUSPEND and self.session.in_exec:
590                         self.session.open(Screens.Standby.Standby)
591
592 profile("Scart")
593 from Screens.Scart import Scart
594
595 class AutoScartControl:
596         def __init__(self, session):
597                 self.force = False
598                 self.current_vcr_sb = eAVSwitch.getInstance().getVCRSlowBlanking()
599                 if self.current_vcr_sb and config.av.vcrswitch.value:
600                         self.scartDialog = session.instantiateDialog(Scart, True)
601                 else:
602                         self.scartDialog = session.instantiateDialog(Scart, False)
603                 config.av.vcrswitch.addNotifier(self.recheckVCRSb)
604                 self.avs_conn = eAVSwitch.getInstance().vcr_sb_notifier.connect(self.VCRSbChanged)
605
606         def recheckVCRSb(self, configElement):
607                 self.VCRSbChanged(self.current_vcr_sb)
608
609         def VCRSbChanged(self, value):
610                 #print "vcr sb changed to", value
611                 self.current_vcr_sb = value
612                 if config.av.vcrswitch.value or value > 2:
613                         if value:
614                                 self.scartDialog.showMessageBox()
615                         else:
616                                 self.scartDialog.switchToTV()
617
618 profile("Load:CI")
619 from enigma import eDVBCIInterfaces
620 from Screens.Ci import CiHandler
621
622 profile("Load:VolumeControl")
623 from Components.VolumeControl import VolumeControl
624
625 def runScreenTest():
626         config.misc.startCounter.value += 1
627
628         profile("Init:Session")
629         nav = Navigation(config.misc.isNextRecordTimerAfterEventActionAuto.value)
630         session = Session(desktop = getDesktop(0), summary_desktop = getDesktop(1), navigation = nav)
631
632         from Components.ScreenAnimations import ScreenAnimations
633         ScreenAnimations().loadDefault()
634
635         from Screens.Toast import ToastManager
636         session.toastManager = ToastManager(session)
637
638         CiHandler.setSession(session)
639
640         try:
641                 from Screens.PackageRestoreWizard import PackageRestoreCheck
642                 PackageRestoreCheck(session)
643         except:
644                 pass
645
646         screensToRun = [ p.__call__ for p in plugins.getPlugins(PluginDescriptor.WHERE_WIZARD) ]
647
648         profile("SetupGuide")
649         if config.misc.firstrun.value:
650                 screensToRun.append((20,SetupGuide))
651         screensToRun.append((100, Screens.InfoBar.InfoBar))
652
653         screensToRun.sort()
654
655 #       eDVBCIInterfaces.getInstance().setDescrambleRules(0 # Slot Number
656 #               ,(      ["1:0:1:24:4:85:C00000:0:0:0:"], #service_list
657 #                       ["PREMIERE"], #provider_list,
658 #                       [] #caid_list
659 #               ));
660
661         def runNextScreen(session, screensToRun, *result):
662                 if result:
663                         quitMainloop(*result)
664                         return
665
666                 if screensToRun:
667                         screen = screensToRun[0][1]
668                         args = screensToRun[0][2:]
669
670                         if screensToRun:
671                                 session.openWithCallback(boundFunction(runNextScreen, session, screensToRun[1:]), screen, *args)
672                         else:
673                                 session.open(screen, *args)
674
675         config.misc.epgcache_outdated_timespan.addNotifier(setOutdatedEPGTimespan)
676         config.misc.epgcache_timespan.addNotifier(setEPGCacheTimespan)
677         config.misc.epgcache_filename.addNotifier(setEPGCachePath)
678
679         api.setSession(session)
680
681         runNextScreen(session, screensToRun)
682
683         profile("Init:VolumeControl")
684         vol = VolumeControl(session)
685         profile("Init:PowerKey")
686         power = PowerKey(session)
687
688         # we need session.scart to access it from within menu.xml
689         session.scart = AutoScartControl(session)
690
691         profile("RunReactor")
692         profile_final()
693         from Components.FrontPanelLed import FrontPanelLed
694         runReactor()
695
696         session.shutdown = True
697         FrontPanelLed.shutdown()
698         while session.current_dialog:
699                 if not isinstance(session.current_dialog, Screens.InfoBar.InfoBar):
700                         session.current_dialog.callback = None
701                 Screen.close(session.current_dialog)
702                 session.processDelay()
703
704         config.misc.startCounter.save()
705
706         profile("wakeup")
707         from time import time, strftime, localtime
708         from Tools.DreamboxHardware import setFPWakeuptime, getFPWakeuptime, setRTCtime
709         #get currentTime
710         nowTime = time()
711         wakeup_on_zaptimers = config.usage.standby_zaptimer_wakeup.value
712         wakeupList = sorted([
713                 x for x in ((session.nav.RecordTimer.getNextRecordingTime(), 0, session.nav.RecordTimer.isNextRecordAfterEventActionAuto()),
714                                         (session.nav.RecordTimer.getNextZapTime(), 1),
715                                         (plugins.getNextWakeupTime(), 2))
716                 if x[0] != -1 and (x[1] != 1 or wakeup_on_zaptimers)
717         ])
718         recordTimerWakeupAuto = False
719         if wakeupList:
720                 from time import strftime
721                 startTime = wakeupList[0]
722                 if (startTime[0] - nowTime) < 270: # no time to switch box back on
723                         wptime = nowTime + 30  # so switch back on in 30 seconds
724                 else:
725                         wptime = startTime[0] - 240
726                 if not config.misc.useTransponderTime.value:
727                         print("dvb time sync disabled... so set RTC now to current linux time!", strftime("%Y/%m/%d %H:%M", localtime(nowTime)))
728                         setRTCtime(nowTime)
729                 print("set wakeup time to", strftime("%Y/%m/%d %H:%M", localtime(wptime)))
730                 setFPWakeuptime(wptime)
731                 recordTimerWakeupAuto = startTime[1] == 0 and startTime[2]
732                 config.misc.prev_wakeup_time.value = startTime[0]
733                 config.misc.prev_wakeup_time_type.value = startTime[1]
734                 config.misc.prev_wakeup_time_type.save()
735         else:
736                 config.misc.prev_wakeup_time.value = 0
737         config.misc.prev_wakeup_time.save()
738         config.misc.isNextRecordTimerAfterEventActionAuto.value = recordTimerWakeupAuto
739         config.misc.isNextRecordTimerAfterEventActionAuto.save()
740
741         profile("stopService")
742         session.nav.stopService()
743         profile("nav shutdown")
744         session.nav.shutdown()
745
746         profile("configfile.save")
747         configfile.save()
748
749         return 0
750
751 profile("Init:skin")
752 import skin
753 skin.loadSkinData(getDesktop(0))
754
755 profile("InputDevice")
756 import Components.InputDevice
757 Components.InputDevice.InitInputDevices()
758
759 profile("AVSwitch")
760 import Components.AVSwitch
761 Components.AVSwitch.InitAVSwitch()
762
763 profile("RecordingConfig")
764 import Components.RecordingConfig
765 Components.RecordingConfig.InitRecordingConfig()
766
767 profile("UsageConfig")
768 import Components.UsageConfig
769 Components.UsageConfig.BaseInitUsageConfig()
770 language.addCallback(Components.UsageConfig.FinalInitUsageConfig)
771
772 profile("keymapparser")
773 import keymapparser
774 keymapparser.readKeymap(config.usage.keymap.value)
775
776 profile("LCD")
777 import Components.Lcd
778 Components.Lcd.InitLcd()
779
780 profile("SetupDevices")
781 import Components.SetupDevices
782 Components.SetupDevices.InitSetupDevices()
783
784 profile("Init:CI")
785 import Screens.Ci
786 Screens.Ci.InitCiConfig()
787
788 #from enigma import dump_malloc_stats
789 #t = eTimer()
790 #t_conn = t.timeout.connect(dump_malloc_stats)
791 #t.start(1000)
792
793 from threading import Thread
794 class FixDemuxThread(Thread):
795         def __init__(self):
796                 Thread.__init__(self)
797                 self.start()
798
799         def process_num(self, name):
800                 # this is a bad example... please dont use popen in enigma2
801                 from os import popen
802                 f = popen('pidof %s' % name, 'r')
803                 if f is not None:
804                         stdin = f.read()
805                         ret = f.close()
806                         if ret is None:
807                                 return int(stdin)
808                 return None
809
810         def run(self):
811                 # this fixes the infrequently broken recordings (missing ts packets in record file)
812                 # when "rave record buffer overflow detected" messages are visible in kernel log
813                 # (when multiple recordings are running at the same time)
814                 #
815                 # under normal circumstances i would prefer to do this in our kernel hardware drivers
816                 # but the linux people only allow to call sched_setscheduler from GPL kernel modules
817                 # so we must do it via userspace syscall
818                 SCHED_FIFO = 1
819                 import ctypes, ctypes.util
820                 c = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c'))
821                 class _SchedParams(ctypes.Structure):
822                         _fields_ = [('sched_priority', ctypes.c_int)]
823                 # set prio of dmxX processes to same prio as linux threaded interrupts
824                 prio = c.sched_get_priority_max(SCHED_FIFO) // 2 + 1
825                 schedParams = _SchedParams(prio)
826                 params = ctypes.byref(schedParams)
827                 process_num = self.process_num
828                 x = 0
829                 while True:
830                         pid = process_num('dmx%d' %x)
831                         if pid is None:
832                                 break
833                         if c.sched_setscheduler(pid, SCHED_FIFO, params) == -1:
834                                 print("sched_setscheduler failed for dmx%d" %x)
835                         x += 1
836
837 # first, setup a screen
838 try:
839         thread = FixDemuxThread()
840
841         runScreenTest()
842
843         plugins.shutdown()
844
845         from Components.ParentalControl import parentalControl
846         parentalControl.save()
847 except Exception as e:
848         print('EXCEPTION IN PYTHON STARTUP CODE:')
849         print('-'*60)
850         print_exc(file=stdout)
851         if isinstance(e, SkinError):
852                 print("SKIN ERROR", e)
853                 print("defaulting to standard skin...")
854                 config.skin.primary_skin.value = "skin.xml"
855                 config.skin.primary_skin.save()
856                 configfile.save()
857         quitMainloop(5)
858         print('-'*60)