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