00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 __title__ ="linuxAction_api - XPath and XSLT functions for the www.jupiterbroadcasting.com RSS/HTML"
00016 __author__="R.D. Vaughan"
00017 __purpose__='''
00018 This python script is intended to perform a variety of utility functions
00019 for the conversion of data to the MNV standard RSS output format.
00020 See this link for the specifications:
00021 http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format
00022 '''
00023
00024 __version__="v0.1.1"
00025
00026
00027
00028
00029 __xpathClassList__ = ['xpathFunctions', ]
00030
00031
00032
00033 __xsltExtentionList__ = []
00034
00035 import os, sys, re, time, datetime, shutil, urllib, string
00036 from copy import deepcopy
00037
00038
00039 class OutStreamEncoder(object):
00040 """Wraps a stream with an encoder"""
00041 def __init__(self, outstream, encoding=None):
00042 self.out = outstream
00043 if not encoding:
00044 self.encoding = sys.getfilesystemencoding()
00045 else:
00046 self.encoding = encoding
00047
00048 def write(self, obj):
00049 """Wraps the output stream, encoding Unicode strings with the specified encoding"""
00050 if isinstance(obj, unicode):
00051 try:
00052 self.out.write(obj.encode(self.encoding))
00053 except IOError:
00054 pass
00055 else:
00056 try:
00057 self.out.write(obj)
00058 except IOError:
00059 pass
00060
00061 def __getattr__(self, attr):
00062 """Delegate everything but write to the stream"""
00063 return getattr(self.out, attr)
00064 sys.stdout = OutStreamEncoder(sys.stdout, 'utf8')
00065 sys.stderr = OutStreamEncoder(sys.stderr, 'utf8')
00066
00067 try:
00068 from StringIO import StringIO
00069 from lxml import etree
00070 except Exception, e:
00071 sys.stderr.write(u'\n! Error - Importing the "lxml" and "StringIO" python libraries failed on error(%s)\n' % e)
00072 sys.exit(1)
00073
00074
00075
00076
00077
00078 version = ''
00079 for digit in etree.LIBXML_VERSION:
00080 version+=str(digit)+'.'
00081 version = version[:-1]
00082 if version < '2.7.2':
00083 sys.stderr.write(u'''
00084 ! Error - The installed version of the "lxml" python library "libxml" version is too old.
00085 At least "libxml" version 2.7.2 must be installed. Your version is (%s).
00086 ''' % version)
00087 sys.exit(1)
00088
00089
00090 class xpathFunctions(object):
00091 """Functions specific extending XPath
00092 """
00093 def __init__(self):
00094 self.functList = ['linuxActionLinkGeneration', 'linuxActionTitleSeEp', 'linuxActioncheckIfDBItem', ]
00095 self.s_e_Regex = [
00096
00097 re.compile(u'''^.+?[Ss](?P<seasno>[0-9]+)\\e(?P<epno>[0-9]+).*$''', re.UNICODE),
00098
00099 re.compile(u'''^.+?Season\\ (?P<seasno>[0-9]+)\\ Episode\\ (?P<epno>[0-9]+).*$''', re.UNICODE),
00100 ]
00101 self.namespaces = {
00102 'atom': "http://www.w3.org/2005/Atom",
00103 'atom10': "http://www.w3.org/2005/Atom",
00104 'media': "http://search.yahoo.com/mrss/",
00105 'itunes':"http://www.itunes.com/dtds/podcast-1.0.dtd",
00106 'xhtml': "http://www.w3.org/1999/xhtml",
00107 'mythtv': "http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format",
00108 'feedburner': "http://rssnamespace.org/feedburner/ext/1.0",
00109 'fb': "http://www.facebook.com/2008/fbml",
00110 }
00111 self.mediaIdFilters = [
00112 [etree.XPath('//object/@id', namespaces=self.namespaces ), None],
00113 ]
00114 self.FullScreen = u'http://linuxAction.com/show/popupPlayer?video_id=%s&quality=high&offset=0'
00115 self.FullScreenParser = common.parsers['html'].copy()
00116
00117
00118
00119
00120
00121
00122
00123
00124 def linuxActionLinkGeneration(self, context, *arg):
00125 '''Generate a link for the video.
00126 Call example: 'mnvXpath:linuxActionLinkGeneration(string(link))'
00127 return the url link
00128 '''
00129 webURL = arg[0]
00130 try:
00131 tmpHandle = urllib.urlopen(webURL)
00132 tmpHTML = unicode(tmpHandle.read(), 'utf-8')
00133 tmpHandle.close()
00134 except Exception, errmsg:
00135 sys.stderr.write(u"Error reading url(%s) error(%s)\n" % (webURL, errmsg))
00136 return webURL
00137
00138 findText = u"<embed src="
00139 lenText = len(findText)
00140 posText = tmpHTML.find(findText)
00141 if posText == -1:
00142 return webURL
00143 tmpHTML = tmpHTML[posText+lenText+1:]
00144
00145 tmpLink = tmpHTML[:tmpHTML.find('"')]
00146 if tmpLink.find('www.youtube.com') != -1:
00147 return u'%s&autoplay=1' % tmpLink
00148 else:
00149 return u'%s?autostart=1' % tmpLink
00150
00151
00152 def linuxActionTitleSeEp(self, context, *arg):
00153 '''Parse the download link and extract an episode number
00154 Call example: 'mnvXpath:linuxActionTitleSeEp(title)'
00155 return the a massaged title element and an episode element in an array
00156 '''
00157 title = arg[0]
00158 index = title.find('|')
00159 if index > 0:
00160 title = title[:index].strip()
00161 index = title.find('The Linux Action Show')
00162 if index > 0:
00163 title = title[:index].strip()
00164 index = title.find('! Season')
00165 if index > 0:
00166 title = title[:index-1].strip()
00167 title = common.htmlToString('dummy', title)
00168
00169 elementArray = []
00170 seasonNumber = u''
00171 episodeNumber = u''
00172 for index in range(len(self.s_e_Regex)):
00173 match = self.s_e_Regex[index].match(arg[0])
00174 if match:
00175 (seasonNumber, episodeNumber) = match.groups()
00176 seasonNumber = u'%s' % int(seasonNumber)
00177 episodeNumber = u'%s' % int(episodeNumber)
00178 elementArray.append(etree.XML(u"<title>%s</title>" % (u'S%02dE%02d: %s' % (int(seasonNumber), int(episodeNumber), title))))
00179 break
00180 else:
00181 elementArray.append(etree.XML(u"<title>%s</title>" % title ))
00182 if seasonNumber:
00183 tmpElement = etree.Element('{http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format}season')
00184 tmpElement.text = seasonNumber
00185 elementArray.append(tmpElement)
00186 if episodeNumber:
00187 tmpElement = etree.Element('{http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format}episode')
00188 tmpElement.text = episodeNumber
00189 elementArray.append(tmpElement)
00190 return elementArray
00191
00192
00193 def linuxActioncheckIfDBItem(self, context, *arg):
00194 '''Use a unique key value pairing to find out if the 'internetcontentarticles' table already
00195 has a matching item. This is done to save accessing the Internet when not required.
00196 Call example: 'mnvXpath:linuxActioncheckIfDBItem(title, author)'
00197 return True if a match was found
00198 return False if a match was not found
00199 '''
00200 titleElement = self.linuxActionTitleSeEp('dummy', arg[0])[0]
00201 return common.checkIfDBItem('dummy', {'feedtitle': 'Technology', 'title': titleElement.text, 'author': arg[1]})
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220