MythTV  master
cinemarv_api.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3 # ----------------------
4 # Name: cinemarv_api - XPath and XSLT functions for the CinemaRV.com grabber
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__ ="cinemarv_api - XPath and XSLT functions for the CinemaRV.com grabber"
16 __author__="R.D. Vaughan"
17 __purpose__='''
18 This python script is intended to perform a variety of utility functions
19 for the conversion of data to the MNV standard RSS output format.
20 See this link for the specifications:
21 http://www.mythtv.org/wiki/MythNetvision_Grabber_Script_Format
22 '''
23 
24 __version__="v0.1.0"
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 
35 import os, sys, re, time, datetime, shutil, urllib, string
36 from copy import deepcopy
37 
38 
39 class 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, unicode):
51  try:
52  self.out.write(obj.encode(self.encoding))
53  except IOError:
54  pass
55  else:
56  try:
57  self.out.write(obj)
58  except IOError:
59  pass
60 
61  def __getattr__(self, attr):
62  """Delegate everything but write to the stream"""
63  return getattr(self.out, attr)
64 sys.stdout = OutStreamEncoder(sys.stdout, 'utf8')
65 sys.stderr = OutStreamEncoder(sys.stderr, 'utf8')
66 
67 try:
68  from StringIO import StringIO
69  from lxml import etree
70 except Exception, e:
71  sys.stderr.write(u'\n! Error - Importing the "lxml" and "StringIO" python libraries failed on error(%s)\n' % e)
72  sys.exit(1)
73 
74 # Check that the lxml library is current enough
75 # From the lxml documents it states: (http://codespeak.net/lxml/installation.html)
76 # "If you want to use XPath, do not use libxml2 2.6.27. We recommend libxml2 2.7.2 or later"
77 # Testing was performed with the Ubuntu 9.10 "python-lxml" version "2.1.5-1ubuntu2" repository package
78 version = ''
79 for digit in etree.LIBXML_VERSION:
80  version+=str(digit)+'.'
81 version = version[:-1]
82 if version < '2.7.2':
83  sys.stderr.write(u'''
84 ! Error - The installed version of the "lxml" python library "libxml" version is too old.
85  At least "libxml" version 2.7.2 must be installed. Your version is (%s).
86 ''' % version)
87  sys.exit(1)
88 
89 
90 class xpathFunctions(object):
91  """Functions specific extending XPath
92  """
93  def __init__(self):
94  self.functList = ['cinemarvLinkGeneration', 'cinemarvIsCustomHTML', 'cinemarvCheckIfDBItem', ]
95  self.TextTail = etree.XPath("string()")
96  self.persistence = {}
97  # end __init__()
98 
99 
104 
105  def cinemarvLinkGeneration(self, context, *args):
106  '''Generate a link for the CinemaRV.com site. A read of the item's web page is required to
107  extract the flash video id.
108  Call example: 'mnvXpath:cinemarvLinkGeneration(string(link))'
109  return the url link
110  '''
111  webURL = args[0]
112  # If this is for the download then just return what was found for the "link" element
113  if self.persistence.has_key('cinemarvLinkGeneration'):
114  if self.persistence['cinemarvLinkGeneration'] != None:
115  returnValue = self.persistence['cinemarvLinkGeneration']
116  self.persistence['cinemarvLinkGeneration'] = None
117  return returnValue
118  else:
119  self.persistence['cinemarvLinkGenerationVideoID'] = etree.XPath('//object[@id="flashObj"]//param[@name="flashVars"]/@value', namespaces=common.namespaces)
120  self.persistence['cinemarvLinkGenerationParser'] = etree.HTMLParser()
121 
122  try:
123  webPageElement = etree.parse(webURL, self.persistence['cinemarvLinkGenerationParser'])
124  except Exception, errmsg:
125  sys.stderr.write(u'!Warning: The web page URL(%s) could not be read, error(%s)\n' % (webURL, errmsg))
126  return webURL
127  if webPageElement == None:
128  self.persistence['cinemarvLinkGeneration'] = webURL
129  return webURL
130 
131  tmpVideoID = self.persistence['cinemarvLinkGenerationVideoID'](webPageElement)
132  if not len(tmpVideoID):
133  self.persistence['cinemarvLinkGeneration'] = webURL
134  return webURL
135  index = tmpVideoID[0].find('&')
136  if index == -1:
137  self.persistence['cinemarvLinkGeneration'] = webURL
138  return webURL
139  videocode = tmpVideoID[0][:index].replace(u'videoId=', u'')
140  self.persistence['cinemarvLinkGeneration'] = common.linkWebPage(u'dummycontext', 'cinemarv')+videocode
141  return self.persistence['cinemarvLinkGeneration']
142  # end cinemarvLinkGeneration()
143 
144  def cinemarvIsCustomHTML(self, context, *args):
145  '''Check if the link is for a custom HTML
146  Example call: mnvXpath:cinemarvIsCustomHTML(('dummy'))
147  return True if the link does not starts with "http://"
148  return False if the link starts with "http://"
149  '''
150  if self.persistence['cinemarvLinkGeneration'] == None:
151  return False
152 
153  if self.persistence['cinemarvLinkGeneration'].startswith(u'http://'):
154  return False
155  else:
156  return True
157  # end cinemarvIsCustomHTML()
158 
159  def cinemarvCheckIfDBItem(self, context, *arg):
160  '''Use a unique key value pairing to find out if the 'internetcontentarticles' table already
161  has a matching item. This is done to save accessing the Internet when not required.
162  Call example: 'mnvXpath:cinemarvCheckIfDBItem(.)'
163  return True if a match was found
164  return False if a match was not found
165  '''
166  return common.checkIfDBItem('dummy', {'feedtitle': 'Movie Trailers', 'title': arg[0].replace('Trailer', u'').strip(), 'author': arg[1], 'description': arg[2]})
167  # end cinemarvCheckIfDBItem()
168 
169 
174 
175 
180 
181 
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
def cinemarvLinkGeneration(self, context, *args)
Start of XPath extension functions.