Clean up admin.py. Add settings to known. Fix auto-subshare help
[pyTivo.git] / httpserver.py
blob44c504143d239d7933ddeb737f2416fc367d8003
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 try:
37 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
38 self.containers[name] = settings
39 except KeyError:
40 print 'Unable to add container', name
42 def reset(self):
43 self.containers.clear()
44 for section, settings in config.getShares():
45 self.add_container(section, settings)
47 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
49 def address_string(self):
50 host, port = self.client_address[:2]
51 return host
53 def do_GET(self):
55 basepath = unquote_plus(self.path).split('/')[1]
57 ## Get File
58 for name, container in self.server.containers.items():
59 if basepath == name:
60 plugin = GetPlugin(container['type'])
61 plugin.send_file(self, container, name)
62 return
64 ## Not a file not a TiVo command fuck them
65 if not self.path.startswith('/TiVoConnect'):
66 self.infopage()
67 return
69 o = urlparse("http://fake.host" + self.path)
70 query = parse_qs(o[4])
72 mname = False
73 if query.has_key('Command') and len(query['Command']) >= 1:
75 command = query['Command'][0]
77 # If we are looking at the root container
78 if command == "QueryContainer" and \
79 (not query.has_key('Container') or query['Container'][0] == '/'):
80 self.root_container()
81 return
83 if query.has_key('Container'):
84 # Dispatch to the container plugin
85 basepath = query['Container'][0].split('/')[0]
86 for name, container in self.server.containers.items():
87 if basepath == name:
88 plugin = GetPlugin(container['type'])
89 if hasattr(plugin, command):
90 method = getattr(plugin, command)
91 method(self, query)
92 return
93 else:
94 break
96 # If we made it here it means we couldn't match the request to
97 # anything.
98 self.unsupported(query)
100 def root_container(self):
101 tsn = self.headers.getheader('TiVo_TCD_ID', '')
102 tsnshares = config.getShares(tsn)
103 tsncontainers = {}
104 for section, settings in tsnshares:
105 try:
106 settings['content_type'] = \
107 GetPlugin(settings['type']).CONTENT_TYPE
108 tsncontainers[section] = settings
109 except Exception, msg:
110 print section, '-', msg
111 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
112 'root_container.tmpl'))
113 t.containers = tsncontainers
114 t.hostname = socket.gethostname()
115 t.escape = escape
116 self.send_response(200)
117 self.end_headers()
118 self.wfile.write(t)
120 def infopage(self):
121 self.send_response(200)
122 self.send_header('Content-type', 'text/html')
123 self.end_headers()
124 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
125 'info_page.tmpl'))
126 t.admin = ''
127 for section, settings in config.getShares():
128 if 'type' in settings and settings['type'] == 'admin':
129 t.admin += '<a href="/TiVoConnect?Command=Admin&Container=' + section\
130 + '">pyTivo Web Configuration</a><br>'
131 self.wfile.write(t)
132 self.end_headers()
134 def unsupported(self, query):
135 if hack83 and 'Command' in query and 'Filter' in query:
136 debug_write(['Unsupported request,',
137 'checking to see if it is video.\n'])
138 command = query['Command'][0]
139 plugin = GetPlugin('video')
140 if ''.join(query['Filter']).find('video') >= 0 and \
141 hasattr(plugin, command):
142 debug_write(['Unsupported request,',
143 'yup it is video',
144 'send to video plugin for it to sort out.\n'])
145 method = getattr(plugin, command)
146 method(self, query)
147 return
149 self.send_response(404)
150 self.send_header('Content-type', 'text/html')
151 self.end_headers()
152 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
153 'unsupported.tmpl'))
154 t.query = query
155 self.wfile.write(t)
157 if __name__ == '__main__':
158 def start_server():
159 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
160 httpd.add_container('test', 'x-container/tivo-videos',
161 r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
162 httpd.serve_forever()
164 start_server()