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