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