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