def prepareRefresh(self): print("[EPGRefresh] About to start refreshing EPG") # Maybe read in configuration try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) self.scanServices = self.generateServicelist(self.services[0], self.services[1]) # Debug print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.refresh()
def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() # Play next service # XXX: we might want to check the return value self.refreshAdapter.play(eServiceReference(service.sref)) # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add( EPGRefreshTimerEntry(time() + delay, self.refresh, nocheck=True))
def nextService(self): print("[EPGRefresh] Maybe zap to next service") try: service = self.scanServices.pop(0) except IndexError: print("[EPGRefresh] Done refreshing EPG") self.cleanUp() else: Notifications.RemovePopup("Parental control") if self.isServiceProtected(service): skipProtectedServices = config.plugins.epgrefresh.skipProtectedServices.value adapter = config.plugins.epgrefresh.adapter.value if (not self.forcedScan ) or skipProtectedServices == "always" or ( self.forcedScan and Screens.Standby.inStandby is None and skipProtectedServices == "bg_only" and (adapter == "pip" or adapter == "main")): print("[EPGRefresh] Service is protected, skipping!") self.refresh() return if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() self.refreshAdapter.play(eServiceReference(service.sref)) delay = service.duration or config.plugins.epgrefresh.interval_seconds.value if not delay: delay = 20 if not self.wait.isActive(): self.wait.start(int(delay * 1000), True)
def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: if self.myEpgCacheInstance is None and config.plugins.epgrefresh.usetimebased.value == False: # get eEPGCache instance if None and eEPGCache-signal based is used print("[EPGRefresh] - myEpgCacheInstance is None. Get it") self.myEpgCacheInstance = eEPGCache.getInstance() self.EpgCacheStateChanged_conn = self.myEpgCacheInstance.cacheState.connect( self._onCacheStateChanged) if self.isServiceProtected(service): if ( not self.forcedScan ) or config.plugins.epgrefresh.skipProtectedServices.value == "always": print("[EPGRefresh] Service is protected, skipping!") self.refresh() return # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() if config.plugins.epgrefresh.usetimebased.value == False: # set timeout timer for eEPGCache-signal based refresh self.epgTimeoutTimer.start(5000, True) # Play next service # XXX: we might want to check the return value self.currentServiceRef = eServiceReference(service.sref) self.refreshAdapter.play(self.currentServiceRef) ref = ServiceReference(service.sref) channelname = ref.getServiceName().replace('\xc2\x86', '').replace( '\xc2\x87', '') print("[EPGRefresh] - Service is: %s" % (str(channelname))) if config.plugins.epgrefresh.usetimebased.value: # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add( EPGRefreshTimerEntry(time() + delay, self.refresh, nocheck=True))
def prepareRefresh(self): if not self.isRefreshAllowed(): return self.isrunning = True print("[EPGRefresh] About to start refreshing EPG") self._initFinishTodos() # Maybe read in configuration try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) self.scanServices = self.generateServicelist(self.services[0], self.services[1]) # Debug print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter try: from plugin import AdjustExtensionsmenu, extStopDescriptor, extPendingServDescriptor, extRunDescriptor AdjustExtensionsmenu(True, extPendingServDescriptor) AdjustExtensionsmenu(True, extStopDescriptor) AdjustExtensionsmenu(False, extRunDescriptor) except: print( "[EPGRefresh] Error while adding 'Stop Running EPG-Refresh' to Extensionmenu" ) print_exc(file=stdout) if config.plugins.epgrefresh.erase.value: print("[EPGRefresh] flushing EPG cache...") from enigma import eEPGCache epgcache = eEPGCache.getInstance() epgcache.flushEPG() self.refresh()
def prepareRefresh(self): print("[EPGRefresh] About to start refreshing EPG") try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) self.scanServices = self.generateServicelist(self.services[0], self.services[1]) print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() if config.plugins.epgrefresh.adapter.value == "main": refreshAdapter = MainPictureAdapter(self.session) elif config.plugins.epgrefresh.adapter.value == "record": refreshAdapter = RecordAdapter(self.session) else: if config.plugins.epgrefresh.adapter.value == "pip": hidden = False elif config.plugins.epgrefresh.adapter.value == "pip_hidden": hidden = True refreshAdapter = PipAdapter(self.session, hide=hidden) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.isrunning = True self.refresh() print("[EPGRefresh] pre start...")
def nextService(self): print("[EPGRefresh] Maybe zap to next service") try: service = self.scanServices.pop(0) except IndexError: print("[EPGRefresh] Done refreshing EPG") self.cleanUp() else: Notifications.RemovePopup("Parental control") if self.isServiceProtected(service): skipProtectedServices = config.plugins.epgrefresh.skipProtectedServices.value adapter = config.plugins.epgrefresh.adapter.value if (not self.forcedScan) or skipProtectedServices == "always" or (self.forcedScan and Screens.Standby.inStandby is None and skipProtectedServices == "bg_only" and (adapter == "pip" or adapter == "main")): print("[EPGRefresh] Service is protected, skipping!") self.refresh() return if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() self.refreshAdapter.play(eServiceReference(service.sref)) delay = service.duration or config.plugins.epgrefresh.interval_seconds.value if not delay: delay = 20 if not self.wait.isActive(): self.wait.start(int(delay*1000), True)
def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby: print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() # Play next service # XXX: we might want to check the return value self.refreshAdapter.play(eServiceReference(service.sref)) # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add(EPGRefreshTimerEntry(time() + delay, self.refresh, nocheck=True))
def prepareRefresh(self): print("[EPGRefresh] About to start refreshing EPG") try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) if len(self.services[0]) == 0 and len(self.services[1]) == 0: self.isrunning = False return self.scanServices = self.generateServicelist(self.services[0], self.services[1]) print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() if config.plugins.epgrefresh.adapter.value == "main": refreshAdapter = MainPictureAdapter(self.session) elif config.plugins.epgrefresh.adapter.value == "record": refreshAdapter = RecordAdapter(self.session) else: if config.plugins.epgrefresh.adapter.value == "pip": hidden = False elif config.plugins.epgrefresh.adapter.value == "pip_hidden": hidden = True refreshAdapter = PipAdapter(self.session, hide=hidden) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.isrunning = True if config.plugins.epgrefresh.erase.value: print("[EPGRefresh] flushing EPG cache...") from enigma import eEPGCache epgcache = eEPGCache.getInstance() epgcache.flushEPG() self.refresh() print("[EPGRefresh] pre start...")
def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: if self.myEpgCacheInstance is None and config.plugins.epgrefresh.usetimebased.value == False: # get eEPGCache instance if None and eEPGCache-signal based is used print("[EPGRefresh] - myEpgCacheInstance is None. Get it") self.myEpgCacheInstance = eEPGCache.getInstance() self.EpgCacheStateChanged_conn = self.myEpgCacheInstance.cacheState.connect(self._onCacheStateChanged) if self.isServiceProtected(service): if (not self.forcedScan) or config.plugins.epgrefresh.skipProtectedServices.value == "always": print("[EPGRefresh] Service is protected, skipping!") self.refresh() return # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() if config.plugins.epgrefresh.usetimebased.value == False: # set timeout timer for eEPGCache-signal based refresh self.epgTimeoutTimer.start(5000, True) # Play next service # XXX: we might want to check the return value self.currentServiceRef = eServiceReference(service.sref) self.refreshAdapter.play(self.currentServiceRef) ref = ServiceReference(service.sref) channelname = ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '') print("[EPGRefresh] - Service is: %s" %(str(channelname))) if config.plugins.epgrefresh.usetimebased.value: # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add(EPGRefreshTimerEntry( time() + delay, self.refresh, nocheck = True) )
scanServices.append(scanservice) channelIdList.append(channelID) del additionalServices[:] # Debug print "[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in scanServices]) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.scanServices = scanServices self.refresh() def cleanUp(self): config.plugins.epgrefresh.lastscan.value = int(time()) config.plugins.epgrefresh.lastscan.save() # Eventually force autotimer to parse epg
class EPGRefresh: """Simple Class to refresh EPGData""" def __init__(self): self.services = (OrderedSet(), OrderedSet()) self.forcedScan = False self.isrunning = False self.DontShutdown = False self.session = None self.checkTimer = eTimer() self.check_finish = False self.wait = eTimer() self.wait.timeout.get().append(self.refresh) self.autotimer_pause = eTimer() self.autotimer_pause.timeout.get().append(self.finish) self.beginOfTimespan = 0 self.refreshAdapter = None self.configMtime = -1 self.readConfiguration() def isRunning(self): return self.isrunning def isServiceProtected(self, service): if not service: return True if not config.ParentalControl.servicepinactive.value: return False refstr = ':'.join(str(service).split(':')[:11]) return parentalControl.getProtectionLevel(refstr) != -1 def readConfiguration(self): if not path.exists(CONFIG): return mtime = path.getmtime(CONFIG) if mtime == self.configMtime: return self.configMtime = mtime self.services[0].clear() self.services[1].clear() configuration = cet_parse(CONFIG).getroot() version = configuration.get("version", None) if version is None: factor = 60 else: factor = 1 for service in configuration.findall("service"): value = service.text if value: pos = value.rfind(':') # don't split alternative service if pos != -1 and not value.startswith('1:134:'): value = value[:pos+1] duration = service.get('duration', None) duration = duration and int(duration)*factor self.services[0].add(EPGRefreshService(value, duration)) for bouquet in configuration.findall("bouquet"): value = bouquet.text if value: duration = bouquet.get('duration', None) duration = duration and int(duration) self.services[1].add(EPGRefreshService(value, duration)) def buildConfiguration(self, webif = False): list = ['<?xml version="1.0" ?>\n<epgrefresh version="', XML_VERSION, '">\n\n'] if webif: for serviceref in self.services[0].union(self.services[1]): ref = ServiceReference(str(serviceref)) list.extend(( ' <e2service>\n', ' <e2servicereference>', str(serviceref), '</e2servicereference>\n', ' <e2servicename>', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n', ' </e2service>\n', )) else: for service in self.services[0]: ref = ServiceReference(service.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <service')) if service.duration is not None: list.extend((' duration="', str(service.duration), '"')) list.extend(('>', stringToXML(service.sref), '</service>\n')) for bouquet in self.services[1]: ref = ServiceReference(bouquet.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <bouquet')) if bouquet.duration is not None: list.extend((' duration="', str(bouquet.duration), '"')) list.extend(('>', stringToXML(bouquet.sref), '</bouquet>\n')) list.append('\n</epgrefresh>') return list def saveConfiguration(self): file = open(CONFIG, 'w') file.writelines(self.buildConfiguration()) file.close() def maybeStopAdapter(self): if self.refreshAdapter: self.refreshAdapter.stop() self.refreshAdapter = None def forceRefresh(self, session = None, dontshutdown = False): print("[EPGRefresh] Forcing start of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False if dontshutdown: self.DontShutdown = True self.forcedScan = True self.prepareRefresh() return True def start(self, session = None): if session is not None: self.session = session if not self.forcedScan: self.stop() epgrefreshtimer.setRefreshTimer(self.createWaitTimer) def stop(self): self.maybeStopAdapter() epgrefreshtimer.clear() if self.wait.isActive(): self.wait.stop() self.forcedScan = False self.isrunning = False self.DontShutdown = False def addServices(self, fromList, toList, channelIds): for scanservice in fromList: service = eServiceReference(scanservice.sref) if (service.flags & eServiceReference.isGroup): service = getBestPlayableServiceReference(eServiceReference(scanservice.sref), eServiceReference()) if not service or not service.valid() or service.type != eServiceReference.idDVB or (service.flags & (eServiceReference.isMarker|eServiceReference.isDirectory)): continue channelID = '%08x%04x%04x' % ( service.getUnsignedData(4), # NAMESPACE service.getUnsignedData(2), # TSID service.getUnsignedData(3), # ONID ) if channelID not in channelIds: toList.append(scanservice) channelIds.append(channelID) def generateServicelist(self, services, bouquets): additionalServices = [] additionalBouquets = [] if config.plugins.epgrefresh.inherit_autotimer.value: try: from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() autotimer.readXml() except Exception as e: print("[EPGRefresh] Could not inherit AutoTimer Services:", e) else: for timer in autotimer.getEnabledTimerList(): additionalServices.extend([EPGRefreshService(x, None) for x in timer.services]) additionalBouquets.extend([EPGRefreshService(x, None) for x in timer.bouquets]) scanServices = [] channelIdList = [] self.addServices(services, scanServices, channelIdList) serviceHandler = eServiceCenter.getInstance() for bouquet in bouquets.union(additionalBouquets): myref = eServiceReference(bouquet.sref) list = serviceHandler.list(myref) if list is not None: while 1: s = list.getNext() if s and s.valid() and s.type == eServiceReference.idDVB: additionalServices.append(EPGRefreshService(s.toString(), None)) else: break del additionalBouquets[:] def sortServices(services): # sort by positions - better for motor unsortedServices = [] for service in services: ref = service.sref position = ref.split(":")[6][:-4] if not position: position = "0" auxiliarySortParameter = int(position, 16) if auxiliarySortParameter > 1800: auxiliarySortParameter = 3600 - auxiliarySortParameter unsortedServices.append((auxiliarySortParameter, service)) unsortedServices.sort() sortedServices = [] for service in unsortedServices: sortedServices.append(service[1]) return sortedServices self.addServices(additionalServices, scanServices, channelIdList) scanServices = sortServices(scanServices) del additionalServices[:] return scanServices def prepareRefresh(self): print("[EPGRefresh] About to start refreshing EPG") try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) if len(self.services[0]) == 0 and len(self.services[1]) == 0: self.isrunning = False return self.scanServices = self.generateServicelist(self.services[0], self.services[1]) print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() if config.plugins.epgrefresh.adapter.value == "main": refreshAdapter = MainPictureAdapter(self.session) elif config.plugins.epgrefresh.adapter.value == "record": refreshAdapter = RecordAdapter(self.session) else: if config.plugins.epgrefresh.adapter.value == "pip": hidden = False elif config.plugins.epgrefresh.adapter.value == "pip_hidden": hidden = True refreshAdapter = PipAdapter(self.session, hide=hidden) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.isrunning = True if config.plugins.epgrefresh.erase.value: print("[EPGRefresh] flushing EPG cache...") from enigma import eEPGCache epgcache = eEPGCache.getInstance() epgcache.flushEPG() self.refresh() print("[EPGRefresh] pre start...") def cleanUp(self): config.plugins.epgrefresh.lastscan.value = int(time()) config.plugins.epgrefresh.lastscan.save() if config.plugins.epgrefresh.save_epg.value: try: from enigma import eEPGCache epgcache = eEPGCache.getInstance() epgcache.save() print("[EPGRefresh] save epgcache...") except: pass if config.plugins.epgrefresh_extra.save_backup.value and config.plugins.epgrefresh_extra.epgcachepath.value != "/etc/enigma2/": from os import system as my_system from os import chmod as my_chmod from os import path as my_path restore_backup = config.misc.epgcache_filename.value + ".backup" if my_path.exists(config.misc.epgcache_filename.value): try: my_system("cp -f %s %s" % (config.misc.epgcache_filename.value, restore_backup)) my_chmod("%s" % (restore_backup), 0644) print("[EPGRefresh] save epgcache backup...") except: pass if config.plugins.epgrefresh.parse_autotimer.value: try: from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() autotimer.readXml() autotimer.parseEPGAsync(simulateOnly=False) if not self.autotimer_pause.isActive(): if config.plugins.epgrefresh.afterevent.value and not self.DontShutdown: try: from Plugins.Extensions.SeriesPlugin.plugin import renameTimer except: self.autotimer_pause.startLongTimer(120) else: self.autotimer_pause.startLongTimer(int(config.plugins.epgrefresh.timeout_shutdown.value)*60) else: self.finish() except Exception as e: print("[EPGRefresh] Could not start AutoTimer:", e) self.finish() else: self.finish() def checkFinish(self): try: if self.checkTimer.callback: self.checkTimer.callback.remove(self.checkFinish) self.checkTimer.stop() print("[EPGRefresh] stop timer...") except: pass self.check_finish = False print("[EPGRefresh] stop check...") def finish(self, *args, **kwargs): if Screens.Standby.inStandby is None and config.plugins.epgrefresh.enablemessage.value: try: Notifications.AddPopup(_("EPG refresh finished."), MessageBox.TYPE_INFO, 4, NOTIFICATIONID) except: pass epgrefreshtimer.cleanup() self.maybeStopAdapter() if not self.check_finish: self.check_finish = True try: self.checkTimer.callback.append(self.checkFinish) self.checkTimer.start(30000, True) self.forcedScan = False print("[EPGRefresh] pause 30 sec...") except: pass else: return self.isrunning = False if config.plugins.epgrefresh.afterevent.value and self.DontShutdown: self.DontShutdown = False self.forcedScan = False print("[EPGRefresh] Return to TV viewing...") return if not self.forcedScan and config.plugins.epgrefresh.afterevent.value and not Screens.Standby.inTryQuitMainloop: self.forcedScan = False print("[EPGRefresh] Shutdown after EPG refresh...") self.session.open( Screens.Standby.TryQuitMainloop, 1 ) self.forcedScan = False self.DontShutdown = False def refresh(self): if self.wait.isActive(): self.wait.stop() if self.forcedScan: self.nextService() else: if self.beginOfTimespan < config.plugins.epgrefresh.lastscan.value: if not self.wait.isActive(): self.isrunning = False return check_standby = False stop_service = False if Screens.Standby.inStandby: check_standby = True if not config.plugins.epgrefresh.force.value and check_standby: rec_time = self.session.nav.RecordTimer.getNextRecordingTime() interval = config.plugins.epgrefresh.interval_seconds.value if interval <= 20: interval = 25 if rec_time > 0 and (rec_time - time()) <= interval: stop_service = True if config.plugins.epgrefresh.force.value or (check_standby and not self.session.nav.RecordTimer.isRecording() and not stop_service): self.nextService() else: if not checkTimespan( config.plugins.epgrefresh.begin.value, config.plugins.epgrefresh.end.value): print("[EPGRefresh] Gone out of timespan while refreshing, sorry!") self.cleanUp() else: print("[EPGRefresh] Box no longer in Standby or Recording started, rescheduling") if check_standby and config.plugins.epgrefresh.adapter.value == "main": self.session.nav.stopService() epgrefreshtimer.add(EPGRefreshTimerEntry( time() + config.plugins.epgrefresh.delay_standby.value*60, self.refresh, nocheck = True) ) def createWaitTimer(self): self.beginOfTimespan = time() epgrefreshtimer.add(EPGRefreshTimerEntry(time() + 30, self.prepareRefresh)) def nextService(self): print("[EPGRefresh] Maybe zap to next service") try: service = self.scanServices.pop(0) except IndexError: print("[EPGRefresh] Done refreshing EPG") self.cleanUp() else: Notifications.RemovePopup("Parental control") if self.isServiceProtected(service): skipProtectedServices = config.plugins.epgrefresh.skipProtectedServices.value adapter = config.plugins.epgrefresh.adapter.value if (not self.forcedScan) or skipProtectedServices == "always" or (self.forcedScan and Screens.Standby.inStandby is None and skipProtectedServices == "bg_only" and (adapter == "pip" or adapter == "main")): print("[EPGRefresh] Service is protected, skipping!") self.refresh() return if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() self.refreshAdapter.play(eServiceReference(service.sref)) delay = service.duration or config.plugins.epgrefresh.interval_seconds.value if not delay: delay = 20 if not self.wait.isActive(): self.wait.start(int(delay*1000), True) def showPendingServices(self, session): if session is None: session = self.session else: if self.session is None: self.session = session if session is None: return False if not self.isRunning(): return False LISTMAX = 10 servcounter = 0 remaining_time = 0 try: servtxt = "" for service in self.scanServices: if self.isServiceProtected(service): skipProtectedServices = config.plugins.epgrefresh.skipProtectedServices.value adapter = config.plugins.epgrefresh.adapter.value if (not self.forcedScan) or skipProtectedServices == "always" or (self.forcedScan and Screens.Standby.inStandby is None and skipProtectedServices == "bg_only" and (adapter == "pip" or adapter == "main")): continue if servcounter <= LISTMAX: ref = ServiceReference(service.sref) txt = ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '') servtxt = servtxt + str(txt) + "\n" servcounter = servcounter + 1 delay = service.duration or config.plugins.epgrefresh.interval_seconds.value if not delay: delay = 20 remaining_time = remaining_time + delay first_text = _("Stop Running EPG-refresh?\n") if servcounter > LISTMAX: servtxt = servtxt + _("%d more services") % (servcounter - LISTMAX) last_text = _("\nRemaining - services: %d / time: %d:%02d min") % (servcounter, remaining_time / 60, remaining_time % 60) if servcounter == 0: text = first_text + _("Scanning last service. Please wait.") else: text = first_text + _("Following Services have to be scanned:") + "\n" + servtxt + last_text session.openWithCallback(self.msgClosed, MessageBox, text, MessageBox.TYPE_YESNO) except: print("[EPGRefresh] showPendingServices Error!") def msgClosed(self, ret=False): if ret: self.stop() if config.plugins.epgrefresh.enabled.value: self.start()
class EPGRefresh: """Simple Class to refresh EPGData""" def __init__(self): # Initialize self.services = (OrderedSet(), OrderedSet()) self.forcedScan = False self.isrunning = False self.doStopRunningRefresh = False self.session = None self.beginOfTimespan = 0 self.refreshAdapter = None # to call additional tasks (from other plugins) self.finishNotifiers = {} # Mtime of configuration files self.configMtime = -1 # Todos after finish self._initFinishTodos() # Read in Configuration self.readConfiguration() def _initFinishTodos(self): self.finishTodos = [ self._ToDoCallAutotimer, self._ToDoAutotimerCalled, self._callFinishNotifiers, self.finish ] def addFinishNotifier(self, notifier): if not callable(notifier): print("[EPGRefresh] notifier" + str(notifier) + " isn't callable") return self.finishNotifiers[str(notifier)] = notifier def removeFinishNotifier(self, notifier): notifierKey = str(notifier) if self.finishNotifiers.has_key(notifierKey): self.finishNotifiers.pop(notifierKey) def readConfiguration(self): # Check if file exists if not path.exists(CONFIG): return # Check if file did not change mtime = path.getmtime(CONFIG) if mtime == self.configMtime: return # Keep mtime self.configMtime = mtime # Empty out list self.services[0].clear() self.services[1].clear() # Open file configuration = cet_parse(CONFIG).getroot() version = configuration.get("version", None) if version is None: factor = 60 else: #if version == "1" factor = 1 # Add References for service in configuration.findall("service"): value = service.text if value: # strip all after last : (custom name) pos = value.rfind(':') # don't split alternative service if value.find('1:134:1') == -1 and pos != -1: value = value[:pos + 1] duration = service.get('duration', None) duration = duration and int(duration) * factor self.services[0].add(EPGRefreshService(value, duration)) for bouquet in configuration.findall("bouquet"): value = bouquet.text if value: duration = bouquet.get('duration', None) duration = duration and int(duration) self.services[1].add(EPGRefreshService(value, duration)) def buildConfiguration(self, webif=False): list = [ '<?xml version="1.0" ?>\n<epgrefresh version="', XML_VERSION, '">\n\n' ] if webif: for serviceref in self.services[0].union(self.services[1]): ref = ServiceReference(str(serviceref)) list.extend(( ' <e2service>\n', ' <e2servicereference>', str(serviceref), '</e2servicereference>\n', ' <e2servicename>', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n', ' </e2service>\n', )) else: for service in self.services[0]: ref = ServiceReference(service.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <service')) if service.duration is not None: list.extend((' duration="', str(service.duration), '"')) list.extend(('>', stringToXML(service.sref), '</service>\n')) for bouquet in self.services[1]: ref = ServiceReference(bouquet.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <bouquet')) if bouquet.duration is not None: list.extend((' duration="', str(bouquet.duration), '"')) list.extend(('>', stringToXML(bouquet.sref), '</bouquet>\n')) list.append('\n</epgrefresh>') return list def saveConfiguration(self): file = open(CONFIG, 'w') file.writelines(self.buildConfiguration()) file.close() def maybeStopAdapter(self): if self.refreshAdapter: self.refreshAdapter.stop() self.refreshAdapter = None def forceRefresh(self, session=None): print("[EPGRefresh] Forcing start of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False self.forcedScan = True self.prepareRefresh() return True def stopRunningRefresh(self, session=None): print("[EPGRefresh] Forcing stop of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False self.doStopRunningRefresh = True def start(self, session=None): if session is not None: self.session = session epgrefreshtimer.setRefreshTimer(self.createWaitTimer) def stop(self): print("[EPGRefresh] Stopping Timer") self.maybeStopAdapter() epgrefreshtimer.clear() def addServices(self, fromList, toList, channelIds): for scanservice in fromList: service = eServiceReference(scanservice.sref) if not service.valid() \ or (service.flags & (eServiceReference.isMarker|eServiceReference.isDirectory)): continue channelID = '%08x%04x%04x' % ( service.getUnsignedData(4), # NAMESPACE service.getUnsignedData(2), # TSID service.getUnsignedData(3), # ONID ) if channelID not in channelIds: toList.append(scanservice) channelIds.append(channelID) def generateServicelist(self, services, bouquets): # This will hold services which are not explicitely in our list additionalServices = [] additionalBouquets = [] # See if we are supposed to read in autotimer services if config.plugins.epgrefresh.inherit_autotimer.value: try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Read in configuration autotimer.readXml() except Exception as e: print("[EPGRefresh] Could not inherit AutoTimer Services:", e) else: # Fetch services for timer in autotimer.getEnabledTimerList(): additionalServices.extend( [EPGRefreshService(x, None) for x in timer.services]) additionalBouquets.extend( [EPGRefreshService(x, None) for x in timer.bouquets]) scanServices = [] channelIdList = [] self.addServices(services, scanServices, channelIdList) serviceHandler = eServiceCenter.getInstance() for bouquet in bouquets.union(additionalBouquets): myref = eServiceReference(bouquet.sref) list = serviceHandler.list(myref) if list is not None: while 1: s = list.getNext() # TODO: I wonder if its sane to assume we get services here (and not just new lists) if s.valid(): additionalServices.append( EPGRefreshService(s.toString(), None)) else: break del additionalBouquets[:] self.addServices(additionalServices, scanServices, channelIdList) del additionalServices[:] return scanServices def isRunning(self): return self.isrunning def isRefreshAllowed(self): if self.isRunning(): message = _( "There is still a refresh running. The Operation isn't allowed at this moment." ) try: if self.session != None: self.session.open(MessageBox, message, \ MessageBox.TYPE_INFO, timeout=10) except: print("[EPGRefresh] Error while opening Messagebox!") print_exc(file=stdout) Notifications.AddPopup(message, MessageBox.TYPE_INFO, 10) return False return True def prepareRefresh(self): if not self.isRefreshAllowed(): return self.isrunning = True print("[EPGRefresh] About to start refreshing EPG") self._initFinishTodos() # Maybe read in configuration try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) self.scanServices = self.generateServicelist(self.services[0], self.services[1]) # Debug print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter try: from plugin import AdjustExtensionsmenu, extStopDescriptor, extPendingServDescriptor, extRunDescriptor AdjustExtensionsmenu(True, extPendingServDescriptor) AdjustExtensionsmenu(True, extStopDescriptor) AdjustExtensionsmenu(False, extRunDescriptor) except: print( "[EPGRefresh] Error while adding 'Stop Running EPG-Refresh' to Extensionmenu" ) print_exc(file=stdout) self.refresh() def cleanUp(self): print("[EPGRefresh] Debug: Cleanup") config.plugins.epgrefresh.lastscan.value = int(time()) config.plugins.epgrefresh.lastscan.save() self.doStopRunningRefresh = False try: from plugin import AdjustExtensionsmenu, housekeepingExtensionsmenu, extStopDescriptor, extPendingServDescriptor AdjustExtensionsmenu(False, extPendingServDescriptor) AdjustExtensionsmenu(False, extStopDescriptor) housekeepingExtensionsmenu( config.plugins.epgrefresh.show_run_in_extensionsmenu, force=True) except: print( "[EPGRefresh] Error while removing 'Stop Running EPG-Refresh' to Extensionmenu:" ) print_exc(file=stdout) # Start Todo-Chain self._nextTodo() def _nextTodo(self, *args, **kwargs): print("[EPGRefresh] Debug: Calling nextTodo") if len(self.finishTodos) > 0: finishTodo = self.finishTodos.pop(0) print("[EPGRefresh] Debug: Call " + str(finishTodo)) finishTodo(*args, **kwargs) def _ToDoCallAutotimer(self): if config.plugins.epgrefresh.parse_autotimer.value != "never": if config.plugins.epgrefresh.parse_autotimer.value in ("ask_yes", "ask_no"): defaultanswer = True if config.plugins.epgrefresh.parse_autotimer.value == "ask_yes" else False if self.forcedScan: # only if we are interactive Notifications.AddNotificationWithCallback(self._ToDoCallAutotimerCB, MessageBox, \ text = _("EPG refresh finished.\nShould AutoTimer be search for new matches?"), \ type = MessageBox.TYPE_YESNO, default = defaultanswer, timeout = 10) else: self._ToDoCallAutotimerCB(parseAT=defaultanswer) else: if self.forcedScan\ and config.plugins.epgrefresh.parse_autotimer.value == "bg_only": self._nextTodo() else: # config.parse_autotimer = always / bg_only self._ToDoCallAutotimerCB(parseAT=True) else: self._nextTodo() def _ToDoCallAutotimerCB(self, parseAT): print("[EPGRefresh] Debug: Call AutoTimer: " + str(parseAT)) if parseAT: try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Parse EPG deferred = autotimer.parseEPGAsync(simulateOnly=False) deferred.addCallback(self._nextTodo) deferred.addErrback(self._autotimerErrback) #except Exception as e: except: from traceback import format_exc #print("[EPGRefresh] Could not start AutoTimer:", e) print("[EPGRefresh] Could not start AutoTimer:" + str(format_exc())) else: self._nextTodo() def _autotimerErrback(self, failure): print("[EPGRefresh] Debug: AutoTimer failed:" + str(failure)) if config.plugins.epgrefresh.enablemessage.value: Notifications.AddPopup(_("AutoTimer failed with error %s") % (str(failure)), \ MessageBox.TYPE_ERROR, 100) self._nextTodo() def _ToDoAutotimerCalled(self, *args, **kwargs): # if config.plugins.epgrefresh.enablemessage.value: # if len(args): # # Autotimer has been started # ret=args[0] # Notifications.AddPopup(_("Found a total of %d matching Events.\n%d Timer were added and\n%d modified,\n%d conflicts encountered,\n%d similars added.") \ # % (ret[0], ret[1], ret[2], len(ret[4]), len(ret[5])), # MessageBox.TYPE_INFO, 10) self._nextTodo() def _callFinishNotifiers(self, *args, **kwargs): for notifier in self.finishNotifiers.keys(): print("[EPGRefresh] Debug: call " + str(notifier)) self.finishNotifiers[notifier]() self._nextTodo() def finish(self, *args, **kwargs): print("[EPGRefresh] Debug: Refresh finished!") if config.plugins.epgrefresh.enablemessage.value: Notifications.AddPopup(_("EPG refresh finished."), MessageBox.TYPE_INFO, 4, ENDNOTIFICATIONID) epgrefreshtimer.cleanup() self.maybeStopAdapter() # shutdown if we're supposed to go to deepstandby and not recording if not self.forcedScan and config.plugins.epgrefresh.afterevent.value \ and not Screens.Standby.inTryQuitMainloop: self.forcedScan = False if Screens.Standby.inStandby: self.session.open(Screens.Standby.TryQuitMainloop, 1) else: Notifications.AddNotificationWithID( "Shutdown", Screens.Standby.TryQuitMainloop, 1) self.forcedScan = False self.isrunning = False self._nextTodo() def refresh(self): if self.doStopRunningRefresh: self.cleanUp() return if self.forcedScan: self.nextService() else: # Abort if a scan finished later than our begin of timespan if self.beginOfTimespan < config.plugins.epgrefresh.lastscan.value: return if config.plugins.epgrefresh.force.value \ or (Screens.Standby.inStandby and \ not self.session.nav.RecordTimer.isRecording()): self.nextService() # We don't follow our rules here - If the Box is still in Standby and not recording we won't reach this line else: if not checkTimespan(config.plugins.epgrefresh.begin.value, config.plugins.epgrefresh.end.value): print( "[EPGRefresh] Gone out of timespan while refreshing, sorry!" ) self.cleanUp() else: print( "[EPGRefresh] Box no longer in Standby or Recording started, rescheduling" ) # Recheck later epgrefreshtimer.add( EPGRefreshTimerEntry( time() + config.plugins.epgrefresh.delay_standby.value * 60, self.refresh, nocheck=True)) def createWaitTimer(self): self.beginOfTimespan = time() # Add wait timer to epgrefreshtimer epgrefreshtimer.add( EPGRefreshTimerEntry(time() + 30, self.prepareRefresh)) def isServiceProtected(self, service): return parentalControl.getProtectionLevel(str(service)) != -1 def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: if self.isServiceProtected(service): if ( not self.forcedScan ) or config.plugins.epgrefresh.skipProtectedServices.value == "always": print("[EPGRefresh] Service is protected, skipping!") self.refresh() return # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() # Play next service # XXX: we might want to check the return value self.refreshAdapter.play(eServiceReference(service.sref)) # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add( EPGRefreshTimerEntry(time() + delay, self.refresh, nocheck=True)) def showPendingServices(self, session): LISTMAX = 10 servcounter = 0 try: servtxt = "" for service in self.scanServices: if self.isServiceProtected(service): if not self.forcedScan or config.plugins.epgrefresh.skipProtectedServices.value == "always": continue if servcounter <= LISTMAX: ref = ServiceReference(service.sref) txt = ref.getServiceName().replace('\xc2\x86', '').replace( '\xc2\x87', '') servtxt = servtxt + str(txt) + "\n" servcounter = servcounter + 1 if servcounter > LISTMAX: servtxt = servtxt + _("%d more services") % (servcounter) session.open(MessageBox, _("Following Services have to be scanned:") \ + "\n" + servtxt, MessageBox.TYPE_INFO) except: print("[EPGRefresh] showPendingServices Error!") print_exc(file=stdout)
class EPGRefresh: """Simple Class to refresh EPGData""" def __init__(self): # Initialize self.services = (OrderedSet(), OrderedSet()) self.forcedScan = False self.isrunning = False self.doStopRunningRefresh = False self.session = None self.beginOfTimespan = 0 self.refreshAdapter = None # to call additional tasks (from other plugins) self.finishNotifiers = { } # Mtime of configuration files self.configMtime = -1 # Todos after finish self._initFinishTodos() # Read in Configuration self.readConfiguration() def _initFinishTodos(self): self.finishTodos = [self._ToDoCallAutotimer, self._ToDoAutotimerCalled, self._callFinishNotifiers, self.finish] def addFinishNotifier(self, notifier): if not callable(notifier): print("[EPGRefresh] notifier" + str(notifier) + " isn't callable") return self.finishNotifiers[str(notifier)] = notifier def removeFinishNotifier(self, notifier): notifierKey = str(notifier) if self.finishNotifiers.has_key(notifierKey): self.finishNotifiers.pop(notifierKey) def readConfiguration(self): # Check if file exists if not path.exists(CONFIG): return # Check if file did not change mtime = path.getmtime(CONFIG) if mtime == self.configMtime: return # Keep mtime self.configMtime = mtime # Empty out list self.services[0].clear() self.services[1].clear() # Open file configuration = cet_parse(CONFIG).getroot() version = configuration.get("version", None) if version is None: factor = 60 else: #if version == "1" factor = 1 # Add References for service in configuration.findall("service"): value = service.text if value: # strip all after last : (custom name) pos = value.rfind(':') # don't split alternative service if pos != -1 and not value.startswith('1:134:'): value = value[:pos+1] duration = service.get('duration', None) duration = duration and int(duration)*factor self.services[0].add(EPGRefreshService(value, duration)) for bouquet in configuration.findall("bouquet"): value = bouquet.text if value: duration = bouquet.get('duration', None) duration = duration and int(duration) self.services[1].add(EPGRefreshService(value, duration)) def buildConfiguration(self, webif = False): list = ['<?xml version="1.0" ?>\n<epgrefresh version="', XML_VERSION, '">\n\n'] if webif: for serviceref in self.services[0].union(self.services[1]): ref = ServiceReference(str(serviceref)) list.extend(( ' <e2service>\n', ' <e2servicereference>', str(serviceref), '</e2servicereference>\n', ' <e2servicename>', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n', ' </e2service>\n', )) else: for service in self.services[0]: ref = ServiceReference(service.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <service')) if service.duration is not None: list.extend((' duration="', str(service.duration), '"')) list.extend(('>', stringToXML(service.sref), '</service>\n')) for bouquet in self.services[1]: ref = ServiceReference(bouquet.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <bouquet')) if bouquet.duration is not None: list.extend((' duration="', str(bouquet.duration), '"')) list.extend(('>', stringToXML(bouquet.sref), '</bouquet>\n')) list.append('\n</epgrefresh>') return list def saveConfiguration(self): file = open(CONFIG, 'w') file.writelines(self.buildConfiguration()) file.close() def maybeStopAdapter(self): if self.refreshAdapter: self.refreshAdapter.stop() self.refreshAdapter = None def forceRefresh(self, session = None): print("[EPGRefresh] Forcing start of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False self.forcedScan = True self.prepareRefresh() return True def stopRunningRefresh(self, session = None): print("[EPGRefresh] Forcing stop of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False self.doStopRunningRefresh = True def start(self, session = None): if session is not None: self.session = session epgrefreshtimer.setRefreshTimer(self.createWaitTimer) def stop(self): print("[EPGRefresh] Stopping Timer") self.maybeStopAdapter() epgrefreshtimer.clear() def addServices(self, fromList, toList, channelIds): for scanservice in fromList: service = eServiceReference(scanservice.sref) if not service.valid() \ or (service.flags & (eServiceReference.isMarker|eServiceReference.isDirectory)): continue channelID = '%08x%04x%04x' % ( service.getUnsignedData(4), # NAMESPACE service.getUnsignedData(2), # TSID service.getUnsignedData(3), # ONID ) if channelID not in channelIds: toList.append(scanservice) channelIds.append(channelID) def generateServicelist(self, services, bouquets): # This will hold services which are not explicitely in our list additionalServices = [] additionalBouquets = [] # See if we are supposed to read in autotimer services if config.plugins.epgrefresh.inherit_autotimer.value: try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Read in configuration autotimer.readXml() except Exception as e: print("[EPGRefresh] Could not inherit AutoTimer Services:", e) else: # Fetch services for timer in autotimer.getEnabledTimerList(): additionalServices.extend([EPGRefreshService(x, None) for x in timer.services]) additionalBouquets.extend([EPGRefreshService(x, None) for x in timer.bouquets]) scanServices = [] channelIdList = [] self.addServices(services, scanServices, channelIdList) serviceHandler = eServiceCenter.getInstance() for bouquet in bouquets.union(additionalBouquets): myref = eServiceReference(bouquet.sref) list = serviceHandler.list(myref) if list is not None: while 1: s = list.getNext() # TODO: I wonder if its sane to assume we get services here (and not just new lists) if s.valid(): additionalServices.append(EPGRefreshService(s.toString(), None)) else: break del additionalBouquets[:] self.addServices(additionalServices, scanServices, channelIdList) del additionalServices[:] return scanServices def isRunning(self): return self.isrunning def isRefreshAllowed(self): if self.isRunning(): message = _("There is still a refresh running. The Operation isn't allowed at this moment.") try: if self.session != None: self.session.open(MessageBox, message, \ MessageBox.TYPE_INFO, timeout=10) except: print("[EPGRefresh] Error while opening Messagebox!") print_exc(file=stdout) Notifications.AddPopup(message, MessageBox.TYPE_INFO, 10, domain = NOTIFICATIONDOMAIN) return False return True def prepareRefresh(self): if not self.isRefreshAllowed(): return self.isrunning = True print("[EPGRefresh] About to start refreshing EPG") self._initFinishTodos() # Maybe read in configuration try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) self.scanServices = self.generateServicelist(self.services[0], self.services[1]) # Debug print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter try: from plugin import AdjustExtensionsmenu, extStopDescriptor, extPendingServDescriptor, extRunDescriptor AdjustExtensionsmenu(True, extPendingServDescriptor) AdjustExtensionsmenu(True, extStopDescriptor) AdjustExtensionsmenu(False, extRunDescriptor) except: print("[EPGRefresh] Error while adding 'Stop Running EPG-Refresh' to Extensionmenu") print_exc(file=stdout) self.refresh() def cleanUp(self): print("[EPGRefresh] Debug: Cleanup") config.plugins.epgrefresh.lastscan.value = int(time()) config.plugins.epgrefresh.lastscan.save() self.doStopRunningRefresh = False try: from plugin import AdjustExtensionsmenu, housekeepingExtensionsmenu, extStopDescriptor, extPendingServDescriptor AdjustExtensionsmenu(False, extPendingServDescriptor) AdjustExtensionsmenu(False, extStopDescriptor) housekeepingExtensionsmenu(config.plugins.epgrefresh.show_run_in_extensionsmenu, force=True) except: print("[EPGRefresh] Error while removing 'Stop Running EPG-Refresh' to Extensionmenu:") print_exc(file=stdout) # Start Todo-Chain self._nextTodo() def _nextTodo(self, *args, **kwargs): print("[EPGRefresh] Debug: Calling nextTodo") if len(self.finishTodos) > 0: finishTodo = self.finishTodos.pop(0) print("[EPGRefresh] Debug: Call " + str(finishTodo)) finishTodo(*args, **kwargs) def _ToDoCallAutotimer(self): if config.plugins.epgrefresh.parse_autotimer.value != "never": if config.plugins.epgrefresh.parse_autotimer.value in ("ask_yes", "ask_no"): defaultanswer = True if config.plugins.epgrefresh.parse_autotimer.value == "ask_yes" else False if self.forcedScan: # only if we are interactive Notifications.AddNotificationWithCallback(self._ToDoCallAutotimerCB, MessageBox, \ text = _("EPG refresh finished.\nShould AutoTimer be search for new matches?"), \ type = MessageBox.TYPE_YESNO, default = defaultanswer, timeout = 10, domain = NOTIFICATIONDOMAIN) else: self._ToDoCallAutotimerCB(parseAT=defaultanswer) else: if self.forcedScan\ and config.plugins.epgrefresh.parse_autotimer.value == "bg_only": self._nextTodo() else: # config.parse_autotimer = always / bg_only self._ToDoCallAutotimerCB(parseAT=True) else: self._nextTodo() def _ToDoCallAutotimerCB(self, parseAT): print("[EPGRefresh] Debug: Call AutoTimer: " + str(parseAT)) if parseAT: try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Parse EPG autotimer.parseEPGAsync(simulateOnly=False).addCallback(self._nextTodo).addErrback(self._autotimerErrback) except: from traceback import format_exc print("[EPGRefresh] Could not start AutoTimer:" + str(format_exc())) else: self._nextTodo() def _autotimerErrback(self, failure): print("[EPGRefresh] Debug: AutoTimer failed:" + str(failure)) if config.plugins.epgrefresh.enablemessage.value: Notifications.AddPopup(_("AutoTimer failed with error %s") % (str(failure)), \ MessageBox.TYPE_ERROR, 10, domain = NOTIFICATIONDOMAIN) self._nextTodo() def _ToDoAutotimerCalled(self, *args, **kwargs): if config.plugins.epgrefresh.enablemessage.value: if len(args): # Autotimer has been started ret=args[0] Notifications.AddPopup(_("Found a total of %d matching Events.\n%d Timer were added and\n%d modified,\n%d conflicts encountered,\n%d similars added.") \ % (ret[0], ret[1], ret[2], len(ret[4]), len(ret[5])), MessageBox.TYPE_INFO, 10, domain = NOTIFICATIONDOMAIN) self._nextTodo() def _callFinishNotifiers(self, *args, **kwargs): for notifier in self.finishNotifiers.keys(): print("[EPGRefresh] Debug: call " + str(notifier)) self.finishNotifiers[notifier]() self._nextTodo() def finish(self, *args, **kwargs): print("[EPGRefresh] Debug: Refresh finished!") if config.plugins.epgrefresh.enablemessage.value: Notifications.AddPopup(_("EPG refresh finished."), MessageBox.TYPE_INFO, 4, ENDNOTIFICATIONID, domain = NOTIFICATIONDOMAIN) epgrefreshtimer.cleanup() self.maybeStopAdapter() # shutdown if we're supposed to go to deepstandby and not recording if not self.forcedScan and config.plugins.epgrefresh.afterevent.value \ and not Screens.Standby.inTryQuitMainloop: self.forcedScan = False if Screens.Standby.inStandby: RecordTimerEntry.TryQuitMainloop() else: Notifications.AddNotificationWithID("Shutdown", Screens.Standby.TryQuitMainloop, 1, domain = NOTIFICATIONDOMAIN) self.forcedScan = False self.isrunning = False self._nextTodo() def refresh(self): if self.doStopRunningRefresh: self.cleanUp() return if self.forcedScan: self.nextService() else: # Abort if a scan finished later than our begin of timespan if self.beginOfTimespan < config.plugins.epgrefresh.lastscan.value: return if config.plugins.epgrefresh.force.value \ or (Screens.Standby.inStandby and \ not self.session.nav.RecordTimer.isRecording()): self.nextService() # We don't follow our rules here - If the Box is still in Standby and not recording we won't reach this line else: if not checkTimespan( config.plugins.epgrefresh.begin.value, config.plugins.epgrefresh.end.value): print("[EPGRefresh] Gone out of timespan while refreshing, sorry!") self.cleanUp() else: print("[EPGRefresh] Box no longer in Standby or Recording started, rescheduling") # Recheck later epgrefreshtimer.add(EPGRefreshTimerEntry( time() + config.plugins.epgrefresh.delay_standby.value*60, self.refresh, nocheck = True) ) def createWaitTimer(self): self.beginOfTimespan = time() # Add wait timer to epgrefreshtimer epgrefreshtimer.add(EPGRefreshTimerEntry(time() + 30, self.prepareRefresh)) def isServiceProtected(self, service): if not config.ParentalControl.configured.value \ or not config.ParentalControl.servicepinactive.value: print("[EPGRefresh] DEBUG: ParentalControl not configured") return False print("[EPGRefresh] DEBUG: ParentalControl ProtectionLevel:" + str(parentalControl.getProtectionLevel(str(service)))) return parentalControl.getProtectionLevel(str(service)) != -1 def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: if self.isServiceProtected(service): if (not self.forcedScan) or config.plugins.epgrefresh.skipProtectedServices.value == "always": print("[EPGRefresh] Service is protected, skipping!") self.refresh() return # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() # Play next service # XXX: we might want to check the return value self.refreshAdapter.play(eServiceReference(service.sref)) # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add(EPGRefreshTimerEntry( time() + delay, self.refresh, nocheck = True) ) def showPendingServices(self, session): LISTMAX = 10 servcounter = 0 try: servtxt = "" for service in self.scanServices: if self.isServiceProtected(service): if not self.forcedScan or config.plugins.epgrefresh.skipProtectedServices.value == "always": continue if servcounter <= LISTMAX: ref = ServiceReference(service.sref) txt = ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '') servtxt = servtxt + str(txt) + "\n" servcounter = servcounter + 1 if servcounter > LISTMAX: servtxt = servtxt + _("%d more services") % (servcounter) session.open(MessageBox, _("Following Services have to be scanned:") \ + "\n" + servtxt, MessageBox.TYPE_INFO) except: print("[EPGRefresh] showPendingServices Error!") print_exc(file=stdout)
class EPGRefresh: """Simple Class to refresh EPGData""" def __init__(self): # Initialize self.services = (OrderedSet(), OrderedSet()) self.forcedScan = False self.session = None self.beginOfTimespan = 0 self.refreshAdapter = None # Mtime of configuration files self.configMtime = -1 # Read in Configuration self.readConfiguration() def readConfiguration(self): # Check if file exists if not path.exists(CONFIG): return # Check if file did not change mtime = path.getmtime(CONFIG) if mtime == self.configMtime: return # Keep mtime self.configMtime = mtime # Empty out list self.services[0].clear() self.services[1].clear() # Open file configuration = cet_parse(CONFIG).getroot() version = configuration.get("version", None) if version is None: factor = 60 else: #if version == "1" factor = 1 # Add References for service in configuration.findall("service"): value = service.text if value: # strip all after last : (custom name) pos = value.rfind(':') if pos != -1: value = value[:pos + 1] duration = service.get('duration', None) duration = duration and int(duration) * factor self.services[0].add(EPGRefreshService(value, duration)) for bouquet in configuration.findall("bouquet"): value = bouquet.text if value: duration = bouquet.get('duration', None) duration = duration and int(duration) self.services[1].add(EPGRefreshService(value, duration)) def buildConfiguration(self, webif=False): list = [ '<?xml version="1.0" ?>\n<epgrefresh version="', XML_VERSION, '">\n\n' ] if webif: for serviceref in self.services[0].union(self.services[1]): ref = ServiceReference(str(serviceref)) list.extend(( ' <e2service>\n', ' <e2servicereference>', str(serviceref), '</e2servicereference>\n', ' <e2servicename>', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n', ' </e2service>\n', )) else: for service in self.services[0]: ref = ServiceReference(service.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <service')) if service.duration is not None: list.extend((' duration="', str(service.duration), '"')) list.extend(('>', stringToXML(service.sref), '</service>\n')) for bouquet in self.services[1]: ref = ServiceReference(bouquet.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <bouquet')) if bouquet.duration is not None: list.extend((' duration="', str(bouquet.duration), '"')) list.extend(('>', stringToXML(bouquet.sref), '</bouquet>\n')) list.append('\n</epgrefresh>') return list def saveConfiguration(self): file = open(CONFIG, 'w') file.writelines(self.buildConfiguration()) file.close() def maybeStopAdapter(self): if self.refreshAdapter: self.refreshAdapter.stop() self.refreshAdapter = None def forceRefresh(self, session=None): print("[EPGRefresh] Forcing start of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False self.forcedScan = True self.prepareRefresh() return True def start(self, session=None): if session is not None: self.session = session epgrefreshtimer.setRefreshTimer(self.createWaitTimer) def stop(self): print("[EPGRefresh] Stopping Timer") self.maybeStopAdapter() epgrefreshtimer.clear() def addServices(self, fromList, toList, channelIds): for scanservice in fromList: service = eServiceReference(scanservice.sref) if not service.valid() \ or (service.flags & (eServiceReference.isMarker|eServiceReference.isDirectory)): continue channelID = '%08x%04x%04x' % ( service.getUnsignedData(4), # NAMESPACE service.getUnsignedData(2), # TSID service.getUnsignedData(3), # ONID ) if channelID not in channelIds: toList.append(scanservice) channelIds.append(channelID) def generateServicelist(self, services, bouquets): # This will hold services which are not explicitely in our list additionalServices = [] additionalBouquets = [] # See if we are supposed to read in autotimer services if config.plugins.epgrefresh.inherit_autotimer.value: removeInstance = False try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: removeInstance = True # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Read in configuration autotimer.readXml() except Exception as e: print("[EPGRefresh] Could not inherit AutoTimer Services:", e) else: # Fetch services for timer in autotimer.getEnabledTimerList(): additionalServices.extend( [EPGRefreshService(x, None) for x in timer.services]) additionalBouquets.extend( [EPGRefreshService(x, None) for x in timer.bouquets]) finally: # Remove instance if there wasn't one before if removeInstance: autotimer = None scanServices = [] channelIdList = [] self.addServices(services, scanServices, channelIdList) serviceHandler = eServiceCenter.getInstance() for bouquet in bouquets.union(additionalBouquets): myref = eServiceReference(bouquet.sref) list = serviceHandler.list(myref) if list is not None: while 1: s = list.getNext() # TODO: I wonder if its sane to assume we get services here (and not just new lists) if s.valid(): additionalServices.append( EPGRefreshService(s.toString(), None)) else: break del additionalBouquets[:] self.addServices(additionalServices, scanServices, channelIdList) del additionalServices[:] return scanServices def prepareRefresh(self): print("[EPGRefresh] About to start refreshing EPG") # Maybe read in configuration try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) self.scanServices = self.generateServicelist(self.services[0], self.services[1]) # Debug print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.refresh() def cleanUp(self): config.plugins.epgrefresh.lastscan.value = int(time()) config.plugins.epgrefresh.lastscan.save() # Eventually force autotimer to parse epg if config.plugins.epgrefresh.parse_autotimer.value: removeInstance = False try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: removeInstance = True # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Parse EPG autotimer.parseEPG() except Exception as e: print("[EPGRefresh] Could not start AutoTimer:", e) finally: # Remove instance if there wasn't one before if removeInstance: autotimer = None # shutdown if we're supposed to go to deepstandby and not recording if not self.forcedScan and config.plugins.epgrefresh.afterevent.value \ and not Screens.Standby.inTryQuitMainloop: self.session.open(Screens.Standby.TryQuitMainloop, 1) if not Screens.Standby.inStandby and not config.plugins.epgrefresh.background and config.plugins.epgrefresh.enablemessage.value: Notifications.AddPopup(_("EPG refresh finished."), MessageBox.TYPE_INFO, 4, NOTIFICATIONID) self.forcedScan = False epgrefreshtimer.cleanup() self.maybeStopAdapter() def refresh(self): if self.forcedScan: self.nextService() else: # Abort if a scan finished later than our begin of timespan if self.beginOfTimespan < config.plugins.epgrefresh.lastscan.value: return if config.plugins.epgrefresh.force.value \ or (Screens.Standby.inStandby and \ not self.session.nav.RecordTimer.isRecording()): self.nextService() # We don't follow our rules here - If the Box is still in Standby and not recording we won't reach this line else: if not checkTimespan(config.plugins.epgrefresh.begin.value, config.plugins.epgrefresh.end.value): print( "[EPGRefresh] Gone out of timespan while refreshing, sorry!" ) self.cleanUp() else: print( "[EPGRefresh] Box no longer in Standby or Recording started, rescheduling" ) # Recheck later epgrefreshtimer.add( EPGRefreshTimerEntry( time() + config.plugins.epgrefresh.delay_standby.value * 60, self.refresh, nocheck=True)) def createWaitTimer(self): self.beginOfTimespan = time() # Add wait timer to epgrefreshtimer epgrefreshtimer.add( EPGRefreshTimerEntry(time() + 30, self.prepareRefresh)) def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() # Play next service # XXX: we might want to check the return value self.refreshAdapter.play(eServiceReference(service.sref)) # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add( EPGRefreshTimerEntry(time() + delay, self.refresh, nocheck=True))
def prepareRefresh(self): print("[EPGRefresh] About to start refreshing EPG") # Maybe read in configuration try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) # This will hold services which are not explicitely in our list additionalServices = [] additionalBouquets = [] # See if we are supposed to read in autotimer services if config.plugins.epgrefresh.inherit_autotimer.value: removeInstance = False try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: removeInstance = True # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Read in configuration autotimer.readXml() except Exception as e: print("[EPGRefresh] Could not inherit AutoTimer Services:", e) else: # Fetch services for timer in autotimer.getEnabledTimerList(): additionalServices.extend( [EPGRefreshService(x, None) for x in timer.services]) additionalBouquets.extend( [EPGRefreshService(x, None) for x in timer.bouquets]) finally: # Remove instance if there wasn't one before if removeInstance: autotimer = None scanServices = [] channelIdList = [] self.addServices(self.services[0], scanServices, channelIdList) serviceHandler = eServiceCenter.getInstance() for bouquet in self.services[1].union(additionalBouquets): myref = eServiceReference(bouquet.sref) list = serviceHandler.list(myref) if list is not None: while 1: s = list.getNext() # TODO: I wonder if its sane to assume we get services here (and not just new lists) if s.valid(): additionalServices.append( EPGRefreshService(s.toString(), None)) else: break del additionalBouquets[:] self.addServices(additionalServices, scanServices, channelIdList) del additionalServices[:] # Debug print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in scanServices])) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.scanServices = scanServices self.refresh()
class EPGRefresh: """Simple Class to refresh EPGData""" def __init__(self): # Initialize self.services = (OrderedSet(), OrderedSet()) self.forcedScan = False self.session = None self.beginOfTimespan = 0 self.refreshAdapter = None # Mtime of configuration files self.configMtime = -1 # Read in Configuration self.readConfiguration() def readConfiguration(self): # Check if file exists if not path.exists(CONFIG): return # Check if file did not change mtime = path.getmtime(CONFIG) if mtime == self.configMtime: return # Keep mtime self.configMtime = mtime # Empty out list self.services[0].clear() self.services[1].clear() # Open file configuration = cet_parse(CONFIG).getroot() version = configuration.get("version", None) if version is None: factor = 60 else: # if version == "1" factor = 1 # Add References for service in configuration.findall("service"): value = service.text if value: # strip all after last : (custom name) pos = value.rfind(":") if pos != -1: value = value[: pos + 1] duration = service.get("duration", None) duration = duration and int(duration) * factor self.services[0].add(EPGRefreshService(value, duration)) for bouquet in configuration.findall("bouquet"): value = bouquet.text if value: duration = bouquet.get("duration", None) duration = duration and int(duration) self.services[1].add(EPGRefreshService(value, duration)) def buildConfiguration(self, webif=False): list = ['<?xml version="1.0" ?>\n<epgrefresh version="', XML_VERSION, '">\n\n'] if webif: for serviceref in self.services[0].union(self.services[1]): ref = ServiceReference(str(serviceref)) list.extend( ( " <e2service>\n", " <e2servicereference>", str(serviceref), "</e2servicereference>\n", " <e2servicename>", stringToXML(ref.getServiceName().replace("\xc2\x86", "").replace("\xc2\x87", "")), "</e2servicename>\n", " </e2service>\n", ) ) else: for service in self.services[0]: ref = ServiceReference(service.sref) list.extend( ( " <!--", stringToXML(ref.getServiceName().replace("\xc2\x86", "").replace("\xc2\x87", "")), "-->\n", " <service", ) ) if service.duration is not None: list.extend((' duration="', str(service.duration), '"')) list.extend((">", stringToXML(service.sref), "</service>\n")) for bouquet in self.services[1]: ref = ServiceReference(bouquet.sref) list.extend( ( " <!--", stringToXML(ref.getServiceName().replace("\xc2\x86", "").replace("\xc2\x87", "")), "-->\n", " <bouquet", ) ) if bouquet.duration is not None: list.extend((' duration="', str(bouquet.duration), '"')) list.extend((">", stringToXML(bouquet.sref), "</bouquet>\n")) list.append("\n</epgrefresh>") return list def saveConfiguration(self): file = open(CONFIG, "w") file.writelines(self.buildConfiguration()) file.close() def maybeStopAdapter(self): if self.refreshAdapter: self.refreshAdapter.stop() self.refreshAdapter = None def forceRefresh(self, session=None): print("[EPGRefresh] Forcing start of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False self.forcedScan = True self.prepareRefresh() return True def start(self, session=None): if session is not None: self.session = session epgrefreshtimer.setRefreshTimer(self.createWaitTimer) def stop(self): print("[EPGRefresh] Stopping Timer") self.maybeStopAdapter() epgrefreshtimer.clear() def addServices(self, fromList, toList, channelIds): for scanservice in fromList: service = eServiceReference(scanservice.sref) if not service.valid() or (service.flags & (eServiceReference.isMarker | eServiceReference.isDirectory)): continue channelID = "%08x%04x%04x" % ( service.getUnsignedData(4), # NAMESPACE service.getUnsignedData(2), # TSID service.getUnsignedData(3), # ONID ) if channelID not in channelIds: toList.append(scanservice) channelIds.append(channelID) def generateServicelist(self, services, bouquets): # This will hold services which are not explicitely in our list additionalServices = [] additionalBouquets = [] # See if we are supposed to read in autotimer services if config.plugins.epgrefresh.inherit_autotimer.value: removeInstance = False try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: removeInstance = True # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Read in configuration autotimer.readXml() except Exception as e: print("[EPGRefresh] Could not inherit AutoTimer Services:", e) else: # Fetch services for timer in autotimer.getEnabledTimerList(): additionalServices.extend([EPGRefreshService(x, None) for x in timer.services]) additionalBouquets.extend([EPGRefreshService(x, None) for x in timer.bouquets]) finally: # Remove instance if there wasn't one before if removeInstance: autotimer = None scanServices = [] channelIdList = [] self.addServices(services, scanServices, channelIdList) serviceHandler = eServiceCenter.getInstance() for bouquet in bouquets.union(additionalBouquets): myref = eServiceReference(bouquet.sref) list = serviceHandler.list(myref) if list is not None: while 1: s = list.getNext() # TODO: I wonder if its sane to assume we get services here (and not just new lists) if s.valid(): additionalServices.append(EPGRefreshService(s.toString(), None)) else: break del additionalBouquets[:] self.addServices(additionalServices, scanServices, channelIdList) del additionalServices[:] return scanServices def prepareRefresh(self): print("[EPGRefresh] About to start refreshing EPG") # Maybe read in configuration try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) self.scanServices = self.generateServicelist(self.services[0], self.services[1]) # Debug print("[EPGRefresh] Services we're going to scan:", ", ".join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.refresh() def cleanUp(self): config.plugins.epgrefresh.lastscan.value = int(time()) config.plugins.epgrefresh.lastscan.save() # Eventually force autotimer to parse epg if config.plugins.epgrefresh.parse_autotimer.value: removeInstance = False try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: removeInstance = True # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Parse EPG autotimer.parseEPG() except Exception as e: print("[EPGRefresh] Could not start AutoTimer:", e) finally: # Remove instance if there wasn't one before if removeInstance: autotimer = None # shutdown if we're supposed to go to deepstandby and not recording if not self.forcedScan and config.plugins.epgrefresh.afterevent.value and not Screens.Standby.inTryQuitMainloop: self.session.open(Screens.Standby.TryQuitMainloop, 1) if ( not Screens.Standby.inStandby and not config.plugins.epgrefresh.background and config.plugins.epgrefresh.enablemessage.value ): Notifications.AddPopup(_("EPG refresh finished."), MessageBox.TYPE_INFO, 4, NOTIFICATIONID) self.forcedScan = False epgrefreshtimer.cleanup() self.maybeStopAdapter() def refresh(self): if self.forcedScan: self.nextService() else: # Abort if a scan finished later than our begin of timespan if self.beginOfTimespan < config.plugins.epgrefresh.lastscan.value: return if config.plugins.epgrefresh.force.value or ( Screens.Standby.inStandby and not self.session.nav.RecordTimer.isRecording() ): self.nextService() # We don't follow our rules here - If the Box is still in Standby and not recording we won't reach this line else: if not checkTimespan(config.plugins.epgrefresh.begin.value, config.plugins.epgrefresh.end.value): print("[EPGRefresh] Gone out of timespan while refreshing, sorry!") self.cleanUp() else: print("[EPGRefresh] Box no longer in Standby or Recording started, rescheduling") # Recheck later epgrefreshtimer.add( EPGRefreshTimerEntry( time() + config.plugins.epgrefresh.delay_standby.value * 60, self.refresh, nocheck=True ) ) def createWaitTimer(self): self.beginOfTimespan = time() # Add wait timer to epgrefreshtimer epgrefreshtimer.add(EPGRefreshTimerEntry(time() + 30, self.prepareRefresh)) def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby: print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() # Play next service # XXX: we might want to check the return value self.refreshAdapter.play(eServiceReference(service.sref)) # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add(EPGRefreshTimerEntry(time() + delay, self.refresh, nocheck=True))
class EPGRefresh: """Simple Class to refresh EPGData""" def __init__(self): # Initialize self.services = (OrderedSet(), OrderedSet()) self.currentServiceRef = None self.forcedScan = False self.isrunning = False self.doStopRunningRefresh = False self.session = None self.beginOfTimespan = 0 self.refreshAdapter = None # to call additional tasks (from other plugins) self.finishNotifiers = { } # Mtime of configuration files self.configMtime = -1 # Todos after finish self._initFinishTodos() # Read in Configuration self.readConfiguration() # Initialise myEpgCacheInstance self.myEpgCacheInstance = None # timeout timer for eEPGCache-signal based refresh self.epgTimeoutTimer = eTimer() self.epgTimeoutTimer_conn = self.epgTimeoutTimer.timeout.connect(self.epgTimeout) # set state for pending services message box self.showPendingServicesMessageShown = False def epgTimeout(self): if eDVBSatelliteEquipmentControl.getInstance().isRotorMoving(): # rotor is moving, timeout raised too early...check again in 5 seconds self.epgTimeoutTimer.start(5000, True) else: # epgcache-signal is not responding...maybe service/transponder is already running or cache was already updated...? step to next entry print("[EPGRefresh] - finished channel without epg update. Reason: epgTimeout") epgrefreshtimer.add(EPGRefreshTimerEntry( time(), self.refresh, nocheck = True) ) # _onCacheStateChanged is called whenever an eEPGCache-signal is sent by enigma2 # 0 = started, 1 = stopped, 2 = aborted, 3 = deferred, 4 = load_finished, 5 = save_finished def _onCacheStateChanged(self, cState): sref = self.currentServiceRef if sref is None: print("[EPGRefresh] - got EPG message but no epgrefresh running... ignore") return if cState.state in (cachestate.load_finished, cachestate.save_finished, cachestate.aborted): print("[EPGRefresh] - assuming the state is not relevant for EPGRefresh. State:" + str(cState.state)) return sdata = sref.getUnsignedData tsid = sdata(2) onid = sdata(3) ns = sdata(4) if cState.tsid != tsid or cState.onid != onid or cState.dvbnamespace != ns: print("[EPGRefresh] - ignored EPG message for wrong transponder %04x:%04x:%08x <> %04x:%04x:%08x" %(cState.tsid, cState.onid, cState.dvbnamespace, tsid, onid, ns)) return print("[EPGRefresh] - state is:" + str(cState.state)) self.epgTimeoutTimer.stop() if cState.state == cachestate.started: print("[EPGRefresh] - EPG update started for transponder %04x:%04x:%08x" %(tsid, onid, ns)) elif cState.state == cachestate.stopped or cState.state == cachestate.deferred: print("[EPGRefresh] - EPG update finished for transponder %04x:%04x:%08x" %(tsid, onid, ns)) if self.refreshAdapter: self.refreshAdapter.stop() epgrefreshtimer.add(EPGRefreshTimerEntry( time(), self.refresh, nocheck = True) ) def _initFinishTodos(self): self.finishTodos = [self._ToDoCallAutotimer, self._ToDoAutotimerCalled, self._callFinishNotifiers, self.finish] def addFinishNotifier(self, notifier): if not callable(notifier): print("[EPGRefresh] notifier" + str(notifier) + " isn't callable") return self.finishNotifiers[str(notifier)] = notifier def removeFinishNotifier(self, notifier): notifierKey = str(notifier) if self.finishNotifiers.has_key(notifierKey): self.finishNotifiers.pop(notifierKey) def readConfiguration(self): # Check if file exists if not path.exists(CONFIG): return # Check if file did not change mtime = path.getmtime(CONFIG) if mtime == self.configMtime: return # Keep mtime self.configMtime = mtime # Empty out list self.services[0].clear() self.services[1].clear() # Open file configuration = cet_parse(CONFIG).getroot() version = configuration.get("version", None) if version is None: factor = 60 else: #if version == "1" factor = 1 # Add References for service in configuration.findall("service"): value = service.text if value: # strip all after last : (custom name) pos = value.rfind(':') # don't split alternative service if pos != -1 and not value.startswith('1:134:'): value = value[:pos+1] duration = service.get('duration', None) duration = duration and int(duration)*factor self.services[0].add(EPGRefreshService(value, duration)) for bouquet in configuration.findall("bouquet"): value = bouquet.text if value: duration = bouquet.get('duration', None) duration = duration and int(duration) self.services[1].add(EPGRefreshService(value, duration)) def buildConfiguration(self, webif = False): list = ['<?xml version="1.0" ?>\n<epgrefresh version="', XML_VERSION, '">\n\n'] if webif: for serviceref in self.services[0].union(self.services[1]): ref = ServiceReference(str(serviceref)) list.extend(( ' <e2service>\n', ' <e2servicereference>', str(serviceref), '</e2servicereference>\n', ' <e2servicename>', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n', ' </e2service>\n', )) else: for service in self.services[0]: ref = ServiceReference(service.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <service')) if service.duration is not None: list.extend((' duration="', str(service.duration), '"')) list.extend(('>', stringToXML(service.sref), '</service>\n')) for bouquet in self.services[1]: ref = ServiceReference(bouquet.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <bouquet')) if bouquet.duration is not None: list.extend((' duration="', str(bouquet.duration), '"')) list.extend(('>', stringToXML(bouquet.sref), '</bouquet>\n')) list.append('\n</epgrefresh>') return list def saveConfiguration(self): file = open(CONFIG, 'w') file.writelines(self.buildConfiguration()) file.close() def maybeStopAdapter(self): if self.refreshAdapter: self.refreshAdapter.stop() self.refreshAdapter = None def forceRefresh(self, session = None): print("[EPGRefresh] Forcing start of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False self.forcedScan = True self.prepareRefresh() return True def stopRunningRefresh(self, session = None): print("[EPGRefresh] Forcing stop of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False self.doStopRunningRefresh = True # stopping the refresh only has an effect when nextService() is still called which is not necessarily happening when signal-based method is used. So, just call it if config.plugins.epgrefresh.usetimebased.value == False: self.nextService() def start(self, session = None): if session is not None: self.session = session epgrefreshtimer.setRefreshTimer(self.createWaitTimer) def stop(self): print("[EPGRefresh] Stopping Timer") self.maybeStopAdapter() epgrefreshtimer.clear() def addServices(self, fromList, toList, channelIds): for scanservice in fromList: service = eServiceReference(scanservice.sref) if not service.valid() \ or service.type != eServiceReference.idDVB \ or (service.flags & (eServiceReference.isMarker|eServiceReference.isDirectory)): continue channelID = '%08x%04x%04x' % ( service.getUnsignedData(4), # NAMESPACE service.getUnsignedData(2), # TSID service.getUnsignedData(3), # ONID ) if channelID not in channelIds: toList.append(scanservice) channelIds.append(channelID) def generateServicelist(self, services, bouquets): # This will hold services which are not explicitely in our list additionalServices = [] additionalBouquets = [] # See if we are supposed to read in autotimer services if config.plugins.epgrefresh.inherit_autotimer.value: try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Read in configuration autotimer.readXml() except Exception as e: print("[EPGRefresh] Could not inherit AutoTimer Services:", e) else: # Fetch services for timer in autotimer.getEnabledTimerList(): additionalServices.extend([EPGRefreshService(x, None) for x in timer.services]) additionalBouquets.extend([EPGRefreshService(x, None) for x in timer.bouquets]) scanServices = [] channelIdList = [] self.addServices(services, scanServices, channelIdList) serviceHandler = eServiceCenter.getInstance() for bouquet in bouquets.union(additionalBouquets): myref = eServiceReference(bouquet.sref) list = serviceHandler.list(myref) if list is not None: while 1: s = list.getNext() # TODO: I wonder if its sane to assume we get services here (and not just new lists) if s.valid() and s.type == eServiceReference.idDVB: additionalServices.append(EPGRefreshService(s.toString(), None)) else: break del additionalBouquets[:] self.addServices(additionalServices, scanServices, channelIdList) del additionalServices[:] return scanServices def isRunning(self): return self.isrunning def isRefreshAllowed(self): if self.isRunning(): message = _("There is still a refresh running. The Operation isn't allowed at this moment.") try: if self.session != None: self.session.open(MessageBox, message, \ MessageBox.TYPE_INFO, timeout=10) except: print("[EPGRefresh] Error while opening Messagebox!") print_exc(file=stdout) Notifications.AddPopup(message, MessageBox.TYPE_INFO, 10, domain = NOTIFICATIONDOMAIN) return False return True def prepareRefresh(self): if not self.isRefreshAllowed(): return self.isrunning = True print("[EPGRefresh] About to start refreshing EPG") self._initFinishTodos() # Maybe read in configuration try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) self.scanServices = self.generateServicelist(self.services[0], self.services[1]) # Debug print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() # NOTE: start notification is handled in adapter initializer if config.plugins.epgrefresh.adapter.value.startswith("pip"): hidden = config.plugins.epgrefresh.adapter.value == "pip_hidden" refreshAdapter = PipAdapter(self.session, hide=hidden) elif config.plugins.epgrefresh.adapter.value.startswith("record"): refreshAdapter = RecordAdapter(self.session) else: refreshAdapter = MainPictureAdapter(self.session) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter try: from plugin import AdjustExtensionsmenu, extStopDescriptor, extPendingServDescriptor, extRunDescriptor AdjustExtensionsmenu(True, extPendingServDescriptor) AdjustExtensionsmenu(True, extStopDescriptor) AdjustExtensionsmenu(False, extRunDescriptor) except: print("[EPGRefresh] Error while adding 'Stop Running EPG-Refresh' to Extensionmenu") print_exc(file=stdout) self.refresh() def cleanUp(self): print("[EPGRefresh] Debug: Cleanup") config.plugins.epgrefresh.lastscan.value = int(time()) config.plugins.epgrefresh.lastscan.save() self.doStopRunningRefresh = False # stop the epgTimeoutTimer - just in case one is running self.epgTimeoutTimer.stop() try: from plugin import AdjustExtensionsmenu, housekeepingExtensionsmenu, extStopDescriptor, extPendingServDescriptor AdjustExtensionsmenu(False, extPendingServDescriptor) AdjustExtensionsmenu(False, extStopDescriptor) housekeepingExtensionsmenu(config.plugins.epgrefresh.show_run_in_extensionsmenu, force=True) except: print("[EPGRefresh] Error while removing 'Stop Running EPG-Refresh' to Extensionmenu:") print_exc(file=stdout) self.currentServiceRef = None # Start Todo-Chain self._nextTodo() def _nextTodo(self, *args, **kwargs): print("[EPGRefresh] Debug: Calling nextTodo") if len(self.finishTodos) > 0: finishTodo = self.finishTodos.pop(0) print("[EPGRefresh] Debug: Call " + str(finishTodo)) finishTodo(*args, **kwargs) def _ToDoCallAutotimer(self): if config.plugins.epgrefresh.parse_autotimer.value != "never": if config.plugins.epgrefresh.parse_autotimer.value in ("ask_yes", "ask_no"): defaultanswer = True if config.plugins.epgrefresh.parse_autotimer.value == "ask_yes" else False if self.forcedScan: # only if we are interactive Notifications.AddNotificationWithCallback(self._ToDoCallAutotimerCB, MessageBox, \ text = _("EPG refresh finished.\nShould AutoTimer be search for new matches?"), \ type = MessageBox.TYPE_YESNO, default = defaultanswer, timeout = 10, domain = NOTIFICATIONDOMAIN) else: self._ToDoCallAutotimerCB(parseAT=defaultanswer) else: if self.forcedScan\ and config.plugins.epgrefresh.parse_autotimer.value == "bg_only": self._nextTodo() else: # config.parse_autotimer = always / bg_only self._ToDoCallAutotimerCB(parseAT=True) else: self._nextTodo() def _ToDoCallAutotimerCB(self, parseAT): print("[EPGRefresh] Debug: Call AutoTimer: " + str(parseAT)) if parseAT: try: # Import Instance from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: # Create an instance from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() # Parse EPG autotimer.parseEPGAsync(simulateOnly=False).addCallback(self._nextTodo).addErrback(self._autotimerErrback) except: from traceback import format_exc print("[EPGRefresh] Could not start AutoTimer:" + str(format_exc())) self._nextTodo() else: self._nextTodo() def _autotimerErrback(self, failure): print("[EPGRefresh] Debug: AutoTimer failed:" + str(failure)) if config.plugins.epgrefresh.enablemessage.value: Notifications.AddPopup(_("AutoTimer failed with error %s") % (str(failure)), \ MessageBox.TYPE_ERROR, 10, domain = NOTIFICATIONDOMAIN) self._nextTodo() def _ToDoAutotimerCalled(self, *args, **kwargs): if config.plugins.epgrefresh.enablemessage.value: if len(args): # Autotimer has been started ret=args[0] try: #try import new advanced AT-message with searchlog-info from Plugins.Extensions.AutoTimer.plugin import showFinishPopup showFinishPopup(ret) except: from traceback import format_exc print("[EPGRefresh] Could not start Autotimer showPopup:" + str(format_exc())) Notifications.AddPopup(_("Found a total of %d matching Events.\n%d Timer were added and\n%d modified,\n%d conflicts encountered,\n%d similars added.") \ % (ret[0], ret[1], ret[2], len(ret[4]), len(ret[5])), MessageBox.TYPE_INFO, 10, domain = NOTIFICATIONDOMAIN) self._nextTodo() def _callFinishNotifiers(self, *args, **kwargs): for notifier in self.finishNotifiers.keys(): print("[EPGRefresh] Debug: call " + str(notifier)) self.finishNotifiers[notifier]() self._nextTodo() def finish(self, *args, **kwargs): if self.showPendingServicesMessageShown: self.msg.close() print("[EPGRefresh] Debug: Refresh finished!") if config.plugins.epgrefresh.enablemessage.value: Notifications.AddPopup(_("EPG refresh finished."), MessageBox.TYPE_INFO, 4, ENDNOTIFICATIONID, domain = NOTIFICATIONDOMAIN) epgrefreshtimer.cleanup() self.maybeStopAdapter() if config.plugins.epgrefresh.epgsave.value: Notifications.AddPopup(_("EPG refresh save."), MessageBox.TYPE_INFO, 4, ENDNOTIFICATIONID, domain = NOTIFICATIONDOMAIN) from enigma import eEPGCache myEpg = None myEpg = eEPGCache.getInstance() myEpg.save() # shutdown if we're supposed to go to deepstandby and not recording if not self.forcedScan and config.plugins.epgrefresh.afterevent.value \ and not Screens.Standby.inTryQuitMainloop: self.forcedScan = False if Screens.Standby.inStandby: RecordTimerEntry.TryQuitMainloop() else: Notifications.AddNotificationWithID("Shutdown", Screens.Standby.TryQuitMainloop, 1, domain = NOTIFICATIONDOMAIN) self.forcedScan = False self.isrunning = False self._nextTodo() def refresh(self): if self.doStopRunningRefresh: self.cleanUp() return if self.forcedScan: self.nextService() else: # Abort if a scan finished later than our begin of timespan if self.beginOfTimespan < config.plugins.epgrefresh.lastscan.value: return if config.plugins.epgrefresh.force.value \ or (Screens.Standby.inStandby and \ not self.session.nav.RecordTimer.isRecording()): self.nextService() # We don't follow our rules here - If the Box is still in Standby and not recording we won't reach this line else: if not checkTimespan( config.plugins.epgrefresh.begin.value, config.plugins.epgrefresh.end.value): print("[EPGRefresh] Gone out of timespan while refreshing, sorry!") self.cleanUp() else: print("[EPGRefresh] Box no longer in Standby or Recording started, rescheduling") # Recheck later epgrefreshtimer.add(EPGRefreshTimerEntry( time() + config.plugins.epgrefresh.delay_standby.value*60, self.refresh, nocheck = True) ) def createWaitTimer(self): self.beginOfTimespan = time() # Add wait timer to epgrefreshtimer epgrefreshtimer.add(EPGRefreshTimerEntry(time() + 30, self.prepareRefresh)) def isServiceProtected(self, service): if not config.ParentalControl.configured.value \ or not config.ParentalControl.servicepinactive.value: print("[EPGRefresh] DEBUG: ParentalControl not configured") return False print("[EPGRefresh] DEBUG: ParentalControl ProtectionLevel:" + str(parentalControl.getProtectionLevel(str(service)))) return parentalControl.getProtectionLevel(str(service)) != -1 def nextService(self): # Debug print("[EPGRefresh] Maybe zap to next service") # update pending services message box (if shown) if self.showPendingServicesMessageShown: print("[EPGRefresh] - MessageBox is shown. Update pending services") self.showPendingServices(self.session) try: # Get next reference service = self.scanServices.pop(0) except IndexError: # Debug print("[EPGRefresh] Done refreshing EPG") # Clean up self.cleanUp() else: if self.myEpgCacheInstance is None and config.plugins.epgrefresh.usetimebased.value == False: # get eEPGCache instance if None and eEPGCache-signal based is used print("[EPGRefresh] - myEpgCacheInstance is None. Get it") self.myEpgCacheInstance = eEPGCache.getInstance() self.EpgCacheStateChanged_conn = self.myEpgCacheInstance.cacheState.connect(self._onCacheStateChanged) if self.isServiceProtected(service): if (not self.forcedScan) or config.plugins.epgrefresh.skipProtectedServices.value == "always": print("[EPGRefresh] Service is protected, skipping!") self.refresh() return # If the current adapter is unable to run in background and we are in fact in background now, # fall back to main picture if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print("[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter") self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() if config.plugins.epgrefresh.usetimebased.value == False: # set timeout timer for eEPGCache-signal based refresh self.epgTimeoutTimer.start(5000, True) # Play next service # XXX: we might want to check the return value self.currentServiceRef = eServiceReference(service.sref) self.refreshAdapter.play(self.currentServiceRef) ref = ServiceReference(service.sref) channelname = ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '') print("[EPGRefresh] - Service is: %s" %(str(channelname))) if config.plugins.epgrefresh.usetimebased.value: # Start Timer delay = service.duration or config.plugins.epgrefresh.interval_seconds.value epgrefreshtimer.add(EPGRefreshTimerEntry( time() + delay, self.refresh, nocheck = True) ) def resetEPG(self, session): self.reset_session=session # remove database if path.exists(config.misc.epgcache_filename.value): remove(config.misc.epgcache_filename.value) # create empty database connection = sqlite.connect(config.misc.epgcache_filename.value, timeout=10) connection.text_factory = str cursor = connection.cursor() cursor.execute("CREATE TABLE T_Service (id INTEGER PRIMARY KEY, sid INTEGER NOT NULL, tsid INTEGER, onid INTEGER, dvbnamespace INTEGER, changed DATETIME NOT NULL DEFAULT current_timestamp)") cursor.execute("CREATE TABLE T_Source (id INTEGER PRIMARY KEY, source_name TEXT NOT NULL, priority INTEGER NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)") cursor.execute("CREATE TABLE T_Title (id INTEGER PRIMARY KEY, hash INTEGER NOT NULL UNIQUE, title TEXT NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)") cursor.execute("CREATE TABLE T_Short_Description (id INTEGER PRIMARY KEY, hash INTEGER NOT NULL UNIQUE, short_description TEXT NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)") cursor.execute("CREATE TABLE T_Extended_Description (id INTEGER PRIMARY KEY, hash INTEGER NOT NULL UNIQUE, extended_description TEXT NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)") cursor.execute("CREATE TABLE T_Event (id INTEGER PRIMARY KEY, service_id INTEGER NOT NULL, begin_time INTEGER NOT NULL, duration INTEGER NOT NULL, source_id INTEGER NOT NULL, dvb_event_id INTEGER, changed DATETIME NOT NULL DEFAULT current_timestamp)") cursor.execute("CREATE TABLE T_Data (event_id INTEGER NOT NULL, title_id INTEGER, short_description_id INTEGER, extended_description_id INTEGER, iso_639_language_code TEXT NOT NULL, changed DATETIME NOT NULL DEFAULT current_timestamp)") cursor.execute("CREATE INDEX data_title ON T_Data (title_id)") cursor.execute("CREATE INDEX data_shortdescr ON T_Data (short_description_id)") cursor.execute("CREATE INDEX data_extdescr ON T_Data (extended_description_id)") cursor.execute("CREATE INDEX service_sid ON T_Service (sid)") cursor.execute("CREATE INDEX event_service_id_begin_time ON T_Event (service_id, begin_time)") cursor.execute("CREATE INDEX event_dvb_id ON T_Event (dvb_event_id)") cursor.execute("CREATE INDEX data_event_id ON T_Data (event_id)") cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_event AFTER DELETE ON T_Event FOR EACH ROW BEGIN DELETE FROM T_Data WHERE event_id = OLD.id; END") cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_service_t_event AFTER DELETE ON T_Service FOR EACH ROW BEGIN DELETE FROM T_Event WHERE service_id = OLD.id; END") cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_data_t_title AFTER DELETE ON T_Data FOR EACH ROW WHEN ((SELECT event_id FROM T_Data WHERE title_id = OLD.title_id LIMIT 1) ISNULL) BEGIN DELETE FROM T_Title WHERE id = OLD.title_id; END") cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_data_t_short_description AFTER DELETE ON T_Data FOR EACH ROW WHEN ((SELECT event_id FROM T_Data WHERE short_description_id = OLD.short_description_id LIMIT 1) ISNULL) BEGIN DELETE FROM T_Short_Description WHERE id = OLD.short_description_id; END") cursor.execute("CREATE TRIGGER tr_on_delete_cascade_t_data_t_extended_description AFTER DELETE ON T_Data FOR EACH ROW WHEN ((SELECT event_id FROM T_Data WHERE extended_description_id = OLD.extended_description_id LIMIT 1) ISNULL) BEGIN DELETE FROM T_Extended_Description WHERE id = OLD.extended_description_id; END") cursor.execute("CREATE TRIGGER tr_on_update_cascade_t_data AFTER UPDATE ON T_Data FOR EACH ROW WHEN (OLD.title_id <> NEW.title_id AND ((SELECT event_id FROM T_Data WHERE title_id = OLD.title_id LIMIT 1) ISNULL)) BEGIN DELETE FROM T_Title WHERE id = OLD.title_id; END") cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('0','Sky Private EPG','0')") cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('1','DVB Now/Next Table','0')") cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('2','DVB Schedule (same Transponder)','0')") cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('3','DVB Schedule Other (other Transponder)','0')") cursor.execute("INSERT INTO T_Source (id,source_name,priority) VALUES('4','Viasat','0')") connection.commit() cursor.close() connection.close() self.myEpgCacheInstance = eEPGCache.getInstance() self.EpgCacheStateChanged_conn = self.myEpgCacheInstance.cacheState.connect(self.resetStateChanged) self.myEpgCacheInstance.load() def resetStateChanged(self, state): if state.state == cachestate.load_finished: self.reset_session.openWithCallback(self.doRestart, MessageBox, \ text = _("Reset")+" "+_("EPG.db")+" "+_("successful")+"\n\n"+_("Restart GUI now?"), \ type = MessageBox.TYPE_YESNO, default = True, timeout = 10) def doRestart(self, answer): if answer is not None: if answer: quitMainloop(3) def showPendingServices(self, session): LISTMAX = 15 servcounter = 0 try: servtxt = "" for service in self.scanServices: if self.isServiceProtected(service): if not self.forcedScan or config.plugins.epgrefresh.skipProtectedServices.value == "always": continue if servcounter < LISTMAX: ref = ServiceReference(service.sref) txt = ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '') servtxt = servtxt + str(txt) + "\n" servcounter = servcounter + 1 if servcounter > LISTMAX: servtxt = servtxt + _("%d more services") % (servcounter-LISTMAX) # open message box only if not already shown if self.showPendingServicesMessageShown == False: self.msg = session.open(MessageBox, _("Following Services have to be scanned:") \ + "\n" + servtxt, MessageBox.TYPE_INFO) # update state for pending services message box on close self.msg.onClose.append(self.setMessageBoxState) self.showPendingServicesMessageShown = True else: self.msg["text"].setText(_("Following Services have to be scanned:") + "\n" + servtxt) except: print("[EPGRefresh] showPendingServices Error!") print_exc(file=stdout) def setMessageBoxState(self): self.showPendingServicesMessageShown = False
class EPGRefresh: """Simple Class to refresh EPGData""" def __init__(self): self.services = (OrderedSet(), OrderedSet()) self.forcedScan = False self.isrunning = False self.DontShutdown = False self.session = None self.checkTimer = eTimer() self.check_finish = False self.wait = eTimer() self.wait.timeout.get().append(self.refresh) self.autotimer_pause = eTimer() self.autotimer_pause.timeout.get().append(self.finish) self.beginOfTimespan = 0 self.refreshAdapter = None self.configMtime = -1 self.readConfiguration() def isRunning(self): return self.isrunning def isServiceProtected(self, service): if not service: return True if not config.ParentalControl.servicepinactive.value: return False refstr = ':'.join(str(service).split(':')[:11]) return parentalControl.getProtectionLevel(refstr) != -1 def readConfiguration(self): if not path.exists(CONFIG): return mtime = path.getmtime(CONFIG) if mtime == self.configMtime: return self.configMtime = mtime self.services[0].clear() self.services[1].clear() configuration = cet_parse(CONFIG).getroot() version = configuration.get("version", None) if version is None: factor = 60 else: factor = 1 for service in configuration.findall("service"): value = service.text if value: pos = value.rfind(':') # don't split alternative service if pos != -1 and not value.startswith('1:134:'): value = value[:pos + 1] duration = service.get('duration', None) duration = duration and int(duration) * factor self.services[0].add(EPGRefreshService(value, duration)) for bouquet in configuration.findall("bouquet"): value = bouquet.text if value: duration = bouquet.get('duration', None) duration = duration and int(duration) self.services[1].add(EPGRefreshService(value, duration)) def buildConfiguration(self, webif=False): list = [ '<?xml version="1.0" ?>\n<epgrefresh version="', XML_VERSION, '">\n\n' ] if webif: for serviceref in self.services[0].union(self.services[1]): ref = ServiceReference(str(serviceref)) list.extend(( ' <e2service>\n', ' <e2servicereference>', str(serviceref), '</e2servicereference>\n', ' <e2servicename>', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '</e2servicename>\n', ' </e2service>\n', )) else: for service in self.services[0]: ref = ServiceReference(service.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <service')) if service.duration is not None: list.extend((' duration="', str(service.duration), '"')) list.extend(('>', stringToXML(service.sref), '</service>\n')) for bouquet in self.services[1]: ref = ServiceReference(bouquet.sref) list.extend((' <!--', stringToXML(ref.getServiceName().replace( '\xc2\x86', '').replace('\xc2\x87', '')), '-->\n', ' <bouquet')) if bouquet.duration is not None: list.extend((' duration="', str(bouquet.duration), '"')) list.extend(('>', stringToXML(bouquet.sref), '</bouquet>\n')) list.append('\n</epgrefresh>') return list def saveConfiguration(self): file = open(CONFIG, 'w') file.writelines(self.buildConfiguration()) file.close() def maybeStopAdapter(self): if self.refreshAdapter: self.refreshAdapter.stop() self.refreshAdapter = None def forceRefresh(self, session=None, dontshutdown=False): print("[EPGRefresh] Forcing start of EPGRefresh") if self.session is None: if session is not None: self.session = session else: return False if dontshutdown: self.DontShutdown = True self.forcedScan = True self.prepareRefresh() return True def start(self, session=None): if session is not None: self.session = session if not self.forcedScan: self.stop() epgrefreshtimer.setRefreshTimer(self.createWaitTimer) def stop(self): self.maybeStopAdapter() epgrefreshtimer.clear() if self.wait.isActive(): self.wait.stop() self.forcedScan = False self.isrunning = False self.DontShutdown = False def addServices(self, fromList, toList, channelIds): for scanservice in fromList: service = eServiceReference(scanservice.sref) if (service.flags & eServiceReference.isGroup): service = getBestPlayableServiceReference( eServiceReference(scanservice.sref), eServiceReference()) if not service or not service.valid( ) or service.type != eServiceReference.idDVB or ( service.flags & (eServiceReference.isMarker | eServiceReference.isDirectory)): continue channelID = '%08x%04x%04x' % ( service.getUnsignedData(4), # NAMESPACE service.getUnsignedData(2), # TSID service.getUnsignedData(3), # ONID ) if channelID not in channelIds: toList.append(scanservice) channelIds.append(channelID) def generateServicelist(self, services, bouquets): additionalServices = [] additionalBouquets = [] if config.plugins.epgrefresh.inherit_autotimer.value: try: from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() autotimer.readXml() except Exception as e: print("[EPGRefresh] Could not inherit AutoTimer Services:", e) else: for timer in autotimer.getEnabledTimerList(): additionalServices.extend( [EPGRefreshService(x, None) for x in timer.services]) additionalBouquets.extend( [EPGRefreshService(x, None) for x in timer.bouquets]) scanServices = [] channelIdList = [] self.addServices(services, scanServices, channelIdList) serviceHandler = eServiceCenter.getInstance() for bouquet in bouquets.union(additionalBouquets): myref = eServiceReference(bouquet.sref) list = serviceHandler.list(myref) if list is not None: while 1: s = list.getNext() if s and s.valid() and s.type == eServiceReference.idDVB: additionalServices.append( EPGRefreshService(s.toString(), None)) else: break del additionalBouquets[:] def sortServices(services): # sort by positions - better for motor unsortedServices = [] for service in services: ref = service.sref position = ref.split(":")[6][:-4] if not position: position = "0" auxiliarySortParameter = int(position, 16) if auxiliarySortParameter > 1800: auxiliarySortParameter = 3600 - auxiliarySortParameter unsortedServices.append((auxiliarySortParameter, service)) unsortedServices.sort() sortedServices = [] for service in unsortedServices: sortedServices.append(service[1]) return sortedServices self.addServices(additionalServices, scanServices, channelIdList) scanServices = sortServices(scanServices) del additionalServices[:] return scanServices def prepareRefresh(self): print("[EPGRefresh] About to start refreshing EPG") try: self.readConfiguration() except Exception as e: print("[EPGRefresh] Error occured while reading in configuration:", e) if len(self.services[0]) == 0 and len(self.services[1]) == 0: self.isrunning = False return self.scanServices = self.generateServicelist(self.services[0], self.services[1]) print("[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in self.scanServices])) self.maybeStopAdapter() if config.plugins.epgrefresh.adapter.value == "main": refreshAdapter = MainPictureAdapter(self.session) elif config.plugins.epgrefresh.adapter.value == "record": refreshAdapter = RecordAdapter(self.session) else: if config.plugins.epgrefresh.adapter.value == "pip": hidden = False elif config.plugins.epgrefresh.adapter.value == "pip_hidden": hidden = True refreshAdapter = PipAdapter(self.session, hide=hidden) if (not refreshAdapter.backgroundCapable and Screens.Standby.inStandby) or not refreshAdapter.prepare(): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) refreshAdapter = MainPictureAdapter(self.session) refreshAdapter.prepare() self.refreshAdapter = refreshAdapter self.isrunning = True if config.plugins.epgrefresh.erase.value: print("[EPGRefresh] flushing EPG cache...") from enigma import eEPGCache epgcache = eEPGCache.getInstance() epgcache.flushEPG() self.refresh() print("[EPGRefresh] pre start...") def cleanUp(self): config.plugins.epgrefresh.lastscan.value = int(time()) config.plugins.epgrefresh.lastscan.save() if config.plugins.epgrefresh.save_epg.value: try: from enigma import eEPGCache epgcache = eEPGCache.getInstance() epgcache.save() print("[EPGRefresh] save epgcache...") except: pass if config.plugins.epgrefresh_extra.save_backup.value and config.plugins.epgrefresh_extra.epgcachepath.value != "/etc/enigma2/": from os import system as my_system from os import chmod as my_chmod from os import path as my_path restore_backup = config.misc.epgcache_filename.value + ".backup" if my_path.exists(config.misc.epgcache_filename.value): try: my_system("cp -f %s %s" % (config.misc.epgcache_filename.value, restore_backup)) my_chmod("%s" % (restore_backup), 0644) print("[EPGRefresh] save epgcache backup...") except: pass if config.plugins.epgrefresh.parse_autotimer.value: try: from Plugins.Extensions.AutoTimer.plugin import autotimer if autotimer is None: from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer autotimer = AutoTimer() autotimer.readXml() autotimer.parseEPGAsync(simulateOnly=False) if not self.autotimer_pause.isActive(): if config.plugins.epgrefresh.afterevent.value and not self.DontShutdown: try: from Plugins.Extensions.SeriesPlugin.plugin import renameTimer except: self.autotimer_pause.startLongTimer(120) else: self.autotimer_pause.startLongTimer( int(config.plugins.epgrefresh.timeout_shutdown. value) * 60) else: self.finish() except Exception as e: print("[EPGRefresh] Could not start AutoTimer:", e) self.finish() else: self.finish() def checkFinish(self): try: if self.checkTimer.callback: self.checkTimer.callback.remove(self.checkFinish) self.checkTimer.stop() print("[EPGRefresh] stop timer...") except: pass self.check_finish = False print("[EPGRefresh] stop check...") def finish(self, *args, **kwargs): if Screens.Standby.inStandby is None and config.plugins.epgrefresh.enablemessage.value: try: Notifications.AddPopup(_("EPG refresh finished."), MessageBox.TYPE_INFO, 4, NOTIFICATIONID) except: pass epgrefreshtimer.cleanup() self.maybeStopAdapter() if not self.check_finish: self.check_finish = True try: self.checkTimer.callback.append(self.checkFinish) self.checkTimer.start(30000, True) self.forcedScan = False print("[EPGRefresh] pause 30 sec...") except: pass else: return self.isrunning = False if config.plugins.epgrefresh.afterevent.value and self.DontShutdown: self.DontShutdown = False self.forcedScan = False print("[EPGRefresh] Return to TV viewing...") return if not self.forcedScan and config.plugins.epgrefresh.afterevent.value and not Screens.Standby.inTryQuitMainloop: self.forcedScan = False print("[EPGRefresh] Shutdown after EPG refresh...") self.session.open(Screens.Standby.TryQuitMainloop, 1) self.forcedScan = False self.DontShutdown = False def refresh(self): if self.wait.isActive(): self.wait.stop() if self.forcedScan: self.nextService() else: if self.beginOfTimespan < config.plugins.epgrefresh.lastscan.value: if not self.wait.isActive(): self.isrunning = False return check_standby = False stop_service = False if Screens.Standby.inStandby: check_standby = True if not config.plugins.epgrefresh.force.value and check_standby: rec_time = self.session.nav.RecordTimer.getNextRecordingTime() interval = config.plugins.epgrefresh.interval_seconds.value if interval <= 20: interval = 25 if rec_time > 0 and (rec_time - time()) <= interval: stop_service = True if config.plugins.epgrefresh.force.value or ( check_standby and not self.session.nav.RecordTimer.isRecording() and not stop_service): self.nextService() else: if not checkTimespan(config.plugins.epgrefresh.begin.value, config.plugins.epgrefresh.end.value): print( "[EPGRefresh] Gone out of timespan while refreshing, sorry!" ) self.cleanUp() else: print( "[EPGRefresh] Box no longer in Standby or Recording started, rescheduling" ) if check_standby and config.plugins.epgrefresh.adapter.value == "main": self.session.nav.stopService() epgrefreshtimer.add( EPGRefreshTimerEntry( time() + config.plugins.epgrefresh.delay_standby.value * 60, self.refresh, nocheck=True)) def createWaitTimer(self): self.beginOfTimespan = time() epgrefreshtimer.add( EPGRefreshTimerEntry(time() + 30, self.prepareRefresh)) def nextService(self): print("[EPGRefresh] Maybe zap to next service") try: service = self.scanServices.pop(0) except IndexError: print("[EPGRefresh] Done refreshing EPG") self.cleanUp() else: Notifications.RemovePopup("Parental control") if self.isServiceProtected(service): skipProtectedServices = config.plugins.epgrefresh.skipProtectedServices.value adapter = config.plugins.epgrefresh.adapter.value if (not self.forcedScan ) or skipProtectedServices == "always" or ( self.forcedScan and Screens.Standby.inStandby is None and skipProtectedServices == "bg_only" and (adapter == "pip" or adapter == "main")): print("[EPGRefresh] Service is protected, skipping!") self.refresh() return if (not self.refreshAdapter.backgroundCapable and Screens.Standby.inStandby): print( "[EPGRefresh] Adapter is not able to run in background or not available, falling back to MainPictureAdapter" ) self.maybeStopAdapter() self.refreshAdapter = MainPictureAdapter(self.session) self.refreshAdapter.prepare() self.refreshAdapter.play(eServiceReference(service.sref)) delay = service.duration or config.plugins.epgrefresh.interval_seconds.value if not delay: delay = 20 if not self.wait.isActive(): self.wait.start(int(delay * 1000), True) def showPendingServices(self, session): if session is None: session = self.session else: if self.session is None: self.session = session if session is None: return False if not self.isRunning(): return False LISTMAX = 10 servcounter = 0 remaining_time = 0 try: servtxt = "" for service in self.scanServices: if self.isServiceProtected(service): skipProtectedServices = config.plugins.epgrefresh.skipProtectedServices.value adapter = config.plugins.epgrefresh.adapter.value if (not self.forcedScan ) or skipProtectedServices == "always" or ( self.forcedScan and Screens.Standby.inStandby is None and skipProtectedServices == "bg_only" and (adapter == "pip" or adapter == "main")): continue if servcounter < LISTMAX: ref = ServiceReference(service.sref) txt = ref.getServiceName().replace('\xc2\x86', '').replace( '\xc2\x87', '') servtxt = servtxt + 2 * ' ' + str(txt) + "\n" servcounter = servcounter + 1 delay = service.duration or config.plugins.epgrefresh.interval_seconds.value if not delay: delay = 20 remaining_time = remaining_time + delay first_text = _("Stop Running EPG-refresh?\n") if servcounter > LISTMAX: servtxt = servtxt + 2 * ' ' + ngettext( "... %d more service", "... %d more services", servcounter - LISTMAX) % (servcounter - LISTMAX) + '\n' last_text = "%s / %s" % ( ngettext("Remaining %d service", "Remaining %d services", servcounter) % servcounter, ngettext("%d:%02d min", "%d:%02d mins", remaining_time / 60) % (remaining_time / 60, remaining_time % 60)) if servcounter == 0: text = first_text + _("Scanning last service. Please wait.") else: text = first_text + _("Following Services have to be scanned:" ) + '\n' + servtxt + last_text session.openWithCallback(self.msgClosed, MessageBox, text, MessageBox.TYPE_YESNO) except: print("[EPGRefresh] showPendingServices Error!") def msgClosed(self, ret=False): if ret: self.stop() if config.plugins.epgrefresh.enabled.value: self.start()