Cosmetic changes.
[pyTivo.git] / httpserver.py
blob1ae92f6efa25a8105708f4af77b0fe329aa61038
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 debug = config.getDebug()
13 hack83 = config.getHack83()
15 def debug_write(data):
16 if debug:
17 debug_out = []
18 debug_out.append('httpserver.py - ')
19 for x in data:
20 debug_out.append(str(x))
21 fdebug = open('debug.txt', 'a')
22 fdebug.write(' '.join(debug_out))
23 fdebug.close()
25 class TivoHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
26 containers = {}
28 def __init__(self, server_address, RequestHandlerClass):
29 BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass)
30 self.daemon_threads = True
32 def add_container(self, name, settings):
33 if self.containers.has_key(name) or name == 'TiVoConnect':
34 raise "Container Name in use"
35 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
36 self.containers[name] = settings
38 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
40 def address_string(self):
41 host, port = self.client_address[:2]
42 return host
44 def do_GET(self):
46 basepath = unquote_plus(self.path).split('/')[1]
48 ## Get File
49 for name, container in self.server.containers.items():
50 if basepath == name:
51 plugin = GetPlugin(container['type'])
52 plugin.send_file(self, container, name)
53 return
55 ## Not a file not a TiVo command fuck them
56 if not self.path.startswith('/TiVoConnect'):
57 self.infopage()
58 return
60 o = urlparse("http://fake.host" + self.path)
61 query = parse_qs(o[4])
63 mname = False
64 if query.has_key('Command') and len(query['Command']) >= 1:
66 command = query['Command'][0]
68 #If we are looking at the root container
69 if command == "QueryContainer" and ( not query.has_key('Container') or query['Container'][0] == '/'):
70 self.root_container()
71 return
73 if query.has_key('Container'):
74 #Dispatch to the container plugin
75 for name, container in self.server.containers.items():
76 if query['Container'][0].startswith(name):
77 plugin = GetPlugin(container['type'])
78 if hasattr(plugin,command):
79 method = getattr(plugin, command)
80 method(self, query)
81 else:
82 self.unsupported(query)
83 break
84 else:
85 self.unsupported(query)
87 def root_container(self):
88 t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'root_container.tmpl'))
89 t.containers = self.server.containers
90 t.hostname = socket.gethostname()
91 t.escape = escape
92 self.send_response(200)
93 self.end_headers()
94 self.wfile.write(t)
96 def infopage(self):
97 self.send_response(200)
98 self.send_header('Content-type', 'text/html')
99 self.end_headers()
100 t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'info_page.tmpl'))
101 self.wfile.write(t)
102 self.end_headers()
104 def unsupported(self, query):
105 if hack83 and 'Command' in query and 'Filter' in query:
106 debug_write(['Unsupported request, checking to see if it is video.', '\n'])
107 command = query['Command'][0]
108 plugin = GetPlugin('video')
109 if "".join(query['Filter']).find('video') >= 0 and hasattr(plugin,command):
110 debug_write(['Unsupported request, yup it is video send to video plugin for it to sort out.', '\n'])
111 method = getattr(plugin, command)
112 method(self, query)
113 return
115 self.send_response(404)
116 self.send_header('Content-type', 'text/html')
117 self.end_headers()
118 t = Template(file=os.path.join(SCRIPTDIR,'templates','unsupported.tmpl'))
119 t.query = query
120 self.wfile.write(t)
122 if __name__ == '__main__':
123 def start_server():
124 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
125 httpd.add_container('test', 'x-container/tivo-videos', r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
126 httpd.serve_forever()
128 start_server()