1 from plugins
.video
.video
import Video
, VideoDetails
16 import xml
.etree
.ElementTree
as ElementTree
20 CLASS_NAME
= 'WebVideo'
23 class WebVideo(Video
):
25 CONTENT_TYPE
= 'x-not-for/tivo'
28 self
.__logger
= logging
.getLogger('pyTivo.webvideo')
29 self
.work_queue
= Queue
.Queue()
30 self
.download_thread_num
= 1
32 self
.in_progress_lock
= threading
.Lock()
35 self
.startWorkerThreads()
39 xmpp_info
= m
.getXMPPLoginInfo()
41 jid
=xmpp
.protocol
.JID(xmpp_info
['username'] + '/pyTivo')
43 server
=xmpp_info
['server'],
44 port
=xmpp_info
['port'],
47 self
.__logger
.debug('Connecting to %s:%s' % (xmpp_info
['server'], xmpp_info
['port']))
49 cl
.RegisterHandler('message', self
.processMessage
)
50 self
.__logger
.debug('Loging in as %s/pyTivo' % xmpp_info
['username'])
51 cl
.auth(user
=jid
.getNode(), password
=config
.getTivoPassword(), resource
='pyTivo')
53 cl
.sendInitPresence(requestRoster
=0)
55 for user_name
in xmpp_info
['presence_list']:
56 self
.__logger
.debug('Sending presence to %s' % user_name
)
57 jid
=xmpp
.protocol
.JID(user_name
)
60 t
= threading
.Thread(target
=self
.processXMPP
, args
=(cl
,))
64 def startWorkerThreads(self
):
65 for i
in range(self
.download_thread_num
):
66 t
= threading
.Thread(target
=self
.processDlRequest
, name
='webvideo downloader')
70 t
= threading
.Thread(target
=self
.watchQueue
, name
='webvideo queue watcher')
74 def processXMPP(self
, client
):
75 while client
.Process(3):
78 def processMessage(self
, sess
, mess
):
79 self
.__logger
.debug('Got message\n %s' % mess
.getBody())
80 xmpp_action
= ElementTree
.fromstring(mess
.getBody())
82 method_name
= 'xmpp_' + xmpp_action
.findtext('action').lower()
83 if not hasattr(self
, method_name
):
86 method
= getattr(self
, method_name
)
94 def xmpp_cdsupdate(self
, xml
=None):
97 self
.in_progress_lock
.acquire()
99 for request
in m
.getDownloadRequests():
100 if not request
['bodyOfferId'] in self
.in_progress
:
101 self
.__logger
.debug('Adding request to queue, %s' % request
)
102 self
.in_progress
[request
['bodyOfferId']] = True
103 self
.work_queue
.put(request
)
105 self
.in_progress_lock
.release()
107 def processDlRequest(self
):
110 data
= self
.work_queue
.get()
112 for share_name
, settings
in config
.getShares():
113 if settings
['type'] == 'webvideo':
115 self
.__logger
.debug('Processing request: %s' % data
)
117 path
= settings
['path']
118 file_name
= os
.path
.join(path
, '%s-%s' % (data
['bodyOfferId'].replace(':', '-'),data
['url'].split('/')[-1]))
120 self
.downloadFile(data
['url'], file_name
)
123 file_info
= VideoDetails()
124 file_info
.update(self
.metadata_full(file_name
, tsn
))
127 s
= socket
.socket(socket
.AF_INET
, socket
.SOCK_DGRAM
)
128 s
.connect(('tivo.com',123))
129 ip
= s
.getsockname()[0]
130 port
= config
.getPort()
132 data
['url'] = 'http://%s:%s' % (ip
, port
) + urllib
.quote('/%s/%s' % (share_name
, os
.path
.split(file_name
)[-1]))
133 data
['duration'] = file_info
['duration'] / 1000
134 data
['size'] = file_info
['size']
136 self
.__logger
.debug('Complete request: %s' % data
)
139 m
.completeDownloadRequest(data
)
141 self
.in_progress_lock
.acquire()
143 del self
.in_progress
[data
['bodyOfferId']]
145 self
.in_progress_lock
.release()
147 def downloadFile(self
, url
, file_path
):
148 self
.__logger
.info('Downloading %s to %s' % (url
, file_path
))
150 outfile
= open(file_path
, 'awb')
151 size
= os
.path
.getsize(file_path
)
152 r
= urllib2
.Request(url
)
154 r
.add_header('Range', 'bytes=%s-' % size
)
157 infile
= urllib2
.urlopen(r
)
158 except urllib2
.HTTPError
, e
:
159 if not e
.code
== 416:
161 infile
= urllib2
.urlopen(url
)
162 if int(infile
.info()['Content-Length']) == size
:
163 self
.__logger
.debug('File was alraedy done. %s' % url
)
166 self
.__logger
.debug('File was not done but could not resume. %s' % url
)
168 outfile
= open(file_path
, 'wb')
170 shutil
.copyfileobj(infile
, outfile
, 8192)
172 self
.__logger
.info('Done downloading %s to %s' % (url
, file_path
))
174 def send_file(self
, handler
, container
, name
):
175 Video
.send_file(self
, handler
, container
, name
)
177 o
= urlparse
.urlparse("http://fake.host" + handler
.path
)
178 path
= urllib
.unquote(o
[2])
179 file_path
= container
['path'] + path
[len(name
) + 1:]
180 if os
.path
.exists(file_path
):
181 self
.__logger
.info('Deleting file %s' % file_path
)