hbmartin commited on
Commit
134b939
·
1 Parent(s): 6470d75

add script to generate test mocks, re-enable tests that depend on it

Browse files
pytube/cipher.py CHANGED
@@ -1,6 +1,6 @@
1
  # -*- coding: utf-8 -*-
2
  """
3
- This module countains all logic necessary to decipher the signature.
4
 
5
  YouTube's strategy to restrict downloading videos is to send a ciphered version
6
  of the signature to the client, along with the decryption algorithm obfuscated
 
1
  # -*- coding: utf-8 -*-
2
  """
3
+ This module contains all logic necessary to decipher the signature.
4
 
5
  YouTube's strategy to restrict downloading videos is to send a ciphered version
6
  of the signature to the client, along with the decryption algorithm obfuscated
pytube/extract.py CHANGED
@@ -142,7 +142,7 @@ def js_url(html: str, age_restricted: bool = False) -> str:
142
  Construct the base JavaScript url, which contains the decipher
143
  "transforms".
144
 
145
- :param str watch_html:
146
  The html contents of the watch page.
147
  :param bool age_restricted:
148
  Is video age restricted.
 
142
  Construct the base JavaScript url, which contains the decipher
143
  "transforms".
144
 
145
+ :param str html:
146
  The html contents of the watch page.
147
  :param bool age_restricted:
148
  Is video age restricted.
tests/conftest.py CHANGED
@@ -34,14 +34,14 @@ def load_and_init_from_playback_file(filename):
34
  @pytest.fixture
35
  def cipher_signature():
36
  """Youtube instance initialized with video id 9bZkp7q19f0."""
37
- filename = 'yt-video-9bZkp7q19f0-1507588332.json.gz'
38
  return load_and_init_from_playback_file(filename)
39
 
40
 
41
  @pytest.fixture
42
  def presigned_video():
43
  """Youtube instance initialized with video id QRS8MkLhQmM."""
44
- filename = 'yt-video-QRS8MkLhQmM-1507588031.json.gz'
45
  return load_and_init_from_playback_file(filename)
46
 
47
 
 
34
  @pytest.fixture
35
  def cipher_signature():
36
  """Youtube instance initialized with video id 9bZkp7q19f0."""
37
+ filename = 'yt-video-9bZkp7q19f0.json.gz'
38
  return load_and_init_from_playback_file(filename)
39
 
40
 
41
  @pytest.fixture
42
  def presigned_video():
43
  """Youtube instance initialized with video id QRS8MkLhQmM."""
44
+ filename = 'yt-video-QRS8MkLhQmM.json.gz'
45
  return load_and_init_from_playback_file(filename)
46
 
47
 
tests/generate_fixture.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+
3
+ from os import path
4
+ import sys
5
+ import json
6
+
7
+ currentdir = path.dirname(path.realpath(__file__))
8
+ parentdir = path.dirname(currentdir)
9
+ sys.path.append(parentdir)
10
+
11
+ from pytube import YouTube
12
+
13
+ yt = YouTube(sys.argv[1], defer_prefetch_init=True)
14
+ yt.prefetch()
15
+ output = {
16
+ "url": sys.argv[1],
17
+ "watch_html": yt.watch_html,
18
+ "video_info": yt.vid_info,
19
+ "js": yt.js,
20
+ }
21
+
22
+ outpath = path.join(currentdir, "mocks", "yt-video-" + yt.video_id + ".json")
23
+ print("Writing to: " + outpath)
24
+ with open(outpath, "w") as f:
25
+ json.dump(output, f)
tests/mocks/yt-video-9bZkp7q19f0-1507588332.json.gz DELETED
Binary file (483 kB)
 
tests/mocks/yt-video-9bZkp7q19f0.json.gz ADDED
Binary file (475 kB). View file
 
tests/mocks/yt-video-QRS8MkLhQmM-1507588031.json.gz DELETED
Binary file (367 kB)
 
tests/mocks/yt-video-QRS8MkLhQmM.json.gz ADDED
Binary file (472 kB). View file
 
tests/test_extract.py CHANGED
@@ -1,6 +1,5 @@
1
  # -*- coding: utf-8 -*-
2
  """Unit tests for the :module:`extract <extract>` module."""
3
- import pytest
4
  from pytube import extract
5
 
6
 
@@ -16,7 +15,6 @@ def test_extract_watch_url():
16
  assert watch_url == 'https://youtube.com/watch?v=9bZkp7q19f0'
17
 
18
 
19
- @pytest.mark.skip(reason="Regex error")
20
  def test_info_url(cipher_signature):
21
  video_info_url = extract.video_info_url(
22
  video_id=cipher_signature.video_id,
@@ -33,7 +31,6 @@ def test_info_url(cipher_signature):
33
  assert video_info_url == expected
34
 
35
 
36
- @pytest.mark.skip(reason="Regex error")
37
  def test_js_url(cipher_signature):
38
  expected = 'https://youtube.com/yts/jsbin/player-vflOdyxa4/en_US/base.js'
39
  result = extract.js_url(cipher_signature.watch_html)
@@ -44,12 +41,10 @@ def test_age_restricted(age_restricted):
44
  assert extract.is_age_restricted(age_restricted['watch_html'])
45
 
46
 
47
- @pytest.mark.skip(reason="Regex error")
48
  def test_non_age_restricted(cipher_signature):
49
  assert not extract.is_age_restricted(cipher_signature.watch_html)
50
 
51
 
52
- @pytest.mark.skip(reason="Regex error")
53
  def test_get_vid_desc(cipher_signature):
54
- expected = "PSY - DADDY(feat. CL of 2NE1) M/V @ https://youtu.be/FrG4TEcSuRg\nPSY - 나팔바지(NAPAL BAJI) M/V @ https://youtu.be/tF27TNC_4pc\nPSY - 7TH ALBUM '칠집싸이다' on iTunes @ http://smarturl.it/PSY_7THALBUM\nPSY - GANGNAM STYLE(강남스타일) on iTunes @ http://smarturl.it/PsyGangnam\n#PSY #싸이 #GANGNAMSTYLE #강남스타일\nMore about PSY@\nhttp://www.psypark.com/\nhttp://www.youtube.com/officialpsy\nhttp://www.facebook.com/officialpsy\nhttp://twitter.com/psy_oppa\nhttps://www.instagram.com/42psy42\nhttp://iTunes.com/PSY\nhttp://sptfy.com/PSY\nhttp://weibo.com/psyoppa\nhttp://twitter.com/ygent_official" # noqa
55
  assert extract.get_vid_descr(cipher_signature.watch_html) == expected
 
1
  # -*- coding: utf-8 -*-
2
  """Unit tests for the :module:`extract <extract>` module."""
 
3
  from pytube import extract
4
 
5
 
 
15
  assert watch_url == 'https://youtube.com/watch?v=9bZkp7q19f0'
16
 
17
 
 
18
  def test_info_url(cipher_signature):
19
  video_info_url = extract.video_info_url(
20
  video_id=cipher_signature.video_id,
 
31
  assert video_info_url == expected
32
 
33
 
 
34
  def test_js_url(cipher_signature):
35
  expected = 'https://youtube.com/yts/jsbin/player-vflOdyxa4/en_US/base.js'
36
  result = extract.js_url(cipher_signature.watch_html)
 
41
  assert extract.is_age_restricted(age_restricted['watch_html'])
42
 
43
 
 
44
  def test_non_age_restricted(cipher_signature):
45
  assert not extract.is_age_restricted(cipher_signature.watch_html)
46
 
47
 
 
48
  def test_get_vid_desc(cipher_signature):
49
+ expected = "PSY - ‘I LUV IT’ M/V @ https://youtu.be/Xvjnoagk6GU\nPSY - ‘New Face’ M/V @https://youtu.be/OwJPPaEyqhI\nPSY - 8TH ALBUM '4X2=8' on iTunes @\nhttps://smarturl.it/PSY_8thAlbum\nPSY - GANGNAM STYLE(강남스타일) on iTunes @ http://smarturl.it/PsyGangnam\n#PSY #싸이 #GANGNAMSTYLE #강남스타일\nMore about PSY@\nhttp://www.youtube.com/officialpsy\nhttp://www.facebook.com/officialpsy\nhttp://twitter.com/psy_oppa\nhttps://www.instagram.com/42psy42\nhttp://iTunes.com/PSY\nhttp://sptfy.com/PSY\nhttp://weibo.com/psyoppa" # noqa
50
  assert extract.get_vid_descr(cipher_signature.watch_html) == expected
tests/test_streams.py CHANGED
@@ -2,27 +2,23 @@
2
  import random
3
 
4
  from unittest import mock
5
- import pytest
6
 
7
  from pytube import request
8
  from pytube import Stream
9
 
10
 
11
- @pytest.mark.skip(reason="Regex error")
12
  def test_filesize(cipher_signature, mocker):
13
  mocker.patch.object(request, 'get')
14
  request.get.return_value = {'content-length': '6796391'}
15
  assert cipher_signature.streams.first().filesize == 6796391
16
 
17
 
18
- @pytest.mark.skip(reason="Regex error")
19
  def test_default_filename(cipher_signature):
20
  expected = 'PSY - GANGNAM STYLE(강남스타일) MV.mp4'
21
  stream = cipher_signature.streams.first()
22
  assert stream.default_filename == expected
23
 
24
 
25
- @pytest.mark.skip(reason="Regex error")
26
  def test_title(cipher_signature):
27
  expected = 'PSY - GANGNAM STYLE(강남스타일) M/V'
28
  stream = cipher_signature.streams.first()
@@ -39,7 +35,6 @@ def test_title(cipher_signature):
39
  assert stream.title == expected
40
 
41
 
42
- @pytest.mark.skip(reason="Regex error")
43
  def test_download(cipher_signature, mocker):
44
  mocker.patch.object(request, 'get')
45
  request.get.side_effect = [
@@ -52,19 +47,16 @@ def test_download(cipher_signature, mocker):
52
  stream.download()
53
 
54
 
55
- @pytest.mark.skip(reason="Regex error")
56
  def test_progressive_streams_return_includes_audio_track(cipher_signature):
57
  stream = cipher_signature.streams.filter(progressive=True).first()
58
  assert stream.includes_audio_track
59
 
60
 
61
- @pytest.mark.skip(reason="Regex error")
62
  def test_progressive_streams_return_includes_video_track(cipher_signature):
63
  stream = cipher_signature.streams.filter(progressive=True).first()
64
  assert stream.includes_video_track
65
 
66
 
67
- @pytest.mark.skip(reason="Regex error")
68
  def test_on_progress_hook(cipher_signature, mocker):
69
  callback_fn = mock.MagicMock()
70
  cipher_signature.register_on_progress_callback(callback_fn)
@@ -85,7 +77,6 @@ def test_on_progress_hook(cipher_signature, mocker):
85
  assert isinstance(stream, Stream)
86
 
87
 
88
- @pytest.mark.skip(reason="Regex error")
89
  def test_on_complete_hook(cipher_signature, mocker):
90
  callback_fn = mock.MagicMock()
91
  cipher_signature.register_on_complete_callback(callback_fn)
@@ -102,7 +93,6 @@ def test_on_complete_hook(cipher_signature, mocker):
102
  assert callback_fn.called
103
 
104
 
105
- @pytest.mark.skip(reason="Regex error")
106
  def test_repr_for_audio_streams(cipher_signature):
107
  stream = str(cipher_signature.streams.filter(only_audio=True).first())
108
  expected = (
@@ -112,7 +102,6 @@ def test_repr_for_audio_streams(cipher_signature):
112
  assert stream == expected
113
 
114
 
115
- @pytest.mark.skip(reason="Regex error")
116
  def test_repr_for_video_streams(cipher_signature):
117
  stream = str(cipher_signature.streams.filter(only_video=True).first())
118
  expected = (
@@ -122,17 +111,15 @@ def test_repr_for_video_streams(cipher_signature):
122
  assert stream == expected
123
 
124
 
125
- @pytest.mark.skip(reason="Regex error")
126
  def test_repr_for_progressive_streams(cipher_signature):
127
  stream = str(cipher_signature.streams.filter(progressive=True).first())
128
  expected = (
129
- '<Stream: itag="22" mime_type="video/mp4" res="720p" '
130
- 'fps="30fps" vcodec="avc1.64001F" acodec="mp4a.40.2">'
131
  )
132
  assert stream == expected
133
 
134
 
135
- @pytest.mark.skip(reason="Regex error")
136
  def test_repr_for_adaptive_streams(cipher_signature):
137
  stream = str(cipher_signature.streams.filter(adaptive=True).first())
138
  expected = (
 
2
  import random
3
 
4
  from unittest import mock
 
5
 
6
  from pytube import request
7
  from pytube import Stream
8
 
9
 
 
10
  def test_filesize(cipher_signature, mocker):
11
  mocker.patch.object(request, 'get')
12
  request.get.return_value = {'content-length': '6796391'}
13
  assert cipher_signature.streams.first().filesize == 6796391
14
 
15
 
 
16
  def test_default_filename(cipher_signature):
17
  expected = 'PSY - GANGNAM STYLE(강남스타일) MV.mp4'
18
  stream = cipher_signature.streams.first()
19
  assert stream.default_filename == expected
20
 
21
 
 
22
  def test_title(cipher_signature):
23
  expected = 'PSY - GANGNAM STYLE(강남스타일) M/V'
24
  stream = cipher_signature.streams.first()
 
35
  assert stream.title == expected
36
 
37
 
 
38
  def test_download(cipher_signature, mocker):
39
  mocker.patch.object(request, 'get')
40
  request.get.side_effect = [
 
47
  stream.download()
48
 
49
 
 
50
  def test_progressive_streams_return_includes_audio_track(cipher_signature):
51
  stream = cipher_signature.streams.filter(progressive=True).first()
52
  assert stream.includes_audio_track
53
 
54
 
 
55
  def test_progressive_streams_return_includes_video_track(cipher_signature):
56
  stream = cipher_signature.streams.filter(progressive=True).first()
57
  assert stream.includes_video_track
58
 
59
 
 
60
  def test_on_progress_hook(cipher_signature, mocker):
61
  callback_fn = mock.MagicMock()
62
  cipher_signature.register_on_progress_callback(callback_fn)
 
77
  assert isinstance(stream, Stream)
78
 
79
 
 
80
  def test_on_complete_hook(cipher_signature, mocker):
81
  callback_fn = mock.MagicMock()
82
  cipher_signature.register_on_complete_callback(callback_fn)
 
93
  assert callback_fn.called
94
 
95
 
 
96
  def test_repr_for_audio_streams(cipher_signature):
97
  stream = str(cipher_signature.streams.filter(only_audio=True).first())
98
  expected = (
 
102
  assert stream == expected
103
 
104
 
 
105
  def test_repr_for_video_streams(cipher_signature):
106
  stream = str(cipher_signature.streams.filter(only_video=True).first())
107
  expected = (
 
111
  assert stream == expected
112
 
113
 
 
114
  def test_repr_for_progressive_streams(cipher_signature):
115
  stream = str(cipher_signature.streams.filter(progressive=True).first())
116
  expected = (
117
+ '<Stream: itag="18" mime_type="video/mp4" res="360p" '
118
+ 'fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2">'
119
  )
120
  assert stream == expected
121
 
122
 
 
123
  def test_repr_for_adaptive_streams(cipher_signature):
124
  stream = str(cipher_signature.streams.filter(adaptive=True).first())
125
  expected = (