New: Limit shares which appear on certain TiVos
[pyTivo/wgw.git] / httpserver.py
blobbcaa6245f9af2ce4e40ab417f1e62479b9175067
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,
16 RequestHandlerClass)
17 self.daemon_threads = True
19 def add_container(self, name, settings):
20 if self.containers.has_key(name) or name == 'TiVoConnect':
21 raise "Container Name in use"
22 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
23 self.containers[name] = settings
25 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
27 def address_string(self):
28 host, port = self.client_address[:2]
29 return host
31 def do_GET(self):
33 basepath = unquote_plus(self.path).split('/')[1]
35 ## Get File
36 for name, container in self.server.containers.items():
37 if basepath == name:
38 plugin = GetPlugin(container['type'])
39 plugin.send_file(self, container, name)
40 return
42 ## Not a file not a TiVo command fuck them
43 if not self.path.startswith('/TiVoConnect'):
44 self.infopage()
45 return
47 o = urlparse("http://fake.host" + self.path)
48 query = parse_qs(o[4])
50 mname = False
51 if query.has_key('Command') and len(query['Command']) >= 1:
53 command = query['Command'][0]
55 # If we are looking at the root container
56 if command == "QueryContainer" and \
57 (not query.has_key('Container') or query['Container'][0] == '/'):
58 self.root_container()
59 return
61 if query.has_key('Container'):
62 # Dispatch to the container plugin
63 for name, container in self.server.containers.items():
64 if query['Container'][0].startswith(name):
65 plugin = GetPlugin(container['type'])
66 if hasattr(plugin,command):
67 method = getattr(plugin, command)
68 method(self, query)
69 else:
70 self.unsupported(query)
71 break
72 else:
73 self.unsupported(query)
75 def root_container(self):
76 tsn = self.headers.getheader('TiVo_TCD_ID', '')
77 tsnshares = config.getShares(tsn)
78 tsncontainers = {}
79 for section, settings in tsnshares:
80 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
81 tsncontainers[section] = settings
82 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
83 'root_container.tmpl'))
84 t.containers = tsncontainers
85 t.hostname = socket.gethostname()
86 t.escape = escape
87 self.send_response(200)
88 self.end_headers()
89 self.wfile.write(t)
91 def infopage(self):
92 self.send_response(200)
93 self.send_header('Content-type', 'text/html')
94 self.end_headers()
95 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
96 'info_page.tmpl'))
97 self.wfile.write(t)
98 self.end_headers()
100 def unsupported(self, query):
101 self.send_response(404)
102 self.send_header('Content-type', 'text/html')
103 self.end_headers()
104 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
105 'unsupported.tmpl'))
106 t.query = query
107 self.wfile.write(t)
109 if __name__ == '__main__':
110 def start_server():
111 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
112 httpd.add_container('test', 'x-container/tivo-videos',
113 r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
114 httpd.serve_forever()
116 start_server()