366560df4c09c01996eb919f4f1e41436e65dc8a
[vuplus_dvbapp-plugin] / autotimer / src / AutoTimerComponent.py
1 # Format Counter
2 from time import strftime
3
4 # regular expression
5 from re import compile as re_compile
6
7 class AutoTimerComponent(object):
8         """AutoTimer Component which also handles validity checks"""
9
10         def __init__(self, id, *args, **kwargs):
11                 self.id = id
12                 self._afterevent = []
13                 self.setValues(*args, **kwargs)
14
15         def __eq__(self, other):
16                 try:
17                         return self.id == other.id
18                 except AttributeError:
19                         return False
20
21         def __ne__(self, other):
22                 return not self.__eq__(other)
23
24         def setValues(self, name, match, enabled, timespan = None, services = None, offset = None, \
25                         afterevent = [], exclude = None, maxduration = None, destination = None, \
26                         include = None, matchCount = 0, matchLeft = 0, matchLimit = '', matchFormatString = '', \
27                         lastBegin = 0, justplay = False, avoidDuplicateDescription = False, bouquets = None):
28                 self.name = name
29                 self.match = match
30                 self.timespan = timespan
31                 self.services = services
32                 self.offset = offset
33                 self.afterevent = afterevent
34                 self.exclude = exclude
35                 self.include = include
36                 self.maxduration = maxduration
37                 self.enabled = enabled
38                 self.destination = destination
39                 self.matchCount = matchCount
40                 self.matchLeft = matchLeft
41                 self.matchLimit = matchLimit
42                 self.matchFormatString = matchFormatString
43                 self.lastBegin = lastBegin
44                 self.justplay = justplay
45                 self.avoidDuplicateDescription = avoidDuplicateDescription
46                 self.bouquets = bouquets
47
48         def calculateDayspan(self, begin, end):
49                 if end[0] < begin[0] or (end[0] == begin[0] and end[1] <= begin[1]):
50                         return (begin, end, True)
51                 else:
52                         return (begin, end, False)
53
54         def setTimespan(self, timespan):
55                 if timespan is None:
56                         self._timespan = (None,)
57                 else:
58                         self._timespan = self.calculateDayspan(*timespan)
59
60         def getTimespan(self):
61                 return self._timespan
62
63         timespan = property(getTimespan, setTimespan)
64
65         def setExclude(self, exclude):
66                 if exclude:
67                         self._exclude = (
68                                 [re_compile(x) for x in exclude[0]],
69                                 [re_compile(x) for x in exclude[1]],
70                                 [re_compile(x) for x in exclude[2]],
71                                 exclude[3]
72                         )
73                 else:
74                         self._exclude = ([], [], [], [])
75
76         def getExclude(self):
77                 return self._exclude
78
79         exclude = property(getExclude, setExclude)
80
81         def setInclude(self, include):
82                 if include:
83                         self._include = (
84                                 [re_compile(x) for x in include[0]],
85                                 [re_compile(x) for x in include[1]],
86                                 [re_compile(x) for x in include[2]],
87                                 include[3]
88                         )
89                 else:
90                         self._include = ([], [], [], [])
91
92         def getInclude(self):
93                 return self._include
94
95         include = property(getInclude, setInclude)
96
97         def setServices(self, services):
98                 if services:
99                         self._services = services
100                 else:
101                         self._services = []
102
103         def getServices(self):
104                 return self._services
105
106         services = property(getServices, setServices)
107
108         def setBouquets(self, bouquets):
109                 if bouquets:
110                         self._bouquets = bouquets
111                 else:
112                         self._bouquets = []
113
114         def getBouquets(self):
115                 return self._bouquets
116
117         bouquets = property(getBouquets, setBouquets)
118
119         def setAfterEvent(self, afterevent):
120                 del self._afterevent[:]
121                 if len(afterevent):
122                         for definition in afterevent:
123                                 action, timespan = definition
124                                 if timespan is None:
125                                         self._afterevent.append((action, (None,)))
126                                 else:
127                                         self._afterevent.append((action, self.calculateDayspan(*timespan)))
128
129         def getCompleteAfterEvent(self):
130                 return self._afterevent
131
132         afterevent = property(getCompleteAfterEvent, setAfterEvent)
133
134         def hasTimespan(self):
135                 return self.timespan[0] is not None
136
137         def getTimespanBegin(self):
138                 return '%02d:%02d' % (self.timespan[0][0], self.timespan[0][1])
139
140         def getTimespanEnd(self):
141                 return '%02d:%02d' % (self.timespan[1][0], self.timespan[1][1])
142
143         def checkAnyTimespan(self, time, begin = None, end = None, haveDayspan = False):
144                 if begin is None:
145                         return False
146
147                 # Check if we span a day
148                 if haveDayspan:
149                         # Check if begin of event is later than our timespan starts
150                         if time.tm_hour > begin[0] or (time.tm_hour == begin[0] and time.tm_min >= begin[1]):
151                                 # If so, event is in our timespan
152                                 return False
153                         # Check if begin of event is earlier than our timespan end
154                         if time.tm_hour < end[0] or (time.tm_hour == end[0] and time.tm_min <= end[1]):
155                                 # If so, event is in our timespan
156                                 return False
157                         return True
158                 else:
159                         # Check if event begins earlier than our timespan starts 
160                         if time.tm_hour < begin[0] or (time.tm_hour == begin[0] and time.tm_min < begin[1]):
161                                 # Its out of our timespan then
162                                 return True
163                         # Check if event begins later than our timespan ends
164                         if time.tm_hour > end[0] or (time.tm_hour == end[0] and time.tm_min > end[1]):
165                                 # Its out of our timespan then
166                                 return True
167                         return False
168
169         def checkTimespan(self, begin):
170                 return self.checkAnyTimespan(begin, *self.timespan)
171
172         def hasDuration(self):
173                 return self.maxduration is not None
174
175         def getDuration(self):
176                 return self.maxduration/60
177
178         def checkDuration(self, length):
179                 if self.maxduration is None:
180                         return False
181                 return length > self.maxduration
182
183         def getFullServices(self):
184                 list = self.services[:]
185
186                 from enigma import eServiceReference, eServiceCenter
187                 serviceHandler = eServiceCenter.getInstance()
188                 for bouquet in self.bouquets:
189                         myref = eServiceReference(str(bouquet))
190                         mylist = serviceHandler.list(myref)
191                         if mylist is not None:
192                                 while 1:
193                                         s = mylist.getNext()
194                                         # TODO: I wonder if its sane to assume we get services here (and not just new lists)
195                                         # We can ignore markers & directorys here because they won't match any event's service :-)
196                                         if s.valid():
197                                                 # TODO: see if we need to check on custom names here
198                                                 list.append(s.toString())
199                                         else:
200                                                 break
201                 
202                 return list
203
204         def checkServices(self, service):
205                 if len(self.services) or len(self.bouquets): 
206                         return service not in self.getFullServices()
207                 return False
208
209         def getExcludedTitle(self):
210                 return [x.pattern for x in self.exclude[0]]
211
212         def getExcludedShort(self):
213                 return [x.pattern for x in self.exclude[1]]
214
215         def getExcludedDescription(self):
216                 return [x.pattern for x in self.exclude[2]]
217
218         def getExcludedDays(self):
219                 return self.exclude[3]
220
221         def getIncludedTitle(self):
222                 return [x.pattern for x in self.include[0]]
223
224         def getIncludedShort(self):
225                 return [x.pattern for x in self.include[1]]
226
227         def getIncludedDescription(self):
228                 return [x.pattern for x in self.include[2]]
229
230         def getIncludedDays(self):
231                 return self.include[3]
232
233         def checkExcluded(self, title, short, extended, dayofweek):
234                 if len(self.exclude[3]):
235                         list = [x for x in self.exclude[3]]
236                         if "weekend" in list:
237                                 list.extend(["5", "6"])
238                         if "weekday" in list:
239                                 list.extend(["0", "1", "2", "3", "4"])
240                         if dayofweek in list:
241                                 return True
242
243                 for exclude in self.exclude[0]:
244                         if exclude.search(title):
245                                 return True
246                 for exclude in self.exclude[1]:
247                         if exclude.search(short):
248                                 return True
249                 for exclude in self.exclude[2]:
250                         if exclude.search(extended):
251                                 return True
252                 return False
253
254         def checkIncluded(self, title, short, extended, dayofweek):
255                 if len(self.include[3]):
256                         list = [x for x in self.include[3]]
257                         if "weekend" in list:
258                                 list.extend(["5", "6"])
259                         if "weekday" in list:
260                                 list.extend(["0", "1", "2", "3", "4"])
261                         if dayofweek not in list:
262                                 return True
263
264                 for include in self.include[0]:
265                         if not include.search(title):
266                                 return True
267                 for include in self.include[1]:
268                         if not include.search(short):
269                                 return True
270                 for include in self.include[2]:
271                         if not include.search(extended):
272                                 return True
273
274                 return False
275
276         def checkFilter(self, title, short, extended, dayofweek):
277                 if self.checkExcluded(title, short, extended, dayofweek):
278                         return True
279
280                 return self.checkIncluded(title, short, extended, dayofweek)
281
282         def hasOffset(self):
283                 return self.offset is not None
284
285         def isOffsetEqual(self):
286                 return self.offset[0] == self.offset[1]
287
288         def applyOffset(self, begin, end):
289                 if self.offset is None:
290                         return (begin, end)
291                 return (begin - self.offset[0], end + self.offset[1])
292
293         def getOffsetBegin(self):
294                 return self.offset[0]/60
295
296         def getOffsetEnd(self):
297                 return self.offset[1]/60
298
299         def hasAfterEvent(self):
300                 return len(self.afterevent)
301
302         def hasAfterEventTimespan(self):
303                 for afterevent in self.afterevent:
304                         if afterevent[1][0] is not None:
305                                 return True
306                 return False
307
308         def getAfterEventTimespan(self, end):
309                 for afterevent in self.afterevent:
310                         if not self.checkAnyTimespan(end, *afterevent[1]):
311                                 return afterevent[0]
312                 return None
313
314         def getAfterEvent(self):
315                 for afterevent in self.afterevent:
316                         if afterevent[1][0] is None:
317                                 return afterevent[0]
318                 return None
319
320         def getEnabled(self):
321                 return self.enabled and "yes" or "no"
322
323         def getJustplay(self):
324                 return self.justplay and "1" or "0"
325
326         def hasDestination(self):
327                 return self.destination is not None
328
329         def hasCounter(self):
330                 return self.matchCount != 0
331
332         def hasCounterFormatString(self):
333                 return self.matchFormatString != ''
334
335         def getCounter(self):
336                 return self.matchCount
337
338         def getCounterLeft(self):
339                 return self.matchLeft
340
341         def getCounterLimit(self):
342                 return self.matchLimit
343
344         def getCounterFormatString(self):
345                 return self.matchFormatString
346
347         def checkCounter(self, timestamp):
348                 # 0-Count is considered "unset"
349                 if self.matchCount == 0:
350                         return False
351
352                 # Check if event is in current timespan (we can only manage one!)
353                 limit = strftime(self.matchFormatString, timestamp)
354                 if limit != self.matchLimit:
355                         return True
356
357                 if self.matchLeft > 0:
358                         self.matchLeft -= 1
359                         return False
360                 return True
361
362         def update(self, begin, timestamp):
363                 # Only update limit when we have new begin
364                 if begin > self.lastBegin:
365                         self.lastBegin = begin
366
367                         # Update Counter:
368                         # %m is Month, %U is week (sunday), %W is week (monday)
369                         newLimit = strftime(self.matchFormatString, timestamp)
370
371                         if newLimit != self.matchLimit:
372                                 self.matchLeft = self.matchCount
373                                 self.matchLimit = newLimit
374
375         def getLastBegin(self):
376                 return self.lastBegin
377
378         def getAvoidDuplicateDescription(self):
379                 return self.avoidDuplicateDescription
380
381         def __repr__(self):
382                 return ''.join([
383                         '<AutomaticTimer ',
384                         self.name,
385                         ' (',
386                         ', '.join([
387                                         str(self.match),
388                                         str(self.timespan),
389                                         str(self.services),
390                                         str(self.offset),
391                                         str(self.afterevent),
392                                         str(self.exclude),
393                                         str(self.maxduration),
394                                         str(self.enabled),
395                                         str(self.destination),
396                                         str(self.matchCount),
397                                         str(self.matchLeft),
398                                         str(self.matchLimit),
399                                         str(self.matchFormatString),
400                                         str(self.lastBegin),
401                                         str(self.justplay)
402                          ]),
403                          ")>"
404                 ])