X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;f=autotimer%2Fsrc%2FAutoTimer.py;h=ea72e13a4a34504d88ed3e16b7efaa866ffc22f6;hb=07aa7c4f56ead32aad37b8ff0cc82d91428d2db6;hp=e1269a123496e0eabf9271ae85f9af0cd8db4f43;hpb=8993b17c5f24627fbf22ef46bd834f17feb9de23;p=vuplus_dvbapp-plugin diff --git a/autotimer/src/AutoTimer.py b/autotimer/src/AutoTimer.py index e1269a1..ea72e13 100644 --- a/autotimer/src/AutoTimer.py +++ b/autotimer/src/AutoTimer.py @@ -1,7 +1,7 @@ # Plugins Config -from xml.dom.minidom import parse as minidom_parse +from xml.etree.cElementTree import parse as cet_parse from os import path as os_path -from AutoTimerConfiguration import parseConfig, writeConfig +from AutoTimerConfiguration import parseConfig, buildConfig # Navigation (RecordTimer) import NavigationInstance @@ -21,7 +21,7 @@ from enigma import eEPGCache, eServiceReference from Components.config import config # AutoTimer Component -from AutoTimerComponent import AutoTimerComponent +from AutoTimerComponent import preferredAutoTimerComponent XML_CONFIG = "/etc/enigma2/autotimer.xml" @@ -32,6 +32,16 @@ def getTimeDiff(timer, begin, end): return timer.end - begin return 0 +typeMap = { + "exact": eEPGCache.EXAKT_TITLE_SEARCH, + "partial": eEPGCache.PARTIAL_TITLE_SEARCH +} + +caseMap = { + "sensitive": eEPGCache.CASE_CHECK, + "insensitive": eEPGCache.NO_CASE_CHECK +} + class AutoTimerIgnoreTimerException(Exception): def __init__(self, cause): self.cause = cause @@ -46,14 +56,11 @@ class AutoTimer: """Read and save xml configuration, query EPGCache""" def __init__(self): - # Keep EPGCache - self.epgcache = eEPGCache.getInstance() - # Initialize self.timers = [] self.configMtime = -1 self.uniqueTimerId = 0 - self.defaultTimer = AutoTimerComponent( + self.defaultTimer = preferredAutoTimerComponent( 0, # Id "", # Name "", # Match @@ -78,26 +85,28 @@ class AutoTimer: self.configMtime = mtime # Parse Config - dom = minidom_parse(XML_CONFIG) - + configuration = cet_parse(XML_CONFIG).getroot() + # Empty out timers and reset Ids del self.timers[:] - self.uniqueTimerId = 0 self.defaultTimer.clear(-1, True) - # Get Config Element - for configuration in dom.getElementsByTagName("autotimer"): - parseConfig( - configuration, - self.timers, - configuration.getAttribute("version"), - self.uniqueTimerId, - self.defaultTimer - ) - self.uniqueTimerId = len(self.timers) + parseConfig( + configuration, + self.timers, + configuration.get("version"), + 0, + self.defaultTimer + ) + self.uniqueTimerId = len(self.timers) + + def getXml(self): + return buildConfig(self.defaultTimer, self.timers, webif = True) def writeXml(self): - writeConfig(XML_CONFIG, self.defaultTimer, self.timers) + file = open(XML_CONFIG, 'w') + file.writelines(buildConfig(self.defaultTimer, self.timers)) + file.close() # Manage List @@ -158,20 +167,26 @@ class AutoTimer: # We include processed timers as we might search for duplicate descriptions recorddict = {} for timer in NavigationInstance.instance.RecordTimer.timer_list + NavigationInstance.instance.RecordTimer.processed_timers: - if not recorddict.has_key(str(timer.service_ref)): - recorddict[str(timer.service_ref)] = [timer] - else: - recorddict[str(timer.service_ref)].append(timer) + recorddict.setdefault(str(timer.service_ref), []).append(timer) # Iterate Timer for timer in self.getEnabledTimerList(): + # Workaround to allow search for umlauts if we know the encoding + match = timer.match + if timer.encoding != 'UTF-8': + try: + match = match.decode('UTF-8').encode(timer.encoding) + except UnicodeDecodeError: + pass + # Search EPG, default to empty list - ret = self.epgcache.search(('RI', 100, eEPGCache.PARTIAL_TITLE_SEARCH, timer.match, eEPGCache.NO_CASE_CHECK)) or [] + epgcache = eEPGCache.getInstance() + ret = epgcache.search(('RI', 100, typeMap[timer.searchType], match, caseMap[timer.searchCase])) or () for serviceref, eit in ret: eserviceref = eServiceReference(serviceref) - evt = self.epgcache.lookupEventId(eserviceref, eit) + evt = epgcache.lookupEventId(eserviceref, eit) if not evt: print "[AutoTimer] Could not create Event!" continue @@ -215,6 +230,9 @@ class AutoTimer: begin -= config.recording.margin_before.value * 60 end += config.recording.margin_after.value * 60 + # Eventually change service to alternative + if timer.overrideAlternatives: + serviceref = timer.getAlternative(serviceref) total += 1 @@ -225,69 +243,72 @@ class AutoTimer: # Initialize newEntry = None + oldExists = False # Check for double Timers # We first check eit and if user wants us to guess event based on time # we try this as backup. The allowed diff should be configurable though. - try: - for rtimer in recorddict.get(serviceref, []): - if rtimer.eit == eit or config.plugins.autotimer.try_guessing.value and getTimeDiff(rtimer, begin, end) > ((duration/10)*8): - newEntry = rtimer - - # Abort if we don't want to modify timers or timer is repeated - if config.plugins.autotimer.refresh.value == "none" or newEntry.repeated: - raise AutoTimerIgnoreTimerException("Won't modify existing timer because either no modification allowed or repeated timer") - - if hasattr(newEntry, "isAutoTimer"): - print "[AutoTimer] Modifying existing AutoTimer!" - else: - if config.plugins.autotimer.refresh.value != "all": - raise AutoTimerIgnoreTimerException("Won't modify existing timer because it's no timer set by us") - print "[AutoTimer] Warning, we're messing with a timer which might not have been set by us" - - func = NavigationInstance.instance.RecordTimer.timeChanged - modified += 1 - - # Modify values saved in timer - newEntry.name = name - newEntry.description = description - newEntry.begin = int(begin) - newEntry.end = int(end) - newEntry.service_ref = ServiceReference(serviceref) + for rtimer in recorddict.get(serviceref, ()): + if rtimer.eit == eit or config.plugins.autotimer.try_guessing.value and getTimeDiff(rtimer, begin, end) > ((duration/10)*8): + oldExists = True + # Abort if we don't want to modify timers or timer is repeated + if config.plugins.autotimer.refresh.value == "none" or rtimer.repeated: + print "[AutoTimer] Won't modify existing timer because either no modification allowed or repeated timer" break - elif timer.getAvoidDuplicateDescription() == 1 and rtimer.description == description: - raise AutoTimerIgnoreTimerException("We found a timer with same description, skipping event") - if newEntry is None and timer.getAvoidDuplicateDescription() == 2: - for list in recorddict.values(): - for rtimer in list: - if rtimer.description == description: - raise AutoTimerIgnoreTimerException("We found a timer with same description, skipping event") - - except AutoTimerIgnoreTimerException, etite: - print etite - continue - # Event not yet in Timers + if hasattr(rtimer, "isAutoTimer"): + print "[AutoTimer] Modifying existing AutoTimer!" + else: + if config.plugins.autotimer.refresh.value != "all": + print "[AutoTimer] Won't modify existing timer because it's no timer set by us" + break + + print "[AutoTimer] Warning, we're messing with a timer which might not have been set by us" + + newEntry = rtimer + modified += 1 + + # Modify values saved in timer + newEntry.name = name + newEntry.description = description + newEntry.begin = int(begin) + newEntry.end = int(end) + newEntry.service_ref = ServiceReference(serviceref) + + break + elif timer.avoidDuplicateDescription == 1 and rtimer.description == description: + oldExists = True + print "[AutoTimer] We found a timer with same description, skipping event" + break + + # We found no timer we want to edit if newEntry is None: - if timer.checkCounter(timestamp): + # But there is a match + if oldExists: continue - new += 1 + # We want to search for possible doubles + if timer.avoidDuplicateDescription == 2: + # I thinks thats the fastest way to do this, though it's a little ugly + try: + for list in recorddict.values(): + for rtimer in list: + if rtimer.description == description: + raise AutoTimerIgnoreTimerException("We found a timer with same description, skipping event") + except AutoTimerIgnoreTimerException, etite: + print etite + continue - print "[AutoTimer] Adding an event." + if timer.checkCounter(timestamp): + continue + print "[AutoTimer] Adding an event." newEntry = RecordTimerEntry(ServiceReference(serviceref), begin, end, name, description, eit) - func = NavigationInstance.instance.RecordTimer.record # Mark this entry as AutoTimer (only AutoTimers will have this Attribute set) newEntry.isAutoTimer = True - if not recorddict.has_key(serviceref): - recorddict[serviceref] = [newEntry] - else: - recorddict[serviceref].append(newEntry) - # Apply afterEvent if timer.hasAfterEvent(): afterEvent = timer.getAfterEventTimespan(localtime(end)) @@ -298,17 +319,21 @@ class AutoTimer: newEntry.dirname = timer.destination newEntry.justplay = timer.justplay - newEntry.tags = timer.tags # This needs my enhanced tag support patch to work - - # Do a sanity check, although it does not do much right now - timersanitycheck = TimerSanityCheck(NavigationInstance.instance.RecordTimer.timer_list, newEntry) - if not timersanitycheck.check(): - print "[Autotimer] Sanity check failed" - else: - print "[Autotimer] Sanity check passed" - - # Either add to List or change time - func(newEntry) + newEntry.tags = timer.tags + + if oldExists: + # XXX: this won't perform a sanity check, but do we actually want to do so? + NavigationInstance.instance.RecordTimer.timeChanged(newEntry) + else: + conflicts = NavigationInstance.instance.RecordTimer.record(newEntry) + if conflicts and config.plugins.autotimer.disabled_on_conflict.value: + newEntry.disabled = True + # We might want to do the sanity check locally so we don't run it twice - but I consider this workaround a hack anyway + conflicts = NavigationInstance.instance.RecordTimer.record(newEntry) + if conflicts is None: + timer.decrementCounter() + new += 1 + recorddict.setdefault(serviceref, []).append(newEntry) return (total, new, modified, timers)