pyTivo
[pyTivo/krkeegan.git] / httpserver.py
blobeef72b6b7da80c1c9e63a758bb252966ffdb4566
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 SCRIPTDIR = os.path.dirname(__file__)
10 class TivoHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
11 containers = {}
13 def add_container(self, name, type, path):
14 if self.containers.has_key(name) or name == 'TivoConnect':
15 raise "Container Name in use"
16 self.containers[name] = {'type' : type, 'path' : path}
18 class TivoHTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
19 def do_GET(self):
21 for name, container in self.server.containers.items():
22 #XXX make a regex
23 if self.path.startswith('/' + name):
24 self.send_static(name, container)
25 return
27 if not self.path.startswith('/TiVoConnect'):
28 self.infopage()
29 return
31 o = urlparse("http://fake.host" + self.path)
32 query = parse_qs(o.query)
34 mname = False
35 if query.has_key('Command') and len(query['Command']) >= 1:
36 mname = 'do_' + query['Command'][0]
37 if mname and hasattr(self, mname):
38 method = getattr(self, mname)
39 method(query)
40 else:
41 self.unsuported(query)
43 def do_QueryContainer(self, query):
45 if not query.has_key('Container'):
46 query['Container'] = ['/']
47 self.send_response(200)
48 self.end_headers()
49 if query['Container'][0] == '/':
50 t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'root_container.tmpl'))
51 t.containers = self.server.containers
52 t.hostname = socket.gethostname()
53 self.wfile.write(t)
54 else:
56 subcname = unquote_plus(query['Container'][0])
57 cname = subcname.split('/')[0]
59 if not self.server.containers.has_key(cname):
60 return
62 container = self.server.containers[cname]
64 folders = subcname.split('/')
65 path = container['path']
66 for folder in folders[1:]:
67 if folder == '..':
68 return
69 path = path + '/' + folder
71 def isdir(file):
72 path = container['path'] + '/' + file
73 return os.path.isdir(path)
75 files = os.listdir(path)
77 files = filter(lambda f: os.path.isdir(path+'/'+f) or transcode.suported_format(path+'/'+f), files)
79 totalFiles = len(files)
81 index = 0
82 if query.has_key('ItemCount'):
83 count = int(query['ItemCount'] [0])
85 if query.has_key('AnchorItem'):
86 anchor = query['AnchorItem'] [0]
87 for i in range(len(files)):
89 if isdir(files[i]):
90 file_url = '/TiVoConnect?Command=QueryContainer&Container=' + subcname + '/' + files[i]
91 else:
92 file_url = '/' + subcname + '/' + files[i]
93 if file_url == anchor:
94 index = i + 1
95 break
96 if query.has_key('AnchorOffset'):
97 index = index + int(query['AnchorOffset'][0])
98 files = files[index:index + count]
100 def isdir(file):
101 path = container['path'] + '/' + file
102 return os.path.isdir(path)
104 t = Template(file=os.path.join(SCRIPTDIR,'templates', 'container.tmpl'))
105 t.name = subcname
106 t.files = files
107 t.total = totalFiles
108 t.start = index
109 t.isdir = isdir
110 self.wfile.write(t)
112 def send_static(self, name, container):
114 #cheep hack
115 if self.headers.getheader('Range') and not self.headers.getheader('Range') == 'bytes=0-':
116 self.send_response(404)
117 self.end_headers()
118 return
120 o = urlparse("http://fake.host" + self.path)
121 path = unquote_plus(o.path)
122 self.send_response(200)
123 self.end_headers()
124 transcode.output_video(container['path'] + path[len(name)+1:], self.wfile)
126 def infopage(self):
127 self.send_response(200)
128 self.send_header('Content-type', 'text/html')
129 self.end_headers()
130 t = Template(file=os.path.join(SCRIPTDIR, 'templates', 'info_page.tmpl'))
131 self.wfile.write(t)
132 self.end_headers()
134 def unsuported(self, query):
135 self.send_response(404)
136 self.send_header('Content-type', 'text/html')
137 self.end_headers()
138 t = Template(file=os.path.join(SCRIPTDIR,'templates','unsuported.tmpl'))
139 t.query = query
140 self.wfile.write(t)
142 if __name__ == '__main__':
143 def start_server():
144 httpd = TivoHTTPServer(('', 9032), TivoHTTPHandler)
145 httpd.add_container('test', 'x-container/tivo-videos', r'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
146 httpd.serve_forever()
148 start_server()