increase max_video_br due to tivo 9.3a software fix
[pyTivo/wmcbrine.git] / httpserver.py
blobdeaaa45a68bc8c197a79bb90bd32a86dfd94c003
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
9 from debug import debug_write, fn_attr
11 SCRIPTDIR = os.path.dirname(__file__)
13 hack83 = config.getHack83()
15 class TivoHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
16 containers = {}
18 def __init__(self, server_address, RequestHandlerClass):
19 BaseHTTPServer.HTTPServer.__init__(self, server_address,
20 RequestHandlerClass)
21 self.daemon_threads = True
23 def add_container(self, name, settings):
24 if self.containers.has_key(name) or name == 'TiVoConnect':
25 raise "Container Name in use"
26 try:
27 settings['content_type'] = GetPlugin(settings['type']).CONTENT_TYPE
28 self.containers[name] = settings
29 except KeyError:
30 print 'Unable to add container', name
32 def reset(self):
33 self.containers.clear()
34 for section, settings in config.getShares():
35 self.add_container(section, settings)
37 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
38 tivos ={}
40 def address_string(self):
41 host, port = self.client_address[:2]
42 return host
44 def do_GET(self):
45 tsn = self.headers.getheader('TiVo_TCD_ID', self.headers.getheader('tsn', ''))
46 ip = self.address_string()
47 self.tivos[tsn] = ip
49 basepath = unquote_plus(self.path).split('/')[1]
51 ## Get File
52 for name, container in self.server.containers.items():
53 if basepath == name:
54 plugin = GetPlugin(container['type'])
55 plugin.send_file(self, container, name)
56 return
58 ## Not a file not a TiVo command fuck them
59 if not self.path.startswith('/TiVoConnect'):
60 self.infopage()
61 return
63 o = urlparse("http://fake.host" + self.path)
64 query = parse_qs(o[4])
66 mname = False
67 if query.has_key('Command') and len(query['Command']) >= 1:
69 command = query['Command'][0]
71 # If we are looking at the root container
72 if command == "QueryContainer" and \
73 (not query.has_key('Container') or query['Container'][0] == '/'):
74 self.root_container()
75 return
77 if query.has_key('Container'):
78 # Dispatch to the container plugin
79 basepath = query['Container'][0].split('/')[0]
80 for name, container in self.server.containers.items():
81 if basepath == name:
82 plugin = GetPlugin(container['type'])
83 if hasattr(plugin, command):
84 method = getattr(plugin, command)
85 method(self, query)
86 return
87 else:
88 break
90 # If we made it here it means we couldn't match the request to
91 # anything.
92 self.unsupported(query)
94 def root_container(self):
95 tsn = self.headers.getheader('TiVo_TCD_ID', '')
96 tsnshares = config.getShares(tsn)
97 tsncontainers = {}
98 for section, settings in tsnshares:
99 try:
100 settings['content_type'] = \
101 GetPlugin(settings['type']).CONTENT_TYPE
102 tsncontainers[section] = settings
103 except Exception, msg:
104 print section, '-', msg
105 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
106 'root_container.tmpl'))
107 t.containers = tsncontainers
108 t.hostname = socket.gethostname()
109 t.escape = escape
110 t.quote = quote
111 self.send_response(200)
112 self.end_headers()
113 self.wfile.write(t)
115 def infopage(self):
116 self.send_response(200)
117 self.send_header('Content-type', 'text/html')
118 self.end_headers()
119 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
120 'info_page.tmpl'))
121 t.admin = ''
122 for section, settings in config.getShares():
123 if 'type' in settings and settings['type'] == 'admin':
124 t.admin += '<a href="/TiVoConnect?Command=Admin&Container=' + quote(section)\
125 + '">pyTivo Web Configuration</a><br>'\
126 + '<a href="/TiVoConnect?Command=NPL&Container=' + quote(section)\
127 + '">pyTivo ToGo</a><br>'
128 if t.admin == '':
129 t.admin = '<br><b>No Admin plugin installed in pyTivo.conf</b><br> If you wish to use'\
130 + ' the admin plugin add the following lines to pyTivo.conf<br><br>'\
131 + '[Admin]<br>type=admin'
133 self.wfile.write(t)
134 self.end_headers()
136 def unsupported(self, query):
137 if hack83 and 'Command' in query and 'Filter' in query:
138 debug_write(__name__, fn_attr(), ['Unsupported request,',
139 'checking to see if it is video.'])
140 command = query['Command'][0]
141 plugin = GetPlugin('video')
142 if ''.join(query['Filter']).find('video') >= 0 and \
143 hasattr(plugin, command):
144 debug_write(__name__, fn_attr(), ['Unsupported request,',
145 'yup it is video',
146 'send to video plugin for it to sort out.'])
147 method = getattr(plugin, command)
148 method(self, query)
149 return
151 self.send_response(404)
152 self.send_header('Content-type', 'text/html')
153 self.end_headers()
154 t = Template(file=os.path.join(SCRIPTDIR, 'templates',
155 'unsupported.tmpl'))
156 t.query = query
157 self.wfile.write(t)
159 if __name__ == '__main__':
160 def start_server():
161 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
162 httpd.add_container('test', 'x-container/tivo-videos',
163 r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
164 httpd.serve_forever()
166 start_server()