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