Get timerlist from Partnerbox in a non-blocking way when opening EPGList (now it...
[enigma2-plugins.git] / partnerbox / src / PartnerboxEPGList.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 from Screens.Screen import Screen
21 from Components.config import config
22 from Components.EpgList import EPGList
23 from enigma import eListboxPythonMultiContent, \
24         RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_VALIGN_CENTER, RT_HALIGN_CENTER
25
26 from time import localtime
27
28 from Tools.LoadPixmap import LoadPixmap
29 from Tools.BoundFunction import boundFunction
30 from PartnerboxFunctions import FillE1TimerList, E2Timer, FillE2TimerList, SetPartnerboxTimerlist, sendPartnerBoxWebCommand
31 import PartnerboxFunctions as partnerboxfunctions
32
33 baseEPGList__init__ = None
34 basebuildSingleEntry = None
35 basebuildSimilarEntry = None
36 basebuildMultiEntry = None
37
38 def Partnerbox_EPGListInit():
39         global baseEPGList__init__, basebuildSingleEntry, basebuildSimilarEntry, basebuildMultiEntry
40         if baseEPGList__init__ is None:
41                 baseEPGList__init__ = EPGList.__init__
42         if basebuildSingleEntry is None:
43                 basebuildSingleEntry = EPGList.buildSingleEntry
44         if basebuildSimilarEntry is None:
45                 basebuildSimilarEntry = EPGList.buildSimilarEntry
46         if basebuildMultiEntry is None:
47                 basebuildMultiEntry = EPGList.buildMultiEntry
48         if partnerboxfunctions.remote_timer_list is None:
49                 partnerboxfunctions.remote_timer_list = []
50         EPGList.__init__ = Partnerbox_EPGList__init__
51         EPGList.buildSingleEntry = Partnerbox_SingleEntry
52         EPGList.buildSimilarEntry = Partnerbox_SimilarEntry
53         EPGList.buildMultiEntry = Partnerbox_MultiEntry
54
55 def Partnerbox_EPGList__init__(self, type=0, selChangedCB=None, timer = None):
56         baseEPGList__init__(self, type, selChangedCB, timer)
57         partnerboxfunctions.remote_timer_list = []
58         if int(config.plugins.Partnerbox.entriescount.value) >= 1:
59                 try:
60                         partnerboxentry = config.plugins.Partnerbox.Entries[0]
61                         partnerboxfunctions.CurrentIP = partnerboxentry.ip.value
62                         ip = "%d.%d.%d.%d" % tuple(partnerboxentry.ip.value)
63                         port = partnerboxentry.port.value
64                         http = "http://%s:%d" % (ip,port)
65                         if int(partnerboxentry.enigma.value) == 0:
66                                 sCommand = http + "web/timerlist"
67                         else:
68                                 sCommand = http + "/xml/timers"
69                         sendPartnerBoxWebCommand(sCommand, None,3, "root", partnerboxentry.password.value).addCallback(boundFunction(GetPartnerboxTimerlistCallback,self, int(partnerboxentry.enigma.value))).addErrback(boundFunction(GetPartnerboxTimerlistCallbackError,self))
70                 except: pass
71         # Partnerbox Clock Icons
72         self.remote_clock_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock.png')
73         self.remote_clock_add_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock_add.png')
74         self.remote_clock_pre_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock_pre.png')
75         self.remote_clock_post_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock_post.png')
76         self.remote_clock_prepost_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock_prepost.png')
77
78 def GetPartnerboxTimerlistCallback(self, enigma_type, sxml = None):
79         if sxml is not None:
80                 if enigma_type == 0:
81                         partnerboxfunctions.remote_timer_list = FillE2TimerList(sxml)
82                 else:
83                         partnerboxfunctions.remote_timer_list = FillE1TimerList(sxml)
84         if len(partnerboxfunctions.remote_timer_list) != 0:
85                 self.l.invalidate()
86
87 def GetPartnerboxTimerlistCallbackError(self, error = None):
88         if error is not None:
89                 print str(error.getErrorMessage())
90
91
92 def Partnerbox_SingleEntry(self, service, eventId, beginTime, duration, EventName):
93         rec1=beginTime and (self.timer.isInTimer(eventId, beginTime, duration, service))
94         rec2=beginTime and (isInRemoteTimer(self,beginTime, duration, service))
95         r1=self.weekday_rect
96         r2=self.datetime_rect
97         r3=self.descr_rect
98         t = localtime(beginTime)
99         res = [
100                 None, # no private data needed
101                 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_RIGHT, self.days[t[6]]),
102                 (eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_RIGHT, "%02d.%02d, %02d:%02d"%(t[2],t[1],t[3],t[4]))
103         ]
104         if rec1 or rec2:
105                 if rec1:                        
106                         clock_pic = self.getClockPixmap(service, beginTime, duration, eventId)
107                         #eventuell auch in der Partnerbox
108                         if rec2:
109                                 clock_pic_partnerbox = getRemoteClockPixmap(self,service, beginTime, duration, eventId)
110                 else:
111                         clock_pic = getRemoteClockPixmap(self,service, beginTime, duration, eventId)
112                 if rec1 and rec2:
113                         # wenn sowohl lokal als auch auf Partnerbox
114                         res.extend((
115                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic),
116                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left() + 25, r3.top(), 21, 21, clock_pic_partnerbox),
117                                 (eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 50, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, EventName)))
118                 else:
119                         res.extend((
120                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic),
121                                 (eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 25, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, EventName)))
122         else:
123                 res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, EventName))
124         return res
125
126
127 def Partnerbox_SimilarEntry(self, service, eventId, beginTime, service_name, duration):
128         rec1=beginTime and (self.timer.isInTimer(eventId, beginTime, duration, service))
129         rec2=beginTime and (isInRemoteTimer(self,beginTime, duration, service))
130         r1=self.weekday_rect
131         r2=self.datetime_rect
132         r3=self.service_rect
133         t = localtime(beginTime)
134         res = [
135                 None,  # no private data needed
136                 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_RIGHT, self.days[t[6]]),
137                 (eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_RIGHT, "%02d.%02d, %02d:%02d"%(t[2],t[1],t[3],t[4]))
138         ]
139         if rec1 or rec2:
140                 if rec1:                        
141                         clock_pic = self.getClockPixmap(service, beginTime, duration, eventId)
142                         #eventuell auch in der Partnerbox
143                         if rec2:
144                                 clock_pic_partnerbox = getRemoteClockPixmap(self,service, beginTime, duration, eventId)
145                 else:
146                         clock_pic = getRemoteClockPixmap(self,service, beginTime, duration, eventId)
147                 if rec1 and rec2:
148                         # wenn sowohl lokal als auch auf Partnerbox
149                         res.extend((
150                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic),
151                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left() + 25, r3.top(), 21, 21, clock_pic_partnerbox),
152                                 (eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 50, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, service_name)
153                         ))
154                 else:
155                         res.extend((
156                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic),
157                                 (eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 25, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, service_name)
158                         ))
159         else:
160                 res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, service_name))
161         return res
162
163 def Partnerbox_MultiEntry(self, changecount, service, eventId, begTime, duration, EventName, nowTime, service_name):
164         # so wie es aussieht wird der MultiEPG ueber ein Plugin angefahren...lasse den Code dennoch mal drinnen...
165         rec1=begTime and (self.timer.isInTimer(eventId, begTime, duration, service))
166         rec2=begTime and (isInRemoteTimer(self,begTime, duration, service))
167         r1=self.service_rect
168         r2=self.progress_rect
169         r3=self.descr_rect
170         r4=self.start_end_rect
171         res = [ None ] # no private data needed
172         if rec1 or rec2:
173                 if rec1:                        
174                         clock_pic = self.getClockPixmap(service, begTime, duration, eventId)
175                         #eventuell auch in der Partnerbox
176                         if rec2:
177                                 clock_pic_partnerbox = getRemoteClockPixmap(self,service, begTime, duration, eventId)
178                 else:
179                         clock_pic = getRemoteClockPixmap(self,service, begTime, duration, eventId)
180                 if rec1 and rec2:
181                         # wenn sowohl lokal als auch auf Partnerbox
182                         res.extend((
183                                 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width()-41, r1.height(), 0, RT_HALIGN_LEFT, service_name),
184                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r1.left()+r1.width()-32, r1.top(), 21, 21, clock_pic),
185                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r1.left()+r1.width()-16, r1.top(), 21, 21, clock_pic_partnerbox)
186                         ))
187                 else:
188                         res.extend((
189                                 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width()-21, r1.height(), 0, RT_HALIGN_LEFT, service_name),
190                                 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r1.left()+r1.width()-16, r1.top(), 21, 21, clock_pic)
191                         ))
192         else:
193                 res.append((eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_LEFT, service_name))
194         if begTime is not None:
195                 if nowTime < begTime:
196                         begin = localtime(begTime)
197                         end = localtime(begTime+duration)
198                         res.extend((
199                                 (eListboxPythonMultiContent.TYPE_TEXT, r4.left(), r4.top(), r4.width(), r4.height(), 1, RT_HALIGN_CENTER|RT_VALIGN_CENTER, "%02d.%02d - %02d.%02d"%(begin[3],begin[4],end[3],end[4])),
200                                 (eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, EventName)
201                         ))
202                 else:
203                         percent = (nowTime - begTime) * 100 / duration
204                         res.extend((
205                                 (eListboxPythonMultiContent.TYPE_PROGRESS, r2.left(), r2.top(), r2.width(), r2.height(), percent),
206                                 (eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, EventName)
207                         ))
208         return res
209
210
211
212 def isInRemoteTimer(self, begin, duration, service):
213         time_match = 0
214         chktime = None
215         chktimecmp = None
216         chktimecmp_end = None
217         end = begin + duration
218         for x in partnerboxfunctions.remote_timer_list:
219                 if x.servicereference.upper() == service.upper():
220                         if x.repeated != 0:
221                                 if chktime is None:
222                                         chktime = localtime(begin)
223                                         chktimecmp = chktime.tm_wday * 1440 + chktime.tm_hour * 60 + chktime.tm_min
224                                         chktimecmp_end = chktimecmp + (duration / 60)
225                                 time = localtime(x.timebegin)
226                                 for y in range(7):
227                                         if x.repeated & (2 ** y):
228                                                 timecmp = y * 1440 + time.tm_hour * 60 + time.tm_min
229                                                 if timecmp <= chktimecmp < (timecmp + ((x.timeend - x.timebegin) / 60)):
230                                                         time_match = ((timecmp + ((x.timeend - x.timebegin) / 60)) - chktimecmp) * 60
231                                                 elif chktimecmp <= timecmp < chktimecmp_end:
232                                                         time_match = (chktimecmp_end - timecmp) * 60
233                         else:
234                                 if begin <= x.timebegin <= end:
235                                         diff = end - x.timebegin
236                                         if time_match < diff:
237                                                 time_match = diff
238                                 elif x.timebegin <= begin <= x.timeend:
239                                         diff = x.timeend - begin
240                                         if time_match < diff:
241                                                 time_match = diff
242                         if time_match:
243                                 break
244         return time_match
245
246
247 def getRemoteClockPixmap(self, refstr, beginTime, duration, eventId):
248         pre_clock = 1
249         post_clock = 2
250         clock_type = 0
251         endTime = beginTime + duration
252         for x in partnerboxfunctions.remote_timer_list:
253                 if x.servicereference.upper() == refstr.upper():
254                         if x.eventId == eventId:
255                                 return self.remote_clock_pixmap
256                         beg = x.timebegin
257                         end = x.timeend
258                         if beginTime > beg and beginTime < end and endTime > end:
259                                 clock_type |= pre_clock
260                         elif beginTime < beg and endTime > beg and endTime < end:
261                                 clock_type |= post_clock
262         if clock_type == 0:
263                 return self.remote_clock_add_pixmap
264         elif clock_type == pre_clock:
265                 return self.remote_clock_pre_pixmap
266         elif clock_type == post_clock:
267                 return self.remote_clock_post_pixmap
268         else:
269                 return self.remote_clock_prepost_pixmap
270