15__title__ =
"pbsXSL_api - XPath and XSLT functions for the PBS RSS/HTML"
16__author__=
"R.D. Vaughan"
18This python script is intended to perform a variety of utility functions
19for the conversion of data to the MNV standard RSS output format.
20See this link for the specifications:
21http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format
29__xpathClassList__ = [
'xpathFunctions', ]
33__xsltExtentionList__ = []
35import os, sys, re, time, datetime, shutil,
urllib.request, urllib.parse, urllib.error, string
36from copy
import deepcopy
40 """Wraps a stream with an encoder"""
49 """Wraps the output stream, encoding Unicode strings with the specified encoding"""
50 if isinstance(obj, str):
53 self.
out.buffer.write(obj)
58 """Delegate everything but write to the stream"""
59 return getattr(self.
out, attr)
61if isinstance(sys.stdout, io.TextIOWrapper):
66 from io
import StringIO
67 from lxml
import etree
69 sys.stderr.write(
'\n! Error - Importing the "lxml" and "StringIO" python libraries failed on error(%s)\n' % e)
74 """Functions specific extending XPath
77 self.
functList = [
'pbsTitleSeriesEpisodeLink',
'pbsDuration',
'pbsDownloadlink']
80 re.compile(
'''^.+?Season\\ (?P<seasno>[0-9]+)\\:\\ Episode\\ (?P<epno>[0-9]+).*$''', re.UNICODE),
82 re.compile(
'''^.+?Season\\ (?P<seasno>[0-9]+)\\,\\ Episode\\ (?P<epno>[0-9]+).*$''', re.UNICODE),
84 re.compile(
'''^.+?Episode\\ (?P<epno>[0-9]+).*$''', re.UNICODE),
87 'media':
"http://search.yahoo.com/mrss/",
88 'xhtml':
"http://www.w3.org/1999/xhtml",
89 'mythtv':
"http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format",
90 'mediaad':
"http://PBS/dtd/mediaad/1.0",
102 '''Generate a link for the PBS site.
103 Call example: 'mnvXpath:pbsTitleSeriesEpisodeLink(normalize-space(./title),normalize-space(./link))/*'
104 return the title, link
and season
and episode number elements
if any were
in the title
110 tmpVideoCode = tmpLink.replace(
'http://video.pbs.org/video/',
'')[:-1]
111 self.
persistence[tmpLink] = common.linkWebPage(
'dummy',
'pbs')
120 (seasonNumber, episodeNumber) = match.groups()
123 episodeNumber = match.groups()[0]
127 index = tmpTitle.rfind(
'|')
129 tmpTitle = tmpTitle[index+1:].strip()
130 if seasonNumber
and episodeNumber:
131 tmpTitle =
'S%02dE%02d: %s' % (int(seasonNumber), int(episodeNumber), tmpTitle)
133 index = tmpTitle.find(
':')
135 tmpTitle = tmpTitle[index+1:].strip()
136 tmpTitle =
'Ep%02d: %s' % (int(episodeNumber), tmpTitle)
137 self.
persistence[tmpLink] = common.linkWebPage(
'dummy',
'pbs').replace(
'TITLE', urllib.parse.quote(tmpTitle)).replace(
'VIDEOCODE', tmpVideoCode)
140 elementTmp = etree.XML(
'<xml></xml>')
141 etree.SubElement(elementTmp,
"title").text = tmpTitle
143 etree.SubElement(elementTmp,
"season").text =
"%s" % int(seasonNumber)
145 etree.SubElement(elementTmp,
"episode").text =
"%s" % int(episodeNumber)
146 etree.SubElement(elementTmp,
"link").text = self.
persistence[tmpLink]
151 '''Return the video duration in seconds
152 Call example: 'mnvXpath:pbsDuration(normalize-string(./dd/p[@class="info"]/span[@class="time"]))'
153 return the video duration
161 '''Return a previously created download link
162 Call example: 'mnvXpath:pbsDownloadlink(normalize-space(./link))'
def __getattr__(self, attr)
def __init__(self, outstream, encoding=None)
def pbsDownloadlink(self, context, *arg)
def pbsDuration(self, context, *arg)
def pbsTitleSeriesEpisodeLink(self, context, *arg)
Start of XPath extension functions.