Updated to use a pool or worker threads
[pyTivo.git] / plugins / webvideo / webvideo.py
blobed28e9c4f2af4656bc30d62b24ce2640139e85ed
1 from plugins.video.video import Video, VideoDetails
2 import mind
3 import config
5 import xmpp
7 import threading
8 import xml.etree.ElementTree as ElementTree
9 import Queue
11 CLASS_NAME = 'WebVideo'
14 class WebVideo(Video):
16 CONTENT_TYPE = 'x-not-for/tivo'
18 def init(self):
19 self.work_queue = Queue.Queue()
20 self.download_thread_num = 1
21 self.in_progress = {}
22 self.in_progress_lock = threading.Lock()
24 self.startXMPP()
25 self.xmpp_cdsupdate()
26 self.startWorkerThreads()
28 def startXMPP(self):
29 m = mind.getMind()
30 xmpp_info = m.getXMPPLoginInfo()
32 jid=xmpp.protocol.JID(xmpp_info['username'] + '/pyTivo')
33 cl=xmpp.Client(
34 server=xmpp_info['server'],
35 port=xmpp_info['port'],
38 cl.connect()
39 cl.RegisterHandler('message', self.processMessage)
40 cl.auth(user=jid.getNode(), password=config.getTivoPassword(), resource='pyTivo')
42 cl.sendInitPresence(requestRoster=0)
44 for user_name in xmpp_info['presence_list']:
45 jid=xmpp.protocol.JID(user_name)
46 cl.sendPresence(jid)
48 t = threading.Thread(target=self.processXMPP, args=(cl,))
49 t.setDaemon(True)
50 t.start()
52 def startWorkerThreads(self):
53 for i in range(self.download_thread_num):
54 t = threading.Thread(target=self.processDlRequest)
55 t.setDaemon(True)
56 t.start()
58 def processXMPP(self, client):
59 while client.Process():
60 pass
62 def processMessage(self, sess,mess):
63 xmpp_action = ElementTree.fromstring(mess.getBody())
65 method_name = 'xmpp_' + xmpp_action.findtext('action').lower()
66 if not hasattr(self, method_name):
67 return False
69 method = getattr(self, method_name)
70 method(xmpp_action)
72 def xmpp_cdsupdate(self, xml=None):
73 m = mind.getMind()
75 self.in_progress_lock.acquire()
76 try:
77 for request in m.getDownloadRequests():
78 if not request['bodyOfferId'] in self.in_progress:
79 self.in_progress[request['bodyOfferId']] = True
80 self.work_queue.put(request)
81 finally:
82 self.in_progress_lock.release()
84 def processDlRequest(self):
85 import shutil
86 import os.path
87 import urllib2
88 import urllib
90 while True:
91 data = self.work_queue.get()
93 for share_name, settings in config.getShares():
94 if settings['type'] == 'webvideo':
95 break
98 path = settings['path']
99 file_name = os.path.join(path, '%s-%s' % (data['bodyOfferId'] ,data['url'].split('/')[-1]))
101 print 'downloading %s to %s' % (data['url'], file_name)
103 outfile = open(file_name, 'wb')
105 infile = urllib2.urlopen(data['url'])
106 shutil.copyfileobj(infile, outfile)
108 print 'done downloading %s to %s' % (data['url'], file_name)
110 tsn = data['bodyId']
111 file_info = VideoDetails()
112 file_info.update(self.metadata_full(file_name, tsn))
114 import socket
115 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
116 s.connect(('tivo.com',123))
117 ip = s.getsockname()[0]
118 port = config.getPort()
120 data['url'] = 'http://%s:%s' % (ip, port) + urllib.quote('/%s/%s' % (share_name, os.path.split(file_name)[-1]))
121 data['duration'] = file_info['duration'] / 1000
122 data['size'] = file_info['size']
124 print data
126 m = mind.getMind()
127 m.completeDownloadRequest(data)
129 self.in_progress_lock.acquire()
130 try:
131 del self.in_progress[data['bodyOfferId']]
132 finally:
133 self.in_progress_lock.release()