MythTV  master
bbciplayer.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # -*- coding: UTF-8 -*-
3 # ----------------------
4 # Name: bbciplayer.py
5 # Python Script
6 # Author: R.D. Vaughan
7 # Purpose:
8 # This python script is intended to perform BBC iplayer video lookups for the MythTV Netvision plugin
9 # based on information found on the http://www.bbc.co.uk/iplayer/ website. It
10 # 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 or treeview 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__ ="BBC iPlayer";
26 __mashup_title__ = "bbcipplayer"
27 __author__="R.D. Vaughan"
28 __version__="0.15"
29 # 0.1.0 Initial development
30 # 0.1.1 Added treeview support
31 # 0.1.2 Convert to detect and use either local or remote processing
32 # 0.13 Change to support xml version information display
33 # 0.14 Added the "command" tag to the xml version information display
34 # 0.15 Converted to new common_api.py library
35 
36 __usage_examples__ ='''
37 (Option Help)
38 > ./bbciplayer.py -h
39 Usage: ./bbciplayer.py -hduvlST [parameters] <search text>
40 Version: v0.1.2 Author: R.D.Vaughan
41 
42 For details on the MythTV Netvision plugin see the wiki page at:
43 http://www.mythtv.org/wiki/MythNetvision
44 
45 Options:
46  -h, --help show this help message and exit
47  -d, --debug Show debugging info (URLs, raw XML ... etc, info
48  varies per grabber)
49  -u, --usage Display examples for executing the script
50  -v, --version Display grabber name and supported options
51  -l LANGUAGE, --language=LANGUAGE
52  Select data that matches the specified language fall
53  back to English if nothing found (e.g. 'es' EspaƱol,
54  'de' Deutsch ... etc). Not all sites or grabbers
55  support this option.
56  -p PAGE NUMBER, --pagenumber=PAGE NUMBER
57  Display specific page of the search results. Default
58  is page 1. Page number is ignored with the Tree View
59  option (-T).
60  -S, --search Search for videos
61  -T, --treeview Display a Tree View of a sites videos
62 
63 > ./bbciplayer.py -v
64 <grabber>
65  <name>BBC iPlayer</name>
66  <author>R.D. Vaughan</author>
67  <thumbnail>bbciplayer.png</thumbnail>
68  <type>video</type>
69  <description>BBC iPlayer is our service that lets you catch up with radio and television programmes from the past week.</description>
70  <version>v0.13</version>
71  <search>true</search>
72  <tree>true</tree>
73 </grabber>
74 
75 > ./bbciplayer.py -S "Doctor Who"
76 <?xml version="1.0" encoding="UTF-8"?>
77 <rss version="2.0" xmlns:amp="http://www.adobe.com/amp/1.0"
78  xmlns:atom="http://www.w3.org/2005/Atom"
79  xmlns:cnettv="http://cnettv.com/mrss/"
80  xmlns:content="http://purl.org/rss/1.0/modules/content/"
81  xmlns:creativecommons="http://backend.userland.com/creativeCommonsRssModule"
82  xmlns:dc="http://purl.org/dc/elements/1.1/"
83  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/">
84  <channel>
85  <title>BBC iPlayer</title>
86  <link>http://www.bbc.co.uk</link>
87  <description>BBC iPlayer is our service that lets you catch up with radio and television programmes from the past week.</description>
88  <numresults>7</numresults>
89  <returned>7</returned>
90  <startindex>7</startindex>
91  <item>
92  <title>Doctor Who - Series 4 - 11. Turn Left</title>
93  <author>British Broadcasting Corporation</author>
94  <pubDate>Wed, 24 Mar 2010 18:35:41 GMT</pubDate>
95  <description>Can Donna and Rose stop the approaching Darkness? (R)</description>
96  <link>http://www.bbc.co.uk/iplayer/episode/b00c7ytx/Doctor_Who_Series_4_Turn_Left/</link>
97  <media:group>
98  <media:thumbnail url="http://node1.bbcimg.co.uk/iplayer/images/episode/b00c7ytx_120_68.jpg"/>
99  <media:content duration="" height="" lang=""
100  url="http://www.bbc.co.uk/iplayer/episode/b00c7ytx/Doctor_Who_Series_4_Turn_Left/" width=""/>
101  </media:group>
102  <rating>0.0</rating>
103  </item>
104 ...
105  <item>
106  <title>Doctor Who Confidential - Series 4 - 13. The End of an Era</title>
107  <author>British Broadcasting Corporation</author>
108  <pubDate>Wed, 24 Mar 2010 18:35:41 GMT</pubDate>
109  <description>The series finale as the Doctor's arch enemy brings the universe to the edge of extinction (R)</description>
110  <link>http://www.bbc.co.uk/iplayer/episode/b00cgphl/Doctor_Who_Confidential_Series_4_The_End_of_an_Era/</link>
111  <media:group>
112  <media:thumbnail url="http://node1.bbcimg.co.uk/iplayer/images/episode/b00cgphl_120_68.jpg"/>
113  <media:content duration="" height="" lang=""
114  url="http://www.bbc.co.uk/iplayer/episode/b00cgphl/Doctor_Who_Confidential_Series_4_The_End_of_an_Era/" width=""/>
115  </media:group>
116  <rating>0.0</rating>
117  </item>
118  </channel>
119 </rss>
120 
121 > ./bbciplayer.py -T
122 <?xml version="1.0" encoding="UTF-8"?>
123 <rss version="2.0" xmlns:amp="http://www.adobe.com/amp/1.0"
124  xmlns:atom="http://www.w3.org/2005/Atom"
125  xmlns:cnettv="http://cnettv.com/mrss/"
126  xmlns:content="http://purl.org/rss/1.0/modules/content/"
127  xmlns:creativecommons="http://backend.userland.com/creativeCommonsRssModule"
128  xmlns:dc="http://purl.org/dc/elements/1.1/"
129  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/">
130  <channel>
131  <title>BBC iPlayer</title>
132  <link>http://www.bbc.co.uk</link>
133  <description>BBC iPlayer is our service that lets you catch up with radio and television programmes from the past week.</description>
134  <numresults>1</numresults>
135  <returned>1</returned>
136  <startindex>1</startindex>
137  <directory name="BBC iPlayer" thumbnail="/usr/local/share/mythtv/mythnetvision/icons/bbciplayer.png">
138  <directory name="BBC iPlayer - TV Highlights" thumbnail="/usr/local/share/mythtv/mythnetvision/icons/bbciplayer.png">
139  <item>
140  <title>Great Ormond Street: Pushing the Boundaries</title>
141  <author>BBC</author>
142  <pubDate>Wed, 07 Apr 2010 17:00:49 GMT</pubDate>
143  <description>A look at the work of the largest children&amp;apos;s cardiac unit in the UK.</description>
144  <link>http://localhost:8080/emml/cgi-bin/bbciplayer_embedded.py?videocode=b00s02ct</link>
145  <mrss:group xmlns:mrss="http://search.yahoo.com/mrss/">
146  <mrss:thumbnail url="http://node2.bbcimg.co.uk/iplayer/images/episode/b00s02ct_150_84.jpg"/>
147  <mrss:content duration="" height="" lang=""
148  url="http://localhost:8080/emml/cgi-bin/bbciplayer_embedded.py?videocode=b00s02ct" width=""/>
149  </mrss:group>
150  <rating>0.0</rating>
151  </item>
152 ...
153  <item>
154  <title>The Real Hustle: Series 7: On Holiday - Cutdowns: Episode 8</title>
155  <author>BBC</author>
156  <pubDate>Fri, 02 Apr 2010 07:29:46 GMT</pubDate>
157  <description>Paul relieves some unsuspecting tourists of their spending money in Oxford.</description>
158  <link>http://localhost:8080/emml/cgi-bin/bbciplayer_embedded.py?videocode=b00rw6xb</link>
159  <mrss:group xmlns:mrss="http://search.yahoo.com/mrss/">
160  <mrss:thumbnail url="http://node2.bbcimg.co.uk/iplayer/images/episode/b00rw6xb_150_84.jpg"/>
161  <mrss:content duration="" height="" lang=""
162  url="http://localhost:8080/emml/cgi-bin/bbciplayer_embedded.py?videocode=b00rw6xb" width=""/>
163  </mrss:group>
164  <rating>0.0</rating>
165  </item>
166  </directory>
167  </directory>
168  </channel>
169 </rss>
170 '''
171 __search_max_page_items__ = 20
172 __tree_max_page_items__ = 20
173 
174 import sys, os
175 import io
176 
177 
178 class OutStreamEncoder(object):
179  """Wraps a stream with an encoder"""
180  def __init__(self, outstream, encoding=None):
181  self.out = outstream
182  if not encoding:
183  self.encoding = sys.getfilesystemencoding()
184  else:
185  self.encoding = encoding
186 
187  def write(self, obj):
188  """Wraps the output stream, encoding Unicode strings with the specified encoding"""
189  if isinstance(obj, str):
190  obj = obj.encode(self.encoding)
191  self.out.buffer.write(obj)
192 
193  def __getattr__(self, attr):
194  """Delegate everything but write to the stream"""
195  return getattr(self.out, attr)
196 
197 if isinstance(sys.stdout, io.TextIOWrapper):
198  sys.stdout = OutStreamEncoder(sys.stdout, 'utf8')
199  sys.stderr = OutStreamEncoder(sys.stderr, 'utf8')
200 
201 
202 # Used for debugging
203 #import nv_python_libs.common.common_api
204 try:
205  '''Import the common python class
206  '''
207  import nv_python_libs.common.common_api as common_api
208 except Exception as e:
209  sys.stderr.write('''
210 The subdirectory "nv_python_libs/common" containing the modules common_api.py and
211 common_exceptions.py (v0.1.3 or greater),
212 They should have been included with the distribution of MythNetvision
213 Error(%s)
214 ''' % e)
215  sys.exit(1)
216 if common_api.__version__ < '0.1.3':
217  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__)
218  sys.exit(1)
219 
220 # Used for debugging
221 #import nv_python_libs.bbciplayer.bbciplayer_api as target
222 try:
223  '''Import the python bbciplayer support classes
224  '''
226 except Exception as e:
227  sys.stderr.write('''
228 The subdirectory "nv_python_libs/bbciplayer" containing the modules bbciplayer_api and
229 bbciplayer_exceptions.py (v0.1.0 or greater),
230 They should have been included with the distribution of bbciplayer.py.
231 Error(%s)
232 ''' % e)
233  sys.exit(1)
234 if target.__version__ < '0.1.0':
235  sys.stderr.write("\n! Error: Your current installed bbciplayer_api.py version is (%s)\nYou must at least have version (0.1.0) or higher.\n" % target.__version__)
236  sys.exit(1)
237 
238 # Verify that the main process modules are installed and accessible
239 try:
240  import nv_python_libs.mainProcess as process
241 except Exception as e:
242  sys.stderr.write('''
243 The python script "nv_python_libs/mainProcess.py" must be present.
244 Error(%s)
245 ''' % e)
246  sys.exit(1)
247 
248 if process.__version__ < '0.2.0':
249  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__)
250  sys.exit(1)
251 
252 if __name__ == '__main__':
253  # No api key is required
254  apikey = ""
255  # Set the base processing directory that the grabber is installed
256  target.baseProcessingDir = os.path.dirname( os.path.realpath( __file__ ))
257  # Make sure the target functions have an instance of the common routines
258  target.common = common_api.Common()
259  main = process.mainProcess(target, apikey, )
260  main.grabberInfo = {}
261  main.grabberInfo['enabled'] = True
262  main.grabberInfo['title'] = __title__
263  main.grabberInfo['mashup_title'] = __mashup_title__
264  main.grabberInfo['command'] = 'bbciplayer.py'
265  main.grabberInfo['author'] = __author__
266  main.grabberInfo['thumbnail'] = 'bbciplayer.png'
267  main.grabberInfo['type'] = ['video', ]
268  main.grabberInfo['desc'] = "BBC iPlayer is our service that lets you catch up with radio and television programmes from the past week."
269  main.grabberInfo['version'] = __version__
270  main.grabberInfo['search'] = True
271  main.grabberInfo['tree'] = True
272  main.grabberInfo['html'] = False
273  main.grabberInfo['usage'] = __usage_examples__
274  main.grabberInfo['SmaxPage'] = __search_max_page_items__
275  main.grabberInfo['TmaxPage'] = __tree_max_page_items__
276  main.main()
bbciplayer.OutStreamEncoder.__init__
def __init__(self, outstream, encoding=None)
Definition: bbciplayer.py:180
bbciplayer.OutStreamEncoder.out
out
Definition: bbciplayer.py:181
nv_python_libs.bbciplayer.bbciplayer_api
Definition: bbciplayer_api.py:1
nv_python_libs.mainProcess
Definition: mainProcess.py:1
bbciplayer.OutStreamEncoder
Definition: bbciplayer.py:178
nv_python_libs.common.common_api
Definition: common_api.py:1
bbciplayer.OutStreamEncoder.__getattr__
def __getattr__(self, attr)
Definition: bbciplayer.py:193
bbciplayer.OutStreamEncoder.write
def write(self, obj)
Definition: bbciplayer.py:187
bbciplayer.OutStreamEncoder.encoding
encoding
Definition: bbciplayer.py:183