Mercurial > ~darius > hgwebdir.cgi > py-iview
view iview.py @ 5:f2e0787f52b8 default tip
Tidy up output to be clearer.
- Don't bother the user with XML errors & lack of asset tags.
- Print a header for the channel & series lists.
- Inform the user how to navigate the menus.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Fri, 21 Aug 2009 13:05:59 +0930 |
parents | f914f08d69f5 |
children |
line wrap: on
line source
#!/usr/bin/env python import exceptions import htmlentitydefs import re import sys import time import urllib2 import xml.dom.minidom as minidom from xml.parsers.expat import ExpatError confurl = 'http://www.abc.net.au/iview/iview_231_config.xml' pattern = re.compile("&(\w+?);") def descape_entity(m, defs=htmlentitydefs.entitydefs): try: return defs[m.group(1)] except KeyError: return m.group(0) # use as is def descape(string): return pattern.sub(descape_entity, string) def toBool(s): if type(s) is bool: return s s = str(s).strip().lower() return not s[0] in ['f','n','0'] class NoAsset(exceptions.Exception): pass class Series(object): def __init__(self, seriesElem): self.id = seriesElem.getAttribute("id") self.url = seriesElem.getAttribute("href") # Fetch titles and so on #print "Fetching series URL " + self.url xmlp = minidom.parse(urllib2.urlopen(self.url)) self.title = self.gatherChildren(xmlp.getElementsByTagName("title")) self.descr = self.gatherChildren(xmlp.getElementsByTagName("description")) # No asset means unpublished? assets = xmlp.getElementsByTagName("abc:videoAsset") if len(assets) == 0: raise NoAsset self.asset = assets[0].childNodes[0].data.rstrip('.flv') rating = xmlp.getElementsByTagName("abc:rating")[0].childNodes if len(rating) > 0: self.rating = descape(rating[0].data) else: self.rating = "unrated" self.imgurl = xmlp.getElementsByTagName("image")[0].getElementsByTagName("url")[0].childNodes[0].data self.expiry = time.strptime(xmlp.getElementsByTagName("abc:expireDate")[0].childNodes[0].data , '%d/%m/%Y %H:%M:%S') def gatherChildren(self, elemList): rtn = [] for e in elemList: if len(e.childNodes) > 0: rtn.append(descape(e.childNodes[0].data.strip())) return rtn class Channel(object): def __init__(self, chanElem): self.id = chanElem.getAttribute("id") self.sort = chanElem.getAttribute("sort") self.path = chanElem.getAttribute("path") self.thumb = chanElem.getAttribute("thumb") self.name = descape(chanElem.getElementsByTagName("name")[0].childNodes[0].data) self.descr = descape(chanElem.getElementsByTagName("description")[0].childNodes[0].data) self.series = [] def getSeries(self): if len(self.series) > 0: return # This can take ages print "Fetching series for channel " + self.name # Series is nested for some reason xmlp = minidom.parse(urllib2.urlopen(self.path)) nl = xmlp.getElementsByTagName("series")[0] for s in nl.getElementsByTagName("series"): try: self.series.append(Series(s)) except ExpatError: #print "Unable to parse XML, skipping" continue except NoAsset: #print "No asset tag, skipping" continue class IView(object): def __init__(self): # Fetch and parse config URL #print "Fetching configuration URL" xmlp = minidom.parse(urllib2.urlopen(confurl)) self.params = {} for param in xmlp.getElementsByTagName("param"): self.params[param.getAttribute("name")] = param.getAttribute("value") # Get token & metered status from auth_path URL #print "Fetching authorisation information" self.getAuth() # Build channel list #print "Fetching channel list" xmlp = minidom.parse(urllib2.urlopen(self.params['base_url'] + '/' + self.params['xml_channels'])) self.channels = [] for chan in xmlp.getElementsByTagName("channel"): self.channels.append(Channel(chan)) def getAuth(self): xmlp = minidom.parse(urllib2.urlopen(self.params['auth_path'])) self.token = xmlp.getElementsByTagName("token")[0].childNodes[0].data self.metered = not toBool(xmlp.getElementsByTagName("free")[0].childNodes[0].data) server = xmlp.getElementsByTagName("server")[0].childNodes if len(server) == 0: self.rtmp = self.params['server_streaming'].rstrip('/ondemand') + '////' + self.params['media_path'] self.tcurl = self.params['server_streaming'] else: self.rtmp = xmlp.getElementsByTagName("server")[0].childNodes[0].data self.tcurl = None def genFetchCmd(self, series, outfile): cmd = ['-m', '1200'] if self.tcurl == None: cmd += ['-r', self.rtmp + '?auth=' + self.token] cmd += ['-y', series.asset] else: cmd += ['-r', self.rtmp + series.asset] cmd += ['-t', self.tcurl + '?auth=' + self.token] cmd += ['-o', outfile] return cmd # Non-metered: #/home/darius/projects/flvstreamer/flvstreamer_x86 # -r rtmp://cp53909.edgefcs.net////flash/playback/_definst_/catch_up/compass_09_23_28 # -t rtmp://cp53909.edgefcs.net/ondemand?auth=daEbFbibab6d4c0cwdjcwcya4dTb9cucucw-bkJnTd-8-klt_rFzqL&aifp=v001 # -o ./compass_09_23_28.flv -m 1200