root/httpserver.py

Revision ae39ac9f4d53ef3c57ac397c956f075cf52245e7, 6.4 kB (checked in by Jason Michalski <armooo@armooo.net>, 5 months ago)

Everything is loging with the logging module

Currently everything is always in debug mode

  • Property mode set to 100644
Line 
1 import time, os, BaseHTTPServer, SocketServer, socket, re
2 from urllib import unquote_plus, quote, unquote
3 from urlparse import urlparse
4 from cgi import parse_qs
5 from Cheetah.Template import Template
6 from plugin import GetPlugin
7 import config
8 from xml.sax.saxutils import escape
9 import logging
10
11 SCRIPTDIR = os.path.dirname(__file__)
12
13 hack83 = config.getHack83()
14
15 class TivoHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
16     containers = {}
17
18     def __init__(self, server_address, RequestHandlerClass):
19         BaseHTTPServer.HTTPServer.__init__(self, server_address,
20                                            RequestHandlerClass)
21         self.daemon_threads = True
22
23     def add_container(self, name, settings):
24         if self.containers.has_key(name) or name == 'TiVoConnect':
25             raise "Container Name in use"
26         try:
27             settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
28             self.containers[name] = settings
29         except KeyError:
30             print 'Unable to add container', name
31
32     def reset(self):
33         self.containers.clear()
34         for section, settings in config.getShares():
35             self.add_container(section, settings)
36
37 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
38     tivos ={}
39
40     def address_string(self):
41         host, port = self.client_address[:2]
42         return host
43
44     def do_GET(self):
45         tsn = self.headers.getheader('TiVo_TCD_ID', self.headers.getheader('tsn', ''))
46         ip = self.address_string()
47         self.tivos[tsn] = ip
48
49         basepath = unquote_plus(self.path).split('/')[1]
50
51         ## Get File
52         for name, container in self.server.containers.items():
53             if basepath == name:
54                 plugin = GetPlugin(container['type'])
55                 plugin.send_file(self, container, name)
56                 return
57
58         ## Not a file not a TiVo command fuck them
59         if not self.path.startswith('/TiVoConnect'):
60             self.infopage()
61             return
62
63         o = urlparse("http://fake.host" + self.path)
64         query = parse_qs(o[4])
65
66         mname = False
67         if query.has_key('Command') and len(query['Command']) >= 1:
68
69             command = query['Command'][0]
70
71             # If we are looking at the root container
72             if command == "QueryContainer" and \
73                (not query.has_key('Container') or query['Container'][0] == '/'):
74                 self.root_container()
75                 return
76
77             if query.has_key('Container'):
78                 # Dispatch to the container plugin
79                 basepath = unquote(query['Container'][0].split('/')[0])
80                 for name, container in self.server.containers.items():
81                     if basepath == name:
82                         plugin = GetPlugin(container['type'])
83                         if hasattr(plugin, command):
84                             method = getattr(plugin, command)
85                             method(self, query)
86                             return
87                         else:
88                             break
89
90         # If we made it here it means we couldn't match the request to
91         # anything.
92         self.unsupported(query)
93
94     def root_container(self):
95         tsn = self.headers.getheader('TiVo_TCD_ID', '')
96         tsnshares = config.getShares(tsn)
97         tsncontainers = {}
98         for section, settings in tsnshares:
99             try:
100                 settings['content_type'] = \
101                     GetPlugin(settings['type']).CONTENT_TYPE
102                 tsncontainers[section] = settings
103             except Exception, msg:
104                 print section, '-', msg
105         t = Template(file=os.path.join(SCRIPTDIR, 'templates',
106                                        'root_container.tmpl'))
107         t.containers = tsncontainers
108         t.hostname = socket.gethostname()
109         t.escape = escape
110         self.send_response(200)
111         self.end_headers()
112         self.wfile.write(t)
113
114     def infopage(self):
115         self.send_response(200)
116         self.send_header('Content-type', 'text/html')
117         self.end_headers()
118         t = Template(file=os.path.join(SCRIPTDIR, 'templates',
119                                        'info_page.tmpl'))
120         t.admin = ''
121         for section, settings in config.getShares():
122             if 'type' in settings and settings['type'] == 'admin':
123                 t.admin += '<a href="/TiVoConnect?Command=Admin&Container=' + section\
124                            + '">pyTivo Web Configuration</a><br>'\
125                            + '<a href="/TiVoConnect?Command=NPL&Container=' + section\
126                            + '">pyTivo ToGo</a><br>'
127         if t.admin == '':
128             t.admin = '<br><b>No Admin plugin installed in pyTivo.conf</b><br> If you wish to use'\
129                       + ' the admin plugin add the following lines to pyTivo.conf<br><br>'\
130                       + '[Admin]<br>type=admin'
131
132         t.shares = 'Video shares:<br/>'
133         for section, settings in config.getShares():
134             if settings.get('type') == 'video':
135                 t.shares += '<a href="TiVoConnect?Command=QueryContainer&Container=' + section\
136                     + '">' +  section + '</a><br/>'
137
138         self.wfile.write(t)
139         self.end_headers()
140
141     def unsupported(self, query):
142         if hack83 and 'Command' in query and 'Filter' in query:
143             logger = logging.getLogger('pyTivo.hack83')
144
145             logger.debug('Unsupported request checking to see if it is video.')
146             command = query['Command'][0]
147             plugin = GetPlugin('video')
148             if ''.join(query['Filter']).find('video') >= 0 and \
149                hasattr(plugin, command):
150                 logger.debug('Unsupported request yup it is video send to video plugin for it to sort out.')
151                 method = getattr(plugin, command)
152                 method(self, query)
153                 return
154
155         self.send_response(404)
156         self.send_header('Content-type', 'text/html')
157         self.end_headers()
158         t = Template(file=os.path.join(SCRIPTDIR, 'templates',
159                                        'unsupported.tmpl'))
160         t.query = query
161         self.wfile.write(t)
162
163 if __name__ == '__main__':
164     def start_server():
165         httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
166         httpd.add_container('test', 'x-container/tivo-videos',
167                             r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
168         httpd.serve_forever()
169
170     start_server()
Note: See TracBrowser for help on using the browser.