(no commit message)
[pyTivo.git] / plugins / video / video.py
blobd819ba436e83dac8847aa9059602aba706ddb66b
1 import transcode, os, socket, re
2 from Cheetah.Template import Template
3 from plugin import Plugin
4 from urllib import unquote_plus, quote, unquote
5 from urlparse import urlparse
6 from xml.sax.saxutils import escape
7 from lrucache import LRUCache
9 SCRIPTDIR = os.path.dirname(__file__)
12 class video(Plugin):
14 content_type = 'x-container/tivo-videos'
15 playable_cache = LRUCache(1000)
17 def SendFile(self, handler, container, name):
19 #No longer a 'cheep' hack :p
20 if handler.headers.getheader('Range') and not handler.headers.getheader('Range') == 'bytes=0-':
21 handler.send_response(206)
22 handler.send_header('Connection', 'close')
23 handler.send_header('Content-Type', 'video/x-tivo-mpeg')
24 handler.send_header('Transfer-Encoding', 'chunked')
25 handler.send_header('Server', 'TiVo Server/1.4.257.475')
26 handler.end_headers()
27 return
29 o = urlparse("http://fake.host" + handler.path)
30 path = unquote_plus(o[2])
31 handler.send_response(200)
32 handler.end_headers()
33 transcode.output_video(container['path'] + path[len(name)+1:], handler.wfile)
37 def QueryContainer(self, handler, query):
39 subcname = query['Container'][0]
40 cname = subcname.split('/')[0]
42 if not handler.server.containers.has_key(cname) or not self.get_local_path(handler, query):
43 handler.send_response(404)
44 handler.end_headers()
45 return
47 path = self.get_local_path(handler, query)
48 def isdir(file):
49 return os.path.isdir(os.path.join(path, file))
51 def duration(file):
52 full_path = os.path.join(path, file)
53 return self.playable_cache[full_path]
55 def VideoFileFilter(file):
56 full_path = os.path.join(path, file)
58 if full_path in self.playable_cache:
59 return self.playable_cache[full_path]
60 if os.path.isdir(full_path):
61 self.playable_cache[full_path] = True
62 return True
63 millisecs = transcode.suported_format(full_path)
64 if millisecs:
65 self.playable_cache[full_path] = millisecs
66 return millisecs
67 else:
68 self.playable_cache[full_path] = False
69 return False
71 handler.send_response(200)
72 handler.end_headers()
73 t = Template(file=os.path.join(SCRIPTDIR,'templates', 'container.tmpl'))
74 t.name = subcname
75 t.files, t.total, t.start = self.get_files(handler, query, VideoFileFilter)
76 t.duration = duration
77 t.isdir = isdir
78 t.quote = quote
79 t.escape = escape
80 handler.wfile.write(t)