Changeset 5027df9739e905098ee65f26d8229a9c55f84925

Show
Ignore:
Timestamp:
04/06/08 00:54:26 (8 months ago)
Author:
Jason Michalski <armooo@armooo.net>
git-committer:
Jason Michalski <armooo@armooo.net> 1207461266 -0500
git-parent:

[a62ba31e7ba19f2b44a02567e60284c920e30af2]

git-author:
Jason Michalski <armooo@armooo.net> 1207461266 -0500
Message:

Updated to support webvideo

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • mind.py

    r4574b4f r5027df9  
    33import urllib 
    44import struct 
    5 import httplib  
     5import httplib 
    66import time 
    77import warnings 
    88import itertools 
     9import config 
    910 
    1011try: 
    11     import xml.etree.ElementTree as ElementTree  
     12    import xml.etree.ElementTree as ElementTree 
    1213except ImportError: 
    1314    try: 
     
    1516    except ImportError: 
    1617        warnings.warn('Python 2.5 or higher or elementtree is needed to use the TivoPush') 
    17          
     18 
    1819if 'ElementTree' not in locals(): 
    1920 
     
    2122        def __init__(self, *arg, **karg): 
    2223            raise Exception('Python 2.5 or higher or elementtree is needed to use the TivoPush') 
    23      
     24 
    2425else: 
    2526 
     
    2728        def __init__(self, username, password, debug=False): 
    2829            self.__username = username 
    29             self.__password = password  
     30            self.__password = password 
    3031 
    3132            self.__debug = debug 
     
    3940                self.__pcBodyStore('pyTivo', True) 
    4041 
    41         def pushVideo(self, tsn, url, description='test', duration='40000', size='3000000', title='test', subtitle='test'): 
    42              
    43             # It looks like tivo only supports one pc per house 
    44             pc_body_id = self.__pcBodySearch()[0] 
    45             offer_id, content_id = self.__bodyOfferModify(tsn, pc_body_id, description, duration, size, title, subtitle, url) 
    46             self.__subscribe(offer_id, content_id, tsn) 
    47  
    48         def bodyOfferSchedule(self, pc_body_id): 
    49  
    50             data = {'pcBodyId' : pc_body_id,} 
    51             r = urllib2.Request( 
    52                 '/Steph%27s%20Videos/The%20Fairly%20Odd%20Parents%20-%20Channel%20Chasers.xvid-pyro.avi',  
    53                 dictcode(data), 
    54                 {'Content-Type' : 'x-tivo/dict-binary'} 
    55             ) 
    56             result = self.__opener.open(r) 
    57  
    58             self.__log('bodyOfferSchedule\n%s\n\n%sg' % (data, result)) 
    59  
    60             return result.read() 
    61  
    62         def __log(self, message): 
    63             if self.__debug: 
    64                 print message 
    65                 print 
    66  
    67         def __login(self): 
    68  
    69             data = { 
    70                 'cams_security_domain' : 'tivocom', 
    71                 'cams_login_config' : 'http', 
    72                 'cams_cb_username' : self.__username, 
    73                 'cams_cb_password' : self.__password, 
    74                 'cams_original_url' : '/mind/mind7?type=infoGet' 
    75             } 
    76  
    77             r =  urllib2.Request( 
    78                 'https://mind.tivo.com:8181/mind/login',  
    79                 urllib.urlencode(data) 
    80             ) 
    81             try: 
    82                 result = self.__opener.open(r) 
    83             except: 
    84                 pass 
    85  
    86             self.__log('__login\n%s' % (data)) 
    87  
    88         def __bodyOfferModify(self, tsn, pc_body_id, description, duration, size, title, subtitle, url): 
    89  
     42        def pushVideo(self, tsn, url, description, duration, size, title, subtitle): 
    9043            data = { 
    9144                'bodyId' : 'tsn:' + tsn, 
     
    10356                'url' : url, 
    10457            } 
    105             r = urllib2.Request( 
    106                 'https://mind.tivo.com:8181/mind/mind7?type=bodyOfferModify&bodyId=tsn:' + tsn,  
    107                 dictcode(data), 
    108                 {'Content-Type' : 'x-tivo/dict-binary'} 
    109             ) 
    110             result = self.__opener.open(r) 
    111  
    112             xml = ElementTree.parse(result).find('.') 
    113              
     58 
     59            # It looks like tivo only supports one pc per house 
     60            pc_body_id = self.__pcBodySearch()[0] 
     61            offer_id, content_id = self.__bodyOfferModify(data) 
     62            self.__subscribe(offer_id, content_id, tsn) 
     63 
     64        def getDownloadRequests(self): 
     65            NEEDED_VALUES = [ 
     66                'bodyId', 
     67                'bodyOfferId', 
     68                'description', 
     69                'partnerId', 
     70                'pcBodyId', 
     71                'publishDate', 
     72                'source', 
     73                'state', 
     74                'subscriptionId', 
     75                'subtitle', 
     76                'title', 
     77                'url', 
     78            ] 
     79 
     80            # It looks like tivo only supports one pc per house 
     81            pc_body_id = self.__pcBodySearch()[0] 
     82 
     83            requests = [] 
     84            offer_list = self.__bodyOfferSchedule(pc_body_id) 
     85 
     86            for offer in offer_list.findall('bodyOffer'): 
     87                d = {} 
     88                if offer.findtext('state') != 'scheduled': 
     89                    continue 
     90 
     91                for n in NEEDED_VALUES: 
     92                    d[n] = offer.findtext(n) 
     93                requests.append(d) 
     94 
     95            return requests 
     96 
     97        def completeDownloadRequest(self, request): 
     98            request['encodingType'] = 'mpeg2ProgramStream' 
     99            request['state'] = 'complete' 
     100            request['type'] = 'bodyOfferModify' 
     101            request['updateDate'] = time.strftime('%Y-%m-%d %H:%M%S', time.gmtime()) 
     102 
     103            offer_id, content_id = self.__bodyOfferModify(request) 
     104            self.__subscribe(offer_id, content_id, request['bodyId'][4:]) 
     105 
     106 
     107        def getXMPPLoginInfo(self): 
     108            # It looks like tivo only supports one pc per house 
     109            pc_body_id = self.__pcBodySearch()[0] 
     110 
     111            xml = self.__bodyXmppInfoGet(pc_body_id) 
     112 
     113            results = {} 
     114            results['server'] = xml.findtext('server') 
     115            results['port'] = int(xml.findtext('port')) 
     116            results['username'] = xml.findtext('xmppId') 
     117 
     118            for sendPresence in xml.findall('sendPresence'): 
     119                results.setdefault('presence_list', []).append(sendPresence.text) 
     120 
     121            return results 
     122 
     123        def __log(self, message): 
     124            if self.__debug: 
     125                print message 
     126                print 
     127 
     128        def __login(self): 
     129 
     130            data = { 
     131                'cams_security_domain' : 'tivocom', 
     132                'cams_login_config' : 'http', 
     133                'cams_cb_username' : self.__username, 
     134                'cams_cb_password' : self.__password, 
     135                'cams_original_url' : '/mind/mind7?type=infoGet' 
     136            } 
     137 
     138            r =  urllib2.Request( 
     139                'https://mind.tivo.com:8181/mind/login', 
     140                urllib.urlencode(data) 
     141            ) 
     142            try: 
     143                result = self.__opener.open(r) 
     144            except: 
     145                pass 
     146 
     147            self.__log('__login\n%s' % (data)) 
     148 
     149        def __bodyOfferModify(self, data): 
     150            """Create an offer""" 
     151            r = urllib2.Request( 
     152                'https://mind.tivo.com:8181/mind/mind7?type=bodyOfferModify&bodyId=' + data['bodyId'], 
     153                dictcode(data), 
     154                {'Content-Type' : 'x-tivo/dict-binary'} 
     155            ) 
     156            result = self.__opener.open(r) 
     157 
     158            xml = ElementTree.parse(result).find('.') 
     159 
    114160            self.__log('__bodyOfferModify\n%s\n\n%sg' % (data, ElementTree.tostring(xml))) 
    115161 
     
    124170 
    125171        def __subscribe(self, offer_id, content_id, tsn): 
     172            """Push the offer to the tivo""" 
    126173            data =  { 
    127174                'bodyId' : 'tsn:' + tsn, 
     
    134181                'uiType' : 'cds', 
    135182            } 
    136              
    137             r = urllib2.Request( 
    138                 'https://mind.tivo.com:8181/mind/mind7?type=subscribe&bodyId=tsn:' + tsn,  
     183 
     184            r = urllib2.Request( 
     185                'https://mind.tivo.com:8181/mind/mind7?type=subscribe&bodyId=tsn:' + tsn, 
    139186                dictcode(data), 
    140187                {'Content-Type' : 'x-tivo/dict-binary'} 
     
    148195            return xml 
    149196 
     197        def __bodyOfferSchedule(self, pc_body_id): 
     198            """Get pending stuff for this pc""" 
     199 
     200            data = {'pcBodyId' : pc_body_id,} 
     201            r = urllib2.Request( 
     202                'https://mind.tivo.com:8181/mind/mind7?type=bodyOfferSchedule', 
     203                dictcode(data), 
     204                {'Content-Type' : 'x-tivo/dict-binary'} 
     205            ) 
     206            result = self.__opener.open(r) 
     207 
     208            xml = ElementTree.parse(result).find('.') 
     209 
     210            self.__log('bodyOfferSchedule\n%s\n\n%sg' % (data, ElementTree.tostring(xml))) 
     211 
     212            return xml 
     213 
    150214        def __pcBodySearch(self): 
     215            """Find PCS""" 
    151216 
    152217            data = {} 
    153218            r = urllib2.Request( 
    154                 'https://mind.tivo.com:8181/mind/mind7?type=pcBodySearch',  
     219                'https://mind.tivo.com:8181/mind/mind7?type=pcBodySearch', 
    155220                dictcode(data), 
    156221                {'Content-Type' : 'x-tivo/dict-binary'} 
     
    166231 
    167232        def __collectionIdSearch(self, url): 
     233            """Find collection ids""" 
    168234 
    169235            data = {'url' : url} 
    170236            r = urllib2.Request( 
    171                 'https://mind.tivo.com:8181/mind/mind7?type=collectionIdSearch',  
     237                'https://mind.tivo.com:8181/mind/mind7?type=collectionIdSearch', 
    172238                dictcode(data), 
    173239                {'Content-Type' : 'x-tivo/dict-binary'} 
     
    183249 
    184250        def __pcBodyStore(self, name, replace=False): 
    185             
     251            """Setup a new PC""" 
     252 
    186253            data = { 
    187254                'name' : name, 
     
    190257 
    191258            r = urllib2.Request( 
    192                 'https://mind.tivo.com:8181/mind/mind7?type=pcBodyStore',  
    193                 dictcode(data),  
     259                'https://mind.tivo.com:8181/mind/mind7?type=pcBodyStore', 
     260                dictcode(data), 
    194261                {'Content-Type' : 'x-tivo/dict-binary'} 
    195262            ) 
     
    199266 
    200267            self.__log('__pcBodySearch\n%s\n\n%s' % (data, ElementTree.tostring(xml))) 
     268 
     269            return xml 
     270 
     271        def __bodyXmppInfoGet(self, body_id): 
     272 
     273            data = { 
     274                'bodyId' : body_id, 
     275            } 
     276 
     277            r = urllib2.Request( 
     278                'https://mind.tivo.com:8181/mind/mind7?type=bodyXmppInfoGet&bodyId=' + body_id, 
     279                dictcode(data), 
     280                {'Content-Type' : 'x-tivo/dict-binary'} 
     281            ) 
     282 
     283            result = self.__opener.open(r) 
     284 
     285            xml = ElementTree.parse(result).find('.') 
     286 
     287            self.__log('__bodyXmppInfoGe\n%s\n\n%s' % (data, ElementTree.tostring(xml))) 
    201288 
    202289            return xml 
     
    221308 
    222309            else: 
    223                 v = str(v
     310                v = unicode(v).encode('utf-8'
    224311                output.append( struct.pack('>B', 0x01) ) 
    225                 output.append( varint( len(v) ) )  
     312                output.append( varint( len(v) ) ) 
    226313                output.append( v ) 
    227314 
     
    239326            bits.append(i & 0x01) 
    240327            i = i  >> 1 
    241          
     328 
    242329        if not bits: 
    243330            output = [0] 
     
    249336            mybits = bits[:7] 
    250337            del bits[:7] 
    251             
     338 
    252339            for bit, p in zip(mybits, itertools.count()): 
    253340                byte += bit * (2 ** p) 
     
    258345        return ''.join([chr(b) for b in output]) 
    259346 
     347 
     348def getMind(): 
     349    username = config.getTivoUsername() 
     350    password = config.getTivoPassword() 
     351 
     352    if not username or not password: 
     353       raise Exception("tivo_username and tivo_password required") 
     354 
     355    m = Mind(username, password, True) 
     356 
     357    return m 
     358