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