Fixed lint violations
Browse files- pytube/__main__.py +10 -11
- pytube/cipher.py +10 -11
- pytube/contrib/playlist.py +6 -6
- pytube/mixins.py +9 -5
- pytube/request.py +6 -6
- pytube/streams.py +2 -1
- setup.cfg +2 -3
- tests/contrib/test_playlist.py +4 -3
- tests/test_streams.py +2 -1
pytube/__main__.py
CHANGED
@@ -119,17 +119,16 @@ class YouTube(object):
|
|
119 |
|
120 |
# Fix for KeyError: 'title' issue #434
|
121 |
if 'title' not in self.player_config_args:
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
self.player_config_args['title'] = title
|
133 |
|
134 |
self.vid_descr = extract.get_vid_descr(self.watch_html)
|
135 |
# https://github.com/nficano/pytube/issues/165
|
|
|
119 |
|
120 |
# Fix for KeyError: 'title' issue #434
|
121 |
if 'title' not in self.player_config_args:
|
122 |
+
i_start = (
|
123 |
+
self.watch_html
|
124 |
+
.lower()
|
125 |
+
.index('<title>') + len('<title>')
|
126 |
+
)
|
127 |
+
i_end = self.watch_html.lower().index('</title>')
|
128 |
+
title = self.watch_html[i_start:i_end].strip()
|
129 |
+
index = title.lower().rfind(' - youtube')
|
130 |
+
title = title[:index] if index > 0 else title
|
131 |
+
self.player_config_args['title'] = title
|
|
|
132 |
|
133 |
self.vid_descr = extract.get_vid_descr(self.watch_html)
|
134 |
# https://github.com/nficano/pytube/issues/165
|
pytube/cipher.py
CHANGED
@@ -36,21 +36,20 @@ def get_initial_function_name(js):
|
|
36 |
"""
|
37 |
# c&&d.set("signature", EE(c));
|
38 |
|
39 |
-
#403 Forbidden fix.
|
40 |
pattern = [
|
41 |
-
r'\b[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
42 |
-
r'\b[a-zA-Z0-9]+\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
43 |
-
r'(?P<sig>[a-zA-Z0-9$]+)\s*=\s*function\(\s*a\s*\)\s*{\s*a\s*=\s*a\.split\(\s*""\s*\)',
|
44 |
r'(["\'])signature\1\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
45 |
r'\.sig\|\|(?P<sig>[a-zA-Z0-9$]+)\(',
|
46 |
-
r'yt\.akamaized\.net/\)\s*\|\|\s*.*?\s*[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*(?:encodeURIComponent\s*\()?\s*(?P<si$',
|
47 |
-
r'\b[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
48 |
-
r'\b[a-zA-Z0-9]+\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
49 |
-
r'\bc\s*&&\s*a\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
50 |
-
r'\bc\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
51 |
-
r'\bc\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\('
|
52 |
]
|
53 |
-
|
54 |
logger.debug('finding initial function name')
|
55 |
return regex_search(pattern, js, group=1)
|
56 |
|
|
|
36 |
"""
|
37 |
# c&&d.set("signature", EE(c));
|
38 |
|
|
|
39 |
pattern = [
|
40 |
+
r'\b[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(', # noqa: E501
|
41 |
+
r'\b[a-zA-Z0-9]+\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*encodeURIComponent\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(', # noqa: E501
|
42 |
+
r'(?P<sig>[a-zA-Z0-9$]+)\s*=\s*function\(\s*a\s*\)\s*{\s*a\s*=\s*a\.split\(\s*""\s*\)', # noqa: E501
|
43 |
r'(["\'])signature\1\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(',
|
44 |
r'\.sig\|\|(?P<sig>[a-zA-Z0-9$]+)\(',
|
45 |
+
r'yt\.akamaized\.net/\)\s*\|\|\s*.*?\s*[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*(?:encodeURIComponent\s*\()?\s*(?P<si$', # noqa: E501
|
46 |
+
r'\b[cs]\s*&&\s*[adf]\.set\([^,]+\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(', # noqa: E501
|
47 |
+
r'\b[a-zA-Z0-9]+\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*(?P<sig>[a-zA-Z0-9$]+)\(', # noqa: E501
|
48 |
+
r'\bc\s*&&\s*a\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(', # noqa: E501
|
49 |
+
r'\bc\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(', # noqa: E501
|
50 |
+
r'\bc\s*&&\s*[a-zA-Z0-9]+\.set\([^,]+\s*,\s*\([^)]*\)\s*\(\s*(?P<sig>[a-zA-Z0-9$]+)\(', # noqa: E501
|
51 |
]
|
52 |
+
|
53 |
logger.debug('finding initial function name')
|
54 |
return regex_search(pattern, js, group=1)
|
55 |
|
pytube/contrib/playlist.py
CHANGED
@@ -180,13 +180,13 @@ class Playlist(object):
|
|
180 |
try:
|
181 |
url = self.construct_playlist_url()
|
182 |
req = request.get(url)
|
183 |
-
open_tag =
|
184 |
-
end_tag =
|
185 |
-
matchresult = re.compile(open_tag +
|
186 |
matchresult = matchresult.search(req).group()
|
187 |
-
matchresult = matchresult.replace(open_tag,
|
188 |
-
matchresult = matchresult.replace(end_tag,
|
189 |
-
matchresult = matchresult.replace(
|
190 |
matchresult = matchresult.strip()
|
191 |
|
192 |
return matchresult
|
|
|
180 |
try:
|
181 |
url = self.construct_playlist_url()
|
182 |
req = request.get(url)
|
183 |
+
open_tag = '<title>'
|
184 |
+
end_tag = '</title>'
|
185 |
+
matchresult = re.compile(open_tag + '(.+?)' + end_tag)
|
186 |
matchresult = matchresult.search(req).group()
|
187 |
+
matchresult = matchresult.replace(open_tag, '')
|
188 |
+
matchresult = matchresult.replace(end_tag, '')
|
189 |
+
matchresult = matchresult.replace('- YouTube', '')
|
190 |
matchresult = matchresult.strip()
|
191 |
|
192 |
return matchresult
|
pytube/mixins.py
CHANGED
@@ -37,10 +37,14 @@ def apply_signature(config_args, fmt, js):
|
|
37 |
url = stream['url']
|
38 |
elif live_stream:
|
39 |
raise LiveStreamError('Video is currently being streamed live')
|
40 |
-
#403 Forbidden fix.
|
41 |
-
if(
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
44 |
# For certain videos, YouTube will just provide them pre-signed, in
|
45 |
# which case there's no real magic to download them and we can skip
|
46 |
# the whole signature descrambling entirely.
|
@@ -63,7 +67,7 @@ def apply_signature(config_args, fmt, js):
|
|
63 |
}, indent=2,
|
64 |
),
|
65 |
)
|
66 |
-
#403 forbidden fix
|
67 |
stream_manifest[i]['url'] = url + '&sig=' + signature
|
68 |
|
69 |
|
|
|
37 |
url = stream['url']
|
38 |
elif live_stream:
|
39 |
raise LiveStreamError('Video is currently being streamed live')
|
40 |
+
# 403 Forbidden fix.
|
41 |
+
if (
|
42 |
+
'signature' in url or (
|
43 |
+
's' not in stream and (
|
44 |
+
'&sig=' in url or '&lsig=' in url
|
45 |
+
)
|
46 |
+
)
|
47 |
+
):
|
48 |
# For certain videos, YouTube will just provide them pre-signed, in
|
49 |
# which case there's no real magic to download them and we can skip
|
50 |
# the whole signature descrambling entirely.
|
|
|
67 |
}, indent=2,
|
68 |
),
|
69 |
)
|
70 |
+
# 403 forbidden fix
|
71 |
stream_manifest[i]['url'] = url + '&sig=' + signature
|
72 |
|
73 |
|
pytube/request.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""Implements a simple wrapper around urlopen."""
|
|
|
|
|
3 |
from pytube.compat import urlopen
|
|
|
4 |
|
5 |
-
#403 forbidden fix
|
6 |
-
import urllib.request
|
7 |
|
8 |
def get(
|
9 |
url=None, headers=False,
|
@@ -21,11 +22,10 @@ def get(
|
|
21 |
The size in bytes of each chunk.
|
22 |
"""
|
23 |
|
24 |
-
#
|
25 |
-
req = urllib.request.Request(url, headers
|
26 |
-
#response = urlopen(url)
|
27 |
response = urlopen(req)
|
28 |
-
|
29 |
if streaming:
|
30 |
return stream_response(response, chunk_size)
|
31 |
elif headers:
|
|
|
1 |
# -*- coding: utf-8 -*-
|
2 |
"""Implements a simple wrapper around urlopen."""
|
3 |
+
import urllib.request
|
4 |
+
|
5 |
from pytube.compat import urlopen
|
6 |
+
# 403 forbidden fix
|
7 |
|
|
|
|
|
8 |
|
9 |
def get(
|
10 |
url=None, headers=False,
|
|
|
22 |
The size in bytes of each chunk.
|
23 |
"""
|
24 |
|
25 |
+
# https://github.com/nficano/pytube/pull/465
|
26 |
+
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
|
|
|
27 |
response = urlopen(req)
|
28 |
+
|
29 |
if streaming:
|
30 |
return stream_response(response, chunk_size)
|
31 |
elif headers:
|
pytube/streams.py
CHANGED
@@ -179,7 +179,8 @@ class Stream(object):
|
|
179 |
return player_config_args['title']
|
180 |
|
181 |
details = self.player_config_args.get(
|
182 |
-
'player_response', {}
|
|
|
183 |
|
184 |
if 'title' in details:
|
185 |
return details['title']
|
|
|
179 |
return player_config_args['title']
|
180 |
|
181 |
details = self.player_config_args.get(
|
182 |
+
'player_response', {},
|
183 |
+
).get('videoDetails', {})
|
184 |
|
185 |
if 'title' in details:
|
186 |
return details['title']
|
setup.cfg
CHANGED
@@ -3,7 +3,7 @@ commit = True
|
|
3 |
tag = True
|
4 |
current_version = 9.5.2
|
5 |
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?
|
6 |
-
serialize =
|
7 |
{major}.{minor}.{patch}
|
8 |
|
9 |
[metadata]
|
@@ -15,9 +15,8 @@ description-file = README.md
|
|
15 |
|
16 |
[coverage:run]
|
17 |
source = pytube
|
18 |
-
omit =
|
19 |
pytube/compat.py
|
20 |
|
21 |
[flake8]
|
22 |
ignore = W605
|
23 |
-
|
|
|
3 |
tag = True
|
4 |
current_version = 9.5.2
|
5 |
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?
|
6 |
+
serialize =
|
7 |
{major}.{minor}.{patch}
|
8 |
|
9 |
[metadata]
|
|
|
15 |
|
16 |
[coverage:run]
|
17 |
source = pytube
|
18 |
+
omit =
|
19 |
pytube/compat.py
|
20 |
|
21 |
[flake8]
|
22 |
ignore = W605
|
|
tests/contrib/test_playlist.py
CHANGED
@@ -1,9 +1,10 @@
|
|
|
|
1 |
from pytube import Playlist
|
2 |
|
3 |
|
4 |
def test_title():
|
5 |
-
list_key =
|
6 |
-
url =
|
7 |
pl = Playlist(url)
|
8 |
pl_title = pl.title()
|
9 |
-
assert pl_title ==
|
|
|
1 |
+
# -*- coding: utf-8 -*-
|
2 |
from pytube import Playlist
|
3 |
|
4 |
|
5 |
def test_title():
|
6 |
+
list_key = 'PLsyeobzWxl7poL9JTVyndKe62ieoN-MZ3'
|
7 |
+
url = 'https://www.youtube.com/playlist?list=' + list_key
|
8 |
pl = Playlist(url)
|
9 |
pl_title = pl.title()
|
10 |
+
assert pl_title == 'Python Tutorial for Beginners'
|
tests/test_streams.py
CHANGED
@@ -26,7 +26,8 @@ def test_title(cipher_signature):
|
|
26 |
|
27 |
expected = 'PSY - GANGNAM STYLE(강남스타일)'
|
28 |
stream.player_config_args = {
|
29 |
-
'player_response': {'videoDetails': {'title': expected}}
|
|
|
30 |
assert stream.title == expected
|
31 |
|
32 |
expected = 'Unknown YouTube Video Title'
|
|
|
26 |
|
27 |
expected = 'PSY - GANGNAM STYLE(강남스타일)'
|
28 |
stream.player_config_args = {
|
29 |
+
'player_response': {'videoDetails': {'title': expected}},
|
30 |
+
}
|
31 |
assert stream.title == expected
|
32 |
|
33 |
expected = 'Unknown YouTube Video Title'
|