4fd522f3420eaec55449e9dff6c8e185ef0d92c7
[pyTivo.git] / plugins / webvideo / webvideo.py
blob4fd522f3420eaec55449e9dff6c8e185ef0d92c7
1 from plugins.video.video import Video, VideoDetails
2 import mind
3 import config
5 import xmpp
7 import threading
8 import urllib2
9 import os.path
10 import shutil
11 import os.path
12 import urllib
13 import xml.etree.ElementTree as ElementTree
14 import Queue
16 CLASS_NAME = 'WebVideo'
19 class WebVideo(Video):
21 CONTENT_TYPE = 'x-not-for/tivo'
23 def init(self):
24 self.work_queue = Queue.Queue()
25 self.download_thread_num = 1
26 self.in_progress = {}
27 self.in_progress_lock = threading.Lock()
29 self.startXMPP()
30 self.xmpp_cdsupdate()
31 self.startWorkerThreads()
33 def startXMPP(self):
34 m = mind.getMind()
35 xmpp_info = m.getXMPPLoginInfo()
37 jid=xmpp.protocol.JID(xmpp_info['username'] + '/pyTivo')
38 cl=xmpp.Client(
39 server=xmpp_info['server'],
40 port=xmpp_info['port'],
43 cl.connect()
44 cl.RegisterHandler('message', self.processMessage)
45 cl.auth(user=jid.getNode(), password=config.getTivoPassword(), resource='pyTivo')
47 cl.sendInitPresence(requestRoster=0)
49 for user_name in xmpp_info['presence_list']:
50 jid=xmpp.protocol.JID(user_name)
51 cl.sendPresence(jid)
53 t = threading.Thread(target=self.processXMPP, args=(cl,))
54 t.setDaemon(True)
55 t.start()
57 def startWorkerThreads(self):
58 for i in range(self.download_thread_num):
59 t = threading.Thread(target=self.processDlRequest)
60 t.setDaemon(True)
61 t.start()
63 def processXMPP(self, client):
64 while client.Process():
65 pass
67 def processMessage(self, sess,mess):
68 xmpp_action = ElementTree.fromstring(mess.getBody())
70 method_name = 'xmpp_' + xmpp_action.findtext('action').lower()
71 if not hasattr(self, method_name):
72 return False
74 method = getattr(self, method_name)
75 method(xmpp_action)
77 def xmpp_cdsupdate(self, xml=None):
78 m = mind.getMind()
80 self.in_progress_lock.acquire()
81 try:
82 for request in m.getDownloadRequests():
83 if not request['bodyOfferId'] in self.in_progress:
84 self.in_progress[request['bodyOfferId']] = True
85 self.work_queue.put(request)
86 finally:
87 self.in_progress_lock.release()
89 def processDlRequest(self):
91 while True:
92 data = self.work_queue.get()
94 for share_name, settings in config.getShares():
95 if settings['type'] == 'webvideo':
96 break
99 path = settings['path']
100 file_name = os.path.join(path, '%s-%s' % (data['bodyOfferId'] ,data['url'].split('/')[-1]))
102 self.downloadFile(data['url'], file_name)
104 tsn = data['bodyId']
105 file_info = VideoDetails()
106 file_info.update(self.metadata_full(file_name, tsn))
108 import socket
109 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
110 s.connect(('tivo.com',123))
111 ip = s.getsockname()[0]
112 port = config.getPort()
114 data['url'] = 'http://%s:%s' % (ip, port) + urllib.quote('/%s/%s' % (share_name, os.path.split(file_name)[-1]))
115 data['duration'] = file_info['duration'] / 1000
116 data['size'] = file_info['size']
118 print data
120 m = mind.getMind()
121 m.completeDownloadRequest(data)
123 self.in_progress_lock.acquire()
124 try:
125 del self.in_progress[data['bodyOfferId']]
126 finally:
127 self.in_progress_lock.release()
130 def downloadFile(self, url, file_path):
131 print 'downloading %s to %s' % (url, file_path)
133 outfile = open(file_path, 'awb')
134 size = os.path.getsize(file_path)
135 r = urllib2.Request(url)
136 if size:
137 r.add_header('Range', 'bytes=%s-' % size)
138 infile = urllib2.urlopen(r)
139 shutil.copyfileobj(infile, outfile, 8192)
141 print 'done downloading %s to %s' % (url, file_path)