2 from time import strftime
5 from re import compile as re_compile
7 class AutoTimerComponent(object):
8 """AutoTimer Component which also handles validity checks"""
10 def __init__(self, id, *args, **kwargs):
13 self.setValues(*args, **kwargs)
15 def __eq__(self, other):
17 return self.id == other.id
18 except AttributeError:
21 def __ne__(self, other):
22 return not self.__eq__(other)
25 return self.__class__(
30 timespan = self.timespan,
31 services = self.services,
33 afterevent = self.afterevent,
34 exclude = (self.getExcludedTitle(), self.getExcludedShort(), self.getExcludedDescription(), self.getExcludedDays()),
35 include = (self.getIncludedTitle(), self.getIncludedShort(), self.getIncludedDescription(), self.getIncludedDays()),
36 matchCount = self.matchCount,
37 matchLeft = self.matchLeft,
38 matchLimit = self.matchLimit,
39 matchFormatString = self.matchFormatString,
40 lastBegin = self.lastBegin,
41 justplay = self.justplay,
42 avoidDuplicateDescription = self.avoidDuplicateDescription,
43 bouquets = self.bouquets,
47 def __deepcopy__(self, memo):
48 return self.__class__(
53 timespan = self.timespan,
54 services = self.services[:],
55 offset = self.offset and self.offset[:],
56 afterevent = self.afterevent[:],
57 exclude = (self.getExcludedTitle(), self.getExcludedShort(), self.getExcludedDescription(), self.exclude[3][:]),
58 include = (self.getIncludedTitle(), self.getIncludedShort(), self.getIncludedDescription(), self.include[3][:]),
59 matchCount = self.matchCount,
60 matchLeft = self.matchLeft,
61 matchLimit = self.matchLimit,
62 matchFormatString = self.matchFormatString,
63 lastBegin = self.lastBegin,
64 justplay = self.justplay,
65 avoidDuplicateDescription = self.avoidDuplicateDescription,
66 bouquets = self.bouquets[:],
71 return self.__deepcopy__({})
73 def setValues(self, name, match, enabled, timespan = None, services = None, offset = None, \
74 afterevent = [], exclude = None, maxduration = None, destination = None, \
75 include = None, matchCount = 0, matchLeft = 0, matchLimit = '', matchFormatString = '', \
76 lastBegin = 0, justplay = False, avoidDuplicateDescription = False, bouquets = None, \
80 self.timespan = timespan
81 self.services = services
83 self.afterevent = afterevent
84 self.exclude = exclude
85 self.include = include
86 self.maxduration = maxduration
87 self.enabled = enabled
88 self.destination = destination
89 self.matchCount = matchCount
90 self.matchLeft = matchLeft
91 self.matchLimit = matchLimit
92 self.matchFormatString = matchFormatString
93 self.lastBegin = lastBegin
94 self.justplay = justplay
95 self.avoidDuplicateDescription = avoidDuplicateDescription
96 self.bouquets = bouquets
97 self.tags = tags or []
99 def calculateDayspan(self, begin, end, ignore = None):
100 if end[0] < begin[0] or (end[0] == begin[0] and end[1] <= begin[1]):
101 return (begin, end, True)
103 return (begin, end, False)
105 def setTimespan(self, timespan):
106 if timespan is None or len(timespan) and timespan[0] is None:
107 self._timespan = (None,)
109 self._timespan = self.calculateDayspan(*timespan)
111 def getTimespan(self):
112 return self._timespan
114 timespan = property(getTimespan, setTimespan)
116 def setExclude(self, exclude):
119 [re_compile(x) for x in exclude[0]],
120 [re_compile(x) for x in exclude[1]],
121 [re_compile(x) for x in exclude[2]],
125 self._exclude = ([], [], [], [])
127 def getExclude(self):
130 exclude = property(getExclude, setExclude)
132 def setInclude(self, include):
135 [re_compile(x) for x in include[0]],
136 [re_compile(x) for x in include[1]],
137 [re_compile(x) for x in include[2]],
141 self._include = ([], [], [], [])
143 def getInclude(self):
146 include = property(getInclude, setInclude)
148 def setServices(self, services):
150 self._services = services
154 def getServices(self):
155 return self._services
157 services = property(getServices, setServices)
159 def setBouquets(self, bouquets):
161 self._bouquets = bouquets
165 def getBouquets(self):
166 return self._bouquets
168 bouquets = property(getBouquets, setBouquets)
170 def setAfterEvent(self, afterevent):
171 del self._afterevent[:]
173 for definition in afterevent:
174 action, timespan = definition
176 self._afterevent.append((action, (None,)))
178 self._afterevent.append((action, self.calculateDayspan(*timespan)))
180 def getCompleteAfterEvent(self):
181 return self._afterevent
183 afterevent = property(getCompleteAfterEvent, setAfterEvent)
185 def hasTimespan(self):
186 return self.timespan[0] is not None
188 def getTimespanBegin(self):
189 return '%02d:%02d' % (self.timespan[0][0], self.timespan[0][1])
191 def getTimespanEnd(self):
192 return '%02d:%02d' % (self.timespan[1][0], self.timespan[1][1])
194 def checkAnyTimespan(self, time, begin = None, end = None, haveDayspan = False):
198 # Check if we span a day
200 # Check if begin of event is later than our timespan starts
201 if time.tm_hour > begin[0] or (time.tm_hour == begin[0] and time.tm_min >= begin[1]):
202 # If so, event is in our timespan
204 # Check if begin of event is earlier than our timespan end
205 if time.tm_hour < end[0] or (time.tm_hour == end[0] and time.tm_min <= end[1]):
206 # If so, event is in our timespan
210 # Check if event begins earlier than our timespan starts
211 if time.tm_hour < begin[0] or (time.tm_hour == begin[0] and time.tm_min < begin[1]):
212 # Its out of our timespan then
214 # Check if event begins later than our timespan ends
215 if time.tm_hour > end[0] or (time.tm_hour == end[0] and time.tm_min > end[1]):
216 # Its out of our timespan then
220 def checkTimespan(self, begin):
221 return self.checkAnyTimespan(begin, *self.timespan)
223 def hasDuration(self):
224 return self.maxduration is not None
226 def getDuration(self):
227 return self.maxduration/60
229 def checkDuration(self, length):
230 if self.maxduration is None:
232 return length > self.maxduration
234 def getFullServices(self):
235 list = self.services[:]
237 from enigma import eServiceReference, eServiceCenter
238 serviceHandler = eServiceCenter.getInstance()
239 for bouquet in self.bouquets:
240 myref = eServiceReference(str(bouquet))
241 mylist = serviceHandler.list(myref)
242 if mylist is not None:
245 # TODO: I wonder if its sane to assume we get services here (and not just new lists)
246 # We can ignore markers & directorys here because they won't match any event's service :-)
248 # strip all after last :
250 pos = value.rfind(':')
252 value = value[:pos+1]
260 def checkServices(self, service):
261 if len(self.services) or len(self.bouquets):
262 return service not in self.getFullServices()
265 def getExcludedTitle(self):
266 return [x.pattern for x in self.exclude[0]]
268 def getExcludedShort(self):
269 return [x.pattern for x in self.exclude[1]]
271 def getExcludedDescription(self):
272 return [x.pattern for x in self.exclude[2]]
274 def getExcludedDays(self):
275 return self.exclude[3]
277 def getIncludedTitle(self):
278 return [x.pattern for x in self.include[0]]
280 def getIncludedShort(self):
281 return [x.pattern for x in self.include[1]]
283 def getIncludedDescription(self):
284 return [x.pattern for x in self.include[2]]
286 def getIncludedDays(self):
287 return self.include[3]
289 def checkExcluded(self, title, short, extended, dayofweek):
290 if len(self.exclude[3]):
291 list = [x for x in self.exclude[3]]
292 if "weekend" in list:
293 list.extend(["5", "6"])
294 if "weekday" in list:
295 list.extend(["0", "1", "2", "3", "4"])
296 if dayofweek in list:
299 for exclude in self.exclude[0]:
300 if exclude.search(title):
302 for exclude in self.exclude[1]:
303 if exclude.search(short):
305 for exclude in self.exclude[2]:
306 if exclude.search(extended):
310 def checkIncluded(self, title, short, extended, dayofweek):
311 if len(self.include[3]):
312 list = [x for x in self.include[3]]
313 if "weekend" in list:
314 list.extend(["5", "6"])
315 if "weekday" in list:
316 list.extend(["0", "1", "2", "3", "4"])
317 if dayofweek not in list:
320 for include in self.include[0]:
321 if not include.search(title):
323 for include in self.include[1]:
324 if not include.search(short):
326 for include in self.include[2]:
327 if not include.search(extended):
332 def checkFilter(self, title, short, extended, dayofweek):
333 if self.checkExcluded(title, short, extended, dayofweek):
336 return self.checkIncluded(title, short, extended, dayofweek)
339 return self.offset is not None
341 def isOffsetEqual(self):
342 return self.offset[0] == self.offset[1]
344 def applyOffset(self, begin, end):
345 if self.offset is None:
347 return (begin - self.offset[0], end + self.offset[1])
349 def getOffsetBegin(self):
350 return self.offset[0]/60
352 def getOffsetEnd(self):
353 return self.offset[1]/60
355 def hasAfterEvent(self):
356 return len(self.afterevent)
358 def hasAfterEventTimespan(self):
359 for afterevent in self.afterevent:
360 if afterevent[1][0] is not None:
364 def getAfterEventTimespan(self, end):
365 for afterevent in self.afterevent:
366 if not self.checkAnyTimespan(end, *afterevent[1]):
370 def getAfterEvent(self):
371 for afterevent in self.afterevent:
372 if afterevent[1][0] is None:
376 def getEnabled(self):
377 return self.enabled and "yes" or "no"
379 def getJustplay(self):
380 return self.justplay and "1" or "0"
382 def hasDestination(self):
383 return self.destination is not None
385 def hasCounter(self):
386 return self.matchCount != 0
388 def hasCounterFormatString(self):
389 return self.matchFormatString != ''
391 def getCounter(self):
392 return self.matchCount
394 def getCounterLeft(self):
395 return self.matchLeft
397 def getCounterLimit(self):
398 return self.matchLimit
400 def getCounterFormatString(self):
401 return self.matchFormatString
403 def checkCounter(self, timestamp):
404 # 0-Count is considered "unset"
405 if self.matchCount == 0:
408 # Check if event is in current timespan (we can only manage one!)
409 limit = strftime(self.matchFormatString, timestamp)
410 if limit != self.matchLimit:
413 if self.matchLeft > 0:
418 def update(self, begin, timestamp):
419 # Only update limit when we have new begin
420 if begin > self.lastBegin:
421 self.lastBegin = begin
424 # %m is Month, %U is week (sunday), %W is week (monday)
425 newLimit = strftime(self.matchFormatString, timestamp)
427 if newLimit != self.matchLimit:
428 self.matchLeft = self.matchCount
429 self.matchLimit = newLimit
431 def getLastBegin(self):
432 return self.lastBegin
434 def getAvoidDuplicateDescription(self):
435 return self.avoidDuplicateDescription
438 return len(self.tags) > 0
450 str(self.afterevent),
451 str(([x.pattern for x in self.exclude[0]],
452 [x.pattern for x in self.exclude[1]],
453 [x.pattern for x in self.exclude[2]],
456 str(([x.pattern for x in self.include[0]],
457 [x.pattern for x in self.include[1]],
458 [x.pattern for x in self.include[2]],
461 str(self.maxduration),
463 str(self.destination),
464 str(self.matchCount),
466 str(self.matchLimit),
467 str(self.matchFormatString),
470 str(self.avoidDuplicateDescription),