more docs + tests
Browse files- docs/conf.py +2 -2
- pytube/__main__.py +1 -1
- pytube/compat.py +3 -1
- setup.py +2 -3
- tests/conftest.py +2 -0
- tests/test_main.py +12 -0
- tests/test_query.py +28 -3
docs/conf.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
#!/usr/bin/env python3
|
2 |
# -*- coding: utf-8 -*-
|
|
|
|
|
3 |
#
|
4 |
-
# pytube documentation build configuration file, created by
|
5 |
-
# sphinx-quickstart on Mon Oct 9 02:11:41 2017.
|
6 |
#
|
7 |
# This file is execfile()d with the current directory set to its
|
8 |
# containing dir.
|
|
|
1 |
#!/usr/bin/env python3
|
2 |
# -*- coding: utf-8 -*-
|
3 |
+
"""pytube documentation build configuration file."""
|
4 |
+
#
|
5 |
#
|
|
|
|
|
6 |
#
|
7 |
# This file is execfile()d with the current directory set to its
|
8 |
# containing dir.
|
pytube/__main__.py
CHANGED
@@ -74,7 +74,7 @@ class YouTube(object):
|
|
74 |
'on_complete': on_complete_callback,
|
75 |
}
|
76 |
|
77 |
-
if
|
78 |
self.prefetch_init()
|
79 |
|
80 |
def prefetch_init(self):
|
|
|
74 |
'on_complete': on_complete_callback,
|
75 |
}
|
76 |
|
77 |
+
if not defer_prefetch_init:
|
78 |
self.prefetch_init()
|
79 |
|
80 |
def prefetch_init(self):
|
pytube/compat.py
CHANGED
@@ -15,6 +15,7 @@ if python_version == 2:
|
|
15 |
from urlparse import parse_qsl
|
16 |
|
17 |
def unicode(s):
|
|
|
18 |
return s.encode('utf-8')
|
19 |
|
20 |
elif python_version == 3:
|
@@ -26,4 +27,5 @@ elif python_version == 3:
|
|
26 |
from urllib.request import urlopen
|
27 |
|
28 |
def unicode(s):
|
29 |
-
|
|
|
|
15 |
from urlparse import parse_qsl
|
16 |
|
17 |
def unicode(s):
|
18 |
+
"""Encode a string to utf-8."""
|
19 |
return s.encode('utf-8')
|
20 |
|
21 |
elif python_version == 3:
|
|
|
27 |
from urllib.request import urlopen
|
28 |
|
29 |
def unicode(s):
|
30 |
+
"""No-op."""
|
31 |
+
return s
|
setup.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1 |
#!/usr/bin/env python
|
2 |
# -*- coding: utf-8 -*-
|
|
|
3 |
try:
|
4 |
from setuptools import setup
|
5 |
except ImportError:
|
@@ -34,7 +35,6 @@ setup(
|
|
34 |
'Operating System :: Microsoft',
|
35 |
'Operating System :: POSIX',
|
36 |
'Operating System :: Unix',
|
37 |
-
'Programming Language :: Python :: 2.6',
|
38 |
'Programming Language :: Python :: 2.7',
|
39 |
'Programming Language :: Python :: 3.3',
|
40 |
'Programming Language :: Python :: 3.4',
|
@@ -47,8 +47,7 @@ setup(
|
|
47 |
'Topic :: Terminals',
|
48 |
'Topic :: Utilities',
|
49 |
],
|
50 |
-
description=('A
|
51 |
long_description=readme,
|
52 |
zip_safe=True,
|
53 |
-
|
54 |
)
|
|
|
1 |
#!/usr/bin/env python
|
2 |
# -*- coding: utf-8 -*-
|
3 |
+
"""This module contains setup instructions for pytube."""
|
4 |
try:
|
5 |
from setuptools import setup
|
6 |
except ImportError:
|
|
|
35 |
'Operating System :: Microsoft',
|
36 |
'Operating System :: POSIX',
|
37 |
'Operating System :: Unix',
|
|
|
38 |
'Programming Language :: Python :: 2.7',
|
39 |
'Programming Language :: Python :: 3.3',
|
40 |
'Programming Language :: Python :: 3.4',
|
|
|
47 |
'Topic :: Terminals',
|
48 |
'Topic :: Utilities',
|
49 |
],
|
50 |
+
description=('A pythonic library for downloading YouTube Videos.'),
|
51 |
long_description=readme,
|
52 |
zip_safe=True,
|
|
|
53 |
)
|
tests/conftest.py
CHANGED
@@ -12,6 +12,7 @@ from pytube import YouTube
|
|
12 |
|
13 |
|
14 |
def load_playback_file(filename):
|
|
|
15 |
cur_fp = os.path.realpath(__file__)
|
16 |
cur_dir = os.path.dirname(cur_fp)
|
17 |
fp = os.path.join(cur_dir, 'mocks', filename)
|
@@ -21,6 +22,7 @@ def load_playback_file(filename):
|
|
21 |
|
22 |
|
23 |
def load_and_init_from_playback_file(filename):
|
|
|
24 |
pb = load_playback_file(filename)
|
25 |
yt = YouTube(pb['url'], defer_prefetch_init=True)
|
26 |
yt.watch_html = pb['watch_html']
|
|
|
12 |
|
13 |
|
14 |
def load_playback_file(filename):
|
15 |
+
"""Load a gzip json playback file."""
|
16 |
cur_fp = os.path.realpath(__file__)
|
17 |
cur_dir = os.path.dirname(cur_fp)
|
18 |
fp = os.path.join(cur_dir, 'mocks', filename)
|
|
|
22 |
|
23 |
|
24 |
def load_and_init_from_playback_file(filename):
|
25 |
+
"""Load a gzip json playback file and create YouTube instance."""
|
26 |
pb = load_playback_file(filename)
|
27 |
yt = YouTube(pb['url'], defer_prefetch_init=True)
|
28 |
yt.watch_html = pb['watch_html']
|
tests/test_main.py
CHANGED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
+
import mock
|
3 |
+
|
4 |
+
from pytube import YouTube
|
5 |
+
|
6 |
+
|
7 |
+
@mock.patch('pytube.__main__.YouTube')
|
8 |
+
def test_prefetch_deferred(MockYouTube):
|
9 |
+
instance = MockYouTube.return_value
|
10 |
+
instance.prefetch_init.return_value = None
|
11 |
+
YouTube('https://www.youtube.com/watch?v=9bZkp7q19f0', True)
|
12 |
+
assert not instance.prefetch_init.called
|
tests/test_query.py
CHANGED
@@ -4,6 +4,7 @@ import pytest
|
|
4 |
|
5 |
|
6 |
def test_count(cipher_signature):
|
|
|
7 |
assert cipher_signature.streams.count() == 22
|
8 |
|
9 |
|
@@ -28,28 +29,43 @@ def test_count(cipher_signature):
|
|
28 |
],
|
29 |
)
|
30 |
def test_filters(test_input, expected, cipher_signature):
|
31 |
-
|
32 |
-
|
33 |
-
|
|
|
|
|
34 |
assert result == expected
|
35 |
|
36 |
|
37 |
@pytest.mark.parametrize('test_input', ['first', 'last'])
|
38 |
def test_empty(test_input, cipher_signature):
|
|
|
|
|
|
|
|
|
39 |
query = cipher_signature.streams.filter(video_codec='vp20')
|
40 |
fn = getattr(query, test_input)
|
41 |
assert fn() is None
|
42 |
|
43 |
|
44 |
def test_get_last(cipher_signature):
|
|
|
|
|
|
|
45 |
assert cipher_signature.streams.last().itag == '251'
|
46 |
|
47 |
|
48 |
def test_get_first(cipher_signature):
|
|
|
|
|
|
|
49 |
assert cipher_signature.streams.first().itag == '22'
|
50 |
|
51 |
|
52 |
def test_order_by(cipher_signature):
|
|
|
|
|
|
|
53 |
itags = [
|
54 |
s.itag for s in cipher_signature.streams
|
55 |
.filter(progressive=True)
|
@@ -61,6 +77,9 @@ def test_order_by(cipher_signature):
|
|
61 |
|
62 |
|
63 |
def test_order_by_descending(cipher_signature):
|
|
|
|
|
|
|
64 |
itags = [
|
65 |
s.itag for s in cipher_signature.streams
|
66 |
.filter(progressive=True)
|
@@ -73,6 +92,9 @@ def test_order_by_descending(cipher_signature):
|
|
73 |
|
74 |
|
75 |
def test_order_by_ascending(cipher_signature):
|
|
|
|
|
|
|
76 |
itags = [
|
77 |
s.itag for s in cipher_signature.streams
|
78 |
.filter(progressive=True)
|
@@ -85,6 +107,9 @@ def test_order_by_ascending(cipher_signature):
|
|
85 |
|
86 |
|
87 |
def test_get_by_itag(cipher_signature):
|
|
|
|
|
|
|
88 |
assert cipher_signature.streams.get_by_itag(22).itag == '22'
|
89 |
|
90 |
|
|
|
4 |
|
5 |
|
6 |
def test_count(cipher_signature):
|
7 |
+
"""Ensure :meth:`~pytube.StreamQuery.count` returns an accurate amount."""
|
8 |
assert cipher_signature.streams.count() == 22
|
9 |
|
10 |
|
|
|
29 |
],
|
30 |
)
|
31 |
def test_filters(test_input, expected, cipher_signature):
|
32 |
+
"""Ensure filters produce the expected results."""
|
33 |
+
result = [
|
34 |
+
s.itag for s
|
35 |
+
in cipher_signature.streams.filter(**test_input).all()
|
36 |
+
]
|
37 |
assert result == expected
|
38 |
|
39 |
|
40 |
@pytest.mark.parametrize('test_input', ['first', 'last'])
|
41 |
def test_empty(test_input, cipher_signature):
|
42 |
+
"""Ensure :meth:`~pytube.StreamQuery.last` and
|
43 |
+
:meth:`~pytube.StreamQuery.first` return ``None`` if the resultset is
|
44 |
+
empty.
|
45 |
+
"""
|
46 |
query = cipher_signature.streams.filter(video_codec='vp20')
|
47 |
fn = getattr(query, test_input)
|
48 |
assert fn() is None
|
49 |
|
50 |
|
51 |
def test_get_last(cipher_signature):
|
52 |
+
"""Ensure :meth:`~pytube.StreamQuery.last` returns the expected
|
53 |
+
:class:`Stream <Stream>`.
|
54 |
+
"""
|
55 |
assert cipher_signature.streams.last().itag == '251'
|
56 |
|
57 |
|
58 |
def test_get_first(cipher_signature):
|
59 |
+
"""Ensure :meth:`~pytube.StreamQuery.first` returns the expected
|
60 |
+
:class:`Stream <Stream>`.
|
61 |
+
"""
|
62 |
assert cipher_signature.streams.first().itag == '22'
|
63 |
|
64 |
|
65 |
def test_order_by(cipher_signature):
|
66 |
+
"""Ensure :meth:`~pytube.StreamQuery.order_by` sorts the list of
|
67 |
+
:class:`Stream <Stream>` instances in the expected order.
|
68 |
+
"""
|
69 |
itags = [
|
70 |
s.itag for s in cipher_signature.streams
|
71 |
.filter(progressive=True)
|
|
|
77 |
|
78 |
|
79 |
def test_order_by_descending(cipher_signature):
|
80 |
+
"""Ensure :meth:`~pytube.StreamQuery.desc` sorts the list of
|
81 |
+
:class:`Stream <Stream>` instances in the reverse order.
|
82 |
+
"""
|
83 |
itags = [
|
84 |
s.itag for s in cipher_signature.streams
|
85 |
.filter(progressive=True)
|
|
|
92 |
|
93 |
|
94 |
def test_order_by_ascending(cipher_signature):
|
95 |
+
"""Ensure :meth:`~pytube.StreamQuery.desc` sorts the list of
|
96 |
+
:class:`Stream <Stream>` instances in ascending order.
|
97 |
+
"""
|
98 |
itags = [
|
99 |
s.itag for s in cipher_signature.streams
|
100 |
.filter(progressive=True)
|
|
|
107 |
|
108 |
|
109 |
def test_get_by_itag(cipher_signature):
|
110 |
+
"""Ensure :meth:`~pytube.StreamQuery.get_by_itag` returns the expected
|
111 |
+
:class:`Stream <Stream>`.
|
112 |
+
"""
|
113 |
assert cipher_signature.streams.get_by_itag(22).itag == '22'
|
114 |
|
115 |
|