New:
[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 twisted.internet import reactor
22 from twisted.web import client
23 from twisted.web.client import HTTPClientFactory
24 from base64 import encodestring
25 import xml.dom.minidom
26
27 remote_timer_list = None
28 oldIP = None
29
30 def getTimerType(refstr, beginTime, duration, eventId, timer_list):
31         pre = 1
32         post = 2
33         type = 0
34         endTime = beginTime + duration
35         for x in timer_list:
36                 if x.servicereference.upper() == refstr.upper():
37                         if x.eventId == eventId:
38                                 return True
39                         beg = x.timebegin
40                         end = x.timeend
41                         if beginTime > beg and beginTime < end and endTime > end:
42                                 type |= pre
43                         elif beginTime < beg and endTime > beg and endTime < end:
44                                 type |= post
45         if type == 0:
46                 return True
47         elif type == pre:
48                 return False
49         elif type == post:
50                 return False
51         else:
52                 return True
53
54 def isInTimerList(begin, duration, service, eventid, timer_list):
55         time_match = 0
56         chktime = None
57         chktimecmp = None
58         chktimecmp_end = None
59         end = begin + duration
60         timerentry = None
61         for x in timer_list:
62                 if x.servicereference.upper() == service.upper():
63                         if x.repeated != 0:
64                                 if chktime is None:
65                                         chktime = localtime(begin)
66                                         chktimecmp = chktime.tm_wday * 1440 + chktime.tm_hour * 60 + chktime.tm_min
67                                         chktimecmp_end = chktimecmp + (duration / 60)
68                                 time = localtime(x.timebegin)
69                                 for y in range(7):
70                                         if x.repeated & (2 ** y):
71                                                 timecmp = y * 1440 + time.tm_hour * 60 + time.tm_min
72                                                 if timecmp <= chktimecmp < (timecmp + ((x.timeend - x.timebegin) / 60)):
73                                                         time_match = ((timecmp + ((x.timeend - x.timebegin) / 60)) - chktimecmp) * 60
74                                                 elif chktimecmp <= timecmp < chktimecmp_end:
75                                                         time_match = (chktimecmp_end - timecmp) * 60
76                         else: 
77                                 if begin <= x.timebegin <= end:
78                                         diff = end - x.timebegin
79                                         if time_match < diff:
80                                                 time_match = diff
81                                 elif x.timebegin <= begin <= x.timeend:
82                                         diff = x.timeend - begin
83                                         if time_match < diff:
84                                                 time_match = diff
85                         if time_match:
86                                 if getTimerType(service, begin, duration, eventid, timer_list):
87                                         timerentry = x
88                                 break
89         return timerentry
90
91
92 class E2Timer:
93         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):
94                 self.servicereference = servicereference
95                 self.servicename = servicename
96                 self.name = name
97                 self.disabled = disabled
98                 self.timebegin = timebegin
99                 self.timeend = timeend
100                 self.duration = duration
101                 self.startprepare = startprepare
102                 self.state = state
103                 self.repeated = repeated
104                 self.justplay = justplay
105                 self.eventId = eventId
106                 self.afterevent = afterevent
107                 self.dirname = dirname
108                 self.description = description
109                 self.type = type
110                 if type != 0: # E1 Timerlist
111                         self.timeend = timebegin + duration
112                         self.name = description
113                         if type & PlaylistEntry.isRepeating:
114                                 self.repeated = 1
115                         self.dirname = "/hdd/movie/"
116
117 def FillE2TimerList(xmlstring):
118         E2TimerList = []
119         dom = xml.dom.minidom.parseString(xmlstring)
120         for node in dom.firstChild.childNodes:
121                 servicereference = ""
122                 servicename = ""
123                 name = ""
124                 disabled = 0
125                 timebegin = 0
126                 timeend = 0
127                 duration = 0
128                 startprepare = 0
129                 state = 0
130                 repeated = 0
131                 justplay = 0
132                 eventId = -1
133                 afterevent = 0
134                 dirname = ""
135                 description = ""
136                 if node.nodeName == "e2timer":
137                         for node2 in node.childNodes:
138                                 if node2.nodeName == "e2servicereference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
139                                 if node2.nodeName == "e2servicename":
140                                         try:servicename = str(node2.firstChild.data.strip().encode("utf-8"))
141                                         except:servicename = "n/a"
142                                 if node2.nodeName == "e2eit": 
143                                         try: eventId = int(node2.firstChild.data.strip())
144                                         except: pass
145                                 if node2.nodeName == "e2name":
146                                         try:name = str(node2.firstChild.data.strip().encode("utf-8"))
147                                         except:name = ""
148                                 if node2.nodeName == "e2description":
149                                         try:description = str(node2.firstChild.data.strip().encode("utf-8"))
150                                         except:description = ""
151                                 if node2.nodeName == "e2dirname" or node2.nodeName == "e2location": # vorerst Kompatibilitaet zum alten Webinterface-Api aufrecht erhalten (e2dirname)
152                                         try:dirname = str(node2.firstChild.data.strip().encode("utf-8"))
153                                         except:dirname = ""
154                                 if node2.nodeName == "e2afterevent": afterevent = int(node2.firstChild.data.strip())
155                                 if node2.nodeName == "e2disabled": disabled = int(node2.firstChild.data.strip())
156                                 if node2.nodeName == "e2timebegin": timebegin = int(node2.firstChild.data.strip())
157                                 if node2.nodeName == "e2timeend": timeend = int(node2.firstChild.data.strip())
158                                 if node2.nodeName == "e2duration": duration = int(node2.firstChild.data.strip())
159                                 if node2.nodeName == "e2startprepare": startprepare = int(node2.firstChild.data.strip())
160                                 if node2.nodeName == "e2state":  state= int(node2.firstChild.data.strip())
161                                 if node2.nodeName == "e2justplay":  justplay= int(node2.firstChild.data.strip())
162                                 if node2.nodeName == "e2repeated":
163                                         repeated= int(node2.firstChild.data.strip())
164                                         E2TimerList.append(E2Timer(servicereference = servicereference, servicename = servicename, name = name, disabled = disabled, timebegin = timebegin, timeend = timeend, duration = duration, startprepare = startprepare, state = state , repeated = repeated, justplay= justplay, eventId = eventId, afterevent = afterevent, dirname = dirname, description = description, type = 0 ))
165         return E2TimerList
166
167
168 def FillE1TimerList(xmlstring):
169         E1TimerList = []
170         dom = xml.dom.minidom.parseString(xmlstring)
171         for node in dom.firstChild.childNodes:
172                 type = 0
173                 servicereference = ""
174                 servicename = ""
175                 name = ""
176                 disabled = 0
177                 timebegin = 0
178                 timeend = 0
179                 duration = 0
180                 startprepare = 0
181                 state = 0
182                 repeated = 0
183                 justplay = 0
184                 eventId = -1
185                 afterevent = 0
186                 dirname = ""
187                 description = ""
188                 if node.nodeName == "timer":
189                         for node2 in node.childNodes:
190                                 if node2.nodeName == "typedata": type = int(node2.firstChild.data.strip())
191                                 if node2.nodeName == "service":
192                                         for node3 in node2.childNodes:
193                                                 if node3.nodeName == "reference": servicereference = str(node3.firstChild.data.strip().encode("utf-8"))
194                                                 if node3.nodeName == "name":
195                                                         try:servicename = str(node3.firstChild.data.strip().encode("utf-8"))
196                                                         except:servicename = "n/a"
197                                 if node2.nodeName == "event":
198                                         for node3 in node2.childNodes:
199                                                 if node3.nodeName == "start": timebegin = int(node3.firstChild.data.strip())
200                                                 if node3.nodeName == "duration": duration = int(node3.firstChild.data.strip())
201                                                 if node3.nodeName == "description":
202                                                         try:description = str(node3.firstChild.data.strip().encode("utf-8"))
203                                                         except:description = ""
204                                                         E1TimerList.append(E2Timer(servicereference = servicereference, servicename = servicename, name = name, disabled = disabled, timebegin = timebegin, timeend = timeend, duration = duration, startprepare = startprepare, state = state , repeated = repeated, justplay= justplay, eventId = eventId, afterevent = afterevent, dirname = dirname, description = description, type = type))
205         return E1TimerList
206
207 class myHTTPClientFactory(HTTPClientFactory):
208         def __init__(self, url, method='GET', postdata=None, headers=None,
209         agent="Twisted Remotetimer", timeout=0, cookies=None,
210         followRedirect=1, lastModified=None, etag=None):
211                 HTTPClientFactory.__init__(self, url, method=method, postdata=postdata,
212                 headers=headers, agent=agent, timeout=timeout, cookies=cookies,followRedirect=followRedirect)
213
214
215 def sendPartnerBoxWebCommand(url, contextFactory=None, timeout=60, username = "root", password = "", *args, **kwargs):
216         scheme, host, port, path = client._parse(url)
217         basicAuth = encodestring(("%s:%s")%(username,password))
218         authHeader = "Basic " + basicAuth.strip()
219         AuthHeaders = {"Authorization": authHeader}
220         if kwargs.has_key("headers"):
221                 kwargs["headers"].update(AuthHeaders)
222         else:
223                 kwargs["headers"] = AuthHeaders
224         factory = myHTTPClientFactory(url, *args, **kwargs)
225         reactor.connectTCP(host, port, factory, timeout=timeout)
226         return factory.deferred
227
228 class PlaylistEntry:
229
230         PlaylistEntry=1                 # normal PlaylistEntry (no Timerlist entry)
231         SwitchTimerEntry=2              #simple service switch timer
232         RecTimerEntry=4                 #timer do recording
233         
234         recDVR=8                                #timer do DVR recording
235         recVCR=16                               #timer do VCR recording (LIRC) not used yet
236         recNgrab=131072                 #timer do record via Ngrab Server
237
238         stateWaiting=32                 #timer is waiting
239         stateRunning=64                 #timer is running
240         statePaused=128                 #timer is paused
241         stateFinished=256               #timer is finished
242         stateError=512                  #timer has error state(s)
243
244         errorNoSpaceLeft=1024   #HDD no space Left ( recDVR )
245         errorUserAborted=2048   #User Action aborts this event
246         errorZapFailed=4096             #Zap to service failed
247         errorOutdated=8192              #Outdated event
248
249         boundFile=16384                 #Playlistentry have an bounded file
250         isSmartTimer=32768              #this is a smart timer (EIT related) not uses Yet
251         isRepeating=262144              #this timer is repeating
252         doFinishOnly=65536              #Finish an running event/action
253
254         doShutdown=67108864             #timer shutdown the box
255         doGoSleep=134217728             #timer set box to standby
256
257         Su=524288
258         Mo=1048576
259         Tue=2097152
260         Wed=4194304
261         Thu=8388608
262         Fr=16777216
263         Sa=33554432
264
265
266 def SetPartnerboxTimerlist(partnerboxentry = None):
267         global remote_timer_list
268         global CurrentIP
269         if partnerboxentry is None:
270                 return  
271         try:
272                 password = partnerboxentry.password.value
273                 username = "root"
274                 CurrentIP = partnerboxentry.ip.value
275                 ip = "%d.%d.%d.%d" % tuple(partnerboxentry.ip.value)
276                 port = partnerboxentry.port.value
277                 if int(partnerboxentry.enigma.value) == 0:
278                         sCommand = "http://%s:%s@%s:%d/web/timerlist" % (username, password, ip,port)
279                 else:
280                         sCommand = "http://%s:%s@%s:%d/xml/timers" % (username, password, ip,port)
281                 print "[RemoteEPGList] Getting timerlist data from %s..."%ip
282                 f = urllib.urlopen(sCommand)
283                 sxml = f.read()
284                 if int(partnerboxentry.enigma.value) == 0:
285                         remote_timer_list = FillE2TimerList(sxml)
286                 else:
287                         remote_timer_list = FillE1TimerList(sxml)
288         except: pass