revert last change
[enigma2-plugins.git] / webinterface / src / plugin.py
1 from Plugins.Plugin import PluginDescriptor
2
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 import webif
7 import os
8
9 sessions = [ ]
10
11 # set DEBUG to True, if twisted should write logoutput to a file.
12 DEBUG = False 
13 DEBUGFILE= "/tmp/twisted.log"
14
15 # Passwordprotection Test
16 # set it only to True, if you have a patched wrapper.py
17 # see http://twistedmatrix.com/trac/ticket/2041
18 # in /usr/lib/python2.4/site-packages/twisted/web2/auth/wrapper.py
19 # The solution is to change this line
20 #       
21 #       return self.authenticate(req), seg[1:]
22 # into this
23 #       return self.authenticate(req), seg
24 PASSWORDPROTECTION = False
25 PASSWORDPROTECTION_pwd = "root"
26 PASSWORDPROTECTION_mode = "sha"; 
27 # twisted supports more than sha ('md5','md5-sess','sha')
28 # but only sha works for me, but IE 
29 # sha, Firefox=ok, Opera=ok, wget=ok, ie=not ok
30 # md5-sess, firefox=not ok, opera=not ok,wget=ok, ie=not ok
31 # md5 same as md5-sess 
32
33 def startWebserver():
34         class ScreenPage(resource.Resource):
35                 def __init__(self, path):
36                         self.path = path
37                         
38                         
39                 def render(self, req):
40                         global sessions
41                         if sessions == [ ]:
42                                 return http.Response(responsecode.OK, stream="please wait until enigma has booted")
43
44                         class myProducerStream(stream.ProducerStream):
45                                 closed_callback = None
46
47                                 def close(self):
48                                         if self.closed_callback:
49                                                 self.closed_callback()
50                                         stream.ProducerStream.close(self)
51
52                         if os.path.isfile(self.path):
53                                 s=myProducerStream()
54                                 webif.renderPage(s, self.path, req, sessions[0])  # login?
55                                 return http.Response(responsecode.OK,stream=s)
56                         else:
57                                 return http.Response(responsecode.NOT_FOUND)
58                         
59                 def locateChild(self, request, segments):
60                         path = self.path+'/'+'/'.join(segments)
61                         if path[-1:] == "/":
62                                 path += "index.html"
63                         path +=".xml"
64                         return ScreenPage(path), ()
65                 
66         class Toplevel(resource.Resource):
67                 addSlash = True
68
69                 def render(self, req):
70                         fp = open(util.sibpath(__file__, "web-data")+"/index.html")
71                         s = fp.read()
72                         fp.close()
73                         return http.Response(responsecode.OK, {'Content-type': http_headers.MimeType('text', 'html')},stream=s)
74
75                 child_web = ScreenPage(util.sibpath(__file__, "web")) # "/web/*"
76                 child_webdata = static.File(util.sibpath(__file__, "web-data")) # FIXME: web-data appears as webdata
77                 child_hdd = static.File("/hdd")
78                 
79         if PASSWORDPROTECTION is False:
80                 site = server.Site(Toplevel())
81         else:
82                 from twisted.cred.portal import Portal
83                 from twisted.cred import checkers
84                 from twisted.web2.auth import digest, basic, wrapper
85                 from zope.interface import Interface, implements
86                 from twisted.cred import portal
87                 class IHTTPUser(Interface):
88                         pass
89
90                 class HTTPUser(object):
91                         implements(IHTTPUser)
92
93                 class HTTPAuthRealm(object):
94                         implements(portal.IRealm)
95                         def requestAvatar(self, avatarId, mind, *interfaces):
96                                 if IHTTPUser in interfaces:
97                                         return IHTTPUser, HTTPUser()
98                                 raise NotImplementedError("Only IHTTPUser interface is supported")
99
100                 portal = Portal(HTTPAuthRealm())
101                 checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(root=PASSWORDPROTECTION_pwd)
102                 portal.registerChecker(checker)
103                 root = wrapper.HTTPAuthResource(Toplevel(),
104                                         (basic.BasicCredentialFactory('DM7025'),digest.DigestCredentialFactory(PASSWORDPROTECTION_mode,'DM7025')),
105                                         portal, (IHTTPUser,))
106                 site = server.Site(root)
107         reactor.listenTCP(80, channel.HTTPFactory(site))
108
109 # start classes for PASSWORDPROTECTION
110 # end  classes for PASSWORDPROTECTION
111
112 def autostart(reason, **kwargs):
113         if "session" in kwargs:
114                 global sessions
115                 sessions.append(kwargs["session"])
116                 return
117
118         if reason == 0:
119                 try:
120                         """
121                          in normal console output, twisted will print only the first Traceback.
122                          is this a bug in twisted or a conflict with enigma2?
123                          with this option enabled, twisted will print all TB to the logfile
124                          use tail -f <file> to view this log
125                         """
126                         if DEBUG:
127                                 from twisted.python.log import startLogging
128                                 print "start twisted logfile, writing to %s" % DEBUGFILE 
129                                 startLogging(open(DEBUGFILE,'w'))
130                         
131                         startWebserver()
132                 except ImportError:
133                         print "twisted not available, not starting web services"
134
135 def Plugins(**kwargs):
136         return PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART, PluginDescriptor.WHERE_AUTOSTART], fnc = autostart)