pep8, pyflakes, fixed typos, better comments.
Browse files- pytube/__init__.py +21 -14
- setup.py +4 -2
pytube/__init__.py
CHANGED
@@ -7,7 +7,8 @@ import re
|
|
7 |
|
8 |
YT_BASE_URL = 'http://www.youtube.com/get_video_info'
|
9 |
|
10 |
-
#
|
|
|
11 |
YT_ENCODING = {
|
12 |
#Flash Video
|
13 |
5: ["flv", "240p", "Sorenson H.263", "N/A", "0.25", "MP3", "64"],
|
@@ -40,6 +41,7 @@ YT_ENCODING = {
|
|
40 |
102: ["webm", "720p", "VP8", "3D", "N/A", "Vorbis", "192"]
|
41 |
}
|
42 |
|
|
|
43 |
YT_ENCODING_KEYS = (
|
44 |
'extension', 'resolution', 'video_codec', 'profile', 'video_bitrate',
|
45 |
'audio_codec', 'audio_bitrate'
|
@@ -47,11 +49,19 @@ YT_ENCODING_KEYS = (
|
|
47 |
|
48 |
|
49 |
class MultipleObjectsReturned(Exception):
|
|
|
|
|
|
|
50 |
pass
|
51 |
|
|
|
52 |
class YouTubeError(Exception):
|
|
|
|
|
|
|
53 |
pass
|
54 |
|
|
|
55 |
class Video(object):
|
56 |
"""
|
57 |
Class representation of a single instance of a YouTube video.
|
@@ -104,7 +114,7 @@ class Video(object):
|
|
104 |
def __repr__(self):
|
105 |
"""A cleaner representation of the class instance."""
|
106 |
return "<Video: %s (.%s) - %s>" % (self.video_codec, self.extension,
|
107 |
-
|
108 |
|
109 |
def __cmp__(self, other):
|
110 |
if type(other) == Video:
|
@@ -182,8 +192,9 @@ class YouTube(object):
|
|
182 |
elif len(result) is 1:
|
183 |
return result[0]
|
184 |
else:
|
185 |
-
|
186 |
-
|
|
|
187 |
|
188 |
def filter(self, extension=None, res=None):
|
189 |
"""
|
@@ -215,7 +226,7 @@ class YouTube(object):
|
|
215 |
data -- The data containing the tree.
|
216 |
"""
|
217 |
elem = path[0]
|
218 |
-
#Get first element in
|
219 |
if type(data) is list:
|
220 |
# Pop it, and let's continue..
|
221 |
return self._fetch(path, data.pop())
|
@@ -223,7 +234,7 @@ class YouTube(object):
|
|
223 |
data = parse_qs(data)
|
224 |
#Get the element in our path
|
225 |
data = data.get(elem, None)
|
226 |
-
#Offset the
|
227 |
path = path[1::1]
|
228 |
#Check if the path has reached the end OR the element return
|
229 |
#nothing.
|
@@ -241,12 +252,8 @@ class YouTube(object):
|
|
241 |
necessary details, and populating the different video
|
242 |
resolutions and formats into a list.
|
243 |
"""
|
244 |
-
querystring = urlencode({
|
245 |
-
|
246 |
-
'el': 'detailpage',
|
247 |
-
'hl': 'en_US',
|
248 |
-
'video_id': self.video_id
|
249 |
-
})
|
250 |
|
251 |
self.title = None
|
252 |
self.videos = []
|
@@ -279,7 +286,7 @@ class YouTube(object):
|
|
279 |
try:
|
280 |
fmt, data = self._extract_fmt(video)
|
281 |
filename = "%s.%s" % (self.filename, data['extension'])
|
282 |
-
except TypeError, KeyError:
|
283 |
pass
|
284 |
else:
|
285 |
v = Video(url, filename, **data)
|
@@ -341,7 +348,7 @@ def safe_filename(text, max_length=200):
|
|
341 |
#Removing these SHOULD make most filename safe for a wide range
|
342 |
#of operating systems.
|
343 |
paranoid = ['\"', '\#', '\$', '\%', '\'', '\*', '\,', '\.', '\/', '\:',
|
344 |
-
|
345 |
|
346 |
blacklist = re.compile('|'.join(ntfs + paranoid), re.UNICODE)
|
347 |
filename = blacklist.sub('', text)
|
|
|
7 |
|
8 |
YT_BASE_URL = 'http://www.youtube.com/get_video_info'
|
9 |
|
10 |
+
#YouTube quality and codecs id map.
|
11 |
+
#source: http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs
|
12 |
YT_ENCODING = {
|
13 |
#Flash Video
|
14 |
5: ["flv", "240p", "Sorenson H.263", "N/A", "0.25", "MP3", "64"],
|
|
|
41 |
102: ["webm", "720p", "VP8", "3D", "N/A", "Vorbis", "192"]
|
42 |
}
|
43 |
|
44 |
+
# The keys corresponding to the quality/codec map above.
|
45 |
YT_ENCODING_KEYS = (
|
46 |
'extension', 'resolution', 'video_codec', 'profile', 'video_bitrate',
|
47 |
'audio_codec', 'audio_bitrate'
|
|
|
49 |
|
50 |
|
51 |
class MultipleObjectsReturned(Exception):
|
52 |
+
"""
|
53 |
+
The query returned multiple objects when only one was expected.
|
54 |
+
"""
|
55 |
pass
|
56 |
|
57 |
+
|
58 |
class YouTubeError(Exception):
|
59 |
+
"""
|
60 |
+
The REST interface returned an error.
|
61 |
+
"""
|
62 |
pass
|
63 |
|
64 |
+
|
65 |
class Video(object):
|
66 |
"""
|
67 |
Class representation of a single instance of a YouTube video.
|
|
|
114 |
def __repr__(self):
|
115 |
"""A cleaner representation of the class instance."""
|
116 |
return "<Video: %s (.%s) - %s>" % (self.video_codec, self.extension,
|
117 |
+
self.resolution)
|
118 |
|
119 |
def __cmp__(self, other):
|
120 |
if type(other) == Video:
|
|
|
192 |
elif len(result) is 1:
|
193 |
return result[0]
|
194 |
else:
|
195 |
+
d = len(result)
|
196 |
+
raise MultipleObjectsReturned("get() returned more than one "
|
197 |
+
"object -- it returned %d!" % d)
|
198 |
|
199 |
def filter(self, extension=None, res=None):
|
200 |
"""
|
|
|
226 |
data -- The data containing the tree.
|
227 |
"""
|
228 |
elem = path[0]
|
229 |
+
#Get first element in tuple, and check if it contains a list.
|
230 |
if type(data) is list:
|
231 |
# Pop it, and let's continue..
|
232 |
return self._fetch(path, data.pop())
|
|
|
234 |
data = parse_qs(data)
|
235 |
#Get the element in our path
|
236 |
data = data.get(elem, None)
|
237 |
+
#Offset the tuple by 1.
|
238 |
path = path[1::1]
|
239 |
#Check if the path has reached the end OR the element return
|
240 |
#nothing.
|
|
|
252 |
necessary details, and populating the different video
|
253 |
resolutions and formats into a list.
|
254 |
"""
|
255 |
+
querystring = urlencode({'asv': 3, 'el': 'detailpage', 'hl': 'en_US',
|
256 |
+
'video_id': self.video_id})
|
|
|
|
|
|
|
|
|
257 |
|
258 |
self.title = None
|
259 |
self.videos = []
|
|
|
286 |
try:
|
287 |
fmt, data = self._extract_fmt(video)
|
288 |
filename = "%s.%s" % (self.filename, data['extension'])
|
289 |
+
except (TypeError, KeyError):
|
290 |
pass
|
291 |
else:
|
292 |
v = Video(url, filename, **data)
|
|
|
348 |
#Removing these SHOULD make most filename safe for a wide range
|
349 |
#of operating systems.
|
350 |
paranoid = ['\"', '\#', '\$', '\%', '\'', '\*', '\,', '\.', '\/', '\:',
|
351 |
+
'\;', '\<', '\>', '\?', '\\', '\^', '\|', '\~', '\\\\']
|
352 |
|
353 |
blacklist = re.compile('|'.join(ntfs + paranoid), re.UNICODE)
|
354 |
filename = blacklist.sub('', text)
|
setup.py
CHANGED
@@ -11,10 +11,10 @@ def read(fname):
|
|
11 |
|
12 |
setup(
|
13 |
name = "pytube",
|
14 |
-
version = "0.0.
|
15 |
author = "Nick Ficano",
|
16 |
author_email = "nficano@gmail.com",
|
17 |
-
description = "A
|
18 |
license='The MIT License: http://www.opensource.org/licenses/mit-license.php',
|
19 |
keywords = "youtube downloader",
|
20 |
url = "https://github.com/NFicano/python-youtube-download",
|
@@ -25,6 +25,8 @@ setup(
|
|
25 |
"Development Status :: 4 - Beta",
|
26 |
"Environment :: Console",
|
27 |
"Intended Audience :: Developers",
|
|
|
|
|
28 |
"License :: OSI Approved :: MIT License",
|
29 |
"Programming Language :: Python :: 2.6",
|
30 |
"Programming Language :: Python :: 2.7",
|
|
|
11 |
|
12 |
setup(
|
13 |
name = "pytube",
|
14 |
+
version = "0.0.5",
|
15 |
author = "Nick Ficano",
|
16 |
author_email = "nficano@gmail.com",
|
17 |
+
description = "A simple, yet versatile package for downloading YouTube videos.",
|
18 |
license='The MIT License: http://www.opensource.org/licenses/mit-license.php',
|
19 |
keywords = "youtube downloader",
|
20 |
url = "https://github.com/NFicano/python-youtube-download",
|
|
|
25 |
"Development Status :: 4 - Beta",
|
26 |
"Environment :: Console",
|
27 |
"Intended Audience :: Developers",
|
28 |
+
"Programming Language :: Python",
|
29 |
+
"Natural Language :: English",
|
30 |
"License :: OSI Approved :: MIT License",
|
31 |
"Programming Language :: Python :: 2.6",
|
32 |
"Programming Language :: Python :: 2.7",
|