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