bug fix: set eventid to -1 when getting no eventid from partnerbox timerlist
[enigma2-plugins.git] / partnerbox / src / PartnerboxFunctions.py
1 #
2 #  Partnerbox E2
3 #
4 #  $Id$
5 #
6 #  Coded by Dr.Best (c) 2009
7 #  Support: www.dreambox-tools.info
8 #
9 #  This program is free software; you can redistribute it and/or
10 #  modify it under the terms of the GNU General Public License
11 #  as published by the Free Software Foundation; either version 2
12 #  of the License, or (at your option) any later version.
13 #
14 #  This program is distributed in the hope that it will be useful,
15 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 #  GNU General Public License for more details.
18 #
19
20 import urllib
21 from time import localtime
22 from timer import TimerEntry
23 from twisted.internet import reactor
24 from twisted.web import client
25 from twisted.web.client import HTTPClientFactory
26 from base64 import encodestring
27 import xml.etree.cElementTree
28
29
30 remote_timer_list = None
31 oldIP = None
32
33 def getTimerType(refstr, beginTime, duration, eventId, timer_list):
34         pre = 1
35         post = 2
36         type = 0
37         endTime = beginTime + duration
38         for x in timer_list:
39                 if x.servicereference.upper() == refstr.upper():
40                         if x.eventId == eventId:
41                                 return True
42                         beg = x.timebegin
43                         end = x.timeend
44                         if beginTime > beg and beginTime < end and endTime > end:
45                                 type |= pre
46                         elif beginTime < beg and endTime > beg and endTime < end:
47                                 type |= post
48         if type == 0:
49                 return True
50         elif type == pre:
51                 return False
52         elif type == post:
53                 return False
54         else:
55                 return True
56
57 def isInTimerList(begin, duration, service, eventid, timer_list):
58         time_match = 0
59         chktime = None
60         chktimecmp = None
61         chktimecmp_end = None
62         end = begin + duration
63         timerentry = None
64         for x in timer_list:
65                 if x.servicereference.upper() == service.upper():
66                         if x.repeated != 0:
67                                 if chktime is None:
68                                         chktime = localtime(begin)
69                                         chktimecmp = chktime.tm_wday * 1440 + chktime.tm_hour * 60 + chktime.tm_min
70                                         chktimecmp_end = chktimecmp + (duration / 60)
71                                 time = localtime(x.timebegin)
72                                 for y in range(7):
73                                         if x.repeated & (2 ** y):
74                                                 timecmp = y * 1440 + time.tm_hour * 60 + time.tm_min
75                                                 if timecmp <= chktimecmp < (timecmp + ((x.timeend - x.timebegin) / 60)):
76                                                         time_match = ((timecmp + ((x.timeend - x.timebegin) / 60)) - chktimecmp) * 60
77                                                 elif chktimecmp <= timecmp < chktimecmp_end:
78                                                         time_match = (chktimecmp_end - timecmp) * 60
79                         else: 
80                                 if begin <= x.timebegin <= end:
81                                         diff = end - x.timebegin
82                                         if time_match < diff:
83                                                 time_match = diff
84                                 elif x.timebegin <= begin <= x.timeend:
85                                         diff = x.timeend - begin
86                                         if time_match < diff:
87                                                 time_match = diff
88                         if time_match:
89                                 if getTimerType(service, begin, duration, eventid, timer_list):
90                                         timerentry = x
91                                 break
92         return timerentry
93
94
95 class E2Timer:
96         def __init__(self, servicereference = "", servicename = "", name = "", disabled = 0, timebegin = 0, timeend = 0, duration = 0, startprepare = 0, state = 0, repeated = 0, justplay = 0, eventId = 0, afterevent = 0, dirname = "", description = "", type = 0):
97                 self.servicereference = servicereference
98                 self.servicename = servicename
99                 self.name = name
100                 self.disabled = disabled
101                 self.timebegin = timebegin
102                 self.timeend = timeend
103                 self.duration = duration
104                 self.startprepare = startprepare
105                 self.state = state
106                 self.repeated = repeated
107                 self.justplay = justplay
108                 self.eventId = eventId
109                 self.afterevent = afterevent
110                 self.dirname = dirname
111                 self.description = description
112                 self.type = type
113                 if type != 0: # E1 Timerlist
114                         self.timeend = timebegin + duration
115                         self.name = description
116                         if type & PlaylistEntry.isRepeating:
117                                 self.repeated = 1
118                         self.dirname = "/hdd/movie/"
119
120 def FillE2TimerList(xmlstring, sreference = None):
121         E2TimerList = []
122         try: root = xml.etree.cElementTree.fromstring(xmlstring)
123         except: return E2TimerList
124         for timer in root.findall("e2timer"):
125                 go = False
126                 state = int(timer.findtext("e2state", 0))
127                 disabled = int(timer.findtext("e2disabled", 0))
128                 servicereference = str(timer.findtext("e2servicereference", '').encode("utf-8", 'ignore'))
129                 if sreference is None:
130                         go = True
131                 else:
132                         if sreference.upper() == servicereference.upper() and state != TimerEntry.StateEnded and not disabled:
133                                 go = True
134                 if go:
135                         eventId = timer.findtext("e2eit", -1)
136                         if eventId is None: eventId = -1
137                         E2TimerList.append(E2Timer(
138                                 servicereference = servicereference,
139                                 servicename = str(timer.findtext("e2servicename", 'n/a').encode("utf-8", 'ignore')),
140                                 name = str(timer.findtext("e2name", '').encode("utf-8", 'ignore')),
141                                 disabled = disabled,
142                                 timebegin = int(timer.findtext("e2timebegin", 0)),
143                                 timeend = int(timer.findtext("e2timeend", 0)),
144                                 duration = int(timer.findtext("e2duration", 0)),
145                                 startprepare = int(timer.findtext("e2startprepare", 0)),
146                                 state = state,
147                                 repeated = int(timer.findtext("e2repeated", 0)),
148                                 justplay = int(timer.findtext("e2justplay", 0)),
149                                 eventId = eventId,
150                                 afterevent = int(timer.findtext("e2afterevent", 0)),
151                                 dirname = str(timer.findtext("e2dirname", '').encode("utf-8", 'ignore')),
152                                 description = str(timer.findtext("e2description", '').encode("utf-8", 'ignore')),
153                                 type = 0))
154         return E2TimerList
155
156
157 def FillE1TimerList(xmlstring, sreference = None):
158         E1TimerList = []
159         try: root = xml.etree.cElementTree.fromstring(xmlstring)
160         except: return E1TimerList
161         for timer in root.findall("timer"):
162                 typedata = int(timer.findtext("typedata", 0))
163                 for service in timer.findall("service"):
164                         servicereference = str(service.findtext("reference", '').encode("utf-8", 'ignore'))
165                         servicename = str(service.findtext("name", 'n/a').encode("utf-8", 'ignore'))
166                 for event in timer.findall("event"):
167                         timebegin = int(event.findtext("start", 0))
168                         duration = int(event.findtext("duration", 0))
169                         description = str(event.findtext("description", '').encode("utf-8", 'ignore'))
170                 go = False
171                 if sreference is None:
172                         go = True
173                 else:
174                         if sreference.upper() == servicereference.upper() and ( (typedata & PlaylistEntry.stateWaiting) or (typedata & PlaylistEntry.stateRunning)):
175                                 go = True
176                 if go:
177                         E1TimerList.append(E2Timer(servicereference = servicereference, servicename = servicename, name = "", disabled = 0, timebegin = timebegin, timeend = 0, duration = duration, startprepare = 0, state = 0 , repeated = 0, justplay= 0, eventId = -1, afterevent = 0, dirname = "", description = description, type = typedata))
178         return E1TimerList
179
180 class myHTTPClientFactory(HTTPClientFactory):
181         def __init__(self, url, method='GET', postdata=None, headers=None,
182         agent="Twisted Remotetimer", timeout=0, cookies=None,
183         followRedirect=1, lastModified=None, etag=None):
184                 HTTPClientFactory.__init__(self, url, method=method, postdata=postdata,
185                 headers=headers, agent=agent, timeout=timeout, cookies=cookies,followRedirect=followRedirect)
186
187
188 def sendPartnerBoxWebCommand(url, contextFactory=None, timeout=60, username = "root", password = "", *args, **kwargs):
189         scheme, host, port, path = client._parse(url)
190         basicAuth = encodestring(("%s:%s")%(username,password))
191         authHeader = "Basic " + basicAuth.strip()
192         AuthHeaders = {"Authorization": authHeader}
193         if kwargs.has_key("headers"):
194                 kwargs["headers"].update(AuthHeaders)
195         else:
196                 kwargs["headers"] = AuthHeaders
197         factory = myHTTPClientFactory(url, *args, **kwargs)
198         reactor.connectTCP(host, port, factory, timeout=timeout)
199         return factory.deferred
200
201 class PlaylistEntry:
202
203         PlaylistEntry=1                 # normal PlaylistEntry (no Timerlist entry)
204         SwitchTimerEntry=2              #simple service switch timer
205         RecTimerEntry=4                 #timer do recording
206         
207         recDVR=8                                #timer do DVR recording
208         recVCR=16                               #timer do VCR recording (LIRC) not used yet
209         recNgrab=131072                 #timer do record via Ngrab Server
210
211         stateWaiting=32                 #timer is waiting
212         stateRunning=64                 #timer is running
213         statePaused=128                 #timer is paused
214         stateFinished=256               #timer is finished
215         stateError=512                  #timer has error state(s)
216
217         errorNoSpaceLeft=1024   #HDD no space Left ( recDVR )
218         errorUserAborted=2048   #User Action aborts this event
219         errorZapFailed=4096             #Zap to service failed
220         errorOutdated=8192              #Outdated event
221
222         boundFile=16384                 #Playlistentry have an bounded file
223         isSmartTimer=32768              #this is a smart timer (EIT related) not uses Yet
224         isRepeating=262144              #this timer is repeating
225         doFinishOnly=65536              #Finish an running event/action
226
227         doShutdown=67108864             #timer shutdown the box
228         doGoSleep=134217728             #timer set box to standby
229
230         Su=524288
231         Mo=1048576
232         Tue=2097152
233         Wed=4194304
234         Thu=8388608
235         Fr=16777216
236         Sa=33554432
237
238
239 def SetPartnerboxTimerlist(partnerboxentry = None, sreference = None):
240         global remote_timer_list
241         global CurrentIP
242         if partnerboxentry is None:
243                 return  
244         try:
245                 password = partnerboxentry.password.value
246                 username = "root"
247                 CurrentIP = partnerboxentry.ip.value
248                 ip = "%d.%d.%d.%d" % tuple(partnerboxentry.ip.value)
249                 port = partnerboxentry.port.value
250                 if int(partnerboxentry.enigma.value) == 0:
251                         sCommand = "http://%s:%s@%s:%d/web/timerlist" % (username, password, ip,port)
252                 else:
253                         sCommand = "http://%s:%s@%s:%d/xml/timers" % (username, password, ip,port)
254                 print "[RemoteEPGList] Getting timerlist data from %s..."%ip
255                 f = urllib.urlopen(sCommand)
256                 sxml = f.read()
257                 if int(partnerboxentry.enigma.value) == 0:
258                         remote_timer_list = FillE2TimerList(sxml, sreference)
259                 else:
260                         remote_timer_list = FillE1TimerList(sxml, sreference)
261         except: pass