Merge branch 'master' into subfolders-8.3
[pyTivo.git] / httpserver.py
blob1236e42668292bd4f57e7756af78a5655157975f
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__)
11 debug = config.getDebug()
12 hack83 = config.getHack83()
13 def debug_write(data):
14 if debug:
15 debug_out = []
16 debug_out.append('httpserver.py - ')
17 for x in data:
18 debug_out.append(str(x))
19 fdebug = open('debug.txt', 'a')
20 fdebug.write(' '.join(debug_out))
21 fdebug.close()
23 class TivoHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
24 containers = {}
26 def __init__(self, server_address, RequestHandlerClass):
27 BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass)
28 self.daemon_threads = True
30 def add_container(self, name, settings):
31 if self.containers.has_key(name) or name == 'TivoConnect':
32 raise "Container Name in use"
33 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
34 self.containers[name] = settings
36 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
38 def address_string(self):
39 host, port = self.client_address[:2]
40 return host
42 def do_GET(self):
44 ## Get File
45 for name, container in self.server.containers.items():
46 #XXX make a regex
47 path = unquote_plus(self.path)
48 if path.startswith('/' + name):
49 plugin = GetPlugin(container['type'])
50 plugin.send_file(self, container, name)
51 return
53 ## Not a file not a TiVo command fuck them
54 if not self.path.startswith('/TiVoConnect'):
55 self.infopage()
56 return
58 o = urlparse("http://fake.host" + self.path)
59 query = parse_qs(o[4])
61 mname = False
62 if query.has_key('Command') and len(query['Command']) >= 1:
64 command = query['Command'][0]
66 #If we are looking at the root container
67 if command == "QueryContainer" and ( not query.has_key('Container') or query['Container'][0] == '/'):
68 self.root_continer()
69 return
71 if query.has_key('Container'):
72 #Dispatch to the container plugin
73 foundContainer = False
74 for name, container in self.server.containers.items():
75 if query['Container'][0].startswith(name):
76 foundContainer = True
77 plugin = GetPlugin(container['type'])
78 if hasattr(plugin,command):
79 method = getattr(plugin, command)
80 method(self, query)
81 else:
82 self.unsuported(query)
83 break
84 if not foundContainer:
85 self.unsuported(query)
86 else:
87 self.unsuported(query)
89 def root_continer(self):
90 t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'root_container.tmpl'))
91 t.containers = self.server.containers
92 t.hostname = socket.gethostname()
93 t.escape = escape
94 self.send_response(200)
95 self.end_headers()
96 self.wfile.write(t)
98 def infopage(self):
99 self.send_response(200)
100 self.send_header('Content-type', 'text/html')
101 self.end_headers()
102 t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'info_page.tmpl'))
103 self.wfile.write(t)
104 self.end_headers()
106 def unsuported(self, query):
107 if hack83 and 'Command' in query and 'Filter' in query:
108 debug_write(['Unsupported request, checking to see if it is video.', '\n'])
109 command = query['Command'][0]
110 plugin = plugin = GetPlugin('video')
111 if "".join(query['Filter']).find('video') >= 0 and hasattr(plugin,command):
112 debug_write(['Unsupported request, yup it is video send to video plugin for it to sort out.', '\n'])
113 method = getattr(plugin, command)
114 method(self, query)
115 else:
116 self.send_response(404)
117 self.send_header('Content-type', 'text/html')
118 self.end_headers()
119 t = Template(file=os.path.join(SCRIPTDIR,'templates','unsuported.tmpl'))
120 t.query = query
121 self.wfile.write(t)
122 else:
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','unsuported.tmpl'))
127 t.query = query
128 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', r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
135 httpd.serve_forever()
137 start_server()