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