def NPL(self, handler, query): def getint(thing): try: result = int(thing) except: result = 0 return result global basic_meta shows_per_page = 50 # Change this to alter the number of shows returned folder = '' FirstAnchor = '' has_tivodecode = bool(config.get_bin('tivodecode')) useragent = handler.headers.getheader('User-Agent', '') if 'TiVo' in query: tivoIP = query['TiVo'][0] tsn = config.tivos_by_ip(tivoIP) tivo_name = config.tivo_names[tsn] tivo_mak = config.get_tsn('tivo_mak', tsn) theurl = ('https://' + tivoIP + '/TiVoConnect?Command=QueryContainer&ItemCount=' + str(shows_per_page) + '&Container=/NowPlaying') if 'Folder' in query: folder += query['Folder'][0] theurl += '/' + folder if 'AnchorItem' in query: theurl += '&AnchorItem=' + quote(query['AnchorItem'][0]) if 'AnchorOffset' in query: theurl += '&AnchorOffset=' + query['AnchorOffset'][0] if (theurl not in tivo_cache or (time.time() - tivo_cache[theurl]['thepage_time']) >= 60): # if page is not cached or old then retreive it auth_handler.add_password('TiVo DVR', tivoIP, 'tivo', tivo_mak) try: page = self.tivo_open(theurl) except IOError, e: handler.redir(UNABLE % tivoIP, 10) return tivo_cache[theurl] = {'thepage': minidom.parse(page), 'thepage_time': time.time()} page.close() xmldoc = tivo_cache[theurl]['thepage'] items = xmldoc.getElementsByTagName('Item') TotalItems = tag_data(xmldoc, 'TiVoContainer/Details/TotalItems') ItemStart = tag_data(xmldoc, 'TiVoContainer/ItemStart') ItemCount = tag_data(xmldoc, 'TiVoContainer/ItemCount') title = tag_data(xmldoc, 'TiVoContainer/Details/Title') if items: FirstAnchor = tag_data(items[0], 'Links/Content/Url') data = [] for item in items: entry = {} entry['ContentType'] = tag_data(item, 'Details/ContentType') for tag in ('CopyProtected', 'UniqueId'): value = tag_data(item, 'Details/' + tag) if value: entry[tag] = value if entry['ContentType'] == 'x-tivo-container/folder': entry['Title'] = tag_data(item, 'Details/Title') entry['TotalItems'] = tag_data(item, 'Details/TotalItems') lc = tag_data(item, 'Details/LastCaptureDate') if not lc: lc = tag_data(item, 'Details/LastChangeDate') entry['LastChangeDate'] = time.strftime('%b %d, %Y', time.localtime(int(lc, 16))) else: keys = {'Icon': 'Links/CustomIcon/Url', 'Url': 'Links/Content/Url', 'SourceSize': 'Details/SourceSize', 'Duration': 'Details/Duration', 'CaptureDate': 'Details/CaptureDate'} for key in keys: value = tag_data(item, keys[key]) if value: entry[key] = value rawsize = entry['SourceSize'] entry['SourceSize'] = metadata.human_size(rawsize) dur = getint(entry['Duration']) / 1000 entry['Duration'] = ( '%d:%02d:%02d' % (dur / 3600, (dur % 3600) / 60, dur % 60) ) entry['CaptureDate'] = time.strftime('%b %d, %Y', time.localtime(int(entry['CaptureDate'], 16))) url = entry['Url'] if url in basic_meta: entry.update(basic_meta[url]) else: basic_data = metadata.from_container(item) entry.update(basic_data) basic_meta[url] = basic_data data.append(entry)
def NPL(self, handler, query): def getint(thing): try: result = int(thing) except: result = 0 return result global basic_meta global details_urls shows_per_page = 50 # Change this to alter the number of shows returned folder = '' FirstAnchor = '' has_tivodecode = bool(config.get_bin('tivodecode')) if 'TiVo' in query: tivoIP = query['TiVo'][0] tsn = config.tivos_by_ip(tivoIP) attrs = config.tivos[tsn] tivo_name = attrs.get('name', tivoIP) tivo_mak = config.get_tsn('tivo_mak', tsn) protocol = attrs.get('protocol', 'https') ip_port = '%s:%d' % (tivoIP, attrs.get('port', 443)) path = attrs.get('path', DEFPATH) baseurl = '%s://%s%s' % (protocol, ip_port, path) theurl = baseurl if 'Folder' in query: folder = query['Folder'][0] theurl = urlparse.urljoin(theurl, folder) theurl += '&ItemCount=%d' % shows_per_page if 'AnchorItem' in query: theurl += '&AnchorItem=' + quote(query['AnchorItem'][0]) if 'AnchorOffset' in query: theurl += '&AnchorOffset=' + query['AnchorOffset'][0] if (theurl not in tivo_cache or (time.time() - tivo_cache[theurl]['thepage_time']) >= 60): # if page is not cached or old then retreive it auth_handler.add_password('TiVo DVR', ip_port, 'tivo', tivo_mak) try: page = self.tivo_open(theurl) except IOError, e: handler.redir(UNABLE % (tivoIP, cgi.escape(str(e))), 10) return tivo_cache[theurl] = { 'thepage': minidom.parse(page), 'thepage_time': time.time() } page.close() xmldoc = tivo_cache[theurl]['thepage'] items = xmldoc.getElementsByTagName('Item') TotalItems = tag_data(xmldoc, 'TiVoContainer/Details/TotalItems') ItemStart = tag_data(xmldoc, 'TiVoContainer/ItemStart') ItemCount = tag_data(xmldoc, 'TiVoContainer/ItemCount') title = tag_data(xmldoc, 'TiVoContainer/Details/Title') if items: FirstAnchor = tag_data(items[0], 'Links/Content/Url') data = [] for item in items: entry = {} for tag in ('CopyProtected', 'ContentType'): value = tag_data(item, 'Details/' + tag) if value: entry[tag] = value if entry['ContentType'].startswith('x-tivo-container'): entry['Url'] = tag_data(item, 'Links/Content/Url') entry['Title'] = tag_data(item, 'Details/Title') entry['TotalItems'] = tag_data(item, 'Details/TotalItems') lc = tag_data(item, 'Details/LastCaptureDate') if not lc: lc = tag_data(item, 'Details/LastChangeDate') entry['LastChangeDate'] = time.strftime( '%b %d, %Y', time.localtime(int(lc, 16))) else: keys = { 'Icon': 'Links/CustomIcon/Url', 'Url': 'Links/Content/Url', 'Details': 'Links/TiVoVideoDetails/Url', 'SourceSize': 'Details/SourceSize', 'Duration': 'Details/Duration', 'CaptureDate': 'Details/CaptureDate' } for key in keys: value = tag_data(item, keys[key]) if value: entry[key] = value if 'SourceSize' in entry: rawsize = entry['SourceSize'] entry['SourceSize'] = metadata.human_size(rawsize) if 'Duration' in entry: dur = getint(entry['Duration']) / 1000 entry['Duration'] = ('%d:%02d:%02d' % (dur / 3600, (dur % 3600) / 60, dur % 60)) if 'CaptureDate' in entry: entry['CaptureDate'] = time.strftime( '%b %d, %Y', time.localtime(int(entry['CaptureDate'], 16))) url = urlparse.urljoin(baseurl, entry['Url']) entry['Url'] = url if url in basic_meta: entry.update(basic_meta[url]) else: basic_data = metadata.from_container(item) entry.update(basic_data) basic_meta[url] = basic_data if 'Details' in entry: details_urls[url] = entry['Details'] data.append(entry)
def NPL(self, handler, query): def getint(thing): try: result = int(thing) except: result = 0 return result global basic_meta global details_urls shows_per_page = 50 # Change this to alter the number of shows returned folder = '' FirstAnchor = '' has_tivodecode = bool(config.get_bin('tivodecode')) if 'TiVo' in query: tivoIP = query['TiVo'][0] tsn = config.tivos_by_ip(tivoIP) attrs = config.tivos[tsn] tivo_name = attrs.get('name', tivoIP) tivo_mak = config.get_tsn('tivo_mak', tsn) protocol = attrs.get('protocol', 'https') ip_port = '%s:%d' % (tivoIP, attrs.get('port', 443)) path = attrs.get('path', DEFPATH) baseurl = '%s://%s%s' % (protocol, ip_port, path) theurl = baseurl if 'Folder' in query: folder = query['Folder'][0] theurl = urlparse.urljoin(theurl, folder) theurl += '&ItemCount=%d' % shows_per_page if 'AnchorItem' in query: theurl += '&AnchorItem=' + quote(query['AnchorItem'][0]) if 'AnchorOffset' in query: theurl += '&AnchorOffset=' + query['AnchorOffset'][0] if (theurl not in tivo_cache or (time.time() - tivo_cache[theurl]['thepage_time']) >= 60): # if page is not cached or old then retreive it auth_handler.add_password('TiVo DVR', ip_port, 'tivo', tivo_mak) try: page = self.tivo_open(theurl) except IOError, e: handler.redir(UNABLE % (tivoIP, cgi.escape(str(e))), 10) return tivo_cache[theurl] = {'thepage': minidom.parse(page), 'thepage_time': time.time()} page.close() xmldoc = tivo_cache[theurl]['thepage'] items = xmldoc.getElementsByTagName('Item') TotalItems = tag_data(xmldoc, 'TiVoContainer/Details/TotalItems') ItemStart = tag_data(xmldoc, 'TiVoContainer/ItemStart') ItemCount = tag_data(xmldoc, 'TiVoContainer/ItemCount') title = tag_data(xmldoc, 'TiVoContainer/Details/Title') if items: FirstAnchor = tag_data(items[0], 'Links/Content/Url') data = [] for item in items: entry = {} for tag in ('CopyProtected', 'ContentType'): value = tag_data(item, 'Details/' + tag) if value: entry[tag] = value if entry['ContentType'].startswith('x-tivo-container'): entry['Url'] = tag_data(item, 'Links/Content/Url') entry['Title'] = tag_data(item, 'Details/Title') entry['TotalItems'] = tag_data(item, 'Details/TotalItems') lc = tag_data(item, 'Details/LastCaptureDate') if not lc: lc = tag_data(item, 'Details/LastChangeDate') entry['LastChangeDate'] = time.strftime('%b %d, %Y', time.localtime(int(lc, 16))) else: keys = {'Icon': 'Links/CustomIcon/Url', 'Url': 'Links/Content/Url', 'Details': 'Links/TiVoVideoDetails/Url', 'SourceSize': 'Details/SourceSize', 'Duration': 'Details/Duration', 'CaptureDate': 'Details/CaptureDate'} for key in keys: value = tag_data(item, keys[key]) if value: entry[key] = value if 'SourceSize' in entry: rawsize = entry['SourceSize'] entry['SourceSize'] = metadata.human_size(rawsize) if 'Duration' in entry: dur = getint(entry['Duration']) / 1000 entry['Duration'] = ( '%d:%02d:%02d' % (dur / 3600, (dur % 3600) / 60, dur % 60) ) if 'CaptureDate' in entry: entry['CaptureDate'] = time.strftime('%b %d, %Y', time.localtime(int(entry['CaptureDate'], 16))) url = urlparse.urljoin(baseurl, entry['Url']) entry['Url'] = url if url in basic_meta: entry.update(basic_meta[url]) else: basic_data = metadata.from_container(item) entry.update(basic_data) basic_meta[url] = basic_data if 'Details' in entry: details_urls[url] = entry['Details'] data.append(entry)
def GetShowsList(self, handler, query): json_config = {} if 'TiVo' in query: tivoIP = query['TiVo'][0] tsn = config.tivos_by_ip(tivoIP) attrs = config.tivos[tsn] tivo_name = attrs.get('name', tivoIP) tivo_mak = config.get_tsn('tivo_mak', tsn) protocol = attrs.get('protocol', 'https') ip_port = '%s:%d' % (tivoIP, attrs.get('port', 443)) path = attrs.get('path', DEFPATH) baseurl = '%s://%s%s' % (protocol, ip_port, path) # Get the total item count first theurl = baseurl + '&Recurse=Yes&ItemCount=0' auth_handler.add_password('TiVo DVR', ip_port, 'tivo', tivo_mak) try: page = self.tivo_open(theurl) except IOError, e: handler.send_error(404) return xmldoc = minidom.parse(page) page.close() LastChangeDate = unicode( tag_data(xmldoc, 'TiVoContainer/Details/LastChangeDate')) # Check date of cache if (tsn in json_cache and json_cache[tsn]['lastChangeDate'] == LastChangeDate): logger.debug("Retrieving shows from cache") handler.send_json(json_cache[tsn]['data']) return global basic_meta global details_urls # loop through grabbing 50 items at a time (50 is max TiVo will return) TotalItems = int( unicode(tag_data(xmldoc, 'TiVoContainer/Details/TotalItems'))) if TotalItems <= 0: logger.debug("Total items 0") handler.send_json(json_config) return GotItems = 0 GeneratedID = 0 while (GotItems < TotalItems): logger.debug("Retrieving shows " + str(GotItems) + "-" + str(GotItems + 50) + " of " + str(TotalItems) + " from " + tivo_name) theurl = baseurl + '&Recurse=Yes&ItemCount=50' theurl += '&AnchorOffset=%d' % GotItems auth_handler.add_password('TiVo DVR', ip_port, 'tivo', tivo_mak) try: page = self.tivo_open(theurl) except IOError, e: handler.send_error(404) return try: xmldoc = minidom.parse(page) items = xmldoc.getElementsByTagName('Item') page.close() except: logger.debug("XML parser error") break if len(items) <= 0: logger.debug("items collection empty") break for item in items: SeriesID = tag_data(item, 'Details/SeriesId') if (not SeriesID): SeriesID = 'PS%08d' % GeneratedID GeneratedID += 1 if (not SeriesID in json_config): json_config[SeriesID] = {} EpisodeID = tag_data(item, 'Details/ProgramId') if (not EpisodeID): EpisodeID = 'PE%08d' % GeneratedID GeneratedID += 1 # Check for duplicate episode IDs and replace with generated ID while EpisodeID in json_config[SeriesID]: EpisodeID = 'PE%08d' % GeneratedID GeneratedID += 1 json_config[SeriesID][EpisodeID] = {} json_config[SeriesID][EpisodeID]['title'] = tag_data( item, 'Details/Title') json_config[SeriesID][EpisodeID]['url'] = tag_data( item, 'Links/Content/Url') json_config[SeriesID][EpisodeID]['detailsUrl'] = tag_data( item, 'Links/TiVoVideoDetails/Url') json_config[SeriesID][EpisodeID][ 'episodeTitle'] = tag_data(item, 'Details/EpisodeTitle') json_config[SeriesID][EpisodeID]['description'] = tag_data( item, 'Details/Description') json_config[SeriesID][EpisodeID]['recordDate'] = tag_data( item, 'Details/CaptureDate') json_config[SeriesID][EpisodeID]['duration'] = tag_data( item, 'Details/Duration') json_config[SeriesID][EpisodeID]['sourceSize'] = tag_data( item, 'Details/SourceSize') json_config[SeriesID][EpisodeID]['channel'] = tag_data( item, 'Details/SourceChannel') json_config[SeriesID][EpisodeID]['stationID'] = tag_data( item, 'Details/SourceStation') json_config[SeriesID][EpisodeID]['episodeID'] = EpisodeID json_config[SeriesID][EpisodeID]['seriesID'] = SeriesID if tag_data(item, 'Details/InProgress') == 'Yes': json_config[SeriesID][EpisodeID]['inProgress'] = True else: json_config[SeriesID][EpisodeID]['inProgress'] = False if tag_data(item, 'Details/CopyProtected') == 'Yes': json_config[SeriesID][EpisodeID]['isProtected'] = True else: json_config[SeriesID][EpisodeID]['isProtected'] = False if tag_data(item, 'Links/CustomIcon/Url' ) == 'urn:tivo:image:suggestion-recording': json_config[SeriesID][EpisodeID]['isSuggestion'] = True else: json_config[SeriesID][EpisodeID][ 'isSuggestion'] = False if tag_data(item, 'Details/CopyProtected') == 'Yes': json_config[SeriesID][EpisodeID]['icon'] = 'protected' elif tag_data(item, 'Links/CustomIcon/Url' ) == 'urn:tivo:image:expires-soon-recording': json_config[SeriesID][EpisodeID]['icon'] = 'expiring' elif tag_data(item, 'Links/CustomIcon/Url' ) == 'urn:tivo:image:expired-recording': json_config[SeriesID][EpisodeID]['icon'] = 'expired' elif tag_data( item, 'Links/CustomIcon/Url' ) == 'urn:tivo:image:save-until-i-delete-recording': json_config[SeriesID][EpisodeID]['icon'] = 'kuid' elif tag_data(item, 'Links/CustomIcon/Url' ) == 'urn:tivo:image:suggestion-recording': json_config[SeriesID][EpisodeID]['icon'] = 'suggestion' elif tag_data(item, 'Links/CustomIcon/Url' ) == 'urn:tivo:image:in-progress-recording': json_config[SeriesID][EpisodeID]['icon'] = 'inprogress' else: json_config[SeriesID][EpisodeID]['icon'] = 'normal' url = urlparse.urljoin( baseurl, json_config[SeriesID][EpisodeID]['url']) json_config[SeriesID][EpisodeID]['url'] = url if not url in basic_meta: basic_meta[url] = metadata.from_container(item) if 'detailsUrl' in json_config[SeriesID][EpisodeID]: details_urls[url] = json_config[SeriesID][ EpisodeID]['detailsUrl'] itemCount = tag_data(xmldoc, 'TiVoContainer/ItemCount') try: logger.debug("Retrieved " + itemCount + " from " + tivo_name) GotItems += int(itemCount) except ValueError: GotItems += len(items)
def NPL(self, handler, query): global basic_meta shows_per_page = 50 # Change this to alter the number of shows returned folder = '' has_tivodecode = bool(config.get_bin('tivodecode')) if 'TiVo' in query: tivoIP = query['TiVo'][0] tsn = config.tivos_by_ip(tivoIP) tivo_name = config.tivo_names[tsn] tivo_mak = config.get_tsn('tivo_mak', tsn) theurl = ('https://' + tivoIP + '/TiVoConnect?Command=QueryContainer&ItemCount=' + str(shows_per_page) + '&Container=/NowPlaying') if 'Folder' in query: folder += query['Folder'][0] theurl += '/' + folder if 'AnchorItem' in query: theurl += '&AnchorItem=' + quote(query['AnchorItem'][0]) if 'AnchorOffset' in query: theurl += '&AnchorOffset=' + query['AnchorOffset'][0] if (theurl not in tivo_cache or (time.time() - tivo_cache[theurl]['thepage_time']) >= 60): # if page is not cached or old then retreive it auth_handler.add_password('TiVo DVR', tivoIP, 'tivo', tivo_mak) try: page = self.tivo_open(theurl) except IOError, e: handler.redir(UNABLE % tivoIP, 10) return tivo_cache[theurl] = { 'thepage': minidom.parse(page), 'thepage_time': time.time() } page.close() xmldoc = tivo_cache[theurl]['thepage'] items = xmldoc.getElementsByTagName('Item') TotalItems = tag_data(xmldoc, 'Details/TotalItems') ItemStart = tag_data(xmldoc, 'ItemStart') ItemCount = tag_data(xmldoc, 'ItemCount') FirstAnchor = tag_data(items[0], 'Links/Content/Url') data = [] for item in items: entry = {} entry['ContentType'] = tag_data(item, 'ContentType') for tag in ('CopyProtected', 'UniqueId'): value = tag_data(item, tag) if value: entry[tag] = value if entry['ContentType'] == 'x-tivo-container/folder': entry['Title'] = tag_data(item, 'Title') entry['TotalItems'] = tag_data(item, 'TotalItems') lc = tag_data(item, 'LastCaptureDate') if not lc: lc = tag_data(item, 'LastChangeDate') entry['LastChangeDate'] = time.strftime( '%b %d, %Y', time.localtime(int(lc, 16))) else: keys = { 'Icon': 'Links/CustomIcon/Url', 'Url': 'Links/Content/Url', 'SourceSize': 'Details/SourceSize', 'Duration': 'Details/Duration', 'CaptureDate': 'Details/CaptureDate' } for key in keys: value = tag_data(item, keys[key]) if value: entry[key] = value entry['SourceSize'] = ('%.3f GB' % (float(entry['SourceSize']) / (1024**3))) dur = int(entry['Duration']) / 1000 entry['Duration'] = ('%02d:%02d:%02d' % (dur / 3600, (dur % 3600) / 60, dur % 60)) entry['CaptureDate'] = time.strftime( '%b %d, %Y', time.localtime(int(entry['CaptureDate'], 16))) url = entry['Url'] if url in basic_meta: entry.update(basic_meta[url]) else: basic_data = metadata.from_container(item) entry.update(basic_data) basic_meta[url] = basic_data data.append(entry)