pyTivo
[pyTivo.git] / httpserver.py
blobebb4a86fbcf74b2a20a5ccafadf17e868dbebc4f
1 import time, os, BaseHTTPServer, SocketServer, socket, shutil, os.path
2 from urllib import unquote_plus
3 from urlparse import urlparse
4 from cgi import parse_qs
5 from Cheetah.Template import Template
6 import transcode
8 class TivoHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
9 containers = {}
11 def add_container(self, name, type, path):
12 if self.containers.has_key(name) or name == 'TivoConnect':
13 raise "Container Name in use"
14 self.containers[name] = {'type' : type, 'path' : path}
16 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
17 def do_GET(self):
19 for name, container in self.server.containers.items():
20 #XXX make a regex
21 if self.path.startswith('/' + name):
22 self.send_static(name, container)
23 return
25 if not self.path.startswith('/TiVoConnect'):
26 self.infopage()
27 return
29 o = urlparse("http://fake.host" + self.path)
30 query = parse_qs(o.query)
32 mname = False
33 if query.has_key('Command') and len(query['Command']) >= 1:
34 mname = 'do_' + query['Command'][0]
35 if mname and hasattr(self, mname):
36 method = getattr(self, mname)
37 method(query)
38 else:
39 self.unsuported(query)
41 def do_QueryContainer(self, query):
43 if not query.has_key('Container'):
44 query['Container'] = ['/']
45 self.send_response(200)
46 self.end_headers()
47 if query['Container'][0] == '/':
48 t = Template(file="templates/root_container.tmpl")
49 t.containers = self.server.containers
50 t.hostname = socket.gethostname()
51 self.wfile.write(t)
52 else:
54 subcname = unquote_plus(query['Container'][0])
55 cname = subcname.split('/')[0]
57 if not self.server.containers.has_key(cname):
58 return
60 container = self.server.containers[cname]
62 folders = subcname.split('/')
63 path = container['path']
64 for folder in folders[1:]:
65 if folder == '..':
66 return
67 path = path + '/' + folder
69 def isdir(file):
70 path = container['path'] + '/' + file
71 return os.path.isdir(path)
73 files = os.listdir(path)
75 files = filter(lambda f: os.path.isdir(path+'/'+f) or transcode.suported_format(path+'/'+f), files)
77 totalFiles = len(files)
79 index = 0
80 if query.has_key('ItemCount'):
81 count = int(query['ItemCount'] [0])
83 if query.has_key('AnchorItem'):
84 anchor = query['AnchorItem'] [0]
85 for i in range(len(files)):
87 if isdir(files[i]):
88 file_url = '/TiVoConnect?Command=QueryContainer&Container=' + subcname + '/' + files[i]
89 else:
90 file_url = '/' + subcname + '/' + files[i]
91 if file_url == anchor:
92 index = i + 1
93 break
94 if query.has_key('AnchorOffset'):
95 index = index + int(query['AnchorOffset'][0])
96 files = files[index:index + count]
98 def isdir(file):
99 path = container['path'] + '/' + file
100 return os.path.isdir(path)
102 t = Template(file="templates/container.tmpl")
103 t.name = subcname
104 t.files = files
105 t.total = totalFiles
106 t.start = index
107 t.isdir = isdir
108 self.wfile.write(t)
110 def send_static(self, name, container):
112 #cheep hack
113 if self.headers.getheader('Range') and not self.headers.getheader('Range') == 'bytes=0-':
114 self.send_response(404)
115 self.end_headers()
116 return
118 o = urlparse("http://fake.host" + self.path)
119 path = unquote_plus(o.path)
120 self.send_response(200)
121 self.end_headers()
122 transcode.output_video(container['path'] + path[len(name)+1:], self.wfile)
124 def infopage(self):
125 self.send_response(200)
126 self.send_header('Content-type', 'text/html')
127 self.end_headers()
128 t = Template(file="templates/info_page.tmpl")
129 self.wfile.write(t)
130 self.end_headers()
132 def unsuported(self, query):
133 self.send_response(404)
134 self.send_header('Content-type', 'text/html')
135 self.end_headers()
136 t = Template(file="templates/unsuported.tmpl")
137 t.query = query
138 self.wfile.write(t)
140 if __name__ == '__main__':
141 def start_server():
142 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
143 httpd.add_container('test', 'x-container/tivo-videos', r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
144 httpd.serve_forever()
146 start_server()