MythTV  master
mnvsearch.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # -*- coding: UTF-8 -*-
3 # ----------------------
4 # Name: mnvsearch.py
5 # Python Script
6 # Author: R.D. Vaughan
7 # Purpose:
8 # This python script is intended to perform a data base search of MythNetvision data base tables for
9 # videos based on a command line search term.
10 # It follows the MythTV Netvision grabber standards.
11 #
12 # Command example:
13 # See help (-u and -h) options
14 #
15 # Design:
16 # 1) Read the ".../emml/feConfig.xml"
17 # 2) Check if the CGI Web server should be used or if the script is run locally
18 # 3) Initialize the correct target functions for processing (local or remote)
19 # 4) Process the search request and display to stdout
20 #
21 #
22 # License:Creative Commons GNU GPL v2
23 # (http://creativecommons.org/licenses/GPL/2.0/)
24 #-------------------------------------
25 __title__ ="Search all tree views";
26 __mashup_title__ = "mnvsearch"
27 __author__="R.D. Vaughan"
28 __version__="0.13"
29 # 0.1.0 Initial development
30 # 0.11 Change to support xml version information display
31 # 0.12 Added the "command" tag to the xml version information display
32 # 0.13 Converted to new common_api.py library
33 
34 __usage_examples__ ='''
35 (Option Help)
36 > ./mnvsearch.py -h
37 Usage: ./mnvsearch.py -hduvlS [parameters] <search text>
38 Version: v0.1.0 Author: R.D.Vaughan
39 
40 For details on the MythTV Netvision plugin see the wiki page at:
41 http://www.mythtv.org/wiki/MythNetvision
42 
43 Options:
44  -h, --help show this help message and exit
45  -d, --debug Show debugging info (URLs, raw XML ... etc, info
46  varies per grabber)
47  -u, --usage Display examples for executing the script
48  -v, --version Display grabber name and supported options
49  -l LANGUAGE, --language=LANGUAGE
50  Select data that matches the specified language fall
51  back to English if nothing found (e.g. 'es' EspaƱol,
52  'de' Deutsch ... etc). Not all sites or grabbers
53  support this option.
54  -p PAGE NUMBER, --pagenumber=PAGE NUMBER
55  Display specific page of the search results. Default
56  is page 1. Page number is ignored with the Tree View
57  option (-T).
58  -S, --search Search for videos
59 
60 > ./mnvsearch.py -v
61 <grabber>
62  <name>Search all tree views</name>
63  <author>R.D.Vaughan</author>
64  <thumbnail>mnvsearch.png</thumbnail>
65  <type>video</type>
66  <description>MythNetvision treeview data base search</description>
67  <version>v0.11</version>
68  <search>true</search>
69 </grabber>
70 
71 > ./mnvsearch.py -S "Doctor Who"
72 <?xml version="1.0" encoding="UTF-8"?>
73 <rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:cnettv="http://cnettv.com/mrss/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:amp="http://www.adobe.com/amp/1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
74 <channel>
75  <title>Search all tree views</title>
76  <link>http://www.mythtv.org/wiki/MythNetvision</link>
77  <description>MythNetvision treeview data base search</description>
78  <numresults>21</numresults>
79  <returned>20</returned>
80  <startindex>20</startindex>
81 <item>
82  <title>Doctor Who - Doctor Who and The Brain of Morbius - Episode 8</title>
83  <author>BBC</author>
84  <pubDate>Sat, 01 May 2010 15:04:02 GMT</pubDate>
85  <description>The Doctor and Sarah Jane confront the Morbius monster and seek help from the Sisterhood.</description>
86  <link>file:///usr/local/share/mythtv/mythnetvision/scripts/nv_python_libs/configs/HTML/bbciplayer.html?videocode=b00s5ztx</link>
87  <media:group>
88  <media:thumbnail url="http://node1.bbcimg.co.uk/iplayer/images/episode/b00s5ztx_120_68.jpg"/>
89  <media:content url="file:///usr/local/share/mythtv/mythnetvision/scripts/nv_python_libs/configs/HTML/bbciplayer.html?videocode=b00s5ztx" length="" duration="" width="" height="" lang=""/>
90  </media:group>
91  <rating>0.0</rating>
92 </item>
93 ...
94 <item>
95  <title>Every Doctor Who Story 1963-2008 - by Babelcolour</title>
96  <author>BabelColour</author>
97  <pubDate>Mon, 07 Jul 2008 14:45:12 GMT</pubDate>
98  <description>To celebrate the 45th Anniversary of the series, here is every Who story from 1963 to 2008, with the spin-off shows and bbci internet productions &amp; the Children In Need specials, but doesn't include any of the spoofs, comedy sketches or other charity skits not made by the official Who Production Team. Edit: It was made &amp; uploaded before the BBC Proms Special 'Music Of The Spheres'. That's why it isn't included! The fabulous music mix (called 'Whorythmics') was created by jex</description>
99  <link>http://www.youtube.com/v/lCZhlEdGIm0?f=videos&amp;app=youtube_gdata&amp;autoplay=1</link>
100  <media:group>
101  <media:thumbnail url="http://i.ytimg.com/vi/lCZhlEdGIm0/hqdefault.jpg"/>
102  <media:content url="http://www.youtube.com/v/lCZhlEdGIm0?f=videos&amp;app=youtube_gdata&amp;autoplay=1" length="" duration="" width="" height="" lang=""/>
103  </media:group>
104  <rating>4.957553</rating>
105 </item></channel></rss>
106 '''
107 __search_max_page_items__ = 20
108 __tree_max_page_items__ = 20
109 
110 import sys, os
111 import io
112 
113 class OutStreamEncoder(object):
114  """Wraps a stream with an encoder"""
115  def __init__(self, outstream, encoding=None):
116  self.out = outstream
117  if not encoding:
118  self.encoding = sys.getfilesystemencoding()
119  else:
120  self.encoding = encoding
121 
122  def write(self, obj):
123  """Wraps the output stream, encoding Unicode strings with the specified encoding"""
124  if isinstance(obj, str):
125  obj = obj.encode(self.encoding)
126  self.out.buffer.write(obj)
127 
128  def __getattr__(self, attr):
129  """Delegate everything but write to the stream"""
130  return getattr(self.out, attr)
131 
132 if isinstance(sys.stdout, io.TextIOWrapper):
133  sys.stdout = OutStreamEncoder(sys.stdout, 'utf8')
134  sys.stderr = OutStreamEncoder(sys.stderr, 'utf8')
135 
136 
137 # Used for debugging
138 #import nv_python_libs.common.common_api
139 try:
140  '''Import the common python class
141  '''
142  import nv_python_libs.common.common_api as common_api
143 except Exception as e:
144  sys.stderr.write('''
145 The subdirectory "nv_python_libs/common" containing the modules common_api.py and
146 common_exceptions.py (v0.1.3 or greater),
147 They should have been included with the distribution of MythNetvision
148 Error(%s)
149 ''' % e)
150  sys.exit(1)
151 if common_api.__version__ < '0.1.3':
152  sys.stderr.write("\n! Error: Your current installed common_api.py version is (%s)\nYou must at least have version (0.1.3) or higher.\n" % target.__version__)
153  sys.exit(1)
154 
155 # Used for debugging
156 #import nv_python_libs.mnvsearch.mnvsearch_api as target
157 try:
158  '''Import the python mnvsearch support classes
159  '''
161 except Exception as e:
162  sys.stderr.write('''
163 The subdirectory "nv_python_libs/mnvsearch" containing the modules mnvsearch_api and
164 mnvsearch_exceptions.py (v0.1.0 or greater),
165 They should have been included with the distribution of mnvsearch.py.
166 Error(%s)
167 ''' % e)
168  sys.exit(1)
169 if target.__version__ < '0.1.0':
170  sys.stderr.write("\n! Error: Your current installed mnvsearch_api.py version is (%s)\nYou must at least have version (0.1.0) or higher.\n" % target.__version__)
171  sys.exit(1)
172 
173 # Verify that the main process modules are installed and accessible
174 try:
175  import nv_python_libs.mainProcess as process
176 except Exception as e:
177  sys.stderr.write('''
178 The python script "nv_python_libs/mainProcess.py" must be present.
179 Error(%s)
180 ''' % e)
181  sys.exit(1)
182 
183 if process.__version__ < '0.2.0':
184  sys.stderr.write("\n! Error: Your current installed mainProcess.py version is (%s)\nYou must at least have version (0.2.0) or higher.\n" % process.__version__)
185  sys.exit(1)
186 
187 if __name__ == '__main__':
188  # No api key is required
189  apikey = ""
190  # Set the base processing directory that the grabber is installed
191  target.baseProcessingDir = os.path.dirname( os.path.realpath( __file__ ))
192  # Make sure the target functions have an instance of the common routines
193  target.common = common_api.Common()
194  main = process.mainProcess(target, apikey, )
195  main.grabberInfo = {}
196  main.grabberInfo['enabled'] = True
197  main.grabberInfo['title'] = __title__
198  main.grabberInfo['command'] = 'mnvsearch.py'
199  main.grabberInfo['mashup_title'] = __mashup_title__
200  main.grabberInfo['author'] = __author__
201  main.grabberInfo['thumbnail'] = 'mnvsearch.png'
202  main.grabberInfo['type'] = ['video', ]
203  main.grabberInfo['desc'] = "MythTV Online Content database search."
204  main.grabberInfo['version'] = __version__
205  main.grabberInfo['search'] = True
206  main.grabberInfo['tree'] = False
207  main.grabberInfo['html'] = False
208  main.grabberInfo['usage'] = __usage_examples__
209  main.grabberInfo['SmaxPage'] = __search_max_page_items__
210  main.grabberInfo['TmaxPage'] = __tree_max_page_items__
211  main.main()
mnvsearch.OutStreamEncoder.encoding
encoding
Definition: mnvsearch.py:118
mnvsearch.OutStreamEncoder.write
def write(self, obj)
Definition: mnvsearch.py:122
mnvsearch.OutStreamEncoder
Definition: mnvsearch.py:113
mnvsearch.OutStreamEncoder.out
out
Definition: mnvsearch.py:116
nv_python_libs.mainProcess
Definition: mainProcess.py:1
nv_python_libs.common.common_api
Definition: common_api.py:1
nv_python_libs.mnvsearch.mnvsearch_api
Definition: mnvsearch_api.py:1
mnvsearch.OutStreamEncoder.__init__
def __init__(self, outstream, encoding=None)
Definition: mnvsearch.py:115
mnvsearch.OutStreamEncoder.__getattr__
def __getattr__(self, attr)
Definition: mnvsearch.py:128