cleanup
[enigma2-plugins.git] / webinterface / src / WebComponents / Sources / Timer.py
1 Version = '$Header$';
2
3 from enigma import eServiceReference, eEPGCache
4 from Components.Sources.Source import Source
5 from Components.config import config
6 from ServiceReference import ServiceReference
7 from RecordTimer import RecordTimerEntry, RecordTimer, AFTEREVENT, parseEvent
8 from Components.config import config
9 from xml.sax.saxutils import unescape
10 from time import time, strftime, localtime, mktime
11
12 class Timer(Source):
13         LIST = 0
14         ADDBYID = 1
15         ADD = 2
16         DEL = 3
17         TVBROWSER = 4
18         CHANGE = 5
19         WRITE = 6
20         RECNOW = 7
21         CLEANUP = 8
22
23         def __init__(self, session, func=LIST):
24                 self.func = func
25                 Source.__init__(self)
26                 self.session = session
27                 self.recordtimer = session.nav.RecordTimer
28                 self.epgcache = eEPGCache.getInstance()
29                 self.res = ( False, "unknown command" )
30
31         def handleCommand(self, cmd):
32                 if self.func is self.ADDBYID:
33                         self.res = self.addTimerByEventID(cmd)
34                         self.writeTimerList()
35
36                 elif self.func is self.ADD:
37                         self.res = self.editTimer(cmd)
38                         self.writeTimerList()
39
40                 elif self.func is self.TVBROWSER:
41                         self.res = self.tvBrowser(cmd)
42                         self.writeTimerList()
43
44                 elif self.func is self.DEL:
45                         self.res = self.delTimer(cmd)
46                         self.writeTimerList()
47
48                 elif self.func is self.CHANGE:
49                         self.res = self.editTimer(cmd)
50                         self.writeTimerList()
51
52                 elif self.func is self.WRITE:
53                         self.res = self.writeTimerList(force=True)
54
55                 elif self.func is self.RECNOW:
56                         self.res = self.recordNow(cmd)
57
58                 elif self.func is self.CLEANUP:
59                         self.res = self.cleanupTimer()
60
61                 else:
62                         self.res = ( False, "Unknown function: '%s'" % (self.func) )
63
64         def cleanupTimer(self):
65                 print "[WebComponents.Timer] cleanupTimer"
66
67                 self.session.nav.RecordTimer.cleanup()
68                 return ( True, "List of Timers has been cleaned" )
69
70
71         def delTimer(self, param):
72                 print "[WebComponents.Timer] delTimer"
73
74                 if 'sRef' in param:
75                         service_ref = ServiceReference(param['sRef'])
76                 else:
77                         return ( False, "Missing Parameter: sRef" )
78
79                 if 'begin' in param:
80                         begin = int(float(param['begin']))
81                 else:
82                         return ( False, "Missing Parameter: begin" )
83
84                 if 'end' in param:
85                         end = int(float(param['end']))
86                 else:
87                         return ( False, "Missing Parameter: end" )
88
89                 try:
90                         for timer in self.recordtimer.timer_list + self.recordtimer.processed_timers:
91                                 if str(timer.service_ref) == str(service_ref) and int(timer.begin) == begin and int(timer.end) == end:
92                                         self.recordtimer.removeEntry(timer)
93                                         return True, "The timer '%s' has been deleted successfully" % (timer.name)
94                 except Exception:
95                         return ( False, "The timer has NOT been deleted" )
96
97                 return False, "No matching Timer found"
98
99         def tvBrowser(self, param):
100                 """ The URL's for the tvBrowser-Capture-Driver are:
101
102                         http://dreambox/web/tvbrowser? +
103
104                 To add something:
105                         &command=add&&year={year}&month={month}&day={day}&shour={start_hour}&smin={start_minute}&ehour={end_hour}&emin={end_minute}&sRef={urlencode(channel_name_external, "utf8")}&name={urlencode(title, "utf8")}&description={urlencode(descr, "utf8")}&dirname={dirname}&tags={urlencode("tag1 tag2...", "utf8")}&afterevent=0&eit=&disabled=0&justplay=0&repeated=0
106
107                 to zap for some time:
108                         &command=add&&year={year}&month={month}&day={day}&shour={start_hour}&smin={start_minute}&ehour={end_hour}&emin={end_minute}&sRef={urlencode(channel_name_external, "utf8")}&name={urlencode(title, "utf8")}&description={urlencode(descr, "utf8")}&dirname={dirname}&tags={urlencode("tag1 tag2...", "utf8")}&afterevent=0&eit=&disabled=0&justplay=1&repeated=0
109
110                 to delete something:
111                         &command=del&&year={year}&month={month}&day={day}&shour={start_hour}&smin={start_minute}&ehour={end_hour}&emin={end_minute}&sRef={urlencode(channel_name_external, "utf8")}
112                 """
113                 print "[WebComponents.Timer] tvbrowser"
114
115                 listDate = ('year', 'month', 'day', 'shour', 'smin', 'ehour', 'emin')
116                 for element in listDate:
117                         if param[element] is None:
118                                 if param['s' + element] is None:
119                                         return ( False, "%s missing" % element )
120                                 else:
121                                         param[element] = int(param['s' + element])
122                         else:
123                                 param[element] = int(param[element])
124                 param['begin'] = int(mktime((param['year'], param['month'], param['day'], param['shour'], param['smin'], 0, 0, 0, -1)))
125                 param['end']     = int(mktime((param['year'], param['month'], param['day'], param['ehour'], param['emin'], 0, 0, 0, -1)))
126                 if param['end'] < param['begin']:
127                         param['end'] += 86400
128                 for element in listDate:
129                         del param[element]
130
131                 if param['sRef'] is None:
132                         return ( False, "Missing Parameter: sRef" )
133                 else:
134                         takeApart = param['sRef'].split('|')
135                         if len(takeApart) > 1:
136                                 param['sRef'] = takeApart[1]
137
138                 repeated = int(param.get('repeated') or 0)
139                 if repeated == 0:
140                         for element in ("mo", "tu", "we", "th", "fr", "sa", "su", "ms", "mf"):
141                                 if element in param:
142                                         number = param[element] or 0
143                                         del param[element]
144                                         repeated = repeated + int(number)
145                         if repeated > 127:
146                                 repeated = 127
147                 param['repeated'] = repeated
148
149                 if param['command'] == "add":
150                         del param['command']
151                         return self.editTimer(param)
152                 elif param['command'] == "del":
153                         del param['command']
154                         return self.delTimer(param)
155                 elif param['command'] == "change":
156                         del param['command']
157                         return self.editTimer(param)
158                 else:
159                         return ( False, "Unknown command: '%s'" % param['command'] )
160
161         def recordNow(self, param):
162                 limitEvent = True
163                 if param == "undefinitely" or param == "infinite":
164                         ret = (True, "Infinite Instant recording started")
165                         limitEvent = False
166                 else:
167                         ret = ( True, "Instant record for current Event started" )
168
169                 serviceref = ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference().toString())
170
171                 event = None
172
173                 try:
174                         service = self.session.nav.getCurrentService()
175                         event = service.info().getEvent(0)
176                 except Exception:
177                         print "[Webcomponents.Timer] recordNow Exception!"
178
179                 begin = time()
180                 end = begin + 3600 * 10
181                 name = "instant record"
182                 description = ""
183                 eventid = 0
184
185                 if event is not None:
186                         curEvent = parseEvent(event)
187                         name = curEvent[2]
188                         description = curEvent[3]
189                         eventid = curEvent[4]
190                         if limitEvent:
191                                 end = curEvent[1]
192                 else:
193                         if limitEvent:
194                                 ret = ( False, "No event found! Not recording!" )
195
196                 if ret[0]:
197                         location = config.movielist.last_videodir.value
198                         timer = RecordTimerEntry(serviceref, begin, end, name, description, eventid, False, False, 0, dirname=location)
199                         timer.dontSave = True
200                         self.recordtimer.record(timer)
201
202                 return ret
203
204
205 #===============================================================================
206 # This Function can add a new or edit an exisiting Timer.
207 # When the Parameter "deleteOldOnSave" is not set, a new Timer will be added.
208 # Otherwise, and if the parameters channelOld, beginOld and endOld are set,
209 # an existing timer with corresponding values will be changed.
210 #===============================================================================
211         def editTimer(self, param):
212                 print "[WebComponents.Timer] editTimer"
213
214                 #OK first we need to parse all of your Parameters
215                 #For some of them (like afterEvent or justplay) we can use default values
216                 #for others (the serviceReference or the Begin/End time of the timer
217                 #we have to quit if they are not set/have illegal values
218
219                 if 'sRef' not in param:
220                         return ( False, "Missing Parameter: sRef" )
221                 service_ref = ServiceReference(param['sRef'])
222
223                 repeated = int(param.get('repeated') or 0)
224
225                 if 'begin' not in param:
226                         return ( False, "Missing Parameter: begin" )
227                 begin = int(float(param['begin']))
228
229                 if 'end' not in param:
230                         return ( False, "Missing Parameter: end" )
231                 end = int(float(param['end']))
232
233                 tm = time()
234                 if tm <= begin:
235                         pass
236                 elif tm > begin and tm < end and repeated == 0:
237                         begin = time()
238                 elif repeated == 0:
239                         return ( False, "Illegal Parameter value for Parameter begin : '%s'" % begin )
240
241                 if 'name' not in param:
242                         return ( False, "Missing Parameter: name" )
243                 name = param['name']
244
245                 if 'description' not in param:
246                         return ( False, "Missing Parameter: description" )
247                 description = param['description'].replace("\n", " ")
248
249                 disabled = False #Default to: Enabled
250                 if 'disabled' in param:
251                         if param['disabled'] == "1":
252                                 disabled = True
253                         else:
254                                 #TODO - maybe we can give the user some useful hint here
255                                 pass
256
257                 justplay = False #Default to: Record
258                 if 'justplay' in param:
259                         if param['justplay'] == "1":
260                                 justplay = True
261
262                 afterEvent = 3 #Default to Afterevent: Auto
263                 if 'afterevent' in param:
264                         if (param['afterevent'] == "0") or (param['afterevent'] == "1") or (param['afterevent'] == "2"):
265                                 afterEvent = int(param['afterevent'])
266
267                 dirname = config.movielist.last_timer_videodir.value
268                 if 'dirname' in param and param['dirname']:
269                         dirname = param['dirname']
270
271                 tags = []
272                 if 'tags' in param and param['tags']:
273                         tags = unescape(param['tags']).split(' ')
274
275                 delold = 0
276                 if 'deleteOldOnSave' in param:
277                         delold = int(param['deleteOldOnSave'])
278
279                 #Try to edit an existing Timer
280                 if delold:
281                         if 'channelOld' in param and param['channelOld']:
282                                 channelOld = ServiceReference(param['channelOld'])
283                         else:
284                                 return ( False, "Missing Parameter: channelOld" )
285                         # We do need all of the following Parameters, too, for being able of finding the Timer.
286                         # Therefore so we can neither use default values in this part nor can we
287                         # continue if a parameter is missing
288                         if 'beginOld' not in param:
289                                 return ( False, "Missing Parameter: beginOld" )
290                         beginOld = int(param['beginOld'])
291
292                         if 'endOld' not in param:
293                                 return ( False, "Missing Parameter: endOld" )
294                         endOld = int(param['endOld'])
295
296                         #let's try to find the timer
297                         try:
298                                 for timer in self.recordtimer.timer_list + self.recordtimer.processed_timers:
299                                         if str(timer.service_ref) == str(channelOld):
300                                                 if int(timer.begin) == beginOld:
301                                                         if int(timer.end) == endOld:
302                                                                 #we've found the timer we've been searching for
303                                                                 #Let's apply the new values
304                                                                 timer.service_ref = service_ref
305                                                                 timer.begin = int(begin)
306                                                                 timer.end = int(end)
307                                                                 timer.name = name
308                                                                 timer.description = description
309                                                                 timer.disabled = disabled
310                                                                 timer.justplay = justplay
311                                                                 timer.afterEvent = afterEvent
312                                                                 timer.repeated = repeated
313                                                                 timer.dirname = dirname
314                                                                 timer.tags = tags
315
316                                                                 #send the changed timer back to enigma2 and hope it's good
317                                                                 self.session.nav.RecordTimer.timeChanged(timer)
318                                                                 print "[WebComponents.Timer] editTimer: Timer changed!"
319                                                                 return ( True, "Timer %s has been changed!" % (timer.name) )
320                         except Exception:
321                                 #obviously some value was not good, return an error
322                                 return ( False, "Changing the timer for '%s' failed!" % name )
323
324                         return ( False, "Could not find timer '%s' with given start and end time!" % name )
325
326                 #Try adding a new Timer
327
328                 try:
329                         #Create a new instance of recordtimerentry
330                         timer = RecordTimerEntry(service_ref, begin, end, name, description, 0, disabled, justplay, afterEvent, dirname=dirname, tags=tags)
331                         timer.repeated = repeated
332                         #add the new timer
333                         self.recordtimer.record(timer)
334                         return ( True, "Timer added successfully!" )
335                 except Exception:
336                         #something went wrong, most possibly one of the given paramater-values was wrong
337                         return ( False, "Could not add timer '%s'!" % name )
338
339                 return ( False, "Unexpected Error" )
340
341         def addTimerByEventID(self, param):
342                 print "[WebComponents.Timer] addTimerByEventID", param
343                 if param['sRef'] is None:
344                         return ( False, "Missing Parameter: sRef" )
345                 if param['eventid'] is None:
346                         return ( False, "Missing Parameter: eventid" )
347
348                 justplay = False
349                 if param['justplay'] is not None:
350                         if param['justplay'] == "1":
351                                 justplay = True
352
353                 location = config.movielist.last_timer_videodir.value
354                 if 'dirname' in param and param['dirname']:
355                         location = param['dirname']
356
357                 tags = []
358                 if 'tags' in param and param['tags']:
359                         tags = unescape(param['tags']).split(' ')
360
361                 epgcache = eEPGCache.getInstance()
362                 event = epgcache.lookupEventId(eServiceReference(param['sRef']), int(param['eventid']))
363                 if event is None:
364                         return ( False, "EventId not found" )
365
366                 (begin, end, name, description, eit) = parseEvent(event)
367
368                 timer = RecordTimerEntry(ServiceReference(param['sRef']), begin , end, name, description, eit, False, justplay, AFTEREVENT.NONE, dirname=location, tags=tags)
369                 self.recordtimer.record(timer)
370                 return ( True, "Timer '%s' added" % (timer.name) )
371
372         def writeTimerList(self, force=False):
373                 # is there an easier and better way? :\
374                 if config.plugins.Webinterface.autowritetimer.value or force:
375                         print "Timer.py writing timer to flash"
376                         self.session.nav.RecordTimer.saveTimer()
377                         return ( True, "TimerList has been saved " )
378                 else:
379                         return ( False, "TimerList has not been saved " )
380
381
382         def getResult(self):
383                 return self.res
384
385         result = property(getResult)
386
387         ## part for listfiller requests
388         def getList(self):
389                 timerlist = []
390
391                 for item in self.recordtimer.timer_list + self.recordtimer.processed_timers:
392                         timer = [
393                                 item.service_ref,
394                                 item.service_ref.getServiceName(),
395                                 item.eit,
396                                 item.name,
397                                 item.description,
398                                 "1" if item.disabled else "0",
399                                 item.begin,
400                                 item.end,
401                                 item.end - item.begin,
402                                 item.start_prepare,
403                                 1 if item.justplay else 0,
404                                 item.afterEvent,
405                                 item.dirname,
406                                 " ".join(item.tags),
407                                 item.log_entries,
408                                 item.backoff,
409                                 item.first_try_prepare,
410                                 item.state,
411                                 item.repeated,
412                                 1 if item.dontSave else 0,
413                                 item.cancelled,
414                         ]
415
416                         try:
417                                 timer.append(item.Filename)
418                         except AttributeError:
419                                 timer.append("")
420
421                         try:
422                                 timer.append(item.next_activation)
423                         except AttributeError:
424                                 timer.append("")
425
426                         if item.eit is not None:
427                                 event = self.epgcache.lookupEvent(['EX', ("%s" % item.service_ref , 2, item.eit)])
428                                 if event and event[0][0] is not None:
429                                         timer.append(event[0][0])
430                                 else:
431                                         timer.append("N/A")
432                         else:
433                                 timer.append("N/A")
434
435                         #toggleDisabled
436                         if item.disabled:
437                                 timer.extend(("0", "on"))
438                         else:
439                                 timer.extend(("1", "off"))
440
441                         timerlist.append(timer)
442
443                 return timerlist
444
445         list = property(getList)
446         lut = {
447                                 "ServiceReference":0,
448                                 "ServiceName": 1,
449                                 "EIT":2,
450                                 "Name":3,
451                                 "Description":4,
452                                 "Disabled":5,
453                                 "TimeBegin":6,
454                                 "TimeEnd":7,
455                                 "Duration":8,
456                                 "startPrepare":9,
457                                 "justPlay":10,
458                                 "afterEvent":11,
459                                 "Location":12,
460                                 "Tags":13,
461                                 "LogEntries":14,
462                                 "Backoff":15,
463                                 "firstTryPrepare":16,
464                                 "State":17,
465                                 "Repeated":18,
466                                 "dontSave":19,
467                                 "Cancled":20,
468                                 "Filename":21,
469                                 "nextActivation":22,
470                                 "DescriptionExtended":23,
471                                 "toggleDisabled":24,
472                                 "toggleDisabledIMG":25,
473                         }