aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/__init__.py0
-rw-r--r--test/helper.py66
-rw-r--r--test/parameters.json1
-rw-r--r--test/test_age_restriction.py55
-rw-r--r--test/test_all_urls.py89
-rw-r--r--test/test_dailymotion_subtitles.py70
-rw-r--r--test/test_download.py73
-rw-r--r--test/test_playlists.py89
-rw-r--r--test/test_utils.py54
-rw-r--r--test/test_write_annotations.py81
-rw-r--r--test/test_write_info_json.py32
-rw-r--r--test/test_youtube_lists.py30
-rwxr-xr-xtest/test_youtube_sig.py62
-rw-r--r--test/test_youtube_signature.py84
-rw-r--r--test/test_youtube_subtitles.py146
15 files changed, 665 insertions, 267 deletions
diff --git a/test/__init__.py b/test/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/test/__init__.py
diff --git a/test/helper.py b/test/helper.py
index a2b468b50..79a0ede48 100644
--- a/test/helper.py
+++ b/test/helper.py
@@ -1,38 +1,63 @@
+import errno
import io
+import hashlib
import json
import os.path
+import re
+import types
import youtube_dl.extractor
-from youtube_dl import YoutubeDL, YoutubeDLHandler
-from youtube_dl.utils import (
- compat_cookiejar,
- compat_urllib_request,
-)
-
-# General configuration (from __init__, not very elegant...)
-jar = compat_cookiejar.CookieJar()
-cookie_processor = compat_urllib_request.HTTPCookieProcessor(jar)
-proxy_handler = compat_urllib_request.ProxyHandler()
-opener = compat_urllib_request.build_opener(proxy_handler, cookie_processor, YoutubeDLHandler())
-compat_urllib_request.install_opener(opener)
-
-PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "parameters.json")
-with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
- parameters = json.load(pf)
+from youtube_dl import YoutubeDL
+
+
+def global_setup():
+ youtube_dl._setup_opener(timeout=10)
+
+
+def get_params(override=None):
+ PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+ "parameters.json")
+ with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
+ parameters = json.load(pf)
+ if override:
+ parameters.update(override)
+ return parameters
+
+
+def try_rm(filename):
+ """ Remove a file if it exists """
+ try:
+ os.remove(filename)
+ except OSError as ose:
+ if ose.errno != errno.ENOENT:
+ raise
+
class FakeYDL(YoutubeDL):
def __init__(self):
- self.result = []
# Different instances of the downloader can't share the same dictionary
# some test set the "sublang" parameter, which would break the md5 checks.
- self.params = dict(parameters)
- def to_screen(self, s):
+ params = get_params()
+ super(FakeYDL, self).__init__(params)
+ self.result = []
+
+ def to_screen(self, s, skip_eol=None):
print(s)
+
def trouble(self, s, tb=None):
raise Exception(s)
+
def download(self, x):
self.result.append(x)
+ def expect_warning(self, regex):
+ # Silence an expected warning matching a regex
+ old_report_warning = self.report_warning
+ def report_warning(self, message):
+ if re.match(regex, message): return
+ old_report_warning(message)
+ self.report_warning = types.MethodType(report_warning, self)
+
def get_testcases():
for ie in youtube_dl.extractor.gen_extractors():
t = getattr(ie, '_TEST', None)
@@ -42,3 +67,6 @@ def get_testcases():
for t in getattr(ie, '_TESTS', []):
t['name'] = type(ie).__name__[:-len('IE')]
yield t
+
+
+md5 = lambda s: hashlib.md5(s.encode('utf-8')).hexdigest()
diff --git a/test/parameters.json b/test/parameters.json
index 96998b5c3..f042880ed 100644
--- a/test/parameters.json
+++ b/test/parameters.json
@@ -38,7 +38,6 @@
"writedescription": false,
"writeinfojson": true,
"writesubtitles": false,
- "onlysubtitles": false,
"allsubtitles": false,
"listssubtitles": false
}
diff --git a/test/test_age_restriction.py b/test/test_age_restriction.py
new file mode 100644
index 000000000..d500c6edc
--- /dev/null
+++ b/test/test_age_restriction.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+# Allow direct execution
+import os
+import sys
+import unittest
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+from test.helper import global_setup, try_rm
+global_setup()
+
+
+from youtube_dl import YoutubeDL
+
+
+def _download_restricted(url, filename, age):
+ """ Returns true iff the file has been downloaded """
+
+ params = {
+ 'age_limit': age,
+ 'skip_download': True,
+ 'writeinfojson': True,
+ "outtmpl": "%(id)s.%(ext)s",
+ }
+ ydl = YoutubeDL(params)
+ ydl.add_default_info_extractors()
+ json_filename = filename + '.info.json'
+ try_rm(json_filename)
+ ydl.download([url])
+ res = os.path.exists(json_filename)
+ try_rm(json_filename)
+ return res
+
+
+class TestAgeRestriction(unittest.TestCase):
+ def _assert_restricted(self, url, filename, age, old_age=None):
+ self.assertTrue(_download_restricted(url, filename, old_age))
+ self.assertFalse(_download_restricted(url, filename, age))
+
+ def test_youtube(self):
+ self._assert_restricted('07FYdnEawAQ', '07FYdnEawAQ.mp4', 10)
+
+ def test_youporn(self):
+ self._assert_restricted(
+ 'http://www.youporn.com/watch/505835/sex-ed-is-it-safe-to-masturbate-daily/',
+ '505835.mp4', 2, old_age=25)
+
+ def test_pornotube(self):
+ self._assert_restricted(
+ 'http://pornotube.com/c/173/m/1689755/Marilyn-Monroe-Bathing',
+ '1689755.flv', 13)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/test_all_urls.py b/test/test_all_urls.py
index c73d0e467..56e5f80e1 100644
--- a/test/test_all_urls.py
+++ b/test/test_all_urls.py
@@ -1,34 +1,66 @@
#!/usr/bin/env python
+# Allow direct execution
+import os
import sys
import unittest
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-# Allow direct execution
-import os
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from youtube_dl.extractor import YoutubeIE, YoutubePlaylistIE, YoutubeChannelIE, JustinTVIE, gen_extractors
-from helper import get_testcases
+from test.helper import get_testcases
+
+from youtube_dl.extractor import (
+ gen_extractors,
+ JustinTVIE,
+ YoutubeIE,
+)
+
class TestAllURLsMatching(unittest.TestCase):
+ def setUp(self):
+ self.ies = gen_extractors()
+
+ def matching_ies(self, url):
+ return [ie.IE_NAME for ie in self.ies if ie.suitable(url) and ie.IE_NAME != 'generic']
+
+ def assertMatch(self, url, ie_list):
+ self.assertEqual(self.matching_ies(url), ie_list)
+
def test_youtube_playlist_matching(self):
- self.assertTrue(YoutubePlaylistIE.suitable(u'ECUl4u3cNGP61MdtwGTqZA0MreSaDybji8'))
- self.assertTrue(YoutubePlaylistIE.suitable(u'UUBABnxM4Ar9ten8Mdjj1j0Q')) #585
- self.assertTrue(YoutubePlaylistIE.suitable(u'PL63F0C78739B09958'))
- self.assertTrue(YoutubePlaylistIE.suitable(u'https://www.youtube.com/playlist?list=UUBABnxM4Ar9ten8Mdjj1j0Q'))
- self.assertTrue(YoutubePlaylistIE.suitable(u'https://www.youtube.com/course?list=ECUl4u3cNGP61MdtwGTqZA0MreSaDybji8'))
- self.assertTrue(YoutubePlaylistIE.suitable(u'https://www.youtube.com/playlist?list=PLwP_SiAcdui0KVebT0mU9Apz359a4ubsC'))
- self.assertTrue(YoutubePlaylistIE.suitable(u'https://www.youtube.com/watch?v=AV6J6_AeFEQ&playnext=1&list=PL4023E734DA416012')) #668
- self.assertFalse(YoutubePlaylistIE.suitable(u'PLtS2H6bU1M'))
+ assertPlaylist = lambda url: self.assertMatch(url, ['youtube:playlist'])
+ assertPlaylist(u'ECUl4u3cNGP61MdtwGTqZA0MreSaDybji8')
+ assertPlaylist(u'UUBABnxM4Ar9ten8Mdjj1j0Q') #585
+ assertPlaylist(u'PL63F0C78739B09958')
+ assertPlaylist(u'https://www.youtube.com/playlist?list=UUBABnxM4Ar9ten8Mdjj1j0Q')
+ assertPlaylist(u'https://www.youtube.com/course?list=ECUl4u3cNGP61MdtwGTqZA0MreSaDybji8')
+ assertPlaylist(u'https://www.youtube.com/playlist?list=PLwP_SiAcdui0KVebT0mU9Apz359a4ubsC')
+ assertPlaylist(u'https://www.youtube.com/watch?v=AV6J6_AeFEQ&playnext=1&list=PL4023E734DA416012') #668
+ self.assertFalse('youtube:playlist' in self.matching_ies(u'PLtS2H6bU1M'))
def test_youtube_matching(self):
self.assertTrue(YoutubeIE.suitable(u'PLtS2H6bU1M'))
self.assertFalse(YoutubeIE.suitable(u'https://www.youtube.com/watch?v=AV6J6_AeFEQ&playnext=1&list=PL4023E734DA416012')) #668
+ self.assertMatch('http://youtu.be/BaW_jenozKc', ['youtube'])
+ self.assertMatch('http://www.youtube.com/v/BaW_jenozKc', ['youtube'])
+ self.assertMatch('https://youtube.googleapis.com/v/BaW_jenozKc', ['youtube'])
def test_youtube_channel_matching(self):
- self.assertTrue(YoutubeChannelIE.suitable('https://www.youtube.com/channel/HCtnHdj3df7iM'))
- self.assertTrue(YoutubeChannelIE.suitable('https://www.youtube.com/channel/HCtnHdj3df7iM?feature=gb_ch_rec'))
- self.assertTrue(YoutubeChannelIE.suitable('https://www.youtube.com/channel/HCtnHdj3df7iM/videos'))
+ assertChannel = lambda url: self.assertMatch(url, ['youtube:channel'])
+ assertChannel('https://www.youtube.com/channel/HCtnHdj3df7iM')
+ assertChannel('https://www.youtube.com/channel/HCtnHdj3df7iM?feature=gb_ch_rec')
+ assertChannel('https://www.youtube.com/channel/HCtnHdj3df7iM/videos')
+
+ def test_youtube_user_matching(self):
+ self.assertMatch('www.youtube.com/NASAgovVideo/videos', ['youtube:user'])
+
+ def test_youtube_feeds(self):
+ self.assertMatch('https://www.youtube.com/feed/watch_later', ['youtube:watch_later'])
+ self.assertMatch('https://www.youtube.com/feed/subscriptions', ['youtube:subscriptions'])
+ self.assertMatch('https://www.youtube.com/feed/recommended', ['youtube:recommended'])
+ self.assertMatch('https://www.youtube.com/my_favorites', ['youtube:favorites'])
+
+ def test_youtube_show_matching(self):
+ self.assertMatch('http://www.youtube.com/show/airdisasters', ['youtube:show'])
def test_justin_tv_channelid_matching(self):
self.assertTrue(JustinTVIE.suitable(u"justin.tv/vanillatv"))
@@ -47,9 +79,13 @@ class TestAllURLsMatching(unittest.TestCase):
self.assertTrue(JustinTVIE.suitable(u"http://www.twitch.tv/tsm_theoddone/c/2349361"))
def test_youtube_extract(self):
- self.assertEqual(YoutubeIE()._extract_id('http://www.youtube.com/watch?&v=BaW_jenozKc'), 'BaW_jenozKc')
- self.assertEqual(YoutubeIE()._extract_id('https://www.youtube.com/watch?&v=BaW_jenozKc'), 'BaW_jenozKc')
- self.assertEqual(YoutubeIE()._extract_id('https://www.youtube.com/watch?feature=player_embedded&v=BaW_jenozKc'), 'BaW_jenozKc')
+ assertExtractId = lambda url, id: self.assertEqual(YoutubeIE()._extract_id(url), id)
+ assertExtractId('http://www.youtube.com/watch?&v=BaW_jenozKc', 'BaW_jenozKc')
+ assertExtractId('https://www.youtube.com/watch?&v=BaW_jenozKc', 'BaW_jenozKc')
+ assertExtractId('https://www.youtube.com/watch?feature=player_embedded&v=BaW_jenozKc', 'BaW_jenozKc')
+ assertExtractId('https://www.youtube.com/watch_popup?v=BaW_jenozKc', 'BaW_jenozKc')
+ assertExtractId('http://www.youtube.com/watch?v=BaW_jenozKcsharePLED17F32AD9753930', 'BaW_jenozKc')
+ assertExtractId('BaW_jenozKc', 'BaW_jenozKc')
def test_no_duplicates(self):
ies = gen_extractors()
@@ -62,15 +98,12 @@ class TestAllURLsMatching(unittest.TestCase):
self.assertFalse(ie.suitable(url), '%s should not match URL %r' % (type(ie).__name__, url))
def test_keywords(self):
- ies = gen_extractors()
- matching_ies = lambda url: [ie.IE_NAME for ie in ies
- if ie.suitable(url) and ie.IE_NAME != 'generic']
- self.assertEqual(matching_ies(':ytsubs'), ['youtube:subscriptions'])
- self.assertEqual(matching_ies(':ytsubscriptions'), ['youtube:subscriptions'])
- self.assertEqual(matching_ies(':thedailyshow'), ['ComedyCentral'])
- self.assertEqual(matching_ies(':tds'), ['ComedyCentral'])
- self.assertEqual(matching_ies(':colbertreport'), ['ComedyCentral'])
- self.assertEqual(matching_ies(':cr'), ['ComedyCentral'])
+ self.assertMatch(':ytsubs', ['youtube:subscriptions'])
+ self.assertMatch(':ytsubscriptions', ['youtube:subscriptions'])
+ self.assertMatch(':thedailyshow', ['ComedyCentral'])
+ self.assertMatch(':tds', ['ComedyCentral'])
+ self.assertMatch(':colbertreport', ['ComedyCentral'])
+ self.assertMatch(':cr', ['ComedyCentral'])
if __name__ == '__main__':
diff --git a/test/test_dailymotion_subtitles.py b/test/test_dailymotion_subtitles.py
new file mode 100644
index 000000000..c596415c4
--- /dev/null
+++ b/test/test_dailymotion_subtitles.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+# Allow direct execution
+import os
+import sys
+import unittest
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+from test.helper import FakeYDL, global_setup, md5
+global_setup()
+
+
+from youtube_dl.extractor import DailymotionIE
+
+class TestDailymotionSubtitles(unittest.TestCase):
+ def setUp(self):
+ self.DL = FakeYDL()
+ self.url = 'http://www.dailymotion.com/video/xczg00'
+ def getInfoDict(self):
+ IE = DailymotionIE(self.DL)
+ info_dict = IE.extract(self.url)
+ return info_dict
+ def getSubtitles(self):
+ info_dict = self.getInfoDict()
+ return info_dict[0]['subtitles']
+ def test_no_writesubtitles(self):
+ subtitles = self.getSubtitles()
+ self.assertEqual(subtitles, None)
+ def test_subtitles(self):
+ self.DL.params['writesubtitles'] = True
+ subtitles = self.getSubtitles()
+ self.assertEqual(md5(subtitles['en']), '976553874490cba125086bbfea3ff76f')
+ def test_subtitles_lang(self):
+ self.DL.params['writesubtitles'] = True
+ self.DL.params['subtitleslangs'] = ['fr']
+ subtitles = self.getSubtitles()
+ self.assertEqual(md5(subtitles['fr']), '594564ec7d588942e384e920e5341792')
+ def test_allsubtitles(self):
+ self.DL.params['writesubtitles'] = True
+ self.DL.params['allsubtitles'] = True
+ subtitles = self.getSubtitles()
+ self.assertEqual(len(subtitles.keys()), 5)
+ def test_list_subtitles(self):
+ self.DL.expect_warning(u'Automatic Captions not supported by this server')
+ self.DL.params['listsubtitles'] = True
+ info_dict = self.getInfoDict()
+ self.assertEqual(info_dict, None)
+ def test_automatic_captions(self):
+ self.DL.expect_warning(u'Automatic Captions not supported by this server')
+ self.DL.params['writeautomaticsub'] = True
+ self.DL.params['subtitleslang'] = ['en']
+ subtitles = self.getSubtitles()
+ self.assertTrue(len(subtitles.keys()) == 0)
+ def test_nosubtitles(self):
+ self.DL.expect_warning(u'video doesn\'t have subtitles')
+ self.url = 'http://www.dailymotion.com/video/x12u166_le-zapping-tele-star-du-08-aout-2013_tv'
+ self.DL.params['writesubtitles'] = True
+ self.DL.params['allsubtitles'] = True
+ subtitles = self.getSubtitles()
+ self.assertEqual(len(subtitles), 0)
+ def test_multiple_langs(self):
+ self.DL.params['writesubtitles'] = True
+ langs = ['es', 'fr', 'de']
+ self.DL.params['subtitleslangs'] = langs
+ subtitles = self.getSubtitles()
+ for lang in langs:
+ self.assertTrue(subtitles.get(lang) is not None, u'Subtitles for \'%s\' not extracted' % lang)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/test_download.py b/test/test_download.py
index 21cb2e694..b9a9be11d 100644
--- a/test/test_download.py
+++ b/test/test_download.py
@@ -1,43 +1,31 @@
#!/usr/bin/env python
-import errno
+# Allow direct execution
+import os
+import sys
+import unittest
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+from test.helper import get_params, get_testcases, global_setup, try_rm, md5
+global_setup()
+
+
import hashlib
import io
-import os
import json
-import unittest
-import sys
import socket
-import binascii
-
-# Allow direct execution
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import youtube_dl.YoutubeDL
-from youtube_dl.utils import *
-
-PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "parameters.json")
+from youtube_dl.utils import (
+ compat_str,
+ compat_urllib_error,
+ DownloadError,
+ ExtractorError,
+ UnavailableVideoError,
+)
RETRIES = 3
-# General configuration (from __init__, not very elegant...)
-jar = compat_cookiejar.CookieJar()
-cookie_processor = compat_urllib_request.HTTPCookieProcessor(jar)
-proxy_handler = compat_urllib_request.ProxyHandler()
-opener = compat_urllib_request.build_opener(proxy_handler, cookie_processor, YoutubeDLHandler())
-compat_urllib_request.install_opener(opener)
-socket.setdefaulttimeout(10)
-
-def _try_rm(filename):
- """ Remove a file if it exists """
- try:
- os.remove(filename)
- except OSError as ose:
- if ose.errno != errno.ENOENT:
- raise
-
-md5 = lambda s: hashlib.md5(s.encode('utf-8')).hexdigest()
-
class YoutubeDL(youtube_dl.YoutubeDL):
def __init__(self, *args, **kwargs):
self.to_stderr = self.to_screen
@@ -54,17 +42,12 @@ def _file_md5(fn):
with open(fn, 'rb') as f:
return hashlib.md5(f.read()).hexdigest()
-from helper import get_testcases
defs = get_testcases()
-with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
- parameters = json.load(pf)
-
class TestDownload(unittest.TestCase):
maxDiff = None
def setUp(self):
- self.parameters = parameters
self.defs = defs
### Dynamically generate tests
@@ -84,8 +67,7 @@ def generator(test_case):
print_skipping(test_case['skip'])
return
- params = self.parameters.copy()
- params.update(test_case.get('params', {}))
+ params = get_params(test_case.get('params', {}))
ydl = YoutubeDL(params)
ydl.add_default_info_extractors()
@@ -97,9 +79,9 @@ def generator(test_case):
test_cases = test_case.get('playlist', [test_case])
for tc in test_cases:
- _try_rm(tc['file'])
- _try_rm(tc['file'] + '.part')
- _try_rm(tc['file'] + '.info.json')
+ try_rm(tc['file'])
+ try_rm(tc['file'] + '.part')
+ try_rm(tc['file'] + '.info.json')
try:
for retry in range(1, RETRIES + 1):
try:
@@ -127,12 +109,11 @@ def generator(test_case):
info_dict = json.load(infof)
for (info_field, expected) in tc.get('info_dict', {}).items():
if isinstance(expected, compat_str) and expected.startswith('md5:'):
- self.assertEqual(expected, 'md5:' + md5(info_dict.get(info_field)))
+ got = 'md5:' + md5(info_dict.get(info_field))
else:
got = info_dict.get(info_field)
- self.assertEqual(
- expected, got,
- u'invalid value for field %s, expected %r, got %r' % (info_field, expected, got))
+ self.assertEqual(expected, got,
+ u'invalid value for field %s, expected %r, got %r' % (info_field, expected, got))
# If checkable fields are missing from the test case, print the info_dict
test_info_dict = dict((key, value if not isinstance(value, compat_str) or len(value) < 250 else 'md5:' + md5(value))
@@ -146,9 +127,9 @@ def generator(test_case):
self.assertTrue(key in info_dict.keys() and info_dict[key])
finally:
for tc in test_cases:
- _try_rm(tc['file'])
- _try_rm(tc['file'] + '.part')
- _try_rm(tc['file'] + '.info.json')
+ try_rm(tc['file'])
+ try_rm(tc['file'] + '.part')
+ try_rm(tc['file'] + '.info.json')
return test_template
diff --git a/test/test_playlists.py b/test/test_playlists.py
new file mode 100644
index 000000000..d6a8d56df
--- /dev/null
+++ b/test/test_playlists.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# encoding: utf-8
+
+
+# Allow direct execution
+import os
+import sys
+import unittest
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+from test.helper import FakeYDL, global_setup
+global_setup()
+
+
+from youtube_dl.extractor import (
+ DailymotionPlaylistIE,
+ DailymotionUserIE,
+ VimeoChannelIE,
+ UstreamChannelIE,
+ SoundcloudUserIE,
+ LivestreamIE,
+ NHLVideocenterIE,
+)
+
+
+class TestPlaylists(unittest.TestCase):
+ def assertIsPlaylist(self, info):
+ """Make sure the info has '_type' set to 'playlist'"""
+ self.assertEqual(info['_type'], 'playlist')
+
+ def test_dailymotion_playlist(self):
+ dl = FakeYDL()
+ ie = DailymotionPlaylistIE(dl)
+ result = ie.extract('http://www.dailymotion.com/playlist/xv4bw_nqtv_sport/1#video=xl8v3q')
+ self.assertIsPlaylist(result)
+ self.assertEqual(result['title'], u'SPORT')
+ self.assertTrue(len(result['entries']) > 20)
+
+ def test_dailymotion_user(self):
+ dl = FakeYDL()
+ ie = DailymotionUserIE(dl)
+ result = ie.extract('http://www.dailymotion.com/user/generation-quoi/')
+ self.assertIsPlaylist(result)
+ self.assertEqual(result['title'], u'Génération Quoi')
+ self.assertTrue(len(result['entries']) >= 26)
+
+ def test_vimeo_channel(self):
+ dl = FakeYDL()
+ ie = VimeoChannelIE(dl)
+ result = ie.extract('http://vimeo.com/channels/tributes')
+ self.assertIsPlaylist(result)
+ self.assertEqual(result['title'], u'Vimeo Tributes')
+ self.assertTrue(len(result['entries']) > 24)
+
+ def test_ustream_channel(self):
+ dl = FakeYDL()
+ ie = UstreamChannelIE(dl)
+ result = ie.extract('http://www.ustream.tv/channel/young-americans-for-liberty')
+ self.assertIsPlaylist(result)
+ self.assertEqual(result['id'], u'5124905')
+ self.assertTrue(len(result['entries']) >= 11)
+
+ def test_soundcloud_user(self):
+ dl = FakeYDL()
+ ie = SoundcloudUserIE(dl)
+ result = ie.extract('https://soundcloud.com/the-concept-band')
+ self.assertIsPlaylist(result)
+ self.assertEqual(result['id'], u'9615865')
+ self.assertTrue(len(result['entries']) >= 12)
+
+ def test_livestream_event(self):
+ dl = FakeYDL()
+ ie = LivestreamIE(dl)
+ result = ie.extract('http://new.livestream.com/tedx/cityenglish')
+ self.assertIsPlaylist(result)
+ self.assertEqual(result['title'], u'TEDCity2.0 (English)')
+ self.assertTrue(len(result['entries']) >= 4)
+
+ def test_nhl_videocenter(self):
+ dl = FakeYDL()
+ ie = NHLVideocenterIE(dl)
+ result = ie.extract('http://video.canucks.nhl.com/videocenter/console?catid=999')
+ self.assertIsPlaylist(result)
+ self.assertEqual(result['id'], u'999')
+ self.assertEqual(result['title'], u'Highlights')
+ self.assertEqual(len(result['entries']), 12)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/test_utils.py b/test/test_utils.py
index be1069105..270669044 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -1,23 +1,27 @@
#!/usr/bin/env python
-# Various small unit tests
-
+# Allow direct execution
+import os
import sys
import unittest
-import xml.etree.ElementTree
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-# Allow direct execution
-import os
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+# Various small unit tests
+import xml.etree.ElementTree
#from youtube_dl.utils import htmlentity_transform
-from youtube_dl.utils import timeconvert
-from youtube_dl.utils import sanitize_filename
-from youtube_dl.utils import unescapeHTML
-from youtube_dl.utils import orderedSet
-from youtube_dl.utils import DateRange
-from youtube_dl.utils import unified_strdate
-from youtube_dl.utils import find_xpath_attr
+from youtube_dl.utils import (
+ timeconvert,
+ sanitize_filename,
+ unescapeHTML,
+ orderedSet,
+ DateRange,
+ unified_strdate,
+ find_xpath_attr,
+ get_meta_content,
+ xpath_with_ns,
+)
if sys.version_info < (3, 0):
_compat_str = lambda b: b.decode('unicode-escape')
@@ -127,5 +131,29 @@ class TestUtil(unittest.TestCase):
self.assertEqual(find_xpath_attr(doc, './/node', 'x', 'a'), doc[1])
self.assertEqual(find_xpath_attr(doc, './/node', 'y', 'c'), doc[2])
+ def test_meta_parser(self):
+ testhtml = u'''
+ <head>
+ <meta name="description" content="foo &amp; bar">
+ <meta content='Plato' name='author'/>
+ </head>
+ '''
+ get_meta = lambda name: get_meta_content(name, testhtml)
+ self.assertEqual(get_meta('description'), u'foo & bar')
+ self.assertEqual(get_meta('author'), 'Plato')
+
+ def test_xpath_with_ns(self):
+ testxml = u'''<root xmlns:media="http://example.com/">
+ <media:song>
+ <media:author>The Author</media:author>
+ <url>http://server.com/download.mp3</url>
+ </media:song>
+ </root>'''
+ doc = xml.etree.ElementTree.fromstring(testxml)
+ find = lambda p: doc.find(xpath_with_ns(p, {'media': 'http://example.com/'}))
+ self.assertTrue(find('media:song') is not None)
+ self.assertEqual(find('media:song/media:author').text, u'The Author')
+ self.assertEqual(find('media:song/url').text, u'http://server.com/download.mp3')
+
if __name__ == '__main__':
unittest.main()
diff --git a/test/test_write_annotations.py b/test/test_write_annotations.py
new file mode 100644
index 000000000..6f08808cd
--- /dev/null
+++ b/test/test_write_annotations.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+# coding: utf-8
+
+# Allow direct execution
+import os
+import sys
+import unittest
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+from test.helper import get_params, global_setup, try_rm
+global_setup()
+
+
+import io
+
+import xml.etree.ElementTree
+
+import youtube_dl.YoutubeDL
+import youtube_dl.extractor
+from youtube_dl.utils import True
+
+
+class YoutubeDL(youtube_dl.YoutubeDL):
+ def __init__(self, *args, **kwargs):
+ super(YoutubeDL, self).__init__(*args, **kwargs)
+ self.to_stderr = self.to_screen
+
+params = get_params({
+ 'writeannotations': True,
+ 'skip_download': True,
+ 'writeinfojson': False,
+ 'format': 'flv',
+})
+
+
+
+TEST_ID = 'gr51aVj-mLg'
+ANNOTATIONS_FILE = TEST_ID + '.flv.annotations.xml'
+EXPECTED_ANNOTATIONS = ['Speech bubble', 'Note', 'Title', 'Spotlight', 'Label']
+
+class TestAnnotations(unittest.TestCase):
+ def setUp(self):
+ # Clear old files
+ self.tearDown()
+
+
+ def test_info_json(self):
+ expected = list(EXPECTED_ANNOTATIONS) #Two annotations could have the same text.
+ ie = youtube_dl.extractor.YoutubeIE()
+ ydl = YoutubeDL(params)
+ ydl.add_info_extractor(ie)
+ ydl.download([TEST_ID])
+ self.assertTrue(os.path.exists(ANNOTATIONS_FILE))
+ annoxml = None
+ with io.open(ANNOTATIONS_FILE, 'r', encoding='utf-8') as annof:
+ annoxml = xml.etree.ElementTree.parse(annof)
+ self.assertTrue(annoxml is not None, 'Failed to parse annotations XML')
+ root = annoxml.getroot()
+ self.assertEqual(root.tag, 'document')
+ annotationsTag = root.find('annotations')
+ self.assertEqual(annotationsTag.tag, 'annotations')
+ annotations = annotationsTag.findall('annotation')
+
+ #Not all the annotations have TEXT children and the annotations are returned unsorted.
+ for a in annotations:
+ self.assertEqual(a.tag, 'annotation')
+ if a.get('type') == 'text':
+ textTag = a.find('TEXT')
+ text = textTag.text
+ self.assertTrue(text in expected) #assertIn only added in python 2.7
+ #remove the first occurance, there could be more than one annotation with the same text
+ expected.remove(text)
+ #We should have seen (and removed) all the expected annotation texts.
+ self.assertEqual(len(expected), 0, 'Not all expected annotations were found.')
+
+
+ def tearDown(self):
+ try_rm(ANNOTATIONS_FILE)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/test_write_info_json.py b/test/test_write_info_json.py
index de6d5180f..a5b6f6972 100644
--- a/test/test_write_info_json.py
+++ b/test/test_write_info_json.py
@@ -1,37 +1,34 @@
#!/usr/bin/env python
# coding: utf-8
-import json
+# Allow direct execution
import os
import sys
import unittest
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-# Allow direct execution
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from test.helper import get_params, global_setup
+global_setup()
+
+
+import io
+import json
import youtube_dl.YoutubeDL
import youtube_dl.extractor
-from youtube_dl.utils import *
-
-PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "parameters.json")
-# General configuration (from __init__, not very elegant...)
-jar = compat_cookiejar.CookieJar()
-cookie_processor = compat_urllib_request.HTTPCookieProcessor(jar)
-proxy_handler = compat_urllib_request.ProxyHandler()
-opener = compat_urllib_request.build_opener(proxy_handler, cookie_processor, YoutubeDLHandler())
-compat_urllib_request.install_opener(opener)
class YoutubeDL(youtube_dl.YoutubeDL):
def __init__(self, *args, **kwargs):
super(YoutubeDL, self).__init__(*args, **kwargs)
self.to_stderr = self.to_screen
-with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
- params = json.load(pf)
-params['writeinfojson'] = True
-params['skip_download'] = True
-params['writedescription'] = True
+params = get_params({
+ 'writeinfojson': True,
+ 'skip_download': True,
+ 'writedescription': True,
+})
+
TEST_ID = 'BaW_jenozKc'
INFO_JSON_FILE = TEST_ID + '.mp4.info.json'
@@ -42,6 +39,7 @@ This is a test video for youtube-dl.
For more information, contact phihag@phihag.de .'''
+
class TestInfoJSON(unittest.TestCase):
def setUp(self):
# Clear old files
diff --git a/test/test_youtube_lists.py b/test/test_youtube_lists.py
index dd9e292b0..c1753b5bb 100644
--- a/test/test_youtube_lists.py
+++ b/test/test_youtube_lists.py
@@ -1,20 +1,26 @@
#!/usr/bin/env python
+# Allow direct execution
+import os
import sys
import unittest
-import json
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-# Allow direct execution
-import os
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from test.helper import FakeYDL, global_setup
+global_setup()
-from youtube_dl.extractor import YoutubeUserIE, YoutubePlaylistIE, YoutubeIE, YoutubeChannelIE, YoutubeShowIE
-from youtube_dl.utils import *
-from helper import FakeYDL
+from youtube_dl.extractor import (
+ YoutubeUserIE,
+ YoutubePlaylistIE,
+ YoutubeIE,
+ YoutubeChannelIE,
+ YoutubeShowIE,
+)
+
class TestYoutubeLists(unittest.TestCase):
- def assertIsPlaylist(self,info):
+ def assertIsPlaylist(self, info):
"""Make sure the info has '_type' set to 'playlist'"""
self.assertEqual(info['_type'], 'playlist')
@@ -27,6 +33,14 @@ class TestYoutubeLists(unittest.TestCase):
ytie_results = [YoutubeIE()._extract_id(url['url']) for url in result['entries']]
self.assertEqual(ytie_results, [ 'bV9L5Ht9LgY', 'FXxLjLQi3Fg', 'tU3Bgo5qJZE'])
+ def test_youtube_playlist_noplaylist(self):
+ dl = FakeYDL()
+ dl.params['noplaylist'] = True
+ ie = YoutubePlaylistIE(dl)
+ result = ie.extract('https://www.youtube.com/watch?v=FXxLjLQi3Fg&list=PLwiyx1dc3P2JR9N8gQaQN_BCvlSlap7re')
+ self.assertEqual(result['_type'], 'url')
+ self.assertEqual(YoutubeIE()._extract_id(result['url']), 'FXxLjLQi3Fg')
+
def test_issue_673(self):
dl = FakeYDL()
ie = YoutubePlaylistIE(dl)
diff --git a/test/test_youtube_sig.py b/test/test_youtube_sig.py
deleted file mode 100755
index bbeb3e2fb..000000000
--- a/test/test_youtube_sig.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-
-import unittest
-import sys
-
-# Allow direct execution
-import os
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-
-from youtube_dl.extractor.youtube import YoutubeIE
-from helper import FakeYDL
-
-sig = YoutubeIE(FakeYDL())._decrypt_signature
-
-class TestYoutubeSig(unittest.TestCase):
- def test_43_43(self):
- wrong = '5AEEAE0EC39677BC65FD9021CCD115F1F2DBD5A59E4.C0B243A3E2DED6769199AF3461781E75122AE135135'
- right = '931EA22157E1871643FA9519676DED253A342B0C.4E95A5DBD2F1F511DCC1209DF56CB77693CE0EAE'
- self.assertEqual(sig(wrong), right)
-
- def test_88(self):
- wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[]}|:;?/>.<"
- right = "J:|}][{=+-_)(*&;%$#@>MNBVCXZASDFGH^KLPOIUYTREWQ0987654321mnbvcxzasdfghrklpoiuytej"
- self.assertEqual(sig(wrong), right)
-
- def test_87(self):
- wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<"
- right = "!?;:|}][{=+-_)(*&^$#@/MNBVCXZASqFGHJKLPOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytr"
- self.assertEqual(sig(wrong), right)
-
- def test_86(self):
- wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<"
- right = "ertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!/#$%^&*()_-+={[|};?@"
- self.assertEqual(sig(wrong), right)
-
- def test_85(self):
- wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<"
- right = "{>/?;}[.=+-_)(*&^%$#@!MqBVCXZASDFwHJKLPOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytr"
- self.assertEqual(sig(wrong), right)
-
- def test_84(self):
- wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?>.<"
- right = "<.>?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWe098765432rmnbvcxzasdfghjklpoiuyt1"
- self.assertEqual(sig(wrong), right)
-
- def test_83(self):
- wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!#$%^&*()_+={[};?/>.<"
- right = "urty8ioplkjhgfdsazxcvbqm1234567S90QWERTYUIOPLKJHGFDnAZXCVBNM!#$%^&*()_+={[};?/>.<"
- self.assertEqual(sig(wrong), right)
-
- def test_82(self):
- wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKHGFDSAZXCVBNM!@#$%^&*(-+={[};?/>.<"
- right = "Q>/?;}[{=+-(*<^%$#@!MNBVCXZASDFGHKLPOIUY8REWT0q&7654321mnbvcxzasdfghjklpoiuytrew9"
- self.assertEqual(sig(wrong), right)
-
- def test_81(self):
- wrong = "qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKHGFDSAZXCVBNM!@#$%^&*(-+={[};?/>."
- right = "urty8ioplkjhgfdsazxcvbqm1234567e90QWERTYUIOPLKHGFDSnZXCVBNM!@#$%^&*(-+={[};?/>."
- self.assertEqual(sig(wrong), right)
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/test/test_youtube_signature.py b/test/test_youtube_signature.py
new file mode 100644
index 000000000..5e1ff5eb0
--- /dev/null
+++ b/test/test_youtube_signature.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+# Allow direct execution
+import os
+import sys
+import unittest
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+from test.helper import global_setup
+global_setup()
+
+
+import io
+import re
+import string
+
+from youtube_dl.extractor import YoutubeIE
+from youtube_dl.utils import compat_str, compat_urlretrieve
+
+_TESTS = [
+ (
+ u'https://s.ytimg.com/yts/jsbin/html5player-vflHOr_nV.js',
+ u'js',
+ 86,
+ u'>=<;:/.-[+*)(\'&%$#"!ZYX0VUTSRQPONMLKJIHGFEDCBA\\yxwvutsrqponmlkjihgfedcba987654321',
+ ),
+ (
+ u'https://s.ytimg.com/yts/jsbin/html5player-vfldJ8xgI.js',
+ u'js',
+ 85,
+ u'3456789a0cdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS[UVWXYZ!"#$%&\'()*+,-./:;<=>?@',
+ ),
+ (
+ u'https://s.ytimg.com/yts/swfbin/watch_as3-vflg5GhxU.swf',
+ u'swf',
+ 82,
+ u':/.-,+*)=\'&%$#"!ZYX0VUTSRQPONMLKJIHGFEDCBAzyxw>utsrqponmlkjihgfedcba987654321'
+ ),
+]
+
+
+class TestSignature(unittest.TestCase):
+ def setUp(self):
+ TEST_DIR = os.path.dirname(os.path.abspath(__file__))
+ self.TESTDATA_DIR = os.path.join(TEST_DIR, 'testdata')
+ if not os.path.exists(self.TESTDATA_DIR):
+ os.mkdir(self.TESTDATA_DIR)
+
+
+def make_tfunc(url, stype, sig_length, expected_sig):
+ basename = url.rpartition('/')[2]
+ m = re.match(r'.*-([a-zA-Z0-9_-]+)\.[a-z]+$', basename)
+ assert m, '%r should follow URL format' % basename
+ test_id = m.group(1)
+
+ def test_func(self):
+ fn = os.path.join(self.TESTDATA_DIR, basename)
+
+ if not os.path.exists(fn):
+ compat_urlretrieve(url, fn)
+
+ ie = YoutubeIE()
+ if stype == 'js':
+ with io.open(fn, encoding='utf-8') as testf:
+ jscode = testf.read()
+ func = ie._parse_sig_js(jscode)
+ else:
+ assert stype == 'swf'
+ with open(fn, 'rb') as testf:
+ swfcode = testf.read()
+ func = ie._parse_sig_swf(swfcode)
+ src_sig = compat_str(string.printable[:sig_length])
+ got_sig = func(src_sig)
+ self.assertEqual(got_sig, expected_sig)
+
+ test_func.__name__ = str('test_signature_' + stype + '_' + test_id)
+ setattr(TestSignature, test_func.__name__, test_func)
+
+for test_spec in _TESTS:
+ make_tfunc(*test_spec)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/test/test_youtube_subtitles.py b/test/test_youtube_subtitles.py
index 86e09c9b1..00430a338 100644
--- a/test/test_youtube_subtitles.py
+++ b/test/test_youtube_subtitles.py
@@ -1,95 +1,95 @@
#!/usr/bin/env python
+# Allow direct execution
+import os
import sys
import unittest
-import json
-import io
-import hashlib
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+from test.helper import FakeYDL, global_setup, md5
+global_setup()
-# Allow direct execution
-import os
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from youtube_dl.extractor import YoutubeIE
-from youtube_dl.utils import *
-from helper import FakeYDL
-md5 = lambda s: hashlib.md5(s.encode('utf-8')).hexdigest()
class TestYoutubeSubtitles(unittest.TestCase):
def setUp(self):
- DL = FakeYDL()
- DL.params['allsubtitles'] = False
- DL.params['writesubtitles'] = False
- DL.params['subtitlesformat'] = 'srt'
- DL.params['listsubtitles'] = False
- def test_youtube_no_subtitles(self):
- DL = FakeYDL()
- DL.params['writesubtitles'] = False
- IE = YoutubeIE(DL)
- info_dict = IE.extract('QRS8MkLhQmM')
- subtitles = info_dict[0]['subtitles']
+ self.DL = FakeYDL()
+ self.url = 'QRS8MkLhQmM'
+
+ def getInfoDict(self):
+ IE = YoutubeIE(self.DL)
+ info_dict = IE.extract(self.url)
+ return info_dict
+
+ def getSubtitles(self):
+ info_dict = self.getInfoDict()
+ return info_dict[0]['subtitles']
+
+ def test_youtube_no_writesubtitles(self):
+ self.DL.params['writesubtitles'] = False
+ subtitles = self.getSubtitles()
self.assertEqual(subtitles, None)
+
def test_youtube_subtitles(self):
- DL = FakeYDL()
- DL.params['writesubtitles'] = True
- IE = YoutubeIE(DL)
- info_dict = IE.extract('QRS8MkLhQmM')
- sub = info_dict[0]['subtitles'][0]
- self.assertEqual(md5(sub[2]), '4cd9278a35ba2305f47354ee13472260')
- def test_youtube_subtitles_it(self):
- DL = FakeYDL()
- DL.params['writesubtitles'] = True
- DL.params['subtitleslang'] = 'it'
- IE = YoutubeIE(DL)
- info_dict = IE.extract('QRS8MkLhQmM')
- sub = info_dict[0]['subtitles'][0]
- self.assertEqual(md5(sub[2]), '164a51f16f260476a05b50fe4c2f161d')
- def test_youtube_onlysubtitles(self):
- DL = FakeYDL()
- DL.params['writesubtitles'] = True
- DL.params['onlysubtitles'] = True
- IE = YoutubeIE(DL)
- info_dict = IE.extract('QRS8MkLhQmM')
- sub = info_dict[0]['subtitles'][0]
- self.assertEqual(md5(sub[2]), '4cd9278a35ba2305f47354ee13472260')
+ self.DL.params['writesubtitles'] = True
+ subtitles = self.getSubtitles()
+ self.assertEqual(md5(subtitles['en']), '4cd9278a35ba2305f47354ee13472260')
+
+ def test_youtube_subtitles_lang(self):
+ self.DL.params['writesubtitles'] = True
+ self.DL.params['subtitleslangs'] = ['it']
+ subtitles = self.getSubtitles()
+ self.assertEqual(md5(subtitles['it']), '164a51f16f260476a05b50fe4c2f161d')
+
def test_youtube_allsubtitles(self):
- DL = FakeYDL()
- DL.params['allsubtitles'] = True
- IE = YoutubeIE(DL)
- info_dict = IE.extract('QRS8MkLhQmM')
- subtitles = info_dict[0]['subtitles']
- self.assertEqual(len(subtitles), 13)
+ self.DL.params['writesubtitles'] = True
+ self.DL.params['allsubtitles'] = True
+ subtitles = self.getSubtitles()
+ self.assertEqual(len(subtitles.keys()), 13)
+
def test_youtube_subtitles_sbv_format(self):
- DL = FakeYDL()
- DL.params['writesubtitles'] = True
- DL.params['subtitlesformat'] = 'sbv'
- IE = YoutubeIE(DL)
- info_dict = IE.extract('QRS8MkLhQmM')
- sub = info_dict[0]['subtitles'][0]
- self.assertEqual(md5(sub[2]), '13aeaa0c245a8bed9a451cb643e3ad8b')
+ self.DL.params['writesubtitles'] = True
+ self.DL.params['subtitlesformat'] = 'sbv'
+ subtitles = self.getSubtitles()
+ self.assertEqual(md5(subtitles['en']), '13aeaa0c245a8bed9a451cb643e3ad8b')
+
def test_youtube_subtitles_vtt_format(self):
- DL = FakeYDL()
- DL.params['writesubtitles'] = True
- DL.params['subtitlesformat'] = 'vtt'
- IE = YoutubeIE(DL)
- info_dict = IE.extract('QRS8MkLhQmM')
- sub = info_dict[0]['subtitles'][0]
- self.assertEqual(md5(sub[2]), '356cdc577fde0c6783b9b822e7206ff7')
+ self.DL.params['writesubtitles'] = True
+ self.DL.params['subtitlesformat'] = 'vtt'
+ subtitles = self.getSubtitles()
+ self.assertEqual(md5(subtitles['en']), '356cdc577fde0c6783b9b822e7206ff7')
+
def test_youtube_list_subtitles(self):
- DL = FakeYDL()
- DL.params['listsubtitles'] = True
- IE = YoutubeIE(DL)
- info_dict = IE.extract('QRS8MkLhQmM')
+ self.DL.expect_warning(u'Video doesn\'t have automatic captions')
+ self.DL.params['listsubtitles'] = True
+ info_dict = self.getInfoDict()
self.assertEqual(info_dict, None)
+
def test_youtube_automatic_captions(self):
- DL = FakeYDL()
- DL.params['writeautomaticsub'] = True
- DL.params['subtitleslang'] = 'it'
- IE = YoutubeIE(DL)
- info_dict = IE.extract('8YoUxe5ncPo')
- sub = info_dict[0]['subtitles'][0]
- self.assertTrue(sub[2] is not None)
+ self.url = '8YoUxe5ncPo'
+ self.DL.params['writeautomaticsub'] = True
+ self.DL.params['subtitleslangs'] = ['it']
+ subtitles = self.getSubtitles()
+ self.assertTrue(subtitles['it'] is not None)
+
+ def test_youtube_nosubtitles(self):
+ self.DL.expect_warning(u'video doesn\'t have subtitles')
+ self.url = 'sAjKT8FhjI8'
+ self.DL.params['writesubtitles'] = True
+ self.DL.params['allsubtitles'] = True
+ subtitles = self.getSubtitles()
+ self.assertEqual(len(subtitles), 0)
+
+ def test_youtube_multiple_langs(self):
+ self.url = 'QRS8MkLhQmM'
+ self.DL.params['writesubtitles'] = True
+ langs = ['it', 'fr', 'de']
+ self.DL.params['subtitleslangs'] = langs
+ subtitles = self.getSubtitles()
+ for lang in langs:
+ self.assertTrue(subtitles.get(lang) is not None, u'Subtitles for \'%s\' not extracted' % lang)
if __name__ == '__main__':
unittest.main()