6 import xml
.etree
.ElementTree
as ElementTree
11 def __init__(self
, username
, password
, debug
=False):
12 self
.__username
= username
13 self
.__password
= password
17 self
.__cj
= cookielib
.CookieJar()
18 self
.__opener
= urllib2
.build_opener(urllib2
.HTTPSHandler(debuglevel
=1), urllib2
.HTTPCookieProcessor(self
.__cj
))
22 if not self
.__pcBodySearch
():
23 self
.__pcBodyStore
('pyTivo', True)
25 def pushVideo(self
, tsn
, url
, description
='test', duration
='40000', size
='3000000', title
='test', subtitle
='test'):
27 # It looks like tivo only supports one pc per house
28 pc_body_id
= self
.__pcBodySearch
()[0]
29 offer_id
, content_id
= self
.__bodyOfferModify
(tsn
, pc_body_id
, description
, duration
, size
, title
, subtitle
, url
)
30 self
.__subscribe
(offer_id
, content_id
, tsn
)
32 def bodyOfferSchedule(self
, pc_body_id
):
34 data
= {'pcBodyId' : pc_body_id
,}
36 '/Steph%27s%20Videos/The%20Fairly%20Odd%20Parents%20-%20Channel%20Chasers.xvid-pyro.avi',
38 {'Content-Type' : 'x-tivo/dict-binary'}
40 result
= self
.__opener
.open(r
)
42 self
.__log
('bodyOfferSchedule\n%s\n\n%sg' % (data
, result
))
46 def __log(self
, message
):
54 'cams_security_domain' : 'tivocom',
55 'cams_login_config' : 'http',
56 'cams_cb_username' : self
.__username
,
57 'cams_cb_password' : self
.__password
,
58 'cams_original_url' : '/mind/mind7?type=infoGet'
62 'https://mind.tivo.com:8181/mind/login',
63 urllib
.urlencode(data
)
66 result
= self
.__opener
.open(r
)
70 self
.__log
('__login\n%s' % (data
))
72 def __bodyOfferModify(self
, tsn
, pc_body_id
, description
, duration
, size
, title
, subtitle
, url
):
75 'bodyId' : 'tsn:' + tsn
,
76 'description' : description
,
77 'duration' : duration
,
78 'encodingType' : 'mpeg2ProgramStream',
79 'partnerId' : 'tivo:pt.3187',
80 'pcBodyId' : pc_body_id
,
81 'publishDate' : time
.strftime('%Y-%m-%d %H:%M%S', time
.gmtime()),
83 'source' : 'file:/C%3A%2FDocuments%20and%20Settings%2FStephanie%2FDesktop%2FVideo',
85 'subtitle' : subtitle
,
90 'https://mind.tivo.com:8181/mind/mind7?type=bodyOfferModify&bodyId=tsn:' + tsn
,
92 {'Content-Type' : 'x-tivo/dict-binary'}
94 result
= self
.__opener
.open(r
)
96 xml
= ElementTree
.parse(result
).find('.')
98 self
.__log
('__bodyOfferModify\n%s\n\n%sg' % (data
, ElementTree
.tostring(xml
)))
100 if xml
.findtext('state') != 'complete':
101 raise Exception(ElementTree
.tostring(xml
))
103 offer_id
= xml
.findtext('offerId')
104 content_id
= offer_id
.replace('of','ct')
106 return offer_id
, content_id
109 def __subscribe(self
, offer_id
, content_id
, tsn
):
111 'bodyId' : 'tsn:' + tsn
,
113 'contentId': content_id
,
114 'offerId' : offer_id
,
115 'type' : 'singleOfferSource',
117 'title' : 'pcBodySubscription',
122 'https://mind.tivo.com:8181/mind/mind7?type=subscribe&bodyId=tsn:' + tsn
,
124 {'Content-Type' : 'x-tivo/dict-binary'}
126 result
= self
.__opener
.open(r
)
128 xml
= ElementTree
.parse(result
).find('.')
130 self
.__log
('__subscribe\n%s\n\n%sg' % (data
, ElementTree
.tostring(xml
)))
134 def __pcBodySearch(self
):
138 'https://mind.tivo.com:8181/mind/mind7?type=pcBodySearch',
140 {'Content-Type' : 'x-tivo/dict-binary'}
142 result
= self
.__opener
.open(r
)
144 xml
= ElementTree
.parse(result
).find('.')
147 self
.__log
('__pcBodySearch\n%s\n\n%sg' % (data
, ElementTree
.tostring(xml
)))
149 return [id.text
for id in xml
.findall('pcBody/pcBodyId')]
151 def __collectionIdSearch(self
, url
):
155 'https://mind.tivo.com:8181/mind/mind7?type=collectionIdSearch',
157 {'Content-Type' : 'x-tivo/dict-binary'}
159 result
= self
.__opener
.open(r
)
161 xml
= ElementTree
.parse( result
).find('.')
162 collection_id
= xml
.findtext('collectionId')
164 self
.__log
('__collectionIdSearch\n%s\n\n%sg' % (data
, ElementTree
.tostring(xml
)))
168 def __pcBodyStore(self
, name
, replace
=False):
172 'replaceExisting' : str(replace
).lower(),
176 'https://mind.tivo.com:8181/mind/mind7?type=pcBodyStore',
178 {'Content-Type' : 'x-tivo/dict-binary'}
180 result
= self
.__opener
.open(r
)
182 xml
= ElementTree
.parse(result
).find('.')
184 self
.__log
('__pcBodySearch\n%s\n\n%s' % (data
, ElementTree
.tostring(xml
)))
190 """Helper to create x-tivo/dict-binary"""
193 keys
= [str(k
) for k
in d
]
200 output
.append( struct
.pack('>B', l
) )
203 if isinstance(v
, dict):
204 output
.append( struct
.pack('>B', 0x02) )
205 output
.append( dictcode(v
) )
209 output
.append( struct
.pack('>B', 0x01) )
211 output
.append( struct
.pack('>B', l
) )
214 output
.append( struct
.pack('>B', 0x00) )
216 output
.append( struct
.pack('>B', 0x80) )
218 return ''.join(output
)
221 if __name__
== '__main__':
222 username
= 'armooo@armooo.net'
223 password
= 'in(into)'
224 tsn
= '6520001802C0F2A'
225 url
= 'http://10.0.1.52:9032/Steph%27s%20Videos/Weekend%20%28Godard%201967%29.avi'
227 mind
= Mind(username
, password
, True)
228 mind
.pushVideo(tsn
, url
)