timer: add name/description, factor out "parse from epg event", fix some cases where...
[openblackhole/openblackhole-enigma2.git] / RecordTimer.py
1 import time
2 import codecs
3 #from time import datetime
4 from Tools import Directories, Notifications
5
6 import timer
7 import xml.dom.minidom
8
9 from Screens.MessageBox import MessageBox
10 import NavigationInstance
11
12 from Tools.XMLTools import elementsWithTag
13 from ServiceReference import ServiceReference
14
15 # ok, for descriptions etc we have:
16 # service reference  (to get the service name)
17 # name               (title)
18 # description        (description)
19 # event data         (ONLY for time adjustments etc.)
20
21
22 # parses an event, and gives out a (begin, end, name, duration, eit)-tuple.
23 def parseEvent(ev):
24         name = ev.getEventName()
25         description = ev.getShortDescription()
26         begin = ev.getBeginTime()
27         end = begin + ev.getDuration()
28         eit = None
29         return (begin, end, name, description, eit)
30
31 class RecordTimerEntry(timer.TimerEntry):
32         def __init__(self, serviceref, begin, end, name, description, eit):
33                 timer.TimerEntry.__init__(self, int(begin), int(end))
34                 
35                 assert isinstance(serviceref, ServiceReference)
36                 
37                 self.service_ref = serviceref
38                 
39                 self.eit = eit
40                 
41                 self.dontSave = False
42                 self.name = name
43                 self.description = description
44                 self.timer = None
45                 self.record_service = None
46                 self.wantStart = False
47                 self.prepareOK = False
48                 
49         def calculateFilename(self):
50                 service_name = self.service_ref.getServiceName()
51 #               begin_date = datetime.fromtimestamp(begin).strf...
52                 begin_date = ""
53                 
54                 print "begin_date: ", begin_date
55                 print "service_name: ", service_name
56                 print "name:", self.name
57                 print "description: ", self.description
58
59                 self.Filename = Directories.getRecordingFilename(service_name)
60                 #begin_date + " - " + service_name + description)
61                 
62         
63         def tryPrepare(self):
64                 self.calculateFilename()
65                 self.record_service = NavigationInstance.instance.recordService(self.service_ref)
66                 if self.record_service == None:
67                         return False
68                 else:   
69                         if self.record_service.prepare(self.Filename + ".ts"):
70                                 self.record_service = None
71                                 return False
72
73                         f = open(self.Filename + ".ts.meta", "w")
74                         f.write(str(self.service_ref) + "\n")
75                         f.write(self.name + "\n")
76                         f.write(self.description + "\n")
77                         f.write(str(self.begin) + "\n")
78                         del f
79                         return True
80
81         def activate(self, event):
82                 if event == self.EventPrepare:
83                         self.prepareOK = False
84                         if self.tryPrepare():
85                                 self.prepareOK = True
86                         else:
87                                 # error.
88                                 Notifications.AddNotificationWithCallback(self.failureCB, MessageBox, _("A timer failed to record!\nDisable TV and try again?\n"))
89                 elif event == self.EventStart:
90                         if self.prepareOK:
91                                 self.record_service.start()
92                                 print "timer started!"
93                         else:
94                                 print "prepare failed, thus start failed, too."
95                                 self.wantStart = True
96                 elif event == self.EventEnd or event == self.EventAbort:
97                         self.wantStart = False
98                         if self.prepareOK:
99                                 self.record_service.stop()
100                                 self.record_service = None
101                                 print "Timer successfully ended"
102                         else:
103                                 print "prepare failed, thus nothing was recorded."
104
105         def abort():
106                 # fixme
107                 pass
108
109         def failureCB(self, answer):
110                 if answer == True:
111                         NavigationInstance.instance.stopUserServices()
112                         self.activate(self.EventPrepare)
113                         if self.wantStart:
114                                 print "post-activating record"
115                                 self.activate(self.EventStart)
116                 else:
117                         print "user killed record"
118
119 def createTimer(xml):
120         begin = int(xml.getAttribute("begin"))
121         end = int(xml.getAttribute("end"))
122         serviceref = ServiceReference(str(xml.getAttribute("serviceref")))
123         description = xml.getAttribute("description").encode("utf-8")
124         repeated = xml.getAttribute("repeated").encode("utf-8")
125         eit = xml.getAttribute("eit").encode("utf-8")
126         name = xml.getAttribute("name").encode("utf-8")
127         #filename = xml.getAttribute("filename").encode("utf-8")
128         entry = RecordTimerEntry(serviceref, begin, end, name, description, eit)
129         entry.repeated = int(repeated)
130         return entry
131
132 class RecordTimer(timer.Timer):
133         def __init__(self):
134                 timer.Timer.__init__(self)
135                 
136                 self.Filename = Directories.resolveFilename(Directories.SCOPE_CONFIG, "timers.xml")
137                 
138                 try:
139                         self.loadTimer()
140                 except IOError:
141                         print "unable to load timers from file!"
142                         
143         def isRecording(self):
144                 isRunning = False
145                 for timer in self.timer_list:
146                         if timer.isRunning():
147                                 isRunning = True
148                 return isRunning
149         
150         def loadTimer(self):
151                 # TODO: PATH!
152                 doc = xml.dom.minidom.parse(self.Filename)
153                 
154                 root = doc.childNodes[0]
155                 for timer in elementsWithTag(root.childNodes, "timer"):
156                         self.record(createTimer(timer))
157         
158         def saveTimer(self):
159                 doc = xml.dom.minidom.Document()
160                 root_element = doc.createElement('timers')
161                 doc.appendChild(root_element)
162                 root_element.appendChild(doc.createTextNode("\n"))
163                 
164                 for timer in self.timer_list + self.processed_timers:
165                         # some timers (instant records) don't want to be saved.
166                         # skip them
167                         if timer.dontSave:
168                                 continue
169                         t = doc.createTextNode("\t")
170                         root_element.appendChild(t)
171                         t = doc.createElement('timer')
172                         t.setAttribute("begin", str(timer.begin))
173                         t.setAttribute("end", str(timer.end))
174                         t.setAttribute("serviceref", str(timer.service_ref))
175                         t.setAttribute("repeated", str(timer.repeated))                 
176                         t.setAttribute("name", timer.name)
177                         t.setAttribute("description", timer.description)
178                         t.setAttribute("eit", str(timer.eit))
179                         
180                         root_element.appendChild(t)
181                         t = doc.createTextNode("\n")
182                         root_element.appendChild(t)
183
184                 file = open(self.Filename, "w")
185                 doc.writexml(file)
186                 file.write("\n")
187                 file.close()
188         
189         def record(self, entry):
190                 print "[Timer] Record " + str(entry)
191                 entry.Timer = self
192                 self.addTimerEntry(entry)
193
194         def removeEntry(self, entry):
195                 print "[Timer] Remove " + str(entry)
196                 
197                 entry.repeated = False
198
199                 if entry.state == timer.TimerEntry.StateRunning:
200                         print "remove running timer."
201                         entry.end = time.time()
202                         self.timeChanged(entry)
203                 elif entry.state != timer.TimerEntry.StateEnded:
204                         entry.activate(timer.TimerEntry.EventAbort)
205                         self.timer_list.remove(entry)
206
207                         self.calcNextActivation()
208                         print "timer did not yet start - removing"
209
210                         # the timer was aborted, and removed.
211                         return
212                 else:
213                         print "timer did already end - doing nothing."
214                 
215                 print "state: ", entry.state
216                 print "in processed: ", entry in self.processed_timers
217                 print "in running: ", entry in self.timer_list
218                 # now the timer should be in the processed_timers list. remove it from there.
219                 self.processed_timers.remove(entry)
220
221         def shutdown(self):
222                 self.saveTimer()