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