KRKeegan's pre-caching.
[pyTivo.git] / httpserver.py
blob7205fc0ebbcf9524f3836ebf714ef91ebf5f0a1e
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
10 SCRIPTDIR = os.path.dirname(__file__)
12 class TivoHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
13 containers = {}
15 def __init__(self, server_address, RequestHandlerClass):
16 BaseHTTPServer.HTTPServer.__init__(self, server_address,
17 RequestHandlerClass)
18 self.daemon_threads = True
20 def add_container(self, name, settings):
21 if self.containers.has_key(name) or name == 'TiVoConnect':
22 raise "Container Name in use"
23 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
24 self.containers[name] = settings
26 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
28 def address_string(self):
29 host, port = self.client_address[:2]
30 return host
32 def do_GET(self):
34 basepath = unquote_plus(self.path).split('/')[1]
36 ## Get File
37 for name, container in self.server.containers.items():
38 if basepath == name:
39 plugin = GetPlugin(container['type'])
40 plugin.send_file(self, container, name)
41 return
43 ## Not a file not a TiVo command fuck them
44 if not self.path.startswith('/TiVoConnect'):
45 self.infopage()
46 return
48 o = urlparse("http://fake.host" + self.path)
49 query = parse_qs(o[4])
51 mname = False
52 if query.has_key('Command') and len(query['Command']) >= 1:
54 command = query['Command'][0]
56 # If we are looking at the root container
57 if command == "QueryContainer" and \
58 (not query.has_key('Container') or query['Container'][0] == '/'):
59 self.root_container()
60 return
62 if query.has_key('Container'):
63 # Dispatch to the container plugin
64 for name, container in self.server.containers.items():
65 if query['Container'][0].startswith(name):
66 plugin = GetPlugin(container['type'])
67 if hasattr(plugin,command):
68 method = getattr(plugin, command)
69 method(self, query)
70 else:
71 self.unsupported(query)
72 break
73 else:
74 self.unsupported(query)
76 def root_container(self):
77 tsn = self.headers.getheader('TiVo_TCD_ID', '')
78 tsnshares = config.getShares(tsn)
79 tsncontainers = {}
80 for section, settings in tsnshares:
81 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
82 tsncontainers[section] = settings
83 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
84 'root_container.tmpl'))
85 t.containers = tsncontainers
86 t.hostname = socket.gethostname()
87 t.escape = escape
88 self.send_response(200)
89 self.end_headers()
90 self.wfile.write(t)
92 def infopage(self):
93 self.send_response(200)
94 self.send_header('Content-type', 'text/html')
95 self.end_headers()
96 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
97 'info_page.tmpl'))
98 self.wfile.write(t)
99 self.end_headers()
101 def unsupported(self, query):
102 self.send_response(404)
103 self.send_header('Content-type', 'text/html')
104 self.end_headers()
105 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
106 'unsupported.tmpl'))
107 t.query = query
108 self.wfile.write(t)
110 if __name__ == '__main__':
111 def start_server():
112 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
113 httpd.add_container('test', 'x-container/tivo-videos',
114 r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
115 httpd.serve_forever()
117 start_server()