1 from Plugins.Plugin import PluginDescriptor
3 from twisted.internet import reactor
4 from twisted.web2 import server, channel, static, resource, stream, http_headers, responsecode, http
5 from twisted.python import util
6 from twisted.python.log import startLogging,discardLogs
12 from Components.config import config, ConfigSubsection, ConfigInteger,ConfigYesNo
14 config.plugins.Webinterface = ConfigSubsection()
15 config.plugins.Webinterface.enable = ConfigYesNo(default = True)
16 config.plugins.Webinterface.port = ConfigInteger(80,limits = (1, 999))
17 config.plugins.Webinterface.includehdd = ConfigYesNo(default = False)
23 set DEBUG to True, if twisted should write logoutput to a file.
24 in normal console output, twisted will print only the first Traceback.
25 is this a bug in twisted or a conflict with enigma2?
26 with this option enabled, twisted will print all TB to the logfile
27 use tail -f <file> to view this log
31 DEBUGFILE= "/tmp/twisted.log"
33 # Passwordprotection Test
34 # set it only to True, if you have a patched wrapper.py
35 # see http://twistedmatrix.com/trac/ticket/2041
36 # in /usr/lib/python2.4/site-packages/twisted/web2/auth/wrapper.py
37 # The solution is to change this line
39 # return self.authenticate(req), seg[1:]
41 # return self.authenticate(req), seg
42 PASSWORDPROTECTION = False
43 PASSWORDPROTECTION_pwd = "root"
44 PASSWORDPROTECTION_mode = "sha";
45 # twisted supports more than sha ('md5','md5-sess','sha')
46 # but only sha works for me, but IE
47 # sha, Firefox=ok, Opera=ok, wget=ok, ie=not ok
48 # md5-sess, firefox=not ok, opera=not ok,wget=ok, ie=not ok
49 # md5 same as md5-sess
52 reactor.disconnectAll()
54 def restartWebserver():
59 if config.plugins.Webinterface.enable.value is not True:
60 print "not starting Werbinterface"
63 print "start twisted logfile, writing to %s" % DEBUGFILE
65 startLogging(open(DEBUGFILE,'w'))
67 class ScreenPage(resource.Resource):
68 def __init__(self, path):
72 def render(self, req):
75 return http.Response(responsecode.OK, stream="please wait until enigma has booted")
77 class myProducerStream(stream.ProducerStream):
78 closed_callback = None
81 if self.closed_callback:
82 self.closed_callback()
83 stream.ProducerStream.close(self)
85 if os.path.isfile(self.path):
87 webif.renderPage(s, self.path, req, sessions[0]) # login?
88 return http.Response(responsecode.OK,{'Content-type': http_headers.MimeType('application', 'xhtml+xml', (('charset', 'UTF-8'),))},stream=s)
89 #return http.Response(responsecode.OK,stream=s)
91 return http.Response(responsecode.NOT_FOUND)
93 def locateChild(self, request, segments):
94 path = self.path+'/'+'/'.join(segments)
98 return ScreenPage(path), ()
100 class Toplevel(resource.Resource):
103 def render(self, req):
104 fp = open(util.sibpath(__file__, "web-data")+"/index.html")
107 return http.Response(responsecode.OK, {'Content-type': http_headers.MimeType('text', 'html')},stream=s)
109 child_web = ScreenPage(util.sibpath(__file__, "web")) # "/web/*"
110 child_webdata = static.File(util.sibpath(__file__, "web-data")) # FIXME: web-data appears as webdata
112 toplevel = Toplevel()
113 if config.plugins.Webinterface.includehdd.value:
114 toplevel.putChild("hdd",static.File("/hdd"))
116 if PASSWORDPROTECTION is False:
117 site = server.Site(toplevel)
119 from twisted.cred.portal import Portal
120 from twisted.cred import checkers
121 from twisted.web2.auth import digest, basic, wrapper
122 from zope.interface import Interface, implements
123 from twisted.cred import portal
124 class IHTTPUser(Interface):
127 class HTTPUser(object):
128 implements(IHTTPUser)
130 class HTTPAuthRealm(object):
131 implements(portal.IRealm)
132 def requestAvatar(self, avatarId, mind, *interfaces):
133 if IHTTPUser in interfaces:
134 return IHTTPUser, HTTPUser()
135 raise NotImplementedError("Only IHTTPUser interface is supported")
137 portal = Portal(HTTPAuthRealm())
138 checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(root=PASSWORDPROTECTION_pwd)
139 portal.registerChecker(checker)
140 root = wrapper.HTTPAuthResource(toplevel,
141 (basic.BasicCredentialFactory('DM7025'),digest.DigestCredentialFactory(PASSWORDPROTECTION_mode,'DM7025')),
142 portal, (IHTTPUser,))
143 site = server.Site(root)
144 print "[WebIf] starting Webinterface on port",config.plugins.Webinterface.port.value
145 reactor.listenTCP(config.plugins.Webinterface.port.value, channel.HTTPFactory(site))
148 def autostart(reason, **kwargs):
149 if "session" in kwargs:
151 sessions.append(kwargs["session"])
156 except ImportError,e:
157 print "[WebIf] twisted not available, not starting web services",e
159 def openconfig(session, **kwargs):
160 session.openWithCallback(configCB,WebIfConfig.WebIfConfigScreen)
162 def configCB(result):
164 print "[WebIf] config changed"
167 print "[WebIf] config not changed"
170 def Plugins(**kwargs):
171 return [PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = autostart),
172 PluginDescriptor(name=_("Webinterface"), description=_("Configuration for the Webinterface"),where = [PluginDescriptor.WHERE_PLUGINMENU], icon="plugin.png",fnc = openconfig)]