Merge branch 'master' into subfolders-8.3
[pyTivo/wmcbrine.git] / httpserver.py
blobe38511941827bbd8b41c138368ce3a151d620211
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,
30 RequestHandlerClass)
31 self.daemon_threads = True
33 def add_container(self, name, settings):
34 if self.containers.has_key(name) or name == 'TiVoConnect':
35 raise "Container Name in use"
36 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
37 self.containers[name] = settings
39 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
41 def address_string(self):
42 host, port = self.client_address[:2]
43 return host
45 def do_GET(self):
47 basepath = unquote_plus(self.path).split('/')[1]
49 ## Get File
50 for name, container in self.server.containers.items():
51 if basepath == name:
52 plugin = GetPlugin(container['type'])
53 plugin.send_file(self, container, name)
54 return
56 ## Not a file not a TiVo command fuck them
57 if not self.path.startswith('/TiVoConnect'):
58 self.infopage()
59 return
61 o = urlparse("http://fake.host" + self.path)
62 query = parse_qs(o[4])
64 mname = False
65 if query.has_key('Command') and len(query['Command']) >= 1:
67 command = query['Command'][0]
69 # If we are looking at the root container
70 if command == "QueryContainer" and \
71 (not query.has_key('Container') or query['Container'][0] == '/'):
72 self.root_container()
73 return
75 if query.has_key('Container'):
76 # Dispatch to the container plugin
77 for name, container in self.server.containers.items():
78 if query['Container'][0].startswith(name):
79 plugin = GetPlugin(container['type'])
80 if hasattr(plugin,command):
81 method = getattr(plugin, command)
82 method(self, query)
83 else:
84 self.unsupported(query)
85 break
86 else:
87 self.unsupported(query)
89 def root_container(self):
90 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
91 'root_container.tmpl'))
92 t.containers = self.server.containers
93 t.hostname = socket.gethostname()
94 t.escape = escape
95 self.send_response(200)
96 self.end_headers()
97 self.wfile.write(t)
99 def infopage(self):
100 self.send_response(200)
101 self.send_header('Content-type', 'text/html')
102 self.end_headers()
103 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
104 'info_page.tmpl'))
105 self.wfile.write(t)
106 self.end_headers()
108 def unsupported(self, query):
109 if hack83 and 'Command' in query and 'Filter' in query:
110 debug_write(['Unsupported request,',
111 'checking to see if it is video.\n'])
112 command = query['Command'][0]
113 plugin = GetPlugin('video')
114 if ''.join(query['Filter']).find('video') >= 0 and \
115 hasattr(plugin, command):
116 debug_write(['Unsupported request,',
117 'yup it is video',
118 'send to video plugin for it to sort out.\n'])
119 method = getattr(plugin, command)
120 method(self, query)
121 return
123 self.send_response(404)
124 self.send_header('Content-type', 'text/html')
125 self.end_headers()
126 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
127 'unsupported.tmpl'))
128 t.query = query
129 self.wfile.write(t)
131 if __name__ == '__main__':
132 def start_server():
133 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
134 httpd.add_container('test', 'x-container/tivo-videos',
135 r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
136 httpd.serve_forever()
138 start_server()