X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;f=autotimer%2Fsrc%2FAutoTimerComponent.py;h=363e8e636389f14ab16a28c3dd1f7c9c89279ead;hb=07aa7c4f56ead32aad37b8ff0cc82d91428d2db6;hp=f013622c166cf8557b40bcd95408c253033fa2ef;hpb=10ef99ba1decc45dd159670303c49ac22e475429;p=vuplus_dvbapp-plugin diff --git a/autotimer/src/AutoTimerComponent.py b/autotimer/src/AutoTimerComponent.py index f013622..363e8e6 100644 --- a/autotimer/src/AutoTimerComponent.py +++ b/autotimer/src/AutoTimerComponent.py @@ -1,9 +1,15 @@ -# Format Counter +# Format counter from time import strftime # regular expression from re import compile as re_compile +# Alternatives and service restriction +from enigma import eServiceReference, eServiceCenter + +# To get preferred component +from Components.config import config + class AutoTimerComponent(object): """AutoTimer Component which also handles validity checks""" @@ -23,7 +29,7 @@ class AutoTimerComponent(object): self.setValues('', '', enabled) """ - Create a deep copy of this instance + Create a deep copy of this instance """ def clone(self): return self.__deepcopy__({}) @@ -41,7 +47,8 @@ class AutoTimerComponent(object): afterevent = [], exclude = None, maxduration = None, destination = None, \ include = None, matchCount = 0, matchLeft = 0, matchLimit = '', matchFormatString = '', \ lastBegin = 0, justplay = False, avoidDuplicateDescription = 0, bouquets = None, \ - tags = None): + tags = None, encoding = 'UTF-8', searchType = "partial", searchCase = "insensitive", \ + overrideAlternatives = False): self.name = name self.match = match self.enabled = enabled @@ -62,18 +69,24 @@ class AutoTimerComponent(object): self.avoidDuplicateDescription = avoidDuplicateDescription self.bouquets = bouquets self.tags = tags or [] + self.encoding = encoding + self.searchType = searchType + self.searchCase = searchCase + self.overrideAlternatives = overrideAlternatives ### Attributes / Properties def setAfterEvent(self, afterevent): - del self._afterevent[:] - if len(afterevent): - for definition in afterevent: - action, timespan = definition - if timespan is None: - self._afterevent.append((action, (None,))) - else: - self._afterevent.append((action, self.calculateDayspan(*timespan))) + if afterevent is not self._afterevent: + del self._afterevent[:] + else: + self._afterevent = [] + + for action, timespan in afterevent: + if timespan is None or timespan[0] is None: + self._afterevent.append((action, (None,))) + else: + self._afterevent.append((action, self.calculateDayspan(*timespan))) afterevent = property(lambda self: self._afterevent, setAfterEvent) @@ -85,6 +98,12 @@ class AutoTimerComponent(object): bouquets = property(lambda self: self._bouquets , setBouquets) + def setEncoding(self, encoding): + if encoding: + self._encoding = encoding + + encoding = property(lambda self: self._encoding, setEncoding) + def setExclude(self, exclude): if exclude: self._exclude = ( @@ -111,17 +130,17 @@ class AutoTimerComponent(object): include = property(lambda self: self._include, setInclude) - def setName(self, name): - self.name = name + def setSearchCase(self, case): + assert case in ("sensitive", "insensitive"), "search case must be sensitive or insensitive" + self._searchCase = case - def getMatch(self): - return self._match + searchCase = property(lambda self: self._searchCase, setSearchCase) - def setMatch(self, match): - # XXX: a sanity check might be useful... - self._match = match + def setSearchType(self, type): + assert type in ("exact", "partial"), "search type must be exact or partial" + self._searchType = type - match = property(getMatch, setMatch) + searchType = property(lambda self: self._searchType, setSearchType) def setServices(self, services): if services: @@ -132,7 +151,7 @@ class AutoTimerComponent(object): services = property(lambda self: self._services, setServices) def setTimespan(self, timespan): - if timespan is None or len(timespan) and timespan[0] is None: + if timespan is None or timespan and timespan[0] is None: self._timespan = (None,) else: self._timespan = self.calculateDayspan(*timespan) @@ -163,7 +182,7 @@ class AutoTimerComponent(object): return self.maxduration is not None def hasTags(self): - return len(self.tags) > 0 + return len(self.tags) def hasTimespan(self): return self.timespan[0] is not None @@ -201,7 +220,7 @@ class AutoTimerComponent(object): return False return True else: - # Check if event begins earlier than our timespan starts + # Check if event begins earlier than our timespan starts if time.tm_hour < begin[0] or (time.tm_hour == begin[0] and time.tm_min < begin[1]): # Its out of our timespan then return True @@ -212,35 +231,6 @@ class AutoTimerComponent(object): return False """ - Returns a list of all allowed services by listing the bouquets - """ - def getFullServices(self): - list = self.services[:] - - from enigma import eServiceReference, eServiceCenter - serviceHandler = eServiceCenter.getInstance() - for bouquet in self.bouquets: - myref = eServiceReference(str(bouquet)) - mylist = serviceHandler.list(myref) - if mylist is not None: - while 1: - s = mylist.getNext() - # TODO: I wonder if its sane to assume we get services here (and not just new lists) - # We can ignore markers & directorys here because they won't match any event's service :-) - if s.valid(): - # strip all after last : - value = s.toString() - pos = value.rfind(':') - if pos != -1: - value = value[:pos+1] - - list.append(value) - else: - break - - return list - - """ Called when a timer based on this component was added """ def update(self, begin, timestamp): @@ -280,7 +270,7 @@ class AutoTimerComponent(object): getExcludedDays = lambda self: self.exclude[3] getExcludedDescription = lambda self: [x.pattern for x in self.exclude[2]] getExcludedShort = lambda self: [x.pattern for x in self.exclude[1]] - getExcludedTitle = lambda self: [x.pattern for x in self.exclude[0]] + getExcludedTitle = lambda self: [x.pattern for x in self.exclude[0]] getInclude = lambda self: self._include getIncludedTitle = lambda self: [x.pattern for x in self.include[0]] @@ -292,11 +282,14 @@ class AutoTimerComponent(object): getLastBegin = lambda self: self.lastBegin + getMatch = lambda self: self.match getName = lambda self: self.name getOffsetBegin = lambda self: self.offset[0]/60 getOffsetEnd = lambda self: self.offset[1]/60 + getOverrideAlternatives = lambda self: self.overrideAlternatives and "1" or "0" + getServices = lambda self: self._services getTags = lambda self: self.tags @@ -306,7 +299,7 @@ class AutoTimerComponent(object): getTimespanEnd = lambda self: '%02d:%02d' % (self.timespan[1][0], self.timespan[1][1]) isOffsetEqual = lambda self: self.offset[0] == self.offset[1] - + ### Actual functionality def applyOffset(self, begin, end): @@ -332,16 +325,16 @@ class AutoTimerComponent(object): if self.maxduration is None: return False return length > self.maxduration - + def checkExcluded(self, title, short, extended, dayofweek): - if len(self.exclude[3]): - list = [x for x in self.exclude[3]] - if "weekend" in list: - list.extend(["5", "6"]) - if "weekday" in list: - list.extend(["0", "1", "2", "3", "4"]) + if self.exclude[3]: + list = self.exclude[3] if dayofweek in list: return True + if "weekend" in list and dayofweek in ("5", "6"): + return True + if "weekday" in list and dayofweek in ("0", "1", "2", "3", "4"): + return True for exclude in self.exclude[0]: if exclude.search(title): @@ -361,12 +354,12 @@ class AutoTimerComponent(object): return self.checkIncluded(title, short, extended, dayofweek) def checkIncluded(self, title, short, extended, dayofweek): - if len(self.include[3]): - list = [x for x in self.include[3]] + if self.include[3]: + list = self.include[3][:] if "weekend" in list: - list.extend(["5", "6"]) + list.extend(("5", "6")) if "weekday" in list: - list.extend(["0", "1", "2", "3", "4"]) + list.extend(("0", "1", "2", "3", "4")) if dayofweek not in list: return True @@ -382,11 +375,76 @@ class AutoTimerComponent(object): return False - def checkServices(self, service): - if len(self.services) or len(self.bouquets): - return service not in self.getFullServices() + def checkServices(self, check_service): + services = self.services + bouquets = self.bouquets + if services or bouquets: + addbouquets = [] + + for service in services: + if service == check_service: + return False + + myref = eServiceReference(str(service)) + if myref.flags & eServiceReference.isGroup: + addbouquets.append(service) + + serviceHandler = eServiceCenter.getInstance() + for bouquet in bouquets + addbouquets: + myref = eServiceReference(str(bouquet)) + mylist = serviceHandler.list(myref) + if mylist is not None: + while 1: + s = mylist.getNext() + # TODO: I wonder if its sane to assume we get services here (and not just new lists) + # We can ignore markers & directorys here because they won't match any event's service :-) + if s.valid(): + # strip all after last : + value = s.toString() + pos = value.rfind(':') + if pos != -1: + if value[pos-1] == ':': + pos -= 1 + value = value[:pos+1] + + if value == check_service: + return False + else: + break + return True return False + """ + Return alternative service including a given ref. + Note that this only works for alternatives that the autotimer is restricted to. + """ + def getAlternative(self, override_service): + services = self.services + if services: + serviceHandler = eServiceCenter.getInstance() + + for service in services: + myref = eServiceReference(str(service)) + if myref.flags & eServiceReference.isGroup: + mylist = serviceHandler.list(myref) + if mylist is not None: + while 1: + s = mylist.getNext() + if s.valid(): + # strip all after last : + value = s.toString() + pos = value.rfind(':') + if pos != -1: + if value[pos-1] == ':': + pos -= 1 + value = value[:pos+1] + + if value == override_service: + return service + else: + break + return override_service + def checkTimespan(self, begin): return self.checkAnyTimespan(begin, *self.timespan) @@ -430,7 +488,11 @@ class AutoTimerComponent(object): justplay = self.justplay, avoidDuplicateDescription = self.avoidDuplicateDescription, bouquets = self.bouquets, - tags = self.tags + tags = self.tags, + encoding = self.encoding, + searchType = self.searchType, + searchCase = self.searchCase, + overrideAlternatives = self.overrideAlternatives ) def __deepcopy__(self, memo): @@ -455,7 +517,11 @@ class AutoTimerComponent(object): justplay = self.justplay, avoidDuplicateDescription = self.avoidDuplicateDescription, bouquets = self.bouquets[:], - tags = self.tags[:] + tags = self.tags[:], + encoding = self.encoding, + searchType = self.searchType, + searchCase = self.searchCase, + overrideAlternatives = self.overrideAlternatives ) def __eq__(self, other): @@ -472,12 +538,15 @@ class AutoTimerComponent(object): return not self.__eq__(other) def __repr__(self): - return ''.join([ + return ''.join(( '" - ]) + )) +class AutoTimerFastscanComponent(AutoTimerComponent): + def __init__(self, *args, **kwargs): + AutoTimerComponent.__init__(self, *args, **kwargs) + self._fastServices = None + + def setBouquets(self, bouquets): + AutoTimerComponent.setBouquets(self, bouquets) + self._fastServices = None + + def setServices(self, services): + AutoTimerComponent.setServices(self, services) + self._fastServices = None + + def getFastServices(self): + if self._fastServices is None: + fastServices = [] + append = fastServices.append + addbouquets = [] + for service in self.services: + myref = eServiceReference(str(service)) + if myref.flags & eServiceReference.isGroup: + addbouquets.append(service) + else: + comp = service.split(':') + append(':'.join(comp[3:])) + + serviceHandler = eServiceCenter.getInstance() + for bouquet in bouquets + addbouquets: + myref = eServiceReference(str(bouquet)) + mylist = serviceHandler.list(myref) + if mylist is not None: + while 1: + s = mylist.getNext() + # TODO: I wonder if its sane to assume we get services here (and not just new lists) + # We can ignore markers & directorys here because they won't match any event's service :-) + if s.valid(): + # strip all after last : + value = s.toString() + pos = value.rfind(':') + if pos != -1: + if value[pos-1] == ':': + pos -= 1 + value = value[:pos+1] + + comp = value.split(':') + append(':'.join(value[3:])) + else: + break + self._fastServices = fastServices + return self._fastServices + + def checkServices(self, check_service): + services = self.getFastServices() + if services: + check = ':'.join(check_service.split(':')[3:]) + for service in services: + if service == check: + return False # included + return True # not included + return False # no restriction + + def getAlternative(self, override_service): + services = self.services + if services: + override = ':'.join(override_service.split(':')[3:]) + serviceHandler = eServiceCenter.getInstance() + + for service in services: + myref = eServiceReference(str(service)) + if myref.flags & eServiceReference.isGroup: + mylist = serviceHandler.list(myref) + if mylist is not None: + while 1: + s = mylist.getNext() + if s.valid(): + # strip all after last : + value = s.toString() + pos = value.rfind(':') + if pos != -1: + if value[pos-1] == ':': + pos -= 1 + value = value[:pos+1] + + if ':'.join(value.split(':')[3:]) == override: + return service + else: + break + return override_service + +# very basic factory ;-) +preferredAutoTimerComponent = lambda *args, **kwargs: AutoTimerFastscanComponent(*args, **kwargs) if config.plugins.autotimer.fastscan.value else AutoTimerComponent(*args, **kwargs)