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