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
6 from Cheetah
.Template
import Template
8 class TivoHTTPServer(SocketServer
.ThreadingMixIn
, BaseHTTPServer
.HTTPServer
):
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
):
19 for name
, container
in self
.server
.containers
.items():
21 if self
.path
.startswith('/' + name
):
22 self
.send_static(name
, container
)
25 if not self
.path
.startswith('/TiVoConnect'):
29 o
= urlparse("http://fake.host" + self
.path
)
30 query
= parse_qs(o
.query
)
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
)
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)
47 if query
['Container'][0] == '/':
48 t
= Template(file="templates/root_container.tmpl")
49 t
.containers
= self
.server
.containers
50 t
.hostname
= socket
.gethostname()
54 subcname
= unquote_plus(query
['Container'][0])
55 cname
= subcname
.split('/')[0]
57 if not self
.server
.containers
.has_key(cname
):
60 container
= self
.server
.containers
[cname
]
62 folders
= subcname
.split('/')
63 path
= container
['path']
64 for folder
in folders
[1:]:
65 path
= path
+ '/' + folder
67 files
= os
.listdir(path
)
68 totalFiles
= len(files
)
70 if query
.has_key('ItemCount'):
71 count
= int(query
['ItemCount'] [0])
74 if query
.has_key('AnchorItem'):
75 anchor
= query
['AnchorItem'] [0]
76 for i
in range(len(files
)):
77 file_url
= '/' + subcname
+ '/' + files
[i
]
78 if file_url
== anchor
:
81 if query
.has_key('AnchorOffset'):
82 index
= index
+ int(query
['AnchorOffset'][0])
83 files
= files
[index
:index
+ count
]
86 path
= container
['path'] + '/' + file
87 return os
.path
.isdir(path
)
89 t
= Template(file="templates/container.tmpl")
96 def send_static(self
, name
, container
):
99 if self
.headers
.getheader('Range') and not self
.headers
.getheader('Range') == 'bytes=0-':
100 self
.send_response(404)
104 o
= urlparse("http://fake.host" + self
.path
)
105 path
= unquote_plus(o
.path
)
106 self
.send_response(200)
108 #rfile = open(container['path'] + path[len(name)+1:], 'rb')
109 #shutil.copyfileobj(rfile, self.wfile)
111 transcode2
.transcode(container
['path'] + path
[len(name
)+1:], self
.wfile
)
114 self
.send_response(200)
115 self
.send_header('Content-type', 'text/html')
117 t
= Template(file="templates/info_page.tmpl")
121 def unsuported(self
, query
):
122 self
.send_response(404)
123 self
.send_header('Content-type', 'text/html')
125 t
= Template(file="templates/unsuported.tmpl")
129 if __name__
== '__main__':
131 httpd
= TivoHTTPServer(('', 9032), TivoHTTPHandler
)
132 httpd
.add_container('test', 'x-container/tivo-videos', r
'C:\Documents and Settings\Armooo\Desktop\pyTivo\test')
133 httpd
.serve_forever()