1 # -*- coding: utf-8 -*-
2 #===============================================================================
3 # Remote Timer Setup by Homey
5 # This is free software; you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation; either version 2, or (at your option) any later
10 # Copyright (C) 2009 by nixkoenner@newnigma2.to
17 #===============================================================================
19 from Plugins.Plugin import PluginDescriptor
20 from Screens.Screen import Screen
22 from Components.ActionMap import NumberActionMap
23 from Components.Button import Button
25 from Components.ConfigList import ConfigList, ConfigListScreen
26 from Components.config import getConfigListEntry, config, \
27 ConfigSubsection, ConfigText, ConfigIP, ConfigYesNo, \
28 ConfigPassword, ConfigNumber, KEY_LEFT, KEY_RIGHT, KEY_0
30 from Screens.TimerEntry import TimerEntry
31 from Screens.MessageBox import MessageBox
32 from Screens.MovieSelection import getPreferredTagEditor
33 from RecordTimer import AFTEREVENT
34 from enigma import eEPGCache
36 from Tools.BoundFunction import boundFunction
39 from twisted.web.client import getPage
40 from xml.dom.minidom import parseString
41 from base64 import encodestring
44 #------------------------------------------------------------------------------------------
46 config.plugins.remoteTimer = ConfigSubsection()
47 config.plugins.remoteTimer.httphost = ConfigText(default = "" , fixed_size = False)
48 config.plugins.remoteTimer.httpip = ConfigIP(default = [0, 0, 0, 0])
49 config.plugins.remoteTimer.httpport = ConfigNumber(default = "0")
50 config.plugins.remoteTimer.username = ConfigText(default = "root", fixed_size = False)
51 config.plugins.remoteTimer.password = ConfigPassword(default = "", fixed_size = False)
53 class RemoteTimerSetup(Screen, ConfigListScreen):
55 <screen position="80,160" size="560,330" title="Settings" >
56 <widget name="config" position="5,40" size="480,335" scrollbarMode="showOnDemand" />
57 <ePixmap name="red" position="120,280" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
58 <ePixmap name="green" position="320,280" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
59 <widget name="key_red" position="120,280" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
60 <widget name="key_green" position="320,280" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
63 def __init__(self, session):
64 Screen.__init__(self, session)
66 self["actions"] = NumberActionMap(["SetupActions", "ColorActions"],
69 "green": self.keySave,
73 "right": self.keyRight,
86 self["key_red"] = Button(_("Cancel"))
87 self["key_green"] = Button(_("OK"))
89 ConfigListScreen.__init__(self, [
90 getConfigListEntry(_("Remote Timer - Hostname"), config.plugins.remoteTimer.httphost),
91 getConfigListEntry(_("Remote Timer - Network IP"), config.plugins.remoteTimer.httpip),
92 getConfigListEntry(_("Remote Timer - WebIf Port"), config.plugins.remoteTimer.httpport),
93 getConfigListEntry(_("Remote Timer - Username"), config.plugins.remoteTimer.username),
94 getConfigListEntry(_("Remote Timer - Password"), config.plugins.remoteTimer.password),
99 self["config"].handleKey(KEY_LEFT)
102 self["config"].handleKey(KEY_RIGHT)
104 def keyNumber(self, number):
105 self["config"].handleKey(KEY_0 + number)
108 #print "################################"
109 #print config.plugins.remoteTimer.httphost.value
110 #print "################################"
111 config.plugins.remoteTimer.save()
118 baseTimerEntrySetup = None
119 baseTimerEntryGo = None
122 global baseTimerEntrySetup, baseTimerEntryGo
123 if baseTimerEntrySetup is None:
124 baseTimerEntrySetup = TimerEntry.createSetup
125 if baseTimerEntryGo is None:
126 baseTimerEntryGo = TimerEntry.keyGo
127 TimerEntry.createSetup = createNewnigma2Setup
128 TimerEntry.keyGo = newnigma2KeyGo
130 def createNewnigma2Setup(self, widget):
131 baseTimerEntrySetup(self, widget)
132 self.timerentry_remote = ConfigYesNo()
133 self.list.insert(0, getConfigListEntry(_("Remote Timer"), self.timerentry_remote))
135 # force re-reading the list
136 self[widget].list = self.list
138 def newnigma2SubserviceSelected(self, service):
139 if service is not None:
140 # ouch, this hurts a little
141 service_ref = timerentry_service_ref
142 self.timerentry_service_ref = ServiceReference(service[1])
144 self.timer.eit = None
148 self.timerentry_service_ref = service_ref
151 def newnigma2KeyGo(self):
152 if not self.timerentry_remote.value:
153 baseTimerEntryGo(self)
155 service_ref = self.timerentry_service_ref
156 if self.timer.eit is not None:
157 event = eEPGCache.getInstance().lookupEventId(service_ref.ref, self.timer.eit)
159 n = event.getNumOfLinkageServices()
162 ref = self.session.nav.getCurrentlyPlayingServiceReference()
163 parent = service_ref.ref
166 i = event.getLinkageService(parent, x)
167 if i.toString() == ref.toString():
169 tlist.append((i.getName(), i))
170 self.session.openWithCallback(boundFunction(newnigma2SubserviceSelected, self), ChoiceBox, title=_("Please select a subservice to record..."), list = tlist, selection = selection)
173 parent = service_ref.ref
174 service_ref = ServiceReference(event.getLinkageService(parent, 0))
176 # XXX: this will - without any hassle - ignore the value of repeated
177 begin, end = self.getBeginEnd()
179 # when a timer end is set before the start, add 1 day
183 rt_name = urllib.quote(self.timerentry_name.value.decode('utf8').encode('utf8','ignore'))
184 rt_description = urllib.quote(self.timerentry_description.value.decode('utf8').encode('utf8','ignore'))
185 rt_disabled = 0 # XXX: do we really want to hardcode this? why do we offer this option then?
186 rt_repeated = 0 # XXX: same here
188 if self.timerentry_justplay.value == "zap":
193 # XXX: this one is tricky since we do not know if the remote box offers afterEventAuto so lets just keep it simple for now
195 "deepstandby": AFTEREVENT.DEEPSTANDBY,
196 "standby": AFTEREVENT.STANDBY,
197 }.get(self.timerentry_afterevent.value, AFTEREVENT.NONE)
199 # Add Timer on RemoteBox via WebIf Command
200 # http://192.168.178.20/web/timeradd?sRef=&begin=&end=&name=&description=&disabled=&justplay=&afterevent=&repeated=
201 remoteip = "%d.%d.%d.%d" % tuple(config.plugins.remoteTimer.httpip.value)
202 remoteurl = "http://%s:%s/web/timeradd?sRef=%s&begin=%s&end=%s&name=%s&description=%s&disabled=%s&justplay=%s&afterevent=%s&repeated=%s" % (
204 config.plugins.remoteTimer.httpport.value,
215 print "######### debug remote", remoteurl
217 username = config.plugins.remoteTimer.username.value
218 password = config.plugins.remoteTimer.password.value
219 if username and password:
220 basicAuth = encodestring("%s:%s" % (username, password))
221 authHeader = "Basic " + basicAuth.strip()
222 headers = {"Authorization": authHeader}
226 defer = getPage(remoteurl, headers = headers)
227 defer.addCallback(boundFunction(_gotPageLoad, self.session, self))
228 defer.addErrback(boundFunction(errorLoad, self.session))
230 def _gotPageLoadCb(timerEntry, doClose, *args):
232 timerEntry.keyCancel()
234 def _gotPageLoad(session, timerEntry, html):
235 remoteresponse = parseXml( html)
236 #print "_gotPageLoad remoteresponse:", remoteresponse
237 # XXX: should be improved...
238 doClose = remoteresponse == "Timer added successfully!"
239 session.openWithCallback(
240 boundFunction(_gotPageLoadCb, timerEntry, doClose),
242 _("Set Timer on Remote DreamBox via WebIf:\n%s") % (remoteresponse),
246 def errorLoad(session, error):
247 #print "errorLoad ERROR:", error
250 _("ERROR - Set Timer on Remote DreamBox via WebIf:\n%s") % (error),
254 def parseXml(string):
256 dom = parseString(string)
257 for entry in dom.firstChild.childNodes:
258 if entry.nodeName == 'e2statetext':
259 result = entry.firstChild.data.encode("utf-8")
260 #print "parseXml debug result:", result
263 return "ERROR XML PARSE"
265 #------------------------------------------------------------------------------------------
267 def autostart(reason, **kwargs):
268 if "session" in kwargs:
269 session = kwargs["session"]
271 if config.plugins.remoteTimer.httpip.value:
274 print "####### NO remoteTimer.httpip.value"
276 def main(session, **kwargs):
277 session.open(RemoteTimerSetup)
279 def Plugins(**kwargs):
281 PluginDescriptor(name="Remote Timer",description="Remote Timer Setup", where = [ PluginDescriptor.WHERE_PLUGINMENU ], fnc = main),
282 PluginDescriptor(name="Remote Timer", where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main),
283 PluginDescriptor(where = PluginDescriptor.WHERE_SESSIONSTART, fnc = autostart)