MythTV  master
hulu.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 # -*- coding: UTF-8 -*-
3 # ----------------------
4 # Name: hulu.py
5 # Python Script
6 # Author: R.D. Vaughan
7 # Purpose:
8 # This python script is intended to perform Hulu video lookups for the MythTV Netvision plugin
9 # based on information found on the http://www.hulu.com/ 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__ ="Hulu";
26 __mashup_title__ = "hulu"
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 > ./hulu.py -h
37 Usage: ./hulu.py -hduvlST [parameters] <search text>
38 Version: v0.1.1 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  -T, --treeview Display a Tree View of a sites videos
60 
61 > ./hulu.py -v
62 <grabber>
63  <name>Hulu</name>
64  <author>R.D.Vaughan</author>
65  <thumbnail>hulu.png</thumbnail>
66  <type>video</type>
67  <description>Hulu.com is a free online video service that offers hit TV shows including Family Guy, 30 Rock, and the Daily Show with Jon Stewart, etc.</description>
68  <version>v0.11</version>
69  <search>true</search>
70  <tree>true</tree>
71 </grabber>
72 
73 > ./hulu.py -S "Burn Notice"
74 <?xml version="1.0" encoding="UTF-8"?>
75 <rss version="2.0" xmlns:amp="http://www.adobe.com/amp/1.0"
76  xmlns:atom="http://www.w3.org/2005/Atom"
77  xmlns:cnettv="http://cnettv.com/mrss/"
78  xmlns:content="http://purl.org/rss/1.0/modules/content/"
79  xmlns:creativecommons="http://backend.userland.com/creativeCommonsRssModule"
80  xmlns:dc="http://purl.org/dc/elements/1.1/"
81  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/">
82  <channel>
83  <title>Hulu</title>
84  <link>http://hulu.com</link>
85  <description>Hulu.com is a free online video service that offers hit TV shows including Family Guy, 30 Rock, and the Daily Show with Jon Stewart, etc.</description>
86  <numresults>25</numresults>
87  <returned>21</returned>
88  <startindex>21</startindex>
89  <item>
90  <title>Burn Notice - A Dark Road</title>
91  <author>USA</author>
92  <pubDate>Mon, 25 Jan 2010 17:45:06 GMT</pubDate>
93  <description>Commentary with Matt Nix</description>
94  <link>http://www.hulu.com/watch/122855/burn-notice-a-dark-road#http%3A%2F%2Fwww.hulu.com%2Ffeed%2Fsearch%3Fquery%3DBurn%2BNotice%2Bdate%253Anewest%26sort_by%3Drelevance%26st%3D0</link>
95  <mrss:group xmlns:mrss="http://search.yahoo.com/mrss/">
96  <mrss:thumbnail url="http://thumbnails.hulu.com/231/50029231/140025_145x80_generated.jpg"/>
97  <mrss:content duration="05:19" height="" lang=""
98  url="http://www.hulu.com/watch/122855/burn-notice-a-dark-road#http%3A%2F%2Fwww.hulu.com%2Ffeed%2Fsearch%3Fquery%3DBurn%2BNotice%2Bdate%253Anewest%26sort_by%3Drelevance%26st%3D0" width=""/>
99  </mrss:group>
100  <rating>4.1</rating>
101  </item>
102 ...
103  <item>
104  <title>Burn Notice - s3 | e15 - Good Intentions</title>
105  <author>USA</author>
106  <pubDate>Sat, 27 Feb 2010 03:05:06 GMT</pubDate>
107  <description>Fiona seems to get more than she bargained for when she becomes involved with a paranoid kidnapper, only to discover that he's more than what he appears.</description>
108  <link>http://www.hulu.com/watch/131000/burn-notice-good-intentions#http%3A%2F%2Fwww.hulu.com%2Ffeed%2Fsearch%3Fquery%3DBurn%2BNotice%2Bdate%253Anewest%26sort_by%3Drelevance%26st%3D0</link>
109  <mrss:group xmlns:mrss="http://search.yahoo.com/mrss/">
110  <mrss:thumbnail url="http://thumbnails.hulu.com/183/50037183/148491_145x80_generated.jpg"/>
111  <mrss:content duration="43:32" height="" lang=""
112  url="http://www.hulu.com/watch/131000/burn-notice-good-intentions#http%3A%2F%2Fwww.hulu.com%2Ffeed%2Fsearch%3Fquery%3DBurn%2BNotice%2Bdate%253Anewest%26sort_by%3Drelevance%26st%3D0" width=""/>
113  </mrss:group>
114  <rating>4.5</rating>
115  </item>
116  </channel>
117 </rss>
118 
119 > ./hulu.py -T
120 <?xml version="1.0" encoding="UTF-8"?>
121 <rss version="2.0" xmlns:amp="http://www.adobe.com/amp/1.0"
122  xmlns:atom="http://www.w3.org/2005/Atom"
123  xmlns:cnettv="http://cnettv.com/mrss/"
124  xmlns:content="http://purl.org/rss/1.0/modules/content/"
125  xmlns:creativecommons="http://backend.userland.com/creativeCommonsRssModule"
126  xmlns:dc="http://purl.org/dc/elements/1.1/"
127  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:media="http://search.yahoo.com/mrss/">
128  <channel>
129  <title>Hulu</title>
130  <link>http://hulu.com</link>
131  <description>Hulu.com is a free online video service that offers hit TV shows including Family Guy, 30 Rock, and the Daily Show with Jon Stewart, etc.</description>
132  <numresults>1</numresults>
133  <returned>1</returned>
134  <startindex>1</startindex>
135  <directory name="Hulu" thumbnail="/usr/local/share/mythtv/mythnetvision/icons/hulu.png">
136  <directory name="Hulu - Recently added videos" thumbnail="/usr/local/share/mythtv/mythnetvision/icons/hulu.png">
137  <item>
138  <title>NBC TODAY Show - Mood Meds Pose ‘Weighty’ Issue</title>
139  <author>MSNBC</author>
140  <pubDate>Wed, 07 Apr 2010 14:54:05 GMT</pubDate>
141  <description>While battling depression, Lauren Slater faced a tough choice: She could take a prescription that would improve her mood, but it would make her gain weight. She discusses her experience with psychiatrist Dr. Catherine Birndorf and Dr. Nancy Snyderman.</description>
142  <link>http://rss.hulu.com/~r/HuluRecentlyAddedVideos/~3/ExUXTu_hOTo/nbc-today-show-mood-meds-pose-%E2%80%98weighty%E2%80%99-issue</link>
143  <mrss:group xmlns:mrss="http://search.yahoo.com/mrss/">
144  <mrss:thumbnail url="http://thumbnails.hulu.com/931/50046931/159024_145x80_generated.jpg"/>
145  <mrss:content duration="05:05" height="" lang=""
146  url="http://rss.hulu.com/~r/HuluRecentlyAddedVideos/~3/ExUXTu_hOTo/nbc-today-show-mood-meds-pose-%E2%80%98weighty%E2%80%99-issue" width=""/>
147  </mrss:group>
148  <rating>0.0</rating>
149  </item>
150 ...
151  <item>
152  <title>X-Play - Top 4 Open World Games of 2008</title>
153  <author>G4</author>
154  <pubDate>Thu, 10 Apr 2008 04:06:27 GMT</pubDate>
155  <description>X-Play brings you their list of the most anticipated sandbox games for this year.</description>
156  <link>http://www.hulu.com/watch/16729/x-play-top-4-open-world-games-of-2008#http%3A%2F%2Fwww.hulu.com%2Ffeed%2Fexpiring%2Fvideos</link>
157  <mrss:group xmlns:mrss="http://search.yahoo.com/mrss/">
158  <mrss:thumbnail url="http://thumbnails.hulu.com/7/827/18906_145x80_manicured__6DZDj36Oa0GlHMbezc3SfA.jpg"/>
159  <mrss:content duration="02:14" height="" lang=""
160  url="http://www.hulu.com/watch/16729/x-play-top-4-open-world-games-of-2008#http%3A%2F%2Fwww.hulu.com%2Ffeed%2Fexpiring%2Fvideos" width=""/>
161  </mrss:group>
162  <rating>4.1</rating>
163  </item>
164  </directory>
165  </directory>
166  </channel>
167 </rss>
168 '''
169 __search_max_page_items__ = 20
170 __tree_max_page_items__ = 20
171 
172 import sys, os
173 import io
174 
175 class OutStreamEncoder(object):
176  """Wraps a stream with an encoder"""
177  def __init__(self, outstream, encoding=None):
178  self.out = outstream
179  if not encoding:
180  self.encoding = sys.getfilesystemencoding()
181  else:
182  self.encoding = encoding
183 
184  def write(self, obj):
185  """Wraps the output stream, encoding Unicode strings with the specified encoding"""
186  if isinstance(obj, str):
187  obj = obj.encode(self.encoding)
188  self.out.buffer.write(obj)
189 
190  def __getattr__(self, attr):
191  """Delegate everything but write to the stream"""
192  return getattr(self.out, attr)
193 
194 if isinstance(sys.stdout, io.TextIOWrapper):
195  sys.stdout = OutStreamEncoder(sys.stdout, 'utf8')
196  sys.stderr = OutStreamEncoder(sys.stderr, 'utf8')
197 
198 
199 # Used for debugging
200 #import nv_python_libs.common.common_api
201 try:
202  '''Import the common python class
203  '''
204  import nv_python_libs.common.common_api as common_api
205 except Exception as e:
206  sys.stderr.write('''
207 The subdirectory "nv_python_libs/common" containing the modules common_api.py and
208 common_exceptions.py (v0.1.3 or greater),
209 They should have been included with the distribution of MythNetvision
210 Error(%s)
211 ''' % e)
212  sys.exit(1)
213 if common_api.__version__ < '0.1.3':
214  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__)
215  sys.exit(1)
216 
217 # Used for debugging
218 #import nv_python_libs.hulu.hulu_api as target
219 try:
220  '''Import the python hulu support classes
221  '''
222  import nv_python_libs.hulu.hulu_api as target
223 except Exception as e:
224  sys.stderr.write('''
225 The subdirectory "nv_python_libs/hulu" containing the modules hulu_api and
226 hulu_exceptions.py (v0.1.0 or greater),
227 They should have been included with the distribution of hulu.py.
228 Error(%s)
229 ''' % e)
230  sys.exit(1)
231 if target.__version__ < '0.1.0':
232  sys.stderr.write("\n! Error: Your current installed hulu_api.py version is (%s)\nYou must at least have version (0.1.0) or higher.\n" % target.__version__)
233  sys.exit(1)
234 
235 # Verify that the main process modules are installed and accessible
236 try:
237  import nv_python_libs.mainProcess as process
238 except Exception as e:
239  sys.stderr.write('''
240 The python script "nv_python_libs/mainProcess.py" must be present.
241 Error(%s)
242 ''' % e)
243  sys.exit(1)
244 
245 if process.__version__ < '0.2.0':
246  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__)
247  sys.exit(1)
248 
249 if __name__ == '__main__':
250  # No api key is required
251  apikey = ""
252  # Set the base processing directory that the grabber is installed
253  target.baseProcessingDir = os.path.dirname( os.path.realpath( __file__ ))
254  # Make sure the target functions have an instance of the common routines
255  target.common = common_api.Common()
256  main = process.mainProcess(target, apikey, )
257  main.grabberInfo = {}
258  main.grabberInfo['enabled'] = True
259  main.grabberInfo['title'] = __title__
260  main.grabberInfo['command'] = 'hulu.py'
261  main.grabberInfo['mashup_title'] = __mashup_title__
262  main.grabberInfo['author'] = __author__
263  main.grabberInfo['thumbnail'] = 'hulu.png'
264  main.grabberInfo['type'] = ['video', ]
265  main.grabberInfo['desc'] = "Hulu.com is a free online video service that offers hit TV shows including Family Guy, 30 Rock, and the Daily Show with Jon Stewart."
266  main.grabberInfo['version'] = __version__
267  main.grabberInfo['search'] = True
268  main.grabberInfo['tree'] = True
269  main.grabberInfo['html'] = False
270  main.grabberInfo['usage'] = __usage_examples__
271  main.grabberInfo['SmaxPage'] = __search_max_page_items__
272  main.grabberInfo['TmaxPage'] = __tree_max_page_items__
273  main.main()
hulu.OutStreamEncoder.write
def write(self, obj)
Definition: hulu.py:184
hulu.OutStreamEncoder
Definition: hulu.py:175
hulu.OutStreamEncoder.__getattr__
def __getattr__(self, attr)
Definition: hulu.py:190
hulu.OutStreamEncoder.encoding
encoding
Definition: hulu.py:180
hulu.OutStreamEncoder.out
out
Definition: hulu.py:178
nv_python_libs.hulu.hulu_api
Definition: hulu_api.py:1
nv_python_libs.mainProcess
Definition: mainProcess.py:1
nv_python_libs.common.common_api
Definition: common_api.py:1
hulu.OutStreamEncoder.__init__
def __init__(self, outstream, encoding=None)
Definition: hulu.py:177