def readXML(self): path = config.plugins.seriesplugin.channel_file.value # Abort if no config found if not os.path.exists(path): splog("No configuration file present") return None # Parse if mtime differs from whats saved mtime = os.path.getmtime(path) if mtime == ChannelsFile.mtime: # No changes in configuration, won't read again return ChannelsFile.cache # Parse XML try: etree = parse(path).getroot() except Exception as e: splog("Exception in readXML: " + str(e)) etree = None mtime = -1 # Save time and cache file content ChannelsFile.mtime = mtime ChannelsFile.cache = etree return ChannelsFile.cache
def sp_extension(session, *args, **kwargs): if config.plugins.seriesplugin.enabled.value: try: if session: session.open(SeriesPluginInfoScreen) except Exception as e: splog(_("SeriesPlugin extension exception ") + str(e))
def saveXML(self): if ChannelsBase.channels_changed: channels = ChannelsBase.channels # Generate List in RAM root = None #splog("saveXML channels", channels) splog("SP saveXML channels", len(channels)) # Build Header from plugin import NAME, VERSION root = Element(NAME) root.set('version', VERSION) root.append(Comment(_("Don't edit this manually unless you really know what you are doing"))) # Build Body def build(root, channels): if channels: for reference, namealternatives in channels.iteritems(): name, alternatives = namealternatives # Add channel element = SubElement( root, "Channel", name = stringToXML(name), reference = stringToXML(reference) ) # Add alternatives if alternatives: for name in alternatives: SubElement( element, "Alternative" ).text = stringToXML(name) return root root = build( root, channels ) self.writeXML( root )
def loadXML(self): # Read xml config file root = self.readXML() if root: channels = {} # Parse Config def parse(root): channels = {} version = root.get("version", "1") if version.startswith("2"): if root: for element in root.findall("Channel"): name = element.get("name", "") reference = element.get("reference", "") if name and reference: alternatives = [] for alternative in element.findall( "Alternative"): alternatives.append(alternative.text) channels[reference] = (name, list(set(alternatives))) elif version.startswith("1"): splog("loadXML channels - Skip old file") return channels channels = parse(root) #splog("loadXML channels", channels) splog("SP loadXML channels", len(channels)) else: channels = {} ChannelsBase.channels = channels
def labelTimer(timer, begin=None, end=None, *args, **kwargs): if config.plugins.seriesplugin.enabled.value: splog("SeriesPlugin labelTimer is deprecated - Update Your AutoTimer!") try: SeriesPluginTimer(timer, timer.name, timer.begin, timer.end) except Exception as e: splog(_("SeriesPlugin label exception ") + str(e))
def loadXML(self): # Read xml config file root = self.readXML() if root: channels = {} # Parse Config def parse(root): channels = {} version = root.get("version", "1") if version.startswith("2"): if root: for element in root.findall("Channel"): name = element.get("name", "") reference = element.get("reference", "") if name and reference: alternatives = [] for alternative in element.findall("Alternative"): alternatives.append( alternative.text ) channels[reference] = (name, list(set(alternatives))) elif version.startswith("1"): splog("loadXML channels - Skip old file") return channels channels = parse( root ) #splog("loadXML channels", channels) splog("SP loadXML channels", len(channels)) else: channels = {} ChannelsBase.channels = channels
def writeXML(self, etree): path = config.plugins.seriesplugin.channel_file.value def indent(elem, level=0): i = "\n" + level*" " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem in elem: indent(elem, level+1) if not elem.tail or not elem.tail.strip(): elem.tail = i else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = i indent(etree) data = tostring(etree, 'utf-8') f = None try: f = open(path, 'w') if data: f.writelines(data) except Exception as e: splog("Exception in writeXML: " + str(e)) finally: if f is not None: f.close() # Save time and cache file content self.mtime = os.path.getmtime( path ) self.cache = etree
def writeXML(self, etree): path = config.plugins.seriesplugin.channel_file.value def indent(elem, level=0): i = "\n" + level * " " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem in elem: indent(elem, level + 1) if not elem.tail or not elem.tail.strip(): elem.tail = i else: if level and (not elem.tail or not elem.tail.strip()): elem.tail = i indent(etree) data = tostring(etree, 'utf-8') f = None try: f = open(path, 'w') if data: f.writelines(data) except Exception as e: splog("Exception in writeXML: " + str(e)) finally: if f is not None: f.close() # Save time and cache file content self.mtime = os.path.getmtime(path) self.cache = etree
def buildSTBchannellist(BouquetName=None): chlist = None chlist = [] mask = (eServiceReference.isMarker | eServiceReference.isDirectory) splog("SPC: read STB Channellist..") tvbouquets = getTVBouquets() splog("SPC: found %s bouquet: %s" % (len(tvbouquets), tvbouquets)) if not BouquetName: for bouquet in tvbouquets: bouquetlist = [] bouquetlist = getServiceList(bouquet[0]) for (serviceref, servicename) in bouquetlist: playable = not (eServiceReference(serviceref).flags & mask) if playable: chlist.append((servicename, re.sub('::.*', ':', serviceref), unifyChannel(servicename))) else: for bouquet in tvbouquets: if bouquet[1] == BouquetName: bouquetlist = [] bouquetlist = getServiceList(bouquet[0]) for (serviceref, servicename) in bouquetlist: playable = not (eServiceReference(serviceref).flags & mask) if playable: chlist.append( (servicename, re.sub('::.*', ':', serviceref), unifyChannel(servicename))) break return chlist
def __init__(self): splog("SP: Main: Init") self.thread = SeriesPluginWorker(self.gotResult) Modules.__init__(self) ChannelsBase.__init__(self) self.serviceHandler = eServiceCenter.getInstance() #http://bugs.python.org/issue7980 datetime.strptime('2012-01-01', '%Y-%m-%d') self.identifier_elapsed = self.instantiateModuleWithName( config.plugins.seriesplugin.identifier_elapsed.value ) #splog(self.identifier_elapsed) self.identifier_today = self.instantiateModuleWithName( config.plugins.seriesplugin.identifier_today.value ) #splog(self.identifier_today) self.identifier_future = self.instantiateModuleWithName( config.plugins.seriesplugin.identifier_future.value ) #splog(self.identifier_future) pattern = config.plugins.seriesplugin.pattern_title.value pattern = pattern.replace("{org:s}", "(.+)") pattern = re.sub('{season:?\d*d?}', '\d+', pattern) pattern = re.sub('{episode:?\d*d?}', '\d+', pattern) pattern = pattern.replace("{title:s}", ".+") self.compiledRegexpSeries = re.compile(pattern)
def buildSTBchannellist(BouquetName = None): chlist = None chlist = [] mask = (eServiceReference.isMarker | eServiceReference.isDirectory) splog("SPC: read STB Channellist..") tvbouquets = getTVBouquets() splog("SPC: found %s bouquet: %s" % (len(tvbouquets), tvbouquets) ) if not BouquetName: for bouquet in tvbouquets: bouquetlist = [] bouquetlist = getServiceList(bouquet[0]) for (serviceref, servicename) in bouquetlist: playable = not (eServiceReference(serviceref).flags & mask) if playable: chlist.append((servicename, re.sub('::.*', ':', serviceref), unifyChannel(servicename))) else: for bouquet in tvbouquets: if bouquet[1] == BouquetName: bouquetlist = [] bouquetlist = getServiceList(bouquet[0]) for (serviceref, servicename) in bouquetlist: playable = not (eServiceReference(serviceref).flags & mask) if playable: chlist.append((servicename, re.sub('::.*', ':', serviceref), unifyChannel(servicename))) break return chlist
def __init__(self, session, service=None, event=None): Screen.__init__(self, session) global instance instance = self self.session = session self.skinName = [ "SeriesPluginInfoScreen" ] self["logo"] = Pixmap() self["cover"] = Pixmap() self["state"] = Pixmap() self["event_title"] = Label() self["event_episode"] = Label() self["event_description"] = ScrollLabel() self["datetime"] = Label() self["channel"] = Label() self["duration"] = Label() self["key_red"] = Button("") # Rename or Record self["key_green"] = Button("") # Trakt Seen / Not Seen self["key_yellow"] = Button("") # Show all Episodes of current season self["key_blue"] = Button("") # Show all Seasons self.redButtonFunction = None #TODO HelpableActionMap self["actions"] = ActionMap(["OkCancelActions", "EventViewActions", "DirectionActions", "ColorActions"], { "cancel": self.close, "ok": self.close, "up": self["event_description"].pageUp, "down": self["event_description"].pageDown, "red": self.redButton, "prevEvent": self.prevEpisode, "nextEvent": self.nextEpisode, #TODO #"pageUp": self.pageUp, #"pageDown": self.pageDown, #"openSimilarList": self.openSimilarList }) splog("SPI: SeriesPluginInfo", service, event) self.service = service self.event = event self.name = "" self.short = "" self.data = None self.path = None self.eservice = None self.epg = eEPGCache.getInstance() self.serviceHandler = eServiceCenter.getInstance() self.seriesPlugin = getInstance() self.onLayoutFinish.append( self.layoutFinished )
def timerCallback(self, timer, data=None): splog("SPT: timerCallback", data) splog(data) if data and len(data) == 4 and timer: # Episode data available, refactor name and description #from SeriesPluginRenamer import newLegacyEncode timer.name = str(refactorTitle(timer.name, data)) #timer.name = newLegacyEncode(refactorTitle(timer.name, data)) timer.description = str(refactorDescription(timer.description, data)) timer.log(610, "[SeriesPlugin] Success: Changed name: %s." % (timer.name)) elif data: timer.log(611, "[SeriesPlugin] Failed: %s." % ( str( data ) )) SeriesPluginTimer.data.append( str(timer.name) + " " + str( data ) ) else: timer.log(612, "[SeriesPlugin] Failed." ) SeriesPluginTimer.data.append( str(timer.name) + " " + _("No data available") ) timer.sp_in_queue = False if config.plugins.seriesplugin.timer_popups.value or config.plugins.seriesplugin.timer_popups_success.value: SeriesPluginTimer.counter = SeriesPluginTimer.counter +1 if SeriesPluginTimer.data or config.plugins.seriesplugin.timer_popups_success.value: # Maybe there is a better way to avoid multiple Popups from SeriesPlugin import getInstance instance = getInstance() if instance.thread.empty() and instance.thread.finished(): if SeriesPluginTimer.data: AddPopup( "SeriesPlugin:\n" + _("Timer rename has been finished with %d errors:\n") % (len(SeriesPluginTimer.data)) +"\n" +"\n".join(SeriesPluginTimer.data), MessageBox.TYPE_ERROR, int(config.plugins.seriesplugin.timer_popups_timeout.value), 'SP_PopUp_ID_TimerFinished' ) else: AddPopup( "SeriesPlugin:\n" + _("%d timer renamed successfully") % (SeriesPluginTimer.counter), MessageBox.TYPE_INFO, int(config.plugins.seriesplugin.timer_popups_timeout.value), 'SP_PopUp_ID_TimerFinished' ) SeriesPluginTimer.data = [] SeriesPluginTimer.counter = 0 return timer
def keyCancel(self): self.help_window_was_shown = False splog("SPC keyCancel") resetInstance() if self["config"].isChanged() or self.changesMade: self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?")) else: self.close()
def getSeasonAndEpisode(timer, name, begin, end, *args, **kwargs): result = None if config.plugins.seriesplugin.enabled.value: try: result = SeriesPluginTimer(timer, name, begin, end, True) except Exception as e: splog(_("SeriesPlugin label exception ") + str(e)) return result
def channelReset(self, answer): if answer: splog("SPC: channel-list reset...") self.resetChannels() self.stbChlist = [] self.webChlist = [] self.stbToWebChlist = [] self.readChannels()
def stop(self): splog("SP: Main: stop") self.thread.stop() # NOTE: while we don't need to join the thread, we should do so in case it's currently parsing #self.thread.join() self.thread = None self.saveXML()
def keyCancel(self): splog("SPC keyCancel") #self.seriesPlugin.resetChannels() resetInstance() if self["config"].isChanged() or self.changesMade: self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?")) else: self.close()
def channel(session, service=None, *args, **kwargs): if config.plugins.seriesplugin.enabled.value: try: from enigma import eServiceCenter info = eServiceCenter.getInstance().info(service) event = info.getEvent(service) session.open(SeriesPluginInfoScreen, service, event) except Exception as e: splog(_("SeriesPlugin extension exception ") + str(e))
def compareChannels(self, ref, remote): splog("SP compareChannels", ref, remote) if ref in ChannelsBase.channels: ( name, alternatives ) = ChannelsBase.channels[ref] for altname in alternatives: if altname in remote or remote in altname: return True return False
def compareChannels(self, ref, remote): splog("SP compareChannels", ref, remote) if ref in ChannelsBase.channels: (name, alternatives) = ChannelsBase.channels[ref] for altname in alternatives: if altname in remote or remote in altname: return True return False
def recoverAutoTimer(): try: global ATmodifyTimer if AutoTimer: if ATmodifyTimer: AutoTimer.modifyTimer = ATmodifyTimer ATmodifyTimer = None except: splog("SeriesPlugin found old AutoTimer")
def episodeCallback(self, data=None): #TODO episode list handling #store the list and just open the first one splog("SPI: episodeCallback", data) #splog(data) if data and len(data) == 4: # Episode data available season, episode, title, series = self.data = data if season == 0 and episode == 0: custom = _("{title:s}").format(**{ 'season': season, 'episode': episode, 'title': title }) elif season == 0: custom = _("Episode: {episode:d}\n{title:s}").format( **{ 'season': season, 'episode': episode, 'title': title }) elif episode == 0: custom = _("Season: {season:d}\n{title:s}").format( **{ 'season': season, 'episode': episode, 'title': title }) else: custom = _( "Season: {season:d} Episode: {episode:d}\n{title:s}" ).format(**{ 'season': season, 'episode': episode, 'title': title }) try: self.setColorButtons() except Exception as e: # Screen already closed splog("SPI: exception:", str(e)) elif data: custom = str(data) else: custom = _("No matching episode found") # Check if the dialog is already closed try: self["event_episode"].setText(custom) except Exception as e: # Screen already closed #splog("SPI: exception:", str(e)) pass
def keyCancel(self): splog("SPC keyCancel") #self.seriesPlugin.resetChannels() resetInstance() if self["config"].isChanged() or self.changesMade: self.session.openWithCallback( self.cancelConfirm, MessageBox, _("Really close without saving settings?")) else: self.close()
def movielist_rename(session, service, services=None, *args, **kwargs): if config.plugins.seriesplugin.enabled.value: try: if services: if not isinstance(services, list): services = [services] else: services = [service] SeriesPluginRenamer(session, services) except Exception as e: splog(_("SeriesPlugin renamer exception ") + str(e))
def gotThreadMsg(self, msg=None): from ctypes import CDLL SYS_gettid = 4222 libc = CDLL("libc.so.6") tid = libc.syscall(SYS_gettid) splog('SP: Worker got message: ', currentThread(), _get_ident(), self.ident, os.getpid(), tid ) data = self.__messages.pop() if callable(self.callback): self.callback(data)
def overwriteAutoTimer(): try: global ATmodifyTimer if AutoTimer: if ATmodifyTimer is None: # Backup original function ATmodifyTimer = AutoTimer.modifyTimer # Overwrite function AutoTimer.modifyTimer = SPmodifyTimer except: splog("SeriesPlugin found old AutoTimer")
def channelShowSeriesInfo(self): splog( "[SeriesPlugin] channelShowSeriesInfo ") if config.plugins.seriesplugin.enabled.value: try: from enigma import eServiceCenter service = self.csel.servicelist.getCurrent() info = eServiceCenter.getInstance().info(service) event = info.getEvent(service) self.session.openWithCallback(self.SPcloseafterfinish, SeriesPluginInfoScreen, service, event) except Exception as e: splog(_("SeriesPlugin info exception ") + str(e))
def lookupChannelByReference(self, ref): if ref in ChannelsBase.channels: ( name, alternatives ) = ChannelsBase.channels[ref] altnames = [] for altname in alternatives: if altname: splog("SP lookupChannelByReference", altname) altnames.append(altname) return ' / '.join(altnames) return False
def lookupChannelByReference(self, ref): if ref in ChannelsBase.channels: (name, alternatives) = ChannelsBase.channels[ref] altnames = [] for altname in alternatives: if altname: splog("SP lookupChannelByReference", altname) altnames.append(altname) return ' / '.join(altnames) return False
def keyRemove(self): check = self['list'].getCurrent() if check == None: splog("SPC: keyRemove list empty") return else: (servicename, webSender, serviceref, state) = self['list'].getCurrent()[0] splog("SPC: keyRemove", servicename, webSender, serviceref, state) if serviceref: #TODO handle multiple links/alternatives - show a choicebox self.session.openWithCallback( boundFunction(self.removeConfirm, servicename, serviceref), MessageBox, _("Remove '%s'?") % servicename, MessageBox.TYPE_YESNO, default = False)
def addChannel(self, ref, name, remote): splog("SP addChannel name remote", name, remote) if ref in ChannelsBase.channels: ( name, alternatives ) = ChannelsBase.channels[ref] if remote not in alternatives: alternatives.append(remote) ChannelsBase.channels[ref] = ( name, alternatives ) else: ChannelsBase.channels[ref] = ( name, [remote] ) ChannelsBase.channels_changed = True
def addChannel(self, ref, name, remote): splog("SP addChannel name remote", name, remote) if ref in ChannelsBase.channels: (name, alternatives) = ChannelsBase.channels[ref] if remote not in alternatives: alternatives.append(remote) ChannelsBase.channels[ref] = (name, alternatives) else: ChannelsBase.channels[ref] = (name, [remote]) ChannelsBase.channels_changed = True
def removeConfirm(self, servicename, serviceref, answer): if not answer: return if serviceref: idx = self.getIndexOfServiceref(serviceref) if idx is not False: splog("SPC: removeConfirm", servicename, serviceref, idx) self.setTitle(_("Channel '- %s -' removed.") % servicename) self.removeChannel(serviceref) self.stbToWebChlist[idx] = (servicename, "", serviceref, "0") self.chooseMenuList.setList(map(self.buildList, self.stbToWebChlist))
def removeConfirm(self, servicename, serviceref, answer): if not answer: return if serviceref: idx = self.getIndexOfServiceref(serviceref) if idx is not False: splog("SPC: removeConfirm", servicename, serviceref, idx) self.setTitle(_("Channel '- %s -' removed.") % servicename) self.removeChannel(serviceref) self.stbToWebChlist[idx] = (servicename, "", serviceref, "0") self.chooseMenuList.setList( map(self.buildList, self.stbToWebChlist))
def add(self, item): from ctypes import CDLL SYS_gettid = 4222 libc = CDLL("libc.so.6") tid = libc.syscall(SYS_gettid) splog('SP: Worker add from thread: ', currentThread(), _get_ident(), self.ident, os.getpid(), tid ) self.__queue.push(item) if not self.__running: self.__running = True self.start() # Start blocking code in Thread
def keyAdd(self): check = self['list'].getCurrent() if check == None: splog("SPC: list empty") return else: idx = 0 (servicename, webSender, serviceref, state) = self['list'].getCurrent()[0] idx = 0 if webSender: idx = self.getIndexOfWebSender(self.webChlist) splog("SPC: keyAdd webSender", webSender, idx) self.session.openWithCallback( boundFunction(self.addConfirm, servicename, serviceref, webSender), ChoiceBox,_("Add Web Channel"), self.webChlist, None, idx)
def resetInstance(): if config.plugins.seriesplugin.lookup_counter.isChanged(): config.plugins.seriesplugin.lookup_counter.save() global instance if instance is not None: splog("SP: SERIESPLUGIN INSTANCE STOP") instance.stop() instance = None from Cacher import cache global cache cache = {}
def gotResult(self, msg): splog("SP: Main: Thread: gotResult:", msg) callback, data = msg if callable(callback): callback(data) if (config.plugins.seriesplugin.lookup_counter.value == 10) \ or (config.plugins.seriesplugin.lookup_counter.value == 100) \ or (config.plugins.seriesplugin.lookup_counter.value % 1000 == 0): from plugin import ABOUT about = ABOUT.format( ** {'lookups': config.plugins.seriesplugin.lookup_counter.value}) AddPopup(about, MessageBox.TYPE_INFO, -1, 'SP_PopUp_ID_About')
def parse(root): channels = {} version = root.get("version", "1") if version.startswith("2"): if root: for element in root.findall("Channel"): name = element.get("name", "") reference = element.get("reference", "") if name and reference: alternatives = [] for alternative in element.findall("Alternative"): alternatives.append( alternative.text ) channels[reference] = (name, list(set(alternatives))) elif version.startswith("1"): splog("loadXML channels - Skip old file") return channels
def keyRemove(self): check = self['list'].getCurrent() if check == None: splog("SPC: keyRemove list empty") return else: (servicename, webSender, serviceref, state) = self['list'].getCurrent()[0] splog("SPC: keyRemove", servicename, webSender, serviceref, state) if serviceref: #TODO handle multiple links/alternatives - show a choicebox self.session.openWithCallback(boundFunction( self.removeConfirm, servicename, serviceref), MessageBox, _("Remove '%s'?") % servicename, MessageBox.TYPE_YESNO, default=False)
def keyAdd(self): check = self['list'].getCurrent() if check == None: splog("SPC: list empty") return else: idx = 0 (servicename, webSender, serviceref, state) = self['list'].getCurrent()[0] idx = 0 if webSender: idx = self.getIndexOfWebSender(self.webChlist) splog("SPC: keyAdd webSender", webSender, idx) self.session.openWithCallback( boundFunction(self.addConfirm, servicename, serviceref, webSender), ChoiceBox, _("Add Web Channel"), self.webChlist, None, idx)
def renameMeta(servicepath, name, data): #TODO Use MetaSupport EitSupport classes from EMC ? if servicepath.endswith(".ts"): meta_file = servicepath + ".meta" else: meta_file = servicepath + ".ts.meta" # Create new meta for ts files if not os.path.exists(meta_file): if os.path.isfile(servicepath): _title = os.path.basename(os.path.splitext(servicepath)[0]) else: _title = name _sid = "" _descr = "" _time = "" _tags = "" metafile = open(meta_file, "w") metafile.write("%s\n%s\n%s\n%s\n%s" % (_sid, _title, _descr, _time, _tags)) metafile.close() if os.path.exists(meta_file): metafile = open(meta_file, "r") sid = metafile.readline() oldtitle = metafile.readline().rstrip() olddescr = metafile.readline().rstrip() rest = metafile.read() metafile.close() if config.plugins.seriesplugin.pattern_title.value and not config.plugins.seriesplugin.pattern_title.value == "Off": title = refactorTitle(oldtitle, data) else: title = oldtitle splog("SPR: title", title) if config.plugins.seriesplugin.pattern_description.value and not config.plugins.seriesplugin.pattern_description.value == "Off": descr = refactorDescription(olddescr, data) else: descr = olddescr splog("SPR: descr", descr) metafile = open(meta_file, "w") metafile.write("%s%s\n%s\n%s" % (sid, title, descr, rest)) metafile.close() return True
def readPatternFile(): path = config.plugins.seriesplugin.pattern_file.value obj = None patterns = None if os.path.exists(path): splog("[SeriesPlugin] Found pattern file") f = None try: f = open(path, 'rb') header, patterns = json.load(f) patterns = [tuple(p) for p in patterns] except Exception as e: splog("[SeriesPlugin] Exception in readEpisodePatternsFile: " + str(e)) finally: if f is not None: f.close() return patterns or scheme_fallback
def parse(root): channels = {} version = root.get("version", "1") if version.startswith("2"): if root: for element in root.findall("Channel"): name = element.get("name", "") reference = element.get("reference", "") if name and reference: alternatives = [] for alternative in element.findall( "Alternative"): alternatives.append(alternative.text) channels[reference] = (name, list(set(alternatives))) elif version.startswith("1"): splog("loadXML channels - Skip old file") return channels