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