MythTV master
linuxAction_api.py
Go to the documentation of this file.
1# -*- coding: UTF-8 -*-
2
3# ----------------------
4# Name: linuxAction_api - XPath and XSLT functions for the www.jupiterbroadcasting.com RSS/HTML items
5# Python Script
6# Author: R.D. Vaughan
7# Purpose: This python script is intended to perform a variety of utility functions
8# for the conversion of data to the MNV standard RSS output format.
9# See this link for the specifications:
10# http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format
11#
12# License:Creative Commons GNU GPL v2
13# (http://creativecommons.org/licenses/GPL/2.0/)
14#-------------------------------------
15__title__ ="linuxAction_api - XPath and XSLT functions for the www.jupiterbroadcasting.com RSS/HTML"
16__author__="R.D. Vaughan"
17__purpose__='''
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
22'''
23
24__version__="v0.1.1"
25# 0.1.0 Initial development
26
27
28# Specify the class names that have XPath extention functions
29__xpathClassList__ = ['xpathFunctions', ]
30
31# Specify the XSLT extention class names. Each class is a stand lone extention function
32#__xsltExtentionList__ = ['xsltExtExample', ]
33__xsltExtentionList__ = []
34
35import os, sys, re, time, datetime, shutil, urllib.request, urllib.parse, urllib.error, string
36from copy import deepcopy
37import io
38
39class OutStreamEncoder(object):
40 """Wraps a stream with an encoder"""
41 def __init__(self, outstream, encoding=None):
42 self.out = outstream
43 if not encoding:
44 self.encoding = sys.getfilesystemencoding()
45 else:
46 self.encoding = encoding
47
48 def write(self, obj):
49 """Wraps the output stream, encoding Unicode strings with the specified encoding"""
50 if isinstance(obj, str):
51 obj = obj.encode(self.encoding)
52 try:
53 self.out.buffer.write(obj)
54 except OSError:
55 pass
56
57 def __getattr__(self, attr):
58 """Delegate everything but write to the stream"""
59 return getattr(self.out, attr)
60
61if isinstance(sys.stdout, io.TextIOWrapper):
62 sys.stdout = OutStreamEncoder(sys.stdout, 'utf8')
63 sys.stderr = OutStreamEncoder(sys.stderr, 'utf8')
64
65try:
66 from io import StringIO
67 from lxml import etree
68except Exception as e:
69 sys.stderr.write('\n! Error - Importing the "lxml" and "StringIO" python libraries failed on error(%s)\n' % e)
70 sys.exit(1)
71
72
73class xpathFunctions(object):
74 """Functions specific extending XPath
75 """
76 def __init__(self):
77 self.functList = ['linuxActionLinkGeneration', 'linuxActionTitleSeEp', 'linuxActioncheckIfDBItem', ]
78 self.s_e_Regex = [
79 # s12e05
80 re.compile('''^.+?[Ss](?P<seasno>[0-9]+)\\e(?P<epno>[0-9]+).*$''', re.UNICODE),
81 # Season 11 Episode 3
82 re.compile('''^.+?Season\\ (?P<seasno>[0-9]+)\\ Episode\\ (?P<epno>[0-9]+).*$''', re.UNICODE),
83 ]
84 self.namespaces = {
85 'atom': "http://www.w3.org/2005/Atom",
86 'atom10': "http://www.w3.org/2005/Atom",
87 'media': "http://search.yahoo.com/mrss/",
88 'itunes':"http://www.itunes.com/dtds/podcast-1.0.dtd",
89 'xhtml': "http://www.w3.org/1999/xhtml",
90 'mythtv': "http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format",
91 'feedburner': "http://rssnamespace.org/feedburner/ext/1.0",
92 'fb': "http://www.facebook.com/2008/fbml",
93 }
95 [etree.XPath('//object/@id', namespaces=self.namespaces ), None],
96 ]
97 self.FullScreen = 'http://linuxAction.com/show/popupPlayer?video_id=%s&quality=high&offset=0'
98 self.FullScreenParser = common.parsers['html'].copy()
99 # end __init__()
100
101
106
107 def linuxActionLinkGeneration(self, context, *arg):
108 '''Generate a link for the video.
109 Call example: 'mnvXpath:linuxActionLinkGeneration(string(link))'
110 return the url link
111 '''
112 webURL = arg[0]
113 try:
114 tmpHandle = urllib.request.urlopen(webURL)
115 tmpHTML = str(tmpHandle.read(), 'utf-8')
116 tmpHandle.close()
117 except Exception as errmsg:
118 sys.stderr.write("Error reading url(%s) error(%s)\n" % (webURL, errmsg))
119 return webURL
120
121 findText = "<embed src="
122 lenText = len(findText)
123 posText = tmpHTML.find(findText)
124 if posText == -1:
125 return webURL
126 tmpHTML = tmpHTML[posText+lenText+1:]
127
128 tmpLink = tmpHTML[:tmpHTML.find('"')]
129 if tmpLink.find('www.youtube.com') != -1:
130 return '%s&autoplay=1' % tmpLink
131 else:
132 return '%s?autostart=1' % tmpLink
133 # end linuxActionLinkGeneration()
134
135 def linuxActionTitleSeEp(self, context, *arg):
136 '''Parse the download link and extract an episode number
137 Call example: 'mnvXpath:linuxActionTitleSeEp(title)'
138 return the a massaged title element and an episode element in an array
139 '''
140 title = arg[0]
141 index = title.find('|')
142 if index > 0:
143 title = title[:index].strip()
144 index = title.find('The Linux Action Show')
145 if index > 0:
146 title = title[:index].strip()
147 index = title.find('! Season')
148 if index > 0:
149 title = title[:index-1].strip()
150 title = common.htmlToString('dummy', title)
151
152 elementArray = []
153 seasonNumber = ''
154 episodeNumber = ''
155 for index in range(len(self.s_e_Regex)):
156 match = self.s_e_Regex[index].match(arg[0])
157 if match:
158 (seasonNumber, episodeNumber) = match.groups()
159 seasonNumber = '%s' % int(seasonNumber)
160 episodeNumber = '%s' % int(episodeNumber)
161 elementArray.append(etree.XML("<title>%s</title>" % ('S%02dE%02d: %s' % (int(seasonNumber), int(episodeNumber), title))))
162 break
163 else:
164 elementArray.append(etree.XML("<title>%s</title>" % title ))
165 if seasonNumber:
166 tmpElement = etree.Element('{http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format}season')
167 tmpElement.text = seasonNumber
168 elementArray.append(tmpElement)
169 if episodeNumber:
170 tmpElement = etree.Element('{http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format}episode')
171 tmpElement.text = episodeNumber
172 elementArray.append(tmpElement)
173 return elementArray
174 # end linuxActionTitleSeEp()
175
176 def linuxActioncheckIfDBItem(self, context, *arg):
177 '''Use a unique key value pairing to find out if the 'internetcontentarticles' table already
178 has a matching item. This is done to save accessing the Internet when not required.
179 Call example: 'mnvXpath:linuxActioncheckIfDBItem(title, author)'
180 return True if a match was found
181 return False if a match was not found
182 '''
183 titleElement = self.linuxActionTitleSeEp('dummy', arg[0])[0]
184 return common.checkIfDBItem('dummy', {'feedtitle': 'Technology', 'title': titleElement.text, 'author': arg[1]})
185 # end linuxActioncheckIfDBItem()
186
187
192
193
198
199
def linuxActionLinkGeneration(self, context, *arg)
Start of XPath extension functions.
MBASE_PUBLIC long long copy(QFile &dst, QFile &src, uint block_size=0)
Copies src file to dst file.