Build a true recursive file list when asked, and omit directories (Ticket #59)
[pyTivo.git] / httpserver.py
blob8c8f3fa8ec60dffcf7eec331c8f7fa66140cce50
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 from xml.sax.saxutils import escape
9 SCRIPTDIR = os.path.dirname(__file__)
11 class TivoHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
12 containers = {}
14 def __init__(self, server_address, RequestHandlerClass):
15 BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass)
16 self.daemon_threads = True
18 def add_container(self, name, settings):
19 if self.containers.has_key(name) or name == 'TivoConnect':
20 raise "Container Name in use"
21 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
22 self.containers[name] = settings
24 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
26 def address_string(self):
27 host, port = self.client_address[:2]
28 return host
30 def do_GET(self):
32 ## Get File
33 for name, container in self.server.containers.items():
34 #XXX make a regex
35 path = unquote_plus(self.path)
36 if path.startswith('/' + name):
37 plugin = GetPlugin(container['type'])
38 plugin.send_file(self, container, name)
39 return
41 ## Not a file not a TiVo command fuck them
42 if not self.path.startswith('/TiVoConnect'):
43 self.infopage()
44 return
46 o = urlparse("http://fake.host" + self.path)
47 query = parse_qs(o[4])
49 mname = False
50 if query.has_key('Command') and len(query['Command']) >= 1:
52 command = query['Command'][0]
54 #If we are looking at the root container
55 if command == "QueryContainer" and ( not query.has_key('Container') or query['Container'][0] == '/'):
56 self.root_container()
57 return
59 if query.has_key('Container'):
60 #Dispatch to the container plugin
61 for name, container in self.server.containers.items():
62 if query['Container'][0].startswith(name):
63 plugin = GetPlugin(container['type'])
64 if hasattr(plugin,command):
65 method = getattr(plugin, command)
66 method(self, query)
67 else:
68 self.unsuported(query)
69 break
70 else:
71 self.unsuported(query)
73 def root_container(self):
74 t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'root_container.tmpl'))
75 t.containers = self.server.containers
76 t.hostname = socket.gethostname()
77 t.escape = escape
78 self.send_response(200)
79 self.end_headers()
80 self.wfile.write(t)
82 def infopage(self):
83 self.send_response(200)
84 self.send_header('Content-type', 'text/html')
85 self.end_headers()
86 t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'info_page.tmpl'))
87 self.wfile.write(t)
88 self.end_headers()
90 def unsuported(self, query):
91 self.send_response(404)
92 self.send_header('Content-type', 'text/html')
93 self.end_headers()
94 t = Template(file=os.path.join(SCRIPTDIR,'templates','unsuported.tmpl'))
95 t.query = query
96 self.wfile.write(t)
98 if __name__ == '__main__':
99 def start_server():
100 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
101 httpd.add_container('test', 'x-container/tivo-videos', r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
102 httpd.serve_forever()
104 start_server()