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