Added Partnerbox Plugin (Remote Timer and Remote TV Player)
[enigma2-plugins.git] / partnerbox / src / plugin.py
1 #
2 #  Partnerbox E2
3 #  Release: 0.93
4 #  Coded by Dr.Best (c) 2009
5 #  Support: www.dreambox-tools.info
6 #
7 #  This program is free software; you can redistribute it and/or
8 #  modify it under the terms of the GNU General Public License
9 #  as published by the Free Software Foundation; either version 2
10 #  of the License, or (at your option) any later version.
11 #
12 #  This program is distributed in the hope that it will be useful,
13 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #  GNU General Public License for more details.
16 #
17
18 from Plugins.Plugin import PluginDescriptor
19 from Screens.Screen import Screen
20 from Screens.MessageBox import MessageBox
21 from Screens.ChoiceBox import ChoiceBox
22 from Components.config import config
23 from Components.ScrollLabel import ScrollLabel
24 from Components.ActionMap import ActionMap, NumberActionMap
25 from Components.MenuList import MenuList
26 from Components.Label import Label
27 from Components.EpgList import Rect
28 from enigma import eServiceReference
29 from enigma import eListboxPythonMultiContent, eListbox, gFont, \
30         RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_VALIGN_CENTER
31 from Tools.LoadPixmap import LoadPixmap
32 from Tools.Directories import resolveFilename, SCOPE_SKIN_IMAGE
33 from Tools.FuzzyDate import FuzzyTime
34 from timer import TimerEntry
35 from enigma import eTimer
36 from time import localtime
37 import time
38 import xml.dom.minidom
39 import urllib
40 import SocketServer
41 import servicewebts
42 ENIGMA_WEBSERVICE_ID = 0x1012
43 from Screens.InfoBarGenerics import InfoBarAudioSelection
44 from RemoteTimerEntry import RemoteTimerEntry, PlaylistEntry, RemoteTimerInit, sendPartnerBoxWebCommand
45 import time
46
47 from Services import Services, E2EPGListAllData, E2ServiceList
48 from Screens.ChannelSelection import service_types_tv
49
50 from Components.ConfigList import ConfigList, ConfigListScreen
51 from Components.config import ConfigSubsection, ConfigIP, ConfigInteger, ConfigSelection, ConfigText, ConfigYesNo, getConfigListEntry, configfile
52
53 config.plugins.partnerbox = ConfigSubsection()
54 config.plugins.partnerbox.ip = ConfigIP(default = [192,168,0,98])
55 config.plugins.partnerbox.port = ConfigInteger(default=80, limits=(1, 65555))
56 config.plugins.partnerbox.enigma = ConfigSelection(default="0", choices = [("0", _("Enigma 2")),("1", _("Enigma 1"))])
57 config.plugins.partnerbox.password = ConfigText(default = "dreambox", visible_width = 50, fixed_size = False)
58 config.plugins.partnerbox.useinternal = ConfigSelection(default="1", choices = [("0", _("use external")),("1", _("use internal"))])
59 config.plugins.partnerbox.showremotetvinextensionsmenu= ConfigYesNo(default = True)
60 config.plugins.partnerbox.showcurrentstreaminextensionsmenu= ConfigYesNo(default = True)
61 config.plugins.partnerbox.showremotetimerinextensionsmenu= ConfigYesNo(default = True)
62 config.plugins.partnerbox.enablepartnerboxintimerevent = ConfigYesNo(default = False)
63
64 def autostart(reason, **kwargs):
65         if "session" in kwargs:
66                 session = kwargs["session"]
67                 try:
68                         RemoteTimerInit()
69                 except: pass
70
71 def main(session,**kwargs):
72         session.open(RemoteTimer)
73
74 def setup(session,**kwargs):
75         session.open(PartnerboxSetup)
76
77 def currentremotetv(session,**kwargs):
78         session.open(CurrentRemoteTV)
79         
80 def remotetvplayer(session,**kwargs):
81
82         useinternal = int(config.plugins.partnerbox.useinternal.value)
83         password = config.plugins.partnerbox.password.value
84         username = "root"
85         ip = "%d.%d.%d.%d" % tuple(config.plugins.partnerbox.ip.value)
86         port = config.plugins.partnerbox.port.value
87         http = "http://%s:%d" % (ip,port)
88         enigma_type = int(config.plugins.partnerbox.enigma.value)
89         E2TimerList = []
90         session.open(RemoteTimerBouquetList, E2TimerList, username,password, http, enigma_type, useinternal, 1)
91
92 def Plugins(**kwargs):
93         list = [PluginDescriptor(name="Partnerbox: RemoteTimer", description=_("Manage timer for other dreamboxes in network"), 
94                 where = [PluginDescriptor.WHERE_EVENTINFO ], fnc=main)]
95         if config.plugins.partnerbox.enablepartnerboxintimerevent.value:
96                 list.append(PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, fnc = autostart))
97         list.append(PluginDescriptor(name="Setup Partnerbox", description=_("setup for partnerbox"), where = [PluginDescriptor.WHERE_PLUGINMENU], fnc=setup))
98         if config.plugins.partnerbox.showremotetimerinextensionsmenu:
99                 list.append(PluginDescriptor(name="Partnerbox: RemoteTimer", description=_("Manage timer for other dreamboxes in network"), 
100                 where = [PluginDescriptor.WHERE_EXTENSIONSMENU], fnc=main))
101         if config.plugins.partnerbox.showremotetvinextensionsmenu.value:
102                 list.append(PluginDescriptor(name="Partnerbox: RemoteTV Player", description=_("Stream TV from your Partnerbox"), where = [PluginDescriptor.WHERE_EXTENSIONSMENU], fnc=remotetvplayer))
103         if config.plugins.partnerbox.showcurrentstreaminextensionsmenu.value:
104                 list.append(PluginDescriptor(name="Stream current Service from Partnerbox", description=_("Stream current service from partnerbox"), where = [PluginDescriptor.WHERE_EXTENSIONSMENU], fnc=currentremotetv))
105         
106         return list
107                         
108 def getTimerType(refstr, beginTime, duration, eventId, timer_list):
109         pre = 1
110         post = 2
111         type = 0
112         endTime = beginTime + duration
113         for x in timer_list:
114                 if x.servicereference.upper() == refstr.upper():
115                         if x.eventId == eventId:
116                                 return True
117                         beg = x.timebegin
118                         end = x.timeend
119                         if beginTime > beg and beginTime < end and endTime > end:
120                                 type |= pre
121                         elif beginTime < beg and endTime > beg and endTime < end:
122                                 type |= post
123         if type == 0:
124                 return True
125         elif type == pre:
126                 return False
127         elif type == post:
128                 return False
129         else:
130                 return True
131
132 def isInTimerList(begin, duration, service, eventid, timer_list):
133         time_match = 0
134         chktime = None
135         chktimecmp = None
136         chktimecmp_end = None
137         end = begin + duration
138         timerentry = None
139         for x in timer_list:
140                 if x.servicereference.upper() == service.upper():
141                         if x.repeated != 0:
142                                 if chktime is None:
143                                         chktime = localtime(begin)
144                                         chktimecmp = chktime.tm_wday * 1440 + chktime.tm_hour * 60 + chktime.tm_min
145                                         chktimecmp_end = chktimecmp + (duration / 60)
146                                 time = localtime(x.timebegin)
147                                 for y in range(7):
148                                         if x.repeated & (2 ** y):
149                                                 timecmp = y * 1440 + time.tm_hour * 60 + time.tm_min
150                                                 if timecmp <= chktimecmp < (timecmp + ((x.timeend - x.timebegin) / 60)):
151                                                         time_match = ((timecmp + ((x.timeend - x.timebegin) / 60)) - chktimecmp) * 60
152                                                 elif chktimecmp <= timecmp < chktimecmp_end:
153                                                         time_match = (chktimecmp_end - timecmp) * 60
154                         else: 
155                                 if begin <= x.timebegin <= end:
156                                         diff = end - x.timebegin
157                                         if time_match < diff:
158                                                 time_match = diff
159                                 elif x.timebegin <= begin <= x.timeend:
160                                         diff = x.timeend - begin
161                                         if time_match < diff:
162                                                 time_match = diff
163                         if time_match:
164                                 if getTimerType(service, begin, duration, eventid, timer_list):
165                                         timerentry = x
166                                 break
167         return timerentry
168
169 def FillE2TimerList(xmlstring):
170         E2TimerList = []
171         dom = xml.dom.minidom.parseString(xmlstring)
172         for node in dom.firstChild.childNodes:
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 == "e2timer":
189                         for node2 in node.childNodes:
190                                 if node2.nodeName == "e2servicereference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
191                                 if node2.nodeName == "e2servicename":
192                                         try:servicename = str(node2.firstChild.data.strip().encode("utf-8"))
193                                         except:servicename = "n/a"
194                                 if node2.nodeName == "e2eit": eventId = int(node2.firstChild.data.strip())
195                                 if node2.nodeName == "e2name":
196                                         try:name = str(node2.firstChild.data.strip().encode("utf-8"))
197                                         except:name = ""
198                                 if node2.nodeName == "e2description":
199                                         try:description = str(node2.firstChild.data.strip().encode("utf-8"))
200                                         except:description = ""
201                                 if node2.nodeName == "e2dirname":
202                                         try:dirname = str(node2.firstChild.data.strip().encode("utf-8"))
203                                         except:dirname = ""
204                                 if node2.nodeName == "e2afterevent": afterevent = int(node2.firstChild.data.strip())
205                                 if node2.nodeName == "e2disabled": disabled = int(node2.firstChild.data.strip())
206                                 if node2.nodeName == "e2timebegin": timebegin = int(node2.firstChild.data.strip())
207                                 if node2.nodeName == "e2timeend": timeend = int(node2.firstChild.data.strip())
208                                 if node2.nodeName == "e2duration": duration = int(node2.firstChild.data.strip())
209                                 if node2.nodeName == "e2startprepare": startprepare = int(node2.firstChild.data.strip())
210                                 if node2.nodeName == "e2state":  state= int(node2.firstChild.data.strip())
211                                 if node2.nodeName == "e2justplay":  justplay= int(node2.firstChild.data.strip())
212                                 if node2.nodeName == "e2repeated":
213                                         repeated= int(node2.firstChild.data.strip())
214                                         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 ))
215         return E2TimerList
216
217 def FillE1TimerList(xmlstring):
218         E1TimerList = []
219         dom = xml.dom.minidom.parseString(xmlstring)
220         for node in dom.firstChild.childNodes:
221                 type = 0
222                 servicereference = ""
223                 servicename = ""
224                 name = ""
225                 disabled = 0
226                 timebegin = 0
227                 timeend = 0
228                 duration = 0
229                 startprepare = 0
230                 state = 0
231                 repeated = 0
232                 justplay = 0
233                 eventId = -1
234                 afterevent = 0
235                 dirname = ""
236                 description = ""
237                 if node.nodeName == "timer":
238                         for node2 in node.childNodes:
239                                 if node2.nodeName == "typedata": type = int(node2.firstChild.data.strip())
240                                 if node2.nodeName == "service":
241                                         for node3 in node2.childNodes:
242                                                 if node3.nodeName == "reference": servicereference = str(node3.firstChild.data.strip().encode("utf-8"))
243                                                 if node3.nodeName == "name":
244                                                         try:servicename = str(node3.firstChild.data.strip().encode("utf-8"))
245                                                         except:servicename = "n/a"
246                                 if node2.nodeName == "event":
247                                         for node3 in node2.childNodes:
248                                                 if node3.nodeName == "start": timebegin = int(node3.firstChild.data.strip())
249                                                 if node3.nodeName == "duration": duration = int(node3.firstChild.data.strip())
250                                                 if node3.nodeName == "description":
251                                                         try:description = str(node3.firstChild.data.strip().encode("utf-8"))
252                                                         except:description = ""
253                                                         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 ))
254         return E1TimerList
255
256 class E2Timer:
257         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):
258                 self.servicereference = servicereference
259                 self.servicename = servicename
260                 self.name = name
261                 self.disabled = disabled
262                 self.timebegin = timebegin
263                 self.timeend = timeend
264                 self.duration = duration
265                 self.startprepare = startprepare
266                 self.state = state
267                 self.repeated = repeated
268                 self.justplay = justplay
269                 self.eventId = eventId
270                 self.afterevent = afterevent
271                 self.dirname = dirname
272                 self.description = description
273                 self.type = type
274                 if type != 0: # E1 Timerlist
275                         self.timeend = timebegin + duration
276                         self.name = description
277                         if type & PlaylistEntry.isRepeating:
278                                 self.repeated = 1
279                         self.dirname = "/hdd/movie/"
280                 
281 def FillLocationList(xmlstring):
282         Locations = []
283         dom = xml.dom.minidom.parseString(xmlstring)
284         for node in dom.firstChild.childNodes:
285                 dirname = ""
286                 if node.nodeName == "e2simplexmlitem":
287                         dirname = str(node.firstChild.data.strip().encode("utf-8"))
288                         Locations.append(dirname)
289         return Locations
290                 
291
292 class PartnerboxSetup(ConfigListScreen, Screen):
293         skin = """
294                 <screen position="100,100" size="550,400" title="Partnerbox Setup" >
295                 <widget name="config" position="20,10" size="510,380" scrollbarMode="showOnDemand" />
296                 </screen>"""
297
298         def __init__(self, session, args = None):
299                 Screen.__init__(self, session)
300                 self.list = [ ]
301                 self.list.append(getConfigListEntry(_("IP:"), config.plugins.partnerbox.ip))
302                 self.list.append(getConfigListEntry(_("Port:"), config.plugins.partnerbox.port))
303                 self.list.append(getConfigListEntry(_("Enigma Type:"), config.plugins.partnerbox.enigma))
304                 self.list.append(getConfigListEntry(_("Password:"), config.plugins.partnerbox.password))
305                 self.list.append(getConfigListEntry(_("Servicelists/EPG:"), config.plugins.partnerbox.useinternal))
306                 self.list.append(getConfigListEntry(_("Show 'RemoteTimer' in E-Menu:"), config.plugins.partnerbox.showremotetimerinextensionsmenu))
307                 self.list.append(getConfigListEntry(_("Show 'RemoteTV Player' in E-Menu:"), config.plugins.partnerbox.showremotetvinextensionsmenu))
308                 self.list.append(getConfigListEntry(_("Show 'Stream current Service' in E-Menu:"), config.plugins.partnerbox.showcurrentstreaminextensionsmenu))
309                 self.list.append(getConfigListEntry(_("Enable Partnerbox-Function in TimerEvent:"), config.plugins.partnerbox.enablepartnerboxintimerevent))
310                 ConfigListScreen.__init__(self, self.list, session)
311                 self["setupActions"] = ActionMap(["SetupActions"],
312                 {
313                         "save": self.save,
314                         "cancel": self.close,
315                         "ok": self.save,
316                 }, -2)
317
318         def save(self):
319                 ConfigListScreen.keySave(self)
320                 configfile.save()
321                 
322 class CurrentRemoteTV(Screen):
323         skin = """
324                 <screen name="CurrentRemoteTV" position="210,160" size="300,240" title="Remote Player">
325                 <widget name="text" position="10,10" zPosition="1" size="290,225" font="Regular;20" halign="center" valign="center" />
326         </screen>"""
327         def __init__(self, session, args = 0):
328                 self.session = session
329                 Screen.__init__(self, session)
330                 self.CurrentService = self.session.nav.getCurrentlyPlayingServiceReference()
331                 self.useinternal = int(config.plugins.partnerbox.useinternal.value)
332                 self.password = config.plugins.partnerbox.password.value
333                 self.username = "root"
334                 self.ip = "%d.%d.%d.%d" % tuple(config.plugins.partnerbox.ip.value)
335                 port = config.plugins.partnerbox.port.value
336                 self.http = "http://%s:%d" % (self.ip,port)
337                 self.enigma_type = int(config.plugins.partnerbox.enigma.value)
338                 if self.enigma_type == 1:
339                         self.url = self.http + "/video.m3u"
340                 else:
341                         self.url = self.http + "/web/getcurrent"
342                         
343                 tt = "Starting Remote Player (IP = %s)" % (self.ip)
344                 self["text"] = Label(tt)
345                 self.onLayoutFinish.append(self.startRun)
346         
347         def startRun(self):
348                 sendPartnerBoxWebCommand(self.url, None,10, self.username, self.password).addCallback(self.Callback).addErrback(self.Error)
349
350         def Callback(self, xmlstring):
351                 url = ""
352                 servicereference = ""
353                 if self.enigma_type == 0:
354                         dom = xml.dom.minidom.parseString(xmlstring)
355                         for node in dom.firstChild.childNodes:
356                                 if node.nodeName == "e2service":
357                                         for node2 in node.childNodes:
358                                                 if node2.nodeName == "e2servicereference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
359                         
360                         if len(servicereference) > 0:
361                                 url = "http://" + self.ip + ":8001/" + servicereference
362                         else:
363                                 self.close()
364                 else:
365                         url = xmlstring
366                 if len(url) > 0:
367                         self.session.nav.stopService()
368                         sref = eServiceReference(ENIGMA_WEBSERVICE_ID, 0, url)
369                         self.session.nav.playService(sref)
370                         self.session.openWithCallback(self.RemotePlayerFinished, RemotePlayer,"" ,"", 0, 0, self.password,self.username, servicereference, self.http , self.enigma_type, self.useinternal)
371                 else:
372                         self.close()
373                 
374         def RemotePlayerFinished(self):
375                 self.session.nav.playService(self.CurrentService)
376                 self.close()
377                 
378         def Error(self, error = None):
379                 self.close()
380
381 class RemoteTimer(Screen):
382         skin = """
383                 <screen name="RemoteTimer" position="90,95" size="560,430" title="RemoteTimer Editor">
384                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on"/>
385                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on"/>
386                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on"/>
387                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on"/>
388                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1"/>
389                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1"/>
390                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1"/>
391                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1"/>
392                         <widget name="text" position="0,60" zPosition="1" size="560,350" font="Regular;20" halign="center" valign="center" />
393                         <widget name="timerlist" position="0,60" zPosition="2" size="560,350" scrollbarMode="showOnDemand"/>
394                 </screen>"""
395         
396         timerlist = []
397         def __init__(self, session, args = 0):
398                 self.session = session
399                 Screen.__init__(self, session)
400                 self["timerlist"] = E2TimerMenu([])
401                 self["key_red"] = Label(_("Delete"))
402                 self["key_green"] = Label() # Dummy, kommt eventuell noch was
403                 self["key_yellow"] = Label(_("EPG Selection")) 
404                 self["key_blue"] = Label(_("Clean up"))
405                 self["text"] = Label(_("Getting Partnerbox Information..."))
406                 self.onLayoutFinish.append(self.startRun)
407                 self.E2TimerList = []
408                 self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EPGSelectActions"],
409                 {
410                         "ok": self.getLocations,
411                         "back": self.close,
412                         "yellow": self.EPGList,
413                         "blue": self.cleanupTimer,
414                         "red": self.deleteTimer,
415                         "input_date_time": self.configmenu,
416                 }, -1)
417
418                 self.password = config.plugins.partnerbox.password.value
419                 self.username = "root"
420                 ip = "%d.%d.%d.%d" % tuple(config.plugins.partnerbox.ip.value)
421                 port = config.plugins.partnerbox.port.value
422                 self.http = "http://%s:%d" % (ip,port)
423                 self.enigma_type = int(config.plugins.partnerbox.enigma.value)
424                 self.useinternal = int(config.plugins.partnerbox.useinternal.value)
425
426                 self.oldstart = 0
427                 self.oldend = 0
428                 self.oldtype = 0
429                 self.Locations = []
430                 
431         def getLocations(self):
432                 if self.enigma_type == 0:
433                         sCommand = self.http + "/web/getlocations"
434                         sendPartnerBoxWebCommand(sCommand, None,3, self.username, self.password).addCallback(self.getLocationsCallback).addErrback(self.deleteTimerError)
435                 else:
436                         self.addTimer()
437         
438         def getLocationsCallback(self, xmlstring):
439                 self.Locations = []
440                 self.Locations = FillLocationList(xmlstring)
441                 self.addTimer()
442
443         def addTimer(self):
444                 cur = self["timerlist"].getCurrent()
445                 if cur is None:
446                                 return
447                 if cur[0].repeated == 0:
448                         self.oldstart = cur[0].timebegin
449                         self.oldend = cur[0].timeend
450                         self.oldtype = cur[0].type
451                         self.session.openWithCallback(self.RemoteTimerEntryFinished, RemoteTimerEntry,cur[0], self.Locations)
452                 else:
453                         text = "Repeated Timer are not supported!"
454                         self.session.open(MessageBox,text,  MessageBox.TYPE_INFO)
455         
456         def RemoteTimerEntryFinished(self, answer):
457                 if answer[0]:
458                         entry = answer[1]
459                         self["timerlist"].instance.hide()
460                         if self.enigma_type == 0:
461                                 ref_old = "&channelOld=" + urllib.quote(entry.servicereference.decode('utf8').encode('latin-1','ignore')) + "&beginOld=" + ("%s"%(self.oldstart)) + "&endOld=" + ("%s"%(self.oldend))  + "&deleteOldOnSave=1"
462                                 ref = urllib.quote(entry.servicereference.decode('utf8').encode('latin-1','ignore')) + "&begin=" + ("%s"%(entry.timebegin)) + "&end=" + ("%s"%(entry.timeend))  + "&name=" + urllib.quote(entry.name) + "&description=" + urllib.quote(entry.description) + "&dirname=" + urllib.quote(entry.dirname) + "&eit=0&justplay=" + ("%s"%(entry.justplay)) + "&afterevent=" + ("%s"%(entry.afterevent))
463                                 sCommand = self.http + "/web/timerchange?sRef=" + ref + ref_old
464                                 sendPartnerBoxWebCommand(sCommand, None,10, self.username, self.password).addCallback(self.deleteTimerCallback).addErrback(self.downloadError)
465                         else:
466                                 if entry.justplay & PlaylistEntry.SwitchTimerEntry:
467                                         action = "zap"
468                                 elif entry.justplay & PlaylistEntry.recNgrab:
469                                         action = "ngrab"
470                                 else:
471                                         action = ""
472                                 tstart = time.localtime(entry.timebegin)
473                                 tend = time.localtime(entry.timeend)
474                                 ref_time_start = "&sday=" + ("%s"%(tstart.tm_mday)) + "&smonth=" + ("%s"%(tstart.tm_mon)) + "&syear=" + ("%s"%(tstart.tm_year)) + "&shour=" + ("%s"%(tstart.tm_hour)) + "&smin=" + ("%s"%(tstart.tm_min))
475                                 ref_time_end = "&eday=" + ("%s"%(tend.tm_mday)) + "&emonth=" + ("%s"%(tend.tm_mon)) + "&eyear=" + ("%s"%(tend.tm_year)) + "&ehour=" + ("%s"%(tend.tm_hour)) + "&emin=" + ("%s"%(tend.tm_min))
476                                 ref_old = "&old_type=" + ("%s"%(self.oldtype)) + "&old_stime=" + ("%s"%(self.oldstart)) + "&force=yes"
477                                 ref = urllib.quote(entry.servicereference.decode('utf8').encode('latin-1','ignore')) + "&descr=" + urllib.quote(entry.description) + "&channel=" + urllib.quote(entry.servicename) + "&after_event=" + ("%s"%(entry.afterevent)) + "&action=" + ("%s"%(action))
478                                 sCommand = self.http + "/changeTimerEvent?ref=" + ref + ref_old + ref_time_start + ref_time_end
479                                 sendPartnerBoxWebCommand(sCommand, None,10, self.username, self.password).addCallback(self.deleteTimerCallback).addErrback(self.downloadError)
480         
481         def configmenu(self):
482                 self.session.openWithCallback(self.PartnerboxSetupFinished, PartnerboxSetup)
483         
484         def PartnerboxSetupFinished(self):
485                 if config.plugins.partnerbox.enablepartnerboxintimerevent.value:
486                         RemoteTimerInit()
487                 self.E2TimerList = []
488                 self.password = config.plugins.partnerbox.password.value
489                 self.username = "root"
490                 ip = "%d.%d.%d.%d" % tuple(config.plugins.partnerbox.ip.value)
491                 port = config.plugins.partnerbox.port.value
492                 self.http = "http://%s:%d" % (ip,port)
493                 self.enigma_type = int(config.plugins.partnerbox.enigma.value)
494                 self.useinternal = int(config.plugins.partnerbox.useinternal.value)
495                 self["text"] = Label(_("Getting Partnerbox Information..."))
496                 self.startRun()
497         
498         def startRun(self):
499                 self["timerlist"].instance.hide()
500                 self.action()
501                 
502         def cleanupTimer(self):
503                 self["timerlist"].instance.hide()
504                 self["text"].setText(_("Cleaning up finished timer entries..."))
505                 if self.enigma_type == 0:
506                         self.cleanupTimerCallback()
507                 else:
508                         sCommand = self.http + "/cleanupTimerList"
509                         sendPartnerBoxWebCommand(sCommand, None,3, self.username, self.password).addCallback(self.cleanupTimerlistE1Callback).addErrback(self.cleanupTimerlistE1Callback)
510                         
511         def cleanupTimerlistE1Callback(self, answer):
512                 self.action()
513                 
514         def cleanupTimerCallback(self, callback = None):
515                 ip = "%d.%d.%d.%d" % tuple(config.plugins.partnerbox.ip.value)
516                 for Timerentry in self["timerlist"].list:
517                         if Timerentry[0].state == TimerEntry.StateEnded:
518                                 temp = "http://" + self.username + ":" + self.password + "@" + ip + "/web/timerdelete?sRef="
519                                 ref = Timerentry[0].servicereference + "&begin=" + ("%s"%(Timerentry[0].timebegin)) + "&end=" +("%s"%(Timerentry[0].timeend))
520                                 urllib.quote(ref.decode('utf8').encode('latin-1','ignore'))
521                                 url = temp + ref
522                                 f = urllib.urlopen(url)
523                                 sxml = f.read()
524                 self.action()
525                 
526         def deleteTimer(self):
527                 try:
528                         sel = self["timerlist"].l.getCurrentSelection()[0]
529                         if sel is None:
530                                 return
531                         if self.enigma_type == 0:
532                                 name = sel.name
533                         else:
534                                 name = sel.description
535                         self.session.openWithCallback(self.deleteTimerConfirmed, MessageBox, _("Do you really want to delete the timer \n%s ?") % name)
536                 except: return
537
538         def deleteTimerConfirmed(self, val):
539                 if val:
540                         sel = self["timerlist"].l.getCurrentSelection()[0]
541                         if sel is None:
542                                 return
543                         if self.enigma_type == 0:
544                                 sCommand = self.http + "/web/timerdelete?sRef=" + sel.servicereference + "&begin=" + ("%s"%(sel.timebegin)) + "&end=" +("%s"%(sel.timeend))
545                         else:
546                                 sCommand = self.http + "/deleteTimerEvent?ref=" + sel.servicereference + "&start=" + ("%s"%(sel.timebegin)) + "&type=" +("%s"%(sel.type)) + "&force=yes"
547                         sendPartnerBoxWebCommand(sCommand, None,3, self.username, self.password).addCallback(self.deleteTimerCallback).addErrback(self.deleteTimerError)
548         
549         def deleteTimerCallback(self, callback = None):
550                 self.action()
551                 
552         def deleteTimerError(self, error = None):
553                 if error is not None:
554                         self["timerlist"].instance.hide()
555                         self["text"].setText(str(error.getErrorMessage()))
556         
557         def downloadCallback(self, callback = None):
558                 self.readXML(callback)
559                 self["timerlist"].instance.show()
560
561         def downloadError(self, error = None):
562                 if error is not None:
563                         self["text"].setText(str(error.getErrorMessage()))
564
565         def action(self):
566                 if self.enigma_type == 0:
567                         url = self.http + "/web/timerlist"
568                 else:
569                         url = self.http + "/xml/timers"
570                 sendPartnerBoxWebCommand(url, None,10, self.username, self.password).addCallback(self.downloadCallback).addErrback(self.downloadError)
571
572         def readXML(self, xmlstring):
573                 self.E2TimerList = []
574                 if self.enigma_type == 0:
575                         self.E2TimerList = FillE2TimerList(xmlstring)
576                         self["timerlist"].buildList(self.E2TimerList)
577                 else:
578                         self.E2TimerList = FillE1TimerList(xmlstring)
579                         self["timerlist"].buildE1List(self.E2TimerList)
580
581         def EPGList(self):
582                 self.session.openWithCallback(self.CallbackEPGList, RemoteTimerBouquetList, self.E2TimerList, self.username, self.password, self.http, self.enigma_type, self.useinternal, 0)
583                 
584         def CallbackEPGList(self):
585                 self.startRun()
586
587 class RemoteTimerBouquetList(Screen):
588         skin = """
589                 <screen name="RemoteTimerBouquetList" position="210,160" size="300,240" title="Choose bouquet">
590                 <widget name="text" position="10,10" zPosition="1" size="290,225" font="Regular;20" halign="center" valign="center" />
591                 <widget name="bouquetlist" position="10,10" zPosition="2" size="290,225" scrollbarMode="showOnDemand" />
592         </screen>"""
593         
594         def __init__(self, session, E2Timerlist, User, Pass, http, enigma_type, useinternal, playeronly):
595                 self.session = session
596                 Screen.__init__(self, session)
597                 self["bouquetlist"] = E2BouquetList([])
598                 self["text"] = Label(_("Getting Partnerbox Bouquet Information..."))
599                 self.onLayoutFinish.append(self.startRun)
600                 self.E2TimerList = E2Timerlist
601                 self["actions"] = ActionMap(["WizardActions", "DirectionActions"],
602                 {
603                         "ok": self.action,
604                         "back": self.close,
605                 }, -1)
606
607                 self.password = Pass
608                 self.username = User
609                 self.http = http
610                 self.enigma_type = enigma_type
611                 self.useinternal = useinternal
612                 self.playeronly = playeronly
613                 if self.enigma_type == 0:
614                         self.url = self.http + "/web/getservices"
615                 else:
616                         self.url = self.http + "/xml/services?mode=0&submode=4"
617                 self.E1XMLString = ""
618                 self.password = Pass
619                 self.username = User
620                 
621                 
622         def action(self):
623                 try:
624                         sel = self["bouquetlist"].l.getCurrentSelection()[0]
625                         if sel is None:
626                                 return
627                         self.session.openWithCallback(self.CallbackEPGList, RemoteTimerChannelList, self.E2TimerList, sel.servicereference, sel.servicename, self.username, self.password, self.E1XMLString, self.http, self.enigma_type, self.useinternal, self.playeronly)
628                 except: return
629                 
630         def CallbackEPGList(self):
631                 pass
632         
633         def startRun(self):
634                 if self.useinternal == 1 :
635                         BouquetList = []
636                         a = Services(self.session)
637                         ref = eServiceReference( service_types_tv + ' FROM BOUQUET "bouquets.tv" ORDER BY bouquet')
638                         BouquetList = a.buildList(ref, False)
639                         self["bouquetlist"].buildList(BouquetList)
640                 else:
641                         self["bouquetlist"].instance.hide()
642                         self.getBouquetList()
643         
644         def getBouquetList(self):
645                 sendPartnerBoxWebCommand(self.url, None,10, self.username, self.password).addCallback(self.downloadCallback).addErrback(self.downloadError)
646                 
647         def downloadCallback(self, callback = None):
648                 if self.enigma_type == 0:
649                         self.readXML(callback)
650                 else:
651                         self.readXMLE1(callback)
652                 self["bouquetlist"].instance.show()
653
654         def downloadError(self, error = None):
655                 if error is not None:
656                         self["text"].setText(str(error.getErrorMessage()))
657
658         def readXMLE1(self,xmlstring):
659                 self.E1XMLString = xmlstring
660                 BouquetList = []
661                 dom = xml.dom.minidom.parseString(xmlstring)
662                 for node in dom.firstChild.childNodes:
663                         if node.nodeName == "bouquet":
664                                 servicereference = ""
665                                 servicename = ""
666                                 for node2 in node.childNodes:
667                                         if node2.nodeName == "reference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
668                                         if node2.nodeName == "name":
669                                                 try:servicename = str(node2.firstChild.data.strip().encode("utf-8"))
670                                                 except:servicename = "n/a"
671                                                 BouquetList.append(E2ServiceList(servicereference = servicereference, servicename = servicename))
672                 self["bouquetlist"].buildList(BouquetList)
673                         
674                         
675         def readXML(self, xmlstring):
676                 BouquetList = []
677                 dom = xml.dom.minidom.parseString(xmlstring)
678                 for node in dom.firstChild.childNodes:
679                         servicereference = ""
680                         servicename = ""
681                         if node.nodeName == "e2service":
682                                 for node2 in node.childNodes:
683                                         if node2.nodeName == "e2servicereference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
684                                         if node2.nodeName == "e2servicename":
685                                                 try:servicename = str(node2.firstChild.data.strip().encode("utf-8"))
686                                                 except:servicename = "n/a"
687                                                 BouquetList.append(E2ServiceList(servicereference = servicereference, servicename = servicename))
688                 self["bouquetlist"].buildList(BouquetList)
689
690 class RemoteTimerChannelList(Screen):
691         EMPTY = 0
692         ADD_TIMER = 1
693         REMOVE_TIMER = 2
694         REMOTE_TIMER_MODE = 0
695         REMOTE_TV_MODE = 1
696         skin = """
697                 <screen name="RemoteTimerChannelList" position="90,95" size="560,430" title ="Bouquet List">
698                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
699                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
700                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
701                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
702                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
703                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
704                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
705                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
706                         <widget name="text" position="0,40" zPosition="1" size="560,375" font="Regular;20" halign="center" valign="center" />
707                         <widget name="channellist" position="0,40" zPosition="2" size="560,375" scrollbarMode="showOnDemand" />
708                 </screen>"""
709         
710         def __init__(self, session, E2Timerlist, ServiceReference, ServiceName, User, Pass, E1XMLString, http, enigma_type, useinternal, playeronly):
711                 self.session = session
712                 Screen.__init__(self, session)
713                 self["channellist"] = E2ChannelList([], selChangedCB = self.onSelectionChanged)
714                 self.playeronly = playeronly
715                 self["key_red"] = Label(_("Zap"))
716                 self["key_green"] = Label()
717                 if self.playeronly == 0:
718                                 self["key_yellow"] = Label(_("EPG Selection"))
719                 else:
720                         self["key_yellow"] = Label()
721                 self["key_blue"] = Label(_("Info"))
722                 
723                 self["text"] = Label(_("Getting Channel Information..."))
724                 self.onLayoutFinish.append(self.startRun)
725                 self.E2TimerList = E2Timerlist
726                 self.E2ChannelList = []
727                 self.servicereference = ServiceReference
728                 self.E1XMLString = E1XMLString
729                 self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions"],
730                 {
731                         "ok": self.PlayRemoteStream,
732                         "back": self.close,
733                         "yellow": self.EPGSelection,
734                         "blue": self.EPGEvent,
735                         "red": self.Zap,
736                 }, -1)
737                 
738                 self.http = http
739                 self.enigma_type = enigma_type
740                 self.useinternal = useinternal
741                 self.password = Pass
742                 self.username = User
743                 self.key_green_choice = self.ADD_TIMER
744                 self.zapTimer = eTimer()
745                 self.zapTimer.timeout.get().append(self.zapTimerTimeout)
746                 self.onClose.append(self.__onClose)
747                 self.ChannelListCurrentIndex = 0
748                 self.mode = self.REMOTE_TIMER_MODE
749                 self.CurrentService = self.session.nav.getCurrentlyPlayingServiceReference()
750                 
751         def __onClose(self):
752                 if self.zapTimer.isActive():
753                         self.zapTimer.stop()
754                         
755         def startRun(self):
756                 if self.useinternal == 1 :
757                         ChannelList = []
758                         a = Services(self.session)
759                         Channelref = eServiceReference(self.servicereference)
760                         ChannelList = a.buildList(Channelref, True)
761                         self["channellist"].buildList(ChannelList)
762                         self["channellist"].instance.show()
763                         if self.ChannelListCurrentIndex !=0:
764                                 sel = self["channellist"].moveSelectionTo(self.ChannelListCurrentIndex)
765                                 self.ChannelListCurrentIndex = 0
766                 else:
767                         self["channellist"].instance.hide()
768                         self.getChannelList()
769         
770         def PlayRemoteStream(self):
771                 if self.playeronly == 1:
772                         if self.mode == self.REMOTE_TIMER_MODE:
773                                 self.mode = self.REMOTE_TV_MODE
774                                 self.Zap()
775                         else:
776                                 self.session.nav.playService(self.CurrentService)
777                                 self.mode = self.REMOTE_TIMER_MODE
778                                 self["channellist"].instance.show()
779                 else:
780                         self.EPGSelection()
781                         
782         def Zap(self):
783                 sel = self["channellist"].l.getCurrentSelection()[0]
784                 if sel is None:
785                         return
786                 self["channellist"].instance.hide()
787                 self.ChannelListCurrentIndex = self["channellist"].getCurrentIndex()
788                 self["text"].setText("Zapping to " + sel.servicename)
789         
790                 if self.useinternal == 1 and self.mode == self.REMOTE_TIMER_MODE:
791                         self.session.nav.playService(eServiceReference(sel.servicereference))
792                         self.ZapCallback(None)
793                 else:
794                         if self.enigma_type == 0:
795                                 url = self.http + "/web/zap?sRef=" + urllib.quote(sel.servicereference.decode('utf8').encode('latin-1','ignore'))
796                         else:
797                                 url = self.http + "/cgi-bin/zapTo?path=" + urllib.quote(sel.servicereference.decode('utf8').encode('latin-1','ignore'))
798                         sendPartnerBoxWebCommand(url, None,10, self.username, self.password).addCallback(self.ZapCallback).addErrback(self.DoNotCareError)
799         
800         def DoNotCareError(self, dnce = None):
801                 # Jesses, E1 sendet 204 nach umschalten, kommt hier also immer rein...
802                 self.ZapCallback(dnce)
803         
804         def ZapCallback(self, callback = None):
805                 if self.mode == self.REMOTE_TIMER_MODE:
806                         self["text"].setText("Give Enigma time to fill epg cache...")
807                         self.zapTimer.start(10000) # 10 Sekunden
808                 else:
809                         self.zapTimer.start(3000) # 3 Sekunden REMOTE_TV
810                 
811         def zapTimerTimeout(self):
812                 if self.zapTimer.isActive():
813                         self.zapTimer.stop()
814                 if self.mode == self.REMOTE_TIMER_MODE:
815                         self.startRun()
816                 else:
817                         self.GetStreamInfosCallback()
818         
819         def GetStreamInfosCallback(self):
820                 if self.enigma_type == 0:
821                         ip = "%d.%d.%d.%d" % tuple(config.plugins.partnerbox.ip.value)
822                         url = "http://" + ip + ":8001/" + self["channellist"].l.getCurrentSelection()[0].servicereference 
823                         self.StreamTV(url)
824                 else:
825                         url = self.http + "/video.m3u"
826                         sendPartnerBoxWebCommand(url, None,10, self.username, self.password).addCallback(self.StreamTV).addErrback(self.ChannelListDownloadError)
827         
828         def StreamTV(self, connectstring):
829                         self.session.nav.stopService()
830                         sref = eServiceReference(ENIGMA_WEBSERVICE_ID, 0, connectstring)
831                         self.session.nav.playService(sref)
832                         self.session.openWithCallback(self.PlayRemoteStream, RemotePlayer, self["channellist"].l.getCurrentSelection()[0].servicename,self["channellist"].l.getCurrentSelection()[0].eventtitle, self["channellist"].l.getCurrentSelection()[0].eventstart, self["channellist"].l.getCurrentSelection()[0].eventduration, self.password,self.username, self["channellist"].l.getCurrentSelection()[0].servicereference, self.http , self.enigma_type, self.useinternal)
833         
834         def EPGEvent(self):
835                 sel = self["channellist"].l.getCurrentSelection()[0]
836                 if sel is None:
837                         return
838                 self.session.openWithCallback(self.CallbackEPGEvent, RemoteTimerEventView, self.E2TimerList, sel, self.username, self.password, self.http, self.enigma_type, self.useinternal)
839
840         def CallbackEPGEvent(self):
841                 pass
842                 
843         def onSelectionChanged(self):
844                 cur = self["channellist"].getCurrent()
845                 if cur is None:
846                         self["key_green"].setText("")
847                         self.key_green_choice = self.EMPTY
848                         self["key_yellow"].setText("")
849                         self["key_blue"].setText("")
850                         return
851                 eventid = cur[0].eventid
852                 if eventid ==0:
853                         self["key_green"].setText("")
854                         self.key_green_choice = self.EMPTY
855                         self["key_yellow"].setText("")
856                         self["key_blue"].setText("")
857                         return
858                 if self.playeronly == 0:
859                         self["key_yellow"].setText(_("EPG Selection"))
860                 self["key_blue"].setText(_("Info"))
861                 serviceref = cur[0].servicereference
862                 
863 #               isRecordEvent = False
864 #               for timer in self.E2TimerList:
865 #                       if timer.eventId == eventid and timer.servicereference == serviceref:
866 #                               isRecordEvent = True
867 #                               break
868 #               if isRecordEvent and self.key_green_choice != self.REMOVE_TIMER:
869 #                       self["key_green"].setText(_("Remove timer"))
870 #                       self.key_green_choice = self.REMOVE_TIMER
871 #               elif not isRecordEvent and self.key_green_choice != self.ADD_TIMER:
872 #                       self["key_green"].setText(_("Add timer"))
873 #                       self.key_green_choice = self.ADD_TIMER
874                 
875         def ChannelListDownloadCallback(self, callback = None):
876                 self.readXMLServiceList(callback)
877         
878         def ChannelListDataDownloadCallback(self, callback = None):
879                 self.readXMLEPGList(callback)
880                 if self.ChannelListCurrentIndex !=0:
881                         sel = self["channellist"].moveSelectionTo(self.ChannelListCurrentIndex)
882                         self.ChannelListCurrentIndex = 0
883                 self["channellist"].instance.show()
884
885         def ChannelListDownloadError(self, error = None):
886                 if error is not None:
887                         self["text"].setText(str(error.getErrorMessage()))
888                         self.mode = REMOTE_TIMER_MODE
889                         
890         def getChannelList(self):
891                 if self.enigma_type == 0:
892                         ref = urllib.quote(self.servicereference.decode('utf8').encode('latin-1','ignore'))
893                         url = self.http + "/web/getservices?sRef=" + ref
894                         sendPartnerBoxWebCommand(url, None,10, self.username, self.password).addCallback(self.ChannelListDownloadCallback).addErrback(self.ChannelListDownloadError)
895                 else:
896                         self.readXMLServiceListE1()
897                         if self.ChannelListCurrentIndex !=0:
898                                 sel = self["channellist"].moveSelectionTo(self.ChannelListCurrentIndex)
899                                 self.ChannelListCurrentIndex = 0
900                         self["channellist"].instance.show()
901         def readXMLServiceListE1(self):
902                 self.E2ChannelList = []
903                 dom = xml.dom.minidom.parseString(self.E1XMLString)
904                 for node in dom.firstChild.childNodes:
905                         if node.nodeName == "bouquet":
906                                 for node2 in node.childNodes:
907                                         if node2.nodeName == "reference": 
908                                                 if self.servicereference  == str(node2.firstChild.data.strip().encode("utf-8")):
909                                                         proceed = True
910                                                 else:
911                                                         proceed = False
912                                         if node2.nodeName == "service":
913                                                 if proceed:
914                                                         servicereference = ""
915                                                         servicename = ""
916                                                         eventstart = 0
917                                                         eventduration = 0
918                                                         eventtitle = ""
919                                                         eventdescriptionextended = ""
920                                                         eventdescription = ""
921                                                         for node3 in node2.childNodes:
922                                                                 if node3.nodeName == "reference": servicereference = str(node3.firstChild.data.strip().encode("utf-8"))
923                                                                 if node3.nodeName == "name":
924                                                                         try:servicename = str(node3.firstChild.data.strip().encode("utf-8"))
925                                                                         except:servicename = "n/a"
926                                                                         ip = "%d.%d.%d.%d" % tuple(config.plugins.partnerbox.ip.value)
927                                                                         url = "http://" + self.username + ":" + self.password + "@" + ip + "/xml/serviceepg?ref=" + servicereference + "&entries=1"
928                                                                         f = urllib.urlopen(url)
929                                                                         sxml = f.read()
930                                                                         eventstart, eventduration, eventtitle, eventdescriptionextended, eventdescription = self.XMLReadEPGDataE1(sxml)
931                                                                         self.E2ChannelList.append(E2EPGListAllData(servicereference = servicereference, servicename = servicename, eventstart = eventstart, eventduration = eventduration, eventtitle = eventtitle, eventid = 1, eventdescription= eventdescription, eventdescriptionextended = eventdescriptionextended))
932                 self["channellist"].buildList(self.E2ChannelList)
933                 
934         def XMLReadEPGDataE1(self,xmlstring):
935                 eventstart = 0
936                 eventduration = 0
937                 eventtitle = ""
938                 eventdescriptionextended = ""
939                 eventdescription = ""
940                 xmlstring = xmlstring.replace("""<?xml-stylesheet type="text/xsl" href="/xml/serviceepg.xsl"?>""","")
941                 dom = xml.dom.minidom.parseString(xmlstring)
942                 for node in dom.firstChild.childNodes:
943                         servicereference = ""
944                         servicename = ""
945                         if node.nodeName == "event":
946                                 for node2 in node.childNodes:
947                                         if node2.nodeName == "description":
948                                                 try:eventtitle = str(node2.firstChild.data.strip().encode("utf-8"))
949                                                 except:pass
950                                         if node2.nodeName == "details":
951                                                 try:eventdescriptionextended = str(node2.firstChild.data.strip().encode("utf-8"))
952                                                 except:pass
953                                         if node2.nodeName == "genre":
954                                                 try:eventdescription = str(node2.firstChild.data.strip().encode("utf-8"))
955                                                 except:pass
956                                         if node2.nodeName == "duration": eventduration = int(node2.firstChild.data.strip())
957                                         if node2.nodeName == "start": eventstart = int(node2.firstChild.data.strip())
958                 return eventstart, eventduration, eventtitle, eventdescriptionextended, eventdescription
959
960         def readXMLServiceList(self, xmlstring):
961                 self.E2ChannelList = []
962                 dom = xml.dom.minidom.parseString(xmlstring)
963                 for node in dom.firstChild.childNodes:
964                         servicereference = ""
965                         servicename = ""
966                         if node.nodeName == "e2service":
967                                 for node2 in node.childNodes:
968                                         if node2.nodeName == "e2servicereference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
969                                         if node2.nodeName == "e2servicename":
970                                                 try:servicename = str(node2.firstChild.data.strip().encode("utf-8"))
971                                                 except:servicename = "n/a"
972                                                 self.E2ChannelList.append(E2EPGListAllData(servicereference = servicereference, servicename = servicename))
973                 
974                 ref = urllib.quote(self.servicereference.decode('utf8').encode('latin-1','ignore'))
975                 url = self.http + "/web/epgnow?bRef=" + ref
976                 sendPartnerBoxWebCommand(url, None,10, self.username, self.password).addCallback(self.ChannelListDataDownloadCallback).addErrback(self.ChannelListDownloadError)
977                 
978         def readXMLEPGList(self, xmlstring):
979                 dom = xml.dom.minidom.parseString(xmlstring)
980                 for node in dom.firstChild.childNodes:
981                         servicereference = ""
982                         servicename = ""
983                         eventid = 0
984                         eventstart = 0
985                         eventduration = 0
986                         eventtitle = ""
987                         eventdescription = ""
988                         eventdescriptionextended = ""
989                         if node.nodeName == "e2event":
990                                 for node2 in node.childNodes:
991                                         if node2.nodeName == "e2eventid": eventid= int(node2.firstChild.data.strip())
992                                         if node2.nodeName == "e2eventstart": eventstart = int(node2.firstChild.data.strip())
993                                         if node2.nodeName == "e2eventduration": eventduration = int(node2.firstChild.data.strip())
994                                         if node2.nodeName == "e2eventtitle":
995                                                 try:eventtitle = str(node2.firstChild.data.strip().encode("utf-8"))
996                                                 except:eventtitle = ""
997                                         if node2.nodeName == "e2eventdescription":
998                                                 try:eventdescription = str(node2.firstChild.data.strip().encode("utf-8"))
999                                                 except:eventdescription = ""
1000                                         if node2.nodeName == "e2eventdescriptionextended":
1001                                                 try:eventdescriptionextended = str(node2.firstChild.data.strip().encode("utf-8"))
1002                                                 except:eventdescriptionextended = "n/a"
1003                                         if node2.nodeName == "e2eventservicereference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
1004                                         if node2.nodeName == "e2eventservicename":
1005                                                 try:
1006                                                         servicename = str(node2.firstChild.data.strip().encode("utf-8"))
1007                                                         for epgdata in self.E2ChannelList:
1008                                                                 if epgdata.servicereference == servicereference:
1009                                                                         epgdata.eventid = eventid
1010                                                                         epgdata.eventstart = eventstart
1011                                                                         epgdata.eventduration = eventduration
1012                                                                         epgdata.eventtitle = eventtitle
1013                                                                         epgdata.eventdescription = eventdescription
1014                                                                         epgdata.eventdescriptionextended = eventdescriptionextended
1015                                                                         break
1016                                                 except:pass
1017                 self["channellist"].buildList(self.E2ChannelList)
1018
1019         def EPGSelection(self):
1020                 if self.playeronly == 0:
1021                         try:
1022                                 sel = self["channellist"].l.getCurrentSelection()[0]
1023                                 if sel is None:
1024                                         return
1025                                 if sel.eventid != 0:
1026                                         self.session.openWithCallback(self.CallbackEPGSelection, RemoteTimerEPGList, self.E2TimerList, sel.servicereference, sel.servicename, self.username, self.password, self.http, self.enigma_type, self.useinternal)
1027                         except: return
1028                 
1029         def CallbackEPGSelection(self):
1030                 pass
1031
1032 class RemotePlayer(Screen, InfoBarAudioSelection):
1033         
1034         
1035         HDSkn = False
1036         try:
1037                 sz_w = getDesktop(0).size().width()
1038                 if sz_w == 1280:
1039                         HDSkn = True
1040                 else:
1041                         HDSkn = False
1042         except:
1043                 HDSkn = False
1044         if HDSkn:
1045                 skin="""
1046                 <screen name="RemotePlayer" flags="wfNoBorder" position="283,102" size="720,576" title="Partnerbox - RemotePlayer" backgroundColor="#FFFFFFFF">
1047                         <ePixmap position="41,388" zPosition="-1" size="630,130" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/ExPlayer.png" alphatest="off" transparent="1"/>
1048                         <widget name="ServiceName" zPosition="1" position="50,404" size="610,59" valign="center" halign="center" font="Regular;21" foregroundColor="#F0F0F0" backgroundColor="#302C2C39" />
1049                         <widget name="DateTime" zPosition="1" position="52,473" size="500,30" halign="left" font="Regular;16" foregroundColor="#F0F0F0" backgroundColor="#302C2C39" transparent="1" />
1050                         <widget name="IP" zPosition="2" position="361,473" size="300,30" halign="right" font="Regular;16" foregroundColor="#F0F0F0" backgroundColor="#302C2C39" transparent="1" />
1051                 </screen>"""
1052         else:
1053                 skin="""
1054                 <screen name="RemotePlayer" flags="wfNoBorder" position="3,30" size="720,576" title="Partnerbox - RemotePlayer" backgroundColor="#FFFFFFFF">
1055                         <ePixmap position="41,388" zPosition="-1" size="630,130" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/ExPlayer.png" alphatest="off" transparent="1"/>
1056                         <widget name="ServiceName" zPosition="1" position="50,404" size="610,59" valign="center" halign="center" font="Regular;21" foregroundColor="#F0F0F0" backgroundColor="#302C2C39" />
1057                         <widget name="DateTime" zPosition="1" position="52,473" size="500,30" halign="left" font="Regular;16" foregroundColor="#F0F0F0" backgroundColor="#302C2C39" transparent="1" />
1058                         <widget name="IP" zPosition="2" position="361,473" size="300,30" halign="right" font="Regular;16" foregroundColor="#F0F0F0" backgroundColor="#302C2C39" transparent="1" />
1059                 </screen>"""
1060         
1061         def __init__(self, session, ServiceName, EventTitle, eventstart, eventduration, password, username, servicereference, http, enigma_type, useinternal):
1062                 self.session = session
1063                 Screen.__init__(self, session)
1064                 InfoBarAudioSelection.__init__(self)
1065                 self.http = http
1066                 self.enigma_type = enigma_type
1067                 self.useinternal = useinternal
1068                 endtime = int(eventstart + eventduration)
1069                 tt = ((" %s ... %s (+%d " + _("mins") + ")") % (FuzzyTime(eventstart)[1], FuzzyTime(endtime)[1], (endtime - time.time()) / 60)) 
1070                 self["ServiceName"] = Label(EventTitle)
1071                 ip = "%d.%d.%d.%d" % tuple(config.plugins.partnerbox.ip.value)
1072                 self["IP"] = Label(ip)
1073                 self["DateTime"] = Label(ServiceName + ": " + tt)
1074                 self.isVisible = True
1075                 self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions"],
1076                 {
1077                         "ok": self.Infobar,
1078                         "back": self.close,
1079                 }, -1)
1080                 self.password = password
1081                 self.username = username
1082                 self.servicereference = servicereference
1083                 self.onLayoutFinish.append(self.startRun)
1084                 self.onClose.append(self.__onClose)
1085                 
1086                 self.Timer = eTimer()
1087                 self.Timer.timeout.get().append(self.TimerTimeout)
1088                 
1089         def TimerTimeout(self):
1090                 if self.Timer.isActive():
1091                         self.Timer.stop()
1092                 self.Infobar()
1093         
1094         def startRun(self):
1095                 idx = config.usage.infobar_timeout.index
1096                 if idx:
1097                         self.Timer.start(idx * 1000)
1098                 else:
1099                         self.Timer.start(6 * 1000)
1100                 if self.enigma_type == 0:
1101                         url = self.http + "/web/epgservicenow?sRef=" + self.servicereference
1102                 else:
1103                         url = self.http + "/xml/serviceepg?ref=" + self.servicereference + "&entries=1"
1104                 sendPartnerBoxWebCommand(url, None,10, self.username, self.password).addCallback(self.CurrentEPGCallback).addErrback(self.CurrentEPGCallbackError)
1105
1106         def CurrentEPGCallback(self, xmlstring):
1107                 xmlstring = xmlstring.replace("""<?xml-stylesheet type="text/xsl" href="/xml/serviceepg.xsl"?>""","")
1108                 dom = xml.dom.minidom.parseString(xmlstring)
1109                 e2eventtitle = ""
1110                 e2eventservicename = ""
1111                 e2eventstart = 0
1112                 e2eventduration = 0
1113                 if self.enigma_type == 0:
1114                         for node in dom.firstChild.childNodes:
1115                                 if node.nodeName == "e2event":
1116                                         for node2 in node.childNodes:
1117                                                 if node2.nodeName == "e2eventservicename":
1118                                                         try:e2eventservicename = str(node2.firstChild.data.strip().encode("utf-8"))
1119                                                         except:e2eventservicename = "n/a"
1120                                                 if node2.nodeName == "e2eventtitle":
1121                                                         try:e2eventtitle = str(node2.firstChild.data.strip().encode("utf-8"))
1122                                                         except:e2eventtitle = "n/a"
1123                                                 if node2.nodeName == "e2eventstart": e2eventstart = int(node2.firstChild.data.strip())
1124                                                 if node2.nodeName == "e2eventduration": e2eventduration = int(node2.firstChild.data.strip())
1125                 else:
1126                         for node in dom.firstChild.childNodes:
1127                                 if node.nodeName == "service":
1128                                         for node2 in node.childNodes:
1129                                                 if node2.nodeName == "name":
1130                                                         try:e2eventservicename = str(node2.firstChild.data.strip().encode("utf-8"))
1131                                                         except:e2eventservicename = "n/a"
1132                                 if node.nodeName == "event":
1133                                         for node2 in node.childNodes:
1134                                                 if node2.nodeName == "description":
1135                                                         try:e2eventtitle = str(node2.firstChild.data.strip().encode("utf-8"))
1136                                                         except:pass
1137                                                 if node2.nodeName == "duration": e2eventduration = int(node2.firstChild.data.strip())
1138                                                 if node2.nodeName == "start": e2eventstart = int(node2.firstChild.data.strip())
1139                 endtime = int(e2eventstart + e2eventduration)
1140                 if endtime != 0:
1141                         tt = ((": %s ... %s (+%d " + _("mins") + ")") % (FuzzyTime(e2eventstart)[1], FuzzyTime(endtime)[1], (endtime - time.time()) / 60))
1142                 else:
1143                         tt = ""
1144                 self["ServiceName"].setText(e2eventtitle)
1145                 self["DateTime"].setText(e2eventservicename + tt)
1146
1147         def CurrentEPGCallbackError(self, error = None):
1148                 print "[RemotePlayer] Error: ",error.getErrorMessage()
1149                 
1150         def readXMSubChanelList(self, xmlstring):
1151                 BouquetList = []
1152                 counter = 0
1153                 dom = xml.dom.minidom.parseString(xmlstring)
1154                 for node in dom.firstChild.childNodes:
1155                         servicereference = ""
1156                         servicename = ""
1157                         if node.nodeName == "e2service":
1158                                 for node2 in node.childNodes:
1159                                         if node2.nodeName == "e2servicereference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
1160                                         if node2.nodeName == "e2servicename":
1161                                                 try:servicename = str(node2.firstChild.data.strip().encode("utf-8"))
1162                                                 except:servicename = "n/a"
1163                                                 if counter != 0: # erster Eintrag ist der aktuelle Sedner, nicht aufnehmen
1164                                                         BouquetList.append(E2ServiceList(servicereference = servicereference, servicename = servicename))
1165                                                 counter += 1
1166         
1167         def Infobar(self):
1168                 if self.isVisible:
1169                         if self.Timer.isActive():
1170                                 self.Timer.stop()
1171                         self.hide()
1172                         self.isVisible = False
1173                 else:
1174                         self.startRun()
1175                         self.show()
1176                         self.isVisible = True
1177                         
1178         def __onClose(self):
1179                 if self.Timer.isActive():
1180                         self.Timer.stop()
1181                 
1182 class RemoteTimerEPGList(Screen):
1183         EMPTY = 0
1184         ADD_TIMER = 1
1185         REMOVE_TIMER = 2
1186         skin = """
1187                 <screen name="RemoteTimerEPGList" position="90,95" size="560,430" title ="EPG Selection">
1188                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1189                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1190                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
1191                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
1192                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1193                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
1194                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
1195                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
1196                         <widget name="text" position="0,40" zPosition="1" size="560,375" font="Regular;20" halign="center" valign="center" />
1197                         <widget name="epglist" position="0,40" zPosition="2" size="560,375" scrollbarMode="showOnDemand" />
1198                 </screen>"""
1199         
1200         def __init__(self, session, E2Timerlist, ServiceReference, ServiceName, User, Pass, http, enigma_type, useinternal):
1201                 self.session = session
1202                 Screen.__init__(self, session)
1203                 self.E2TimerList = E2Timerlist
1204                 self["epglist"] = E2EPGList([],selChangedCB = self.onSelectionChanged)
1205                 self["key_red"] = Label()# Dummy, kommt eventuell noch was
1206                 self["key_green"] = Label(_("Add timer"))
1207                 self.key_green_choice = self.ADD_TIMER
1208                 self["key_yellow"] = Label() # Dummy, kommt eventuell noch was
1209                 self["key_blue"] = Label(_("Info"))
1210                 self["text"] = Label(_("Getting EPG Information..."))
1211                 self.onLayoutFinish.append(self.startRun)
1212                 self.servicereference = ServiceReference
1213                 self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions"],
1214                 {
1215                         "back": self.close,
1216                         "green": self.GreenPressed,
1217                         "blue": self.EPGEvent,
1218                 }, -1)
1219                 
1220                 self.http = http
1221                 self.enigma_type = enigma_type
1222                 self.useinternal = useinternal
1223                 
1224                 if self.enigma_type == 0:
1225                         self.url = self.http + "/web/epgservice?sRef=" + urllib.quote(self.servicereference.decode('utf8').encode('latin-1','ignore'))
1226                 else:
1227                         self.url = self.http + "/xml/serviceepg?ref=" + urllib.quote(self.servicereference.decode('utf8').encode('latin-1','ignore'))
1228                 self.password = Pass
1229                 self.username = User
1230                 self.ListCurrentIndex = 0
1231                 self.Locations = []
1232                 
1233         def EPGEvent(self):
1234                 
1235                 sel = self["epglist"].l.getCurrentSelection()[0]
1236                 if sel is None:
1237                         return
1238                 self.session.openWithCallback(self.CallbackEPGEvent, RemoteTimerEventView, self.E2TimerList, sel, self.username, self.password, self.http, self.enigma_type, self.useinternal)
1239                 
1240         def CallbackEPGEvent(self):
1241                 pass
1242                 
1243         def onSelectionChanged(self):
1244                 cur = self["epglist"].getCurrent()
1245                 if cur is None:
1246                         self["key_green"].setText("")
1247                         self.key_green_choice = self.EMPTY
1248                         self["key_blue"].setText("")
1249                         return
1250                 serviceref = cur[0].servicereference
1251                 eventid = cur[0].eventid
1252                 if eventid ==0:
1253                         self["key_green"].setText("")
1254                         self.key_green_choice = self.EMPTY
1255                         self["key_blue"].setText("")
1256                         return
1257                 self["key_blue"].setText(_("Info"))
1258                 
1259                 timerentry = isInTimerList(cur[0].eventstart,cur[0].eventduration, cur[0].servicereference, cur[0].eventid, self.E2TimerList)
1260                 if timerentry is None:
1261                         if self.key_green_choice != self.ADD_TIMER:
1262                                 self["key_green"].setText(_("Add timer"))
1263                                 self.key_green_choice = self.ADD_TIMER
1264                 else:
1265                         if self.key_green_choice != self.REMOVE_TIMER:
1266                                 self["key_green"].setText(_("Remove timer"))
1267                                 self.key_green_choice = self.REMOVE_TIMER
1268         
1269         def startRun(self):
1270                 if self.useinternal == 1:
1271                         EPGList = []
1272                         a = Services(self.session)
1273                         EPGList = a.buildEPGList(self.servicereference)
1274                         self["epglist"].buildList(EPGList, self.E2TimerList)
1275                         if self.ListCurrentIndex != 0:
1276                                 sel = self["epglist"].moveSelectionTo(self.ListCurrentIndex)
1277                                 self.ListCurrentIndex = 0
1278                 else:
1279                         self["epglist"].instance.hide()
1280                         self.getEPGList()
1281         
1282         def getEPGList(self):
1283                         sendPartnerBoxWebCommand(self.url, None,10, self.username, self.password).addCallback(self.EPGListDownloadCallback).addErrback(self.EPGListDownloadError)
1284                 
1285         def EPGListDownloadCallback(self, callback = None):
1286                 if self.enigma_type == 0:
1287                         self.readXMLEPGList(callback)
1288                 else:
1289                         self.readXMLEPGListE1(callback)
1290                 self["epglist"].instance.show()
1291         
1292         def EPGListDownloadError(self, error = None):
1293                 if error is not None:
1294                         self["text"].setText(str(error.getErrorMessage()))
1295         
1296         def readXMLEPGListE1(self, xmlstring):
1297                 E1ListEPG = []
1298                 xmlstring = xmlstring.replace("""<?xml-stylesheet type="text/xsl" href="/xml/serviceepg.xsl"?>""","")
1299                 dom = xml.dom.minidom.parseString(xmlstring)
1300                 servicereference = ""
1301                 servicename = ""
1302                 for node in dom.firstChild.childNodes:
1303                         eventstart = 0
1304                         eventduration = 0
1305                         eventtitle = ""
1306                         eventdescriptionextended = ""
1307                         eventdescription = ""
1308                         if node.nodeName == "service":
1309                                 for node2 in node.childNodes:
1310                                         if node2.nodeName == "reference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
1311                                         if node2.nodeName == "name":
1312                                                 try:servicename = str(node2.firstChild.data.strip().encode("utf-8"))
1313                                                 except:servicename = "n/a"
1314                         if node.nodeName == "event":
1315                                 for node2 in node.childNodes:
1316                                         if node2.nodeName == "description":
1317                                                 try:eventtitle = str(node2.firstChild.data.strip().encode("utf-8"))
1318                                                 except:pass
1319                                         if node2.nodeName == "duration": eventduration = int(node2.firstChild.data.strip())
1320                                         if node2.nodeName == "start": eventstart = int(node2.firstChild.data.strip())
1321                                         if node2.nodeName == "genre":
1322                                                 try:eventdescription = str(node2.firstChild.data.strip().encode("utf-8"))
1323                                                 except:pass
1324                                         if node2.nodeName == "details":
1325                                                 try:eventdescriptionextended = str(node2.firstChild.data.strip().encode("utf-8"))
1326                                                 except:pass
1327                                                 E1ListEPG.append(E2EPGListAllData(servicereference = servicereference, servicename = servicename, eventid = 1, eventstart = eventstart, eventduration = eventduration, eventtitle = eventtitle, eventdescription = eventdescription, eventdescriptionextended = eventdescriptionextended  ))
1328                 self["epglist"].buildList(E1ListEPG, self.E2TimerList)
1329                 if self.ListCurrentIndex != 0:
1330                         sel = self["epglist"].moveSelectionTo(self.ListCurrentIndex)
1331                         self.ListCurrentIndex = 0
1332         
1333         def readXMLEPGList(self, xmlstring):
1334                 E2ListEPG = []
1335                 dom = xml.dom.minidom.parseString(xmlstring)
1336                 for node in dom.firstChild.childNodes:
1337                         servicereference = ""
1338                         servicename = ""
1339                         eventid = 0
1340                         eventstart = 0
1341                         eventduration = 0
1342                         eventtitle = ""
1343                         eventdescription = ""
1344                         eventdescriptionextended = ""
1345                         if node.nodeName == "e2event":
1346                                 for node2 in node.childNodes:
1347                                         if node2.nodeName == "e2eventid": eventid= int(node2.firstChild.data.strip())
1348                                         if node2.nodeName == "e2eventstart": eventstart = int(node2.firstChild.data.strip())
1349                                         if node2.nodeName == "e2eventduration": eventduration = int(node2.firstChild.data.strip())
1350                                         if node2.nodeName == "e2eventtitle":
1351                                                 try:eventtitle = str(node2.firstChild.data.strip().encode("utf-8"))
1352                                                 except:eventtitle = ""
1353                                         if node2.nodeName == "e2eventdescription":
1354                                                 try:eventdescription = str(node2.firstChild.data.strip().encode("utf-8"))
1355                                                 except:eventdescription = ""
1356                                         if node2.nodeName == "e2eventdescriptionextended":
1357                                                 try:eventdescriptionextended = str(node2.firstChild.data.strip().encode("utf-8"))
1358                                                 except:eventdescriptionextended = "n/a"
1359                                         if node2.nodeName == "e2eventservicereference": servicereference = str(node2.firstChild.data.strip().encode("utf-8"))
1360                                         if node2.nodeName == "e2eventservicename":
1361                                                 try:
1362                                                         servicename = str(node2.firstChild.data.strip().encode("utf-8"))
1363                                                         E2ListEPG.append(E2EPGListAllData(servicereference = servicereference, servicename = servicename, eventid = eventid, eventstart = eventstart, eventduration = eventduration, eventtitle = eventtitle, eventdescription = eventdescription, eventdescriptionextended = eventdescriptionextended  ))
1364                                                 except:pass
1365                 self["epglist"].buildList(E2ListEPG, self.E2TimerList)
1366                 if self.ListCurrentIndex != 0:
1367                         sel = self["epglist"].moveSelectionTo(self.ListCurrentIndex)
1368                         self.ListCurrentIndex = 0
1369                 
1370         def GreenPressed(self):
1371                 if self.key_green_choice == self.ADD_TIMER:
1372                         if self.enigma_type == 0:
1373                                 self.getLocations()
1374                         else:
1375                                 self.addTimerEvent()
1376                 elif self.key_green_choice == self.REMOVE_TIMER:
1377                         print "removetimer"
1378                         self.deleteTimer()
1379         
1380         def LocationsError(self, error = None):
1381                 if error is not None:
1382                         self["epglist"].instance.hide()
1383                         self["text"].setText(str(error.getErrorMessage()))
1384         
1385         def getLocations(self):
1386                 sCommand = self.http + "/web/getlocations"
1387                 sendPartnerBoxWebCommand(sCommand, None,3, self.username, self.password).addCallback(self.getLocationsCallback).addErrback(self.LocationsError)
1388         
1389         def getLocationsCallback(self, xmlstring):
1390                 self.Locations = []
1391                 self.Locations = FillLocationList(xmlstring)
1392                 self.addTimerEvent()
1393                         
1394         def addTimerEvent(self):
1395                 cur = self["epglist"].getCurrent()
1396                 if cur is None:
1397                         return
1398                 if self.enigma_type == 0:
1399                         description = cur[0].eventdescription
1400                         type = 0
1401                         dirname = "/hdd/movie/"
1402                 else:
1403                         dirname = ""
1404                         type = PlaylistEntry.RecTimerEntry|PlaylistEntry.recDVR
1405                         description = cur[0].eventtitle
1406                 timerentry = E2Timer(servicereference = cur[0].servicereference, servicename = cur[0].servicename, name = cur[0].eventtitle, disabled = 0, timebegin = cur[0].eventstart, timeend = cur[0].eventstart + cur[0].eventduration, duration = cur[0].eventduration, startprepare = 0, state = 0 , repeated = 0, justplay= 0, eventId = 0, afterevent = 0, dirname = dirname, description = description, type = type )
1407                 self.session.openWithCallback(self.RemoteTimerEntryFinished, RemoteTimerEntry,timerentry, self.Locations)
1408
1409         def RemoteTimerEntryFinished(self, answer):
1410                 if answer[0]:
1411                         self.ListCurrentIndex = self["epglist"].getCurrentIndex()
1412                         entry = answer[1]
1413                         self["epglist"].instance.hide()
1414                         if self.enigma_type == 0:
1415                                 ref = urllib.quote(entry.servicereference.decode('utf8').encode('latin-1','ignore')) + "&begin=" + ("%s"%(entry.timebegin)) + "&end=" + ("%s"%(entry.timeend))  + "&name=" + urllib.quote(entry.name) + "&description=" + urllib.quote(entry.description) + "&dirname=" + urllib.quote(entry.dirname) + "&eit=0&justplay=" + ("%s"%(entry.justplay)) + "&afterevent=" + ("%s"%(entry.afterevent))
1416                                 sCommand = self.http + "/web/timeradd?sRef=" + ref
1417                                 sendPartnerBoxWebCommand(sCommand, None,10, self.username, self.password).addCallback(self.deleteTimerCallback).addErrback(self.EPGListDownloadError)
1418                         else:
1419                                 if entry.justplay & PlaylistEntry.SwitchTimerEntry:
1420                                         action = "zap"
1421                                 elif entry.justplay & PlaylistEntry.recNgrab:
1422                                         action = "ngrab"
1423                                 else:
1424                                         action = ""
1425                                 ref = urllib.quote(entry.servicereference.decode('utf8').encode('latin-1','ignore')) + "&start=" + ("%s"%(entry.timebegin)) + "&duration=" + ("%s"%(entry.timeend - entry.timebegin))  + "&descr=" + urllib.quote(entry.description) + "&channel=" + urllib.quote(entry.servicename) + "&after_event=" + ("%s"%(entry.afterevent)) + "&action=" + ("%s"%(action))
1426                                 sCommand = self.http + "/addTimerEvent?ref=" + ref
1427                                 sendPartnerBoxWebCommand(sCommand, None,10, self.username, self.password).addCallback(self.deleteTimerCallback).addErrback(self.EPGListDownloadError)
1428         
1429         def deleteTimer(self):
1430                 cur = self["epglist"].getCurrent()
1431                 if cur is None:
1432                         return
1433                 timerentry = isInTimerList(cur[0].eventstart,cur[0].eventduration, cur[0].servicereference, cur[0].eventid, self.E2TimerList)
1434                 if timerentry is None:
1435                         return
1436                 else:
1437                         self.session.openWithCallback(self.deleteTimerConfirmed, MessageBox, _("Do you really want to delete the timer \n%s ?") % timerentry.name)
1438
1439         def deleteTimerConfirmed(self, val):
1440                 if val:
1441                         cur = self["epglist"].getCurrent()
1442                         if cur is None:
1443                                 return
1444                         self.ListCurrentIndex = self["epglist"].getCurrentIndex()
1445                         timerentry = isInTimerList(cur[0].eventstart,cur[0].eventduration, cur[0].servicereference, cur[0].eventid, self.E2TimerList)
1446                         if timerentry is None:
1447                                 return
1448                         else:
1449                                 self["epglist"].instance.hide()
1450                                 if self.enigma_type == 0:
1451                                         sCommand = self.http + "/web/timerdelete?sRef=" + timerentry.servicereference + "&begin=" + ("%s"%(timerentry.timebegin)) + "&end=" +("%s"%(timerentry.timeend))
1452                                 else:
1453                                         sCommand = self.http + "/deleteTimerEvent?ref=" + timerentry.servicereference + "&start=" + ("%s"%(timerentry.timebegin)) + "&type=" +("%s"%(timerentry.type)) + "&force=yes"
1454                                 sendPartnerBoxWebCommand(sCommand, None,3, self.username, self.password).addCallback(self.deleteTimerCallback).addErrback(self.EPGListDownloadError)
1455         
1456         def deleteTimerCallback(self, callback = None):
1457                 if self.enigma_type == 0:
1458                         url = self.http + "/web/timerlist"
1459                 else:
1460                         if callback.find("Timer event deleted successfully.") != -1:
1461                                 msg = "Timer event deleted successfully."
1462                         else:
1463                                 msg = callback
1464                         self.session.open(MessageBox,msg,  MessageBox.TYPE_INFO, timeout = 3)
1465                         url = self.http + "/xml/timers"
1466                 sendPartnerBoxWebCommand(url, None,10, self.username, self.password).addCallback(self.readXML).addErrback(self.EPGListDownloadError)
1467
1468         def readXML(self, xmlstring = None):
1469                 if xmlstring is not None:
1470                         self["text"].setText("Getting timerlist data...")
1471                         self.E2TimerList = []
1472                         if self.enigma_type == 0:
1473                                 self.E2TimerList = FillE2TimerList(xmlstring)
1474                         else:
1475                                 self.E2TimerList = FillE1TimerList(xmlstring)
1476                         self["text"].setText("Getting EPG data...")
1477                         if self.useinternal == 1:
1478                                 EPGList = []
1479                                 a = Services(self.session)
1480                                 EPGList = a.buildEPGList(self.servicereference)
1481                                 self["epglist"].buildList(EPGList, self.E2TimerList)
1482                                 self["epglist"].instance.show()
1483                                 if self.ListCurrentIndex != 0:
1484                                         sel = self["epglist"].moveSelectionTo(self.ListCurrentIndex)
1485                                         self.ListCurrentIndex = 0
1486                         else:
1487                                 self.getEPGList()
1488                         
1489 class E2TimerMenu(MenuList):
1490         def __init__(self, list, enableWrapAround = True):
1491                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
1492                 self.l.setFont(0, gFont("Regular", 20))
1493                 self.l.setFont(1, gFont("Regular", 18))
1494         def postWidgetCreate(self, instance):
1495                 MenuList.postWidgetCreate(self, instance)
1496                 instance.setItemHeight(70)
1497
1498         def buildList(self,listnew):
1499                 self.list=[]
1500                 width = self.l.getItemSize().width()
1501                 for timer in listnew:
1502                         res = [ timer ]
1503                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 0, width, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, timer.servicename))
1504                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 30, width, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, timer.name))
1505
1506                         repeatedtext = ""
1507                         days = [ _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun") ]
1508                         if timer.repeated:
1509                                 flags = timer.repeated
1510                                 count = 0
1511                                 for x in range(0, 7):
1512                                                 if (flags & 1 == 1):
1513                                                         if (count != 0):
1514                                                                 repeatedtext += ", "
1515                                                         repeatedtext += days[x]
1516                                                         count += 1
1517                                                 flags = flags >> 1
1518                                 if timer.justplay:
1519                                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s "+ _("(ZAP)")) % (FuzzyTime(timer.timebegin)[1]))))
1520                                 else:
1521                                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.timebegin)[1], FuzzyTime(timer.timeend)[1], (timer.timeend - timer.timebegin) / 60))))
1522                         else:
1523                                 if timer.justplay:
1524                                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s " + _("(ZAP)")) % (FuzzyTime(timer.timebegin)))))
1525                                 else:
1526                                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.timebegin) + FuzzyTime(timer.timeend)[1:] + ((timer.timeend - timer.timebegin) / 60,)))))
1527                         
1528                         if timer.state == TimerEntry.StateWaiting:
1529                                 state = _("waiting")
1530                         elif timer.state == TimerEntry.StatePrepared:
1531                                 state = _("about to start")
1532                         elif timer.state == TimerEntry.StateRunning:
1533                                 if timer.justplay:
1534                                         state = _("zapped")
1535                                 else:
1536                                         state = _("recording...")
1537                         elif timer.state == TimerEntry.StateEnded:
1538                                 state = _("done!")
1539                         else:
1540                                 state = _("<unknown>")
1541
1542                         if timer.disabled:
1543                                 state = _("disabled")
1544
1545                         res.append((eListboxPythonMultiContent.TYPE_TEXT, width-150, 50, 150, 20, 1, RT_HALIGN_RIGHT|RT_VALIGN_CENTER, state))
1546
1547                         if timer.disabled:
1548                                 png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/redx.png"))
1549                                 res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 490, 5, 40, 40, png))
1550
1551                         self.list.append(res)
1552                 self.l.setList(self.list)
1553                 self.moveToIndex(0)
1554                 
1555         def buildE1List(self,listnew):
1556                 self.list=[]
1557                 width = self.l.getItemSize().width()
1558                 for timer in listnew:
1559                         res = [ timer ]
1560                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 0, width, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, timer.servicename))
1561                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 30, width, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, timer.description))
1562
1563                         repeatedtext = ""
1564                         days = [ _("Sun"), _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat") ]
1565                         if timer.type & PlaylistEntry.isRepeating :
1566                                 mask = PlaylistEntry.Su
1567                                 count = 0
1568                                 for x in range(0, 7):
1569                                         if timer.type & mask:
1570                                                 if (count != 0):
1571                                                         repeatedtext += ", "
1572                                                 repeatedtext += days[x]
1573                                                 count += 1
1574                                         mask *= 2
1575                                 if timer.type & PlaylistEntry.SwitchTimerEntry:
1576                                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-170, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s "+ _("(ZAP)")) % (FuzzyTime(timer.timebegin)[1]))))
1577                                 elif timer.type & PlaylistEntry.RecTimerEntry:
1578                                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-170, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + ((" %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.timebegin)[1], FuzzyTime(timer.timeend)[1], (timer.timeend - timer.timebegin) / 60))))
1579                         else:
1580                                 if timer.type & PlaylistEntry.SwitchTimerEntry:
1581                                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-170, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ") ") % (FuzzyTime(timer.timebegin) + FuzzyTime(timer.timeend)[1:] + ((timer.timeend - timer.timebegin) / 60,))) + _("(ZAP)")))
1582                                 elif timer.type & PlaylistEntry.RecTimerEntry:
1583                                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-170, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, repeatedtext + (("%s, %s ... %s (%d " + _("mins") + ")") % (FuzzyTime(timer.timebegin) + FuzzyTime(timer.timeend)[1:] + ((timer.timeend - timer.timebegin) / 60,)))))
1584                         
1585                         if timer.type & PlaylistEntry.stateWaiting:
1586                                 state = _("waiting")
1587                         elif timer.type & PlaylistEntry.stateRunning:
1588                                 if timer.type & PlaylistEntry.SwitchTimerEntry:
1589                                         state = _("zapped")
1590                                 elif timer.type & PlaylistEntry.RecTimerEntry:
1591                                         state = _("recording...")
1592                         elif timer.type & PlaylistEntry.stateFinished:
1593                                 state = _("done!")
1594                         elif timer.type & PlaylistEntry.stateError:
1595                                 if timer.type & PlaylistEntry.errorNoSpaceLeft:
1596                                         state = _("Error: No space left")
1597                                 elif timer.type & PlaylistEntry.errorUserAborted:
1598                                         state = _("Error: User aborted")
1599                                 elif timer.type & PlaylistEntry.errorZapFailed:
1600                                         state = _("Error: Zap failed")
1601                                 elif timer.type & PlaylistEntry.errorOutdated:
1602                                         state = _("Error: Outdated")
1603                                 else:
1604                                         state = "Error: " + _("<unknown>")
1605                         else:
1606                                 state = _("<unknown>")
1607                         res.append((eListboxPythonMultiContent.TYPE_TEXT, width-170, 50, 170, 20, 1, RT_HALIGN_RIGHT|RT_VALIGN_CENTER, state))
1608                         self.list.append(res)
1609                 self.l.setList(self.list)
1610                 self.moveToIndex(0)
1611                 
1612 class E2BouquetList(MenuList):
1613         def __init__(self, list, enableWrapAround = True):
1614                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
1615                 self.l.setFont(0, gFont("Regular", 20))
1616                 self.l.setFont(1, gFont("Regular", 18))
1617         def postWidgetCreate(self, instance):
1618                 MenuList.postWidgetCreate(self, instance)
1619                 instance.setItemHeight(30)
1620
1621         def buildList(self,listnew):
1622                 self.list=[]
1623                 width = self.l.getItemSize().width()
1624                 for bouquets in listnew:
1625                         res = [ bouquets ]
1626                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 0, width, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, bouquets.servicename))
1627                         self.list.append(res)
1628                 self.l.setList(self.list)
1629                 self.moveToIndex(0)
1630
1631 class E2ChannelList(MenuList):
1632         def __init__(self, list, selChangedCB=None, enableWrapAround = True):
1633                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
1634                 self.onSelChanged = [ ]
1635                 if selChangedCB is not None:
1636                         self.onSelChanged.append(selChangedCB)
1637                 self.l.setFont(0, gFont("Regular", 20))
1638                 self.l.setFont(1, gFont("Regular", 18))
1639         def postWidgetCreate(self, instance):
1640                 MenuList.postWidgetCreate(self, instance)
1641                 instance.setItemHeight(70)
1642                 instance.selectionChanged.get().append(self.selectionChanged)
1643         
1644         def preWidgetRemove(self, instance):
1645                 instance.selectionChanged.get().remove(self.selectionChanged)
1646                 
1647         def selectionChanged(self):
1648                 for x in self.onSelChanged:
1649                         if x is not None:
1650                                 x()
1651                                 
1652         def getCurrentIndex(self):
1653                 return self.instance.getCurrentIndex()
1654                 
1655         def moveSelectionTo(self,index):
1656                 self.moveToIndex(index)
1657         
1658         def buildList(self,listnew):
1659                 self.list=[]
1660                 width = self.l.getItemSize().width()
1661                 for epgdata in listnew:
1662                         res = [ epgdata ]
1663                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 0, width, 30, 0, RT_HALIGN_LEFT|RT_VALIGN_CENTER, epgdata.servicename))
1664                         res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 30, width, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, epgdata.eventtitle))
1665                         if epgdata.eventstart != 0:
1666                                 endtime = int(epgdata.eventstart + epgdata.eventduration)
1667                                 res.append((eListboxPythonMultiContent.TYPE_TEXT, 0, 50, width-150, 20, 1, RT_HALIGN_LEFT|RT_VALIGN_CENTER, (("%s ... %s (%d " + _("mins") + ")") % (FuzzyTime(epgdata.eventstart)[1], FuzzyTime(endtime)[1], (endtime - epgdata.eventstart) / 60))))
1668                         self.list.append(res)
1669                 self.l.setList(self.list)
1670                 self.moveToIndex(0)
1671
1672 class E2EPGList(MenuList):
1673         def __init__(self, list, selChangedCB=None, enableWrapAround = True):
1674                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
1675                 self.onSelChanged = [ ]
1676                 if selChangedCB is not None:
1677                         self.onSelChanged.append(selChangedCB)
1678                 self.l.setFont(0, gFont("Regular", 22))
1679                 self.l.setFont(1, gFont("Regular", 16))
1680                 self.days = [ _("Mon"), _("Tue"), _("Wed"), _("Thu"), _("Fri"), _("Sat"), _("Sun") ]
1681                 self.timer_list = []
1682                 self.clock_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock.png'))
1683                 self.clock_add_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_add.png'))
1684                 self.clock_pre_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_pre.png'))
1685                 self.clock_post_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_post.png'))
1686                 self.clock_prepost_pixmap = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, 'skin_default/icons/epgclock_prepost.png'))
1687                 
1688         def postWidgetCreate(self, instance):
1689                 MenuList.postWidgetCreate(self, instance)
1690                 instance.setItemHeight(30)
1691                 instance.selectionChanged.get().append(self.selectionChanged)
1692         
1693         def preWidgetRemove(self, instance):
1694                 instance.selectionChanged.get().remove(self.selectionChanged)
1695         
1696         def getCurrentIndex(self):
1697                 return self.instance.getCurrentIndex()
1698                 
1699         def moveSelectionTo(self,index):
1700                 self.moveToIndex(index)
1701                 
1702         def selectionChanged(self):
1703                 for x in self.onSelChanged:
1704                         if x is not None:
1705                                 x()
1706         
1707         def buildList(self,listnew, timerlist):
1708                 self.list=[]
1709                 self.timer_list = timerlist
1710                 for epgdata in listnew:
1711                         res = [ epgdata ]
1712                         rec=epgdata.eventstart and (self.isInTimer(epgdata.eventstart, epgdata.eventduration, epgdata.servicereference))
1713                         esize = self.l.getItemSize()
1714                         width = esize.width()
1715                         height = esize.height()
1716                         r1 = Rect(0, 0, width/20*2-10, height)
1717                         r2 = Rect(width/20*2, 0, width/20*5-15, height)
1718                         r3 = Rect(width/20*7, 0, width/20*13, height)
1719                         t = localtime(epgdata.eventstart)
1720                         res.append((eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_RIGHT, self.days[t[6]]))
1721                         res.append((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])))
1722                         if rec:
1723                                 clock_pic = self.getClockPixmap(epgdata.servicereference, epgdata.eventstart, epgdata.eventduration, epgdata.eventid)
1724                                 res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic))
1725                                 res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 25, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, epgdata.eventtitle))
1726                         else:
1727                                 res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, epgdata.eventtitle))
1728                         
1729                         self.list.append(res)
1730                 self.l.setList(self.list)
1731                 self.moveToIndex(0)
1732                 
1733         def isInTimer(self, begin, duration, service):
1734                 time_match = 0
1735                 chktime = None
1736                 chktimecmp = None
1737                 chktimecmp_end = None
1738                 end = begin + duration
1739                 for x in self.timer_list:
1740                         if x.servicereference.upper() == service.upper():
1741                                 if x.repeated != 0:
1742                                         if chktime is None:
1743                                                 chktime = localtime(begin)
1744                                                 chktimecmp = chktime.tm_wday * 1440 + chktime.tm_hour * 60 + chktime.tm_min
1745                                                 chktimecmp_end = chktimecmp + (duration / 60)
1746                                         time = localtime(x.timebegin)
1747                                         for y in range(7):
1748                                                 if x.repeated & (2 ** y):
1749                                                         timecmp = y * 1440 + time.tm_hour * 60 + time.tm_min
1750                                                         if timecmp <= chktimecmp < (timecmp + ((x.timeend - x.timebegin) / 60)):
1751                                                                 time_match = ((timecmp + ((x.timeend - x.timebegin) / 60)) - chktimecmp) * 60
1752                                                         elif chktimecmp <= timecmp < chktimecmp_end:
1753                                                                 time_match = (chktimecmp_end - timecmp) * 60
1754                                 else: 
1755                                         if begin <= x.timebegin <= end:
1756                                                 diff = end - x.timebegin
1757                                                 if time_match < diff:
1758                                                         time_match = diff
1759                                         elif x.timebegin <= begin <= x.timeend:
1760                                                 diff = x.timeend - begin
1761                                                 if time_match < diff:
1762                                                         time_match = diff
1763                                 if time_match:
1764                                         break
1765                 return time_match
1766         
1767         def getClockPixmap(self, refstr, beginTime, duration, eventId):
1768
1769                 pre_clock = 1
1770                 post_clock = 2
1771                 clock_type = 0
1772                 endTime = beginTime + duration
1773                 for x in self.timer_list:
1774                         if x.servicereference.upper() == refstr.upper():
1775                                 if x.eventId == eventId:
1776                                         return self.clock_pixmap
1777                                 beg = x.timebegin
1778                                 end = x.timeend
1779                                 if beginTime > beg and beginTime < end and endTime > end:
1780                                         clock_type |= pre_clock
1781                                 elif beginTime < beg and endTime > beg and endTime < end:
1782                                         clock_type |= post_clock
1783                 if clock_type == 0:
1784                         return self.clock_add_pixmap
1785                 elif clock_type == pre_clock:
1786                         return self.clock_pre_pixmap
1787                 elif clock_type == post_clock:
1788                         return self.clock_post_pixmap
1789                 else:
1790                         return self.clock_prepost_pixmap
1791
1792 class RemoteTimerEventView(Screen):
1793         EMPTY = 0
1794         ADD_TIMER = 1
1795         REMOVE_TIMER = 2
1796         skin = """
1797                 <screen name="RemoteTimerEventView" position="90,95" size="560,430" title="Eventview">
1798                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
1799                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
1800                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
1801                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
1802                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
1803                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
1804                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
1805                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
1806                         <widget name="epg_description" position="10,50" size="540,330" font="Regular;22" />
1807                         <widget name="datetime" position="10,395" size="130,25" font="Regular;22" />
1808                         <widget name="duration" position="140,395" size="100,25" font="Regular;22" />
1809                         <widget name="channel" position="240,395" size="305,25" font="Regular;22" halign="right" />
1810                 </screen>"""
1811         
1812         def __init__(self, session, E2Timerlist, epgdata , User, Pass, http, enigma_type, useinternal):
1813                 self.session = session
1814                 Screen.__init__(self, session)
1815                 self["epg_description"] = ScrollLabel()
1816                 self["datetime"] = Label()
1817                 self["channel"] = Label()
1818                 self["duration"] = Label()
1819                 self["key_red"] = Label() # Dummy, kommt eventuell noch was
1820                 self["key_green"] = Label() # Dummy, kommt eventuell noch was
1821                 self["key_yellow"] = Label() # Dummy, kommt eventuell noch was
1822                 self["key_blue"] = Label() # Dummy, kommt eventuell noch was
1823                 self.key_green_choice = self.ADD_TIMER
1824                 self.onLayoutFinish.append(self.startRun)
1825                 self.E2TimerList = E2Timerlist
1826                 self.epgdata = epgdata
1827                 
1828                 self["actions"] = ActionMap(["WizardActions", "DirectionActions", "ColorActions", "EventViewActions"],
1829                 {
1830                         "back": self.close,
1831                         "pageUp": self.pageUp,
1832                         "pageDown": self.pageDown,
1833                 }, -1)
1834                 self.password = Pass
1835                 self.username = User
1836                 self.http = http
1837                 self.enigma_type = enigma_type
1838                 self.useinternal = useinternal
1839         
1840         def startRun(self):
1841                 name = self.epgdata.servicename
1842                 if name != "n/a":
1843                         self["channel"].setText(name)
1844                 else:
1845                         self["channel"].setText(_("unknown service"))
1846                 text = self.epgdata.eventtitle
1847                 short = self.epgdata.eventdescription
1848                 ext = self.epgdata.eventdescriptionextended
1849                 if len(short) > 0 and short != text:
1850                         text = text + '\n\n' + short
1851                 if len(ext) > 0:
1852                         if len(text) > 0:
1853                                 text = text + '\n\n'
1854                         text = text + ext
1855                 self.setTitle(self.epgdata.eventtitle)
1856                 self["epg_description"].setText(text)
1857                 endtime = int(self.epgdata.eventstart + self.epgdata.eventduration)
1858                 t = localtime(self.epgdata.eventstart)
1859                 datetime = ("%02d.%02d, %02d:%02d"%(t[2],t[1],t[3],t[4]))
1860                 duration = (" (%d " + _("mins")+")") % ((self.epgdata.eventduration ) / 60)
1861                 self["datetime"].setText(datetime)
1862                 self["duration"].setText(duration)
1863                 self["key_red"].setText("")     
1864
1865         def pageUp(self):
1866                 self["epg_description"].pageUp()
1867
1868         def pageDown(self):
1869                 self["epg_description"].pageDown()