Nick Ficano
commited on
Commit
·
b0c3c02
1
Parent(s):
6718818
updated docstrings + commented models.
Browse files- pytube/models.py +41 -29
pytube/models.py
CHANGED
@@ -15,49 +15,49 @@ class Video(object):
|
|
15 |
"""Class representation of a single instance of a YouTube video.
|
16 |
"""
|
17 |
def __init__(self, url, filename, **attributes):
|
18 |
-
"""
|
19 |
-
Define the variables required to declare a new video.
|
20 |
|
21 |
-
:param
|
22 |
-
The
|
23 |
-
:param
|
24 |
-
The broadcasting standard of the video.
|
25 |
-
:param url:
|
26 |
-
The url of the video. (e.g.: youtube.com/watch?v=...)
|
27 |
-
:param filename:
|
28 |
The filename (minus the extention) to save the video.
|
|
|
|
|
|
|
29 |
"""
|
30 |
-
|
31 |
self.url = url
|
32 |
self.filename = filename
|
|
|
33 |
self.__dict__.update(**attributes)
|
34 |
|
35 |
def download(self, path='', chunk_size=8 * 1024, on_progress=None,
|
36 |
on_finish=None, force_overwrite=False):
|
37 |
-
"""
|
38 |
-
Downloads the file of the URL defined within the class
|
39 |
instance.
|
40 |
|
41 |
-
:param path:
|
42 |
-
|
43 |
-
:param chunk_size:
|
44 |
File size (in bytes) to write to buffer at a time (default: 8
|
45 |
bytes).
|
46 |
-
:param on_progress:
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
|
|
|
|
52 |
"""
|
53 |
-
|
54 |
if isdir(normpath(path)):
|
55 |
path = (normpath(path) + '/' if path else '')
|
56 |
-
fullpath = '{
|
57 |
else:
|
58 |
fullpath = normpath(path)
|
59 |
|
60 |
-
#
|
|
|
61 |
if isfile(fullpath) and not force_overwrite:
|
62 |
raise OSError("Conflicting filename:'{}'".format(self.filename))
|
63 |
|
@@ -71,8 +71,12 @@ class Video(object):
|
|
71 |
with open(fullpath, 'wb') as dst_file:
|
72 |
while True:
|
73 |
self._buffer = response.read(chunk_size)
|
|
|
74 |
if not self._buffer:
|
75 |
if on_finish:
|
|
|
|
|
|
|
76 |
on_finish(fullpath)
|
77 |
break
|
78 |
|
@@ -81,7 +85,7 @@ class Video(object):
|
|
81 |
if on_progress:
|
82 |
on_progress(self._bytes_received, file_size, start)
|
83 |
|
84 |
-
# Catch possible exceptions occurring during download
|
85 |
except IOError:
|
86 |
raise IOError("Failed to open file.")
|
87 |
|
@@ -89,16 +93,24 @@ class Video(object):
|
|
89 |
raise BufferError("Failed to write video to file.")
|
90 |
|
91 |
except KeyboardInterrupt:
|
|
|
|
|
92 |
remove(fullpath)
|
93 |
-
raise KeyboardInterrupt(
|
94 |
-
|
95 |
|
96 |
def __repr__(self):
|
97 |
-
"""A
|
98 |
-
return "<Video: {
|
99 |
self.video_codec, self.extension, self.resolution, self.profile)
|
100 |
|
101 |
def __lt__(self, other):
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
if isinstance(other, Video):
|
103 |
v1 = "{0} {1}".format(self.extension, self.resolution)
|
104 |
v2 = "{0} {1}".format(other.extension, other.resolution)
|
|
|
15 |
"""Class representation of a single instance of a YouTube video.
|
16 |
"""
|
17 |
def __init__(self, url, filename, **attributes):
|
18 |
+
"""Sets-up the video object.
|
|
|
19 |
|
20 |
+
:param str url:
|
21 |
+
The url of the video. (e.g.: https://youtube.com/watch?v=...)
|
22 |
+
:param str filename:
|
|
|
|
|
|
|
|
|
23 |
The filename (minus the extention) to save the video.
|
24 |
+
:param **attributes:
|
25 |
+
Additional keyword arguments for additional quality profile
|
26 |
+
attribures.
|
27 |
"""
|
|
|
28 |
self.url = url
|
29 |
self.filename = filename
|
30 |
+
# TODO: this a bit hacky, rewrite to be explicit.
|
31 |
self.__dict__.update(**attributes)
|
32 |
|
33 |
def download(self, path='', chunk_size=8 * 1024, on_progress=None,
|
34 |
on_finish=None, force_overwrite=False):
|
35 |
+
"""Downloads the file of the URL defined within the class
|
|
|
36 |
instance.
|
37 |
|
38 |
+
:param str path:
|
39 |
+
The destination output directory.
|
40 |
+
:param int chunk_size:
|
41 |
File size (in bytes) to write to buffer at a time (default: 8
|
42 |
bytes).
|
43 |
+
:param func on_progress:
|
44 |
+
The function to be called every time the buffer is written
|
45 |
+
to. Arguments passed are the bytes recieved, file size, and start
|
46 |
+
datetime.
|
47 |
+
:param func on_finish:
|
48 |
+
The function to be called when the download is complete. Arguments
|
49 |
+
passed are the full path to downloaded the file.
|
50 |
+
:param bool force_overwrite:
|
51 |
+
Force a file overwrite if conflicting one exists.
|
52 |
"""
|
|
|
53 |
if isdir(normpath(path)):
|
54 |
path = (normpath(path) + '/' if path else '')
|
55 |
+
fullpath = '{}{}.{}'.format(path, self.filename, self.extension)
|
56 |
else:
|
57 |
fullpath = normpath(path)
|
58 |
|
59 |
+
# TODO: Move this into cli, this kind of logic probably shouldn't be
|
60 |
+
# handled by the library.
|
61 |
if isfile(fullpath) and not force_overwrite:
|
62 |
raise OSError("Conflicting filename:'{}'".format(self.filename))
|
63 |
|
|
|
71 |
with open(fullpath, 'wb') as dst_file:
|
72 |
while True:
|
73 |
self._buffer = response.read(chunk_size)
|
74 |
+
# If the buffer is empty (aka no bytes remaining).
|
75 |
if not self._buffer:
|
76 |
if on_finish:
|
77 |
+
# TODO: We possibly want to flush the
|
78 |
+
# `_bytes_recieved`` buffer before we call
|
79 |
+
# ``on_finish()``.
|
80 |
on_finish(fullpath)
|
81 |
break
|
82 |
|
|
|
85 |
if on_progress:
|
86 |
on_progress(self._bytes_received, file_size, start)
|
87 |
|
88 |
+
# Catch possible exceptions occurring during download.
|
89 |
except IOError:
|
90 |
raise IOError("Failed to open file.")
|
91 |
|
|
|
93 |
raise BufferError("Failed to write video to file.")
|
94 |
|
95 |
except KeyboardInterrupt:
|
96 |
+
# TODO: Move this into the cli, ``KeyboardInterrupt`` handling
|
97 |
+
# should be taken care of by the client.
|
98 |
remove(fullpath)
|
99 |
+
raise KeyboardInterrupt("Interrupt signal given. Deleting "
|
100 |
+
"incomplete video.")
|
101 |
|
102 |
def __repr__(self):
|
103 |
+
"""A clean representation of the class instance."""
|
104 |
+
return "<Video: {} (.{}) - {} - {}>".format(
|
105 |
self.video_codec, self.extension, self.resolution, self.profile)
|
106 |
|
107 |
def __lt__(self, other):
|
108 |
+
"""The "less than" (lt) method is used for comparing video object to
|
109 |
+
one another. This useful when sorting.
|
110 |
+
|
111 |
+
:param Video other:
|
112 |
+
The instance of the other video instance for comparison.
|
113 |
+
"""
|
114 |
if isinstance(other, Video):
|
115 |
v1 = "{0} {1}".format(self.extension, self.resolution)
|
116 |
v2 = "{0} {1}".format(other.extension, other.resolution)
|