mirror of https://github.com/yt-dlp/yt-dlp.git
[cleanup] Upgrade syntax
Using https://github.com/asottile/pyupgrade 1. `__future__` imports and `coding: utf-8` were removed 2. Files were rewritten with `pyupgrade --py36-plus --keep-percent-format` 3. f-strings were cherry-picked from `pyupgrade --py36-plus` Extractors are left untouched (except removing header) to avoid unnecessary merge conflicts
This commit is contained in:
parent
f9934b9614
commit
86e5f3ed2e
|
@ -178,7 +178,6 @@ After you have ensured this site is distributing its content legally, you can fo
|
|||
1. Start with this simple template and save it to `yt_dlp/extractor/yourextractor.py`:
|
||||
|
||||
```python
|
||||
# coding: utf-8
|
||||
from .common import InfoExtractor
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
from os.path import dirname as dirn
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, dirn(dirn((os.path.abspath(__file__)))))
|
||||
sys.path.insert(0, dirn(dirn(os.path.abspath(__file__))))
|
||||
import yt_dlp
|
||||
|
||||
BASH_COMPLETION_FILE = "completions/bash/yt-dlp"
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
"""
|
||||
This script employs a VERY basic heuristic ('porn' in webpage.lower()) to check
|
||||
if we are not 'age_limit' tagging some porn site
|
||||
|
@ -29,7 +27,7 @@ for test in gettestcases():
|
|||
try:
|
||||
webpage = compat_urllib_request.urlopen(test['url'], timeout=10).read()
|
||||
except Exception:
|
||||
print('\nFail: {0}'.format(test['name']))
|
||||
print('\nFail: {}'.format(test['name']))
|
||||
continue
|
||||
|
||||
webpage = webpage.decode('utf8', 'replace')
|
||||
|
@ -39,7 +37,7 @@ for test in gettestcases():
|
|||
elif METHOD == 'LIST':
|
||||
domain = compat_urllib_parse_urlparse(test['url']).netloc
|
||||
if not domain:
|
||||
print('\nFail: {0}'.format(test['name']))
|
||||
print('\nFail: {}'.format(test['name']))
|
||||
continue
|
||||
domain = '.'.join(domain.split('.')[-2:])
|
||||
|
||||
|
@ -47,11 +45,11 @@ for test in gettestcases():
|
|||
|
||||
if RESULT and ('info_dict' not in test or 'age_limit' not in test['info_dict']
|
||||
or test['info_dict']['age_limit'] != 18):
|
||||
print('\nPotential missing age_limit check: {0}'.format(test['name']))
|
||||
print('\nPotential missing age_limit check: {}'.format(test['name']))
|
||||
|
||||
elif not RESULT and ('info_dict' in test and 'age_limit' in test['info_dict']
|
||||
and test['info_dict']['age_limit'] == 18):
|
||||
print('\nPotential false negative: {0}'.format(test['name']))
|
||||
print('\nPotential false negative: {}'.format(test['name']))
|
||||
|
||||
else:
|
||||
sys.stdout.write('.')
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import optparse
|
||||
import os
|
||||
from os.path import dirname as dirn
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, dirn(dirn((os.path.abspath(__file__)))))
|
||||
sys.path.insert(0, dirn(dirn(os.path.abspath(__file__))))
|
||||
import yt_dlp
|
||||
from yt_dlp.utils import shell_quote
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import codecs
|
||||
import subprocess
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# coding: utf-8
|
||||
import re
|
||||
|
||||
from ..utils import bug_reports_message, write_string
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import optparse
|
||||
import re
|
||||
|
||||
|
@ -16,7 +13,7 @@ def main():
|
|||
|
||||
infile, outfile = args
|
||||
|
||||
with io.open(infile, encoding='utf-8') as inf:
|
||||
with open(infile, encoding='utf-8') as inf:
|
||||
readme = inf.read()
|
||||
|
||||
bug_text = re.search(
|
||||
|
@ -26,7 +23,7 @@ def main():
|
|||
|
||||
out = bug_text + dev_text
|
||||
|
||||
with io.open(outfile, 'w', encoding='utf-8') as outf:
|
||||
with open(outfile, 'w', encoding='utf-8') as outf:
|
||||
outf.write(out)
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import optparse
|
||||
|
||||
|
@ -13,7 +11,7 @@ def main():
|
|||
|
||||
infile, outfile = args
|
||||
|
||||
with io.open(infile, encoding='utf-8') as inf:
|
||||
with open(infile, encoding='utf-8') as inf:
|
||||
issue_template_tmpl = inf.read()
|
||||
|
||||
# Get the version from yt_dlp/version.py without importing the package
|
||||
|
@ -22,8 +20,9 @@ def main():
|
|||
|
||||
out = issue_template_tmpl % {'version': locals()['__version__']}
|
||||
|
||||
with io.open(outfile, 'w', encoding='utf-8') as outf:
|
||||
with open(outfile, 'w', encoding='utf-8') as outf:
|
||||
outf.write(out)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals, print_function
|
||||
|
||||
from inspect import getsource
|
||||
import io
|
||||
import os
|
||||
from os.path import dirname as dirn
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, dirn(dirn((os.path.abspath(__file__)))))
|
||||
sys.path.insert(0, dirn(dirn(os.path.abspath(__file__))))
|
||||
|
||||
lazy_extractors_filename = sys.argv[1] if len(sys.argv) > 1 else 'yt_dlp/extractor/lazy_extractors.py'
|
||||
if os.path.exists(lazy_extractors_filename):
|
||||
|
@ -25,7 +22,7 @@ from yt_dlp.extractor.common import InfoExtractor, SearchInfoExtractor
|
|||
if os.path.exists(plugins_blocked_dirname):
|
||||
os.rename(plugins_blocked_dirname, plugins_dirname)
|
||||
|
||||
with open('devscripts/lazy_load_template.py', 'rt') as f:
|
||||
with open('devscripts/lazy_load_template.py') as f:
|
||||
module_template = f.read()
|
||||
|
||||
CLASS_PROPERTIES = ['ie_key', 'working', '_match_valid_url', 'suitable', '_match_id', 'get_temp_id']
|
||||
|
@ -72,7 +69,7 @@ classes = _ALL_CLASSES[:-1]
|
|||
ordered_cls = []
|
||||
while classes:
|
||||
for c in classes[:]:
|
||||
bases = set(c.__bases__) - set((object, InfoExtractor, SearchInfoExtractor))
|
||||
bases = set(c.__bases__) - {object, InfoExtractor, SearchInfoExtractor}
|
||||
stop = False
|
||||
for b in bases:
|
||||
if b not in classes and b not in ordered_cls:
|
||||
|
@ -97,9 +94,9 @@ for ie in ordered_cls:
|
|||
names.append(name)
|
||||
|
||||
module_contents.append(
|
||||
'\n_ALL_CLASSES = [{0}]'.format(', '.join(names)))
|
||||
'\n_ALL_CLASSES = [{}]'.format(', '.join(names)))
|
||||
|
||||
module_src = '\n'.join(module_contents) + '\n'
|
||||
|
||||
with io.open(lazy_extractors_filename, 'wt', encoding='utf-8') as f:
|
||||
with open(lazy_extractors_filename, 'wt', encoding='utf-8') as f:
|
||||
f.write(module_src)
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
# yt-dlp --help | make_readme.py
|
||||
# This must be run in a console of correct width
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
@ -15,7 +11,7 @@ helptext = sys.stdin.read()
|
|||
if isinstance(helptext, bytes):
|
||||
helptext = helptext.decode('utf-8')
|
||||
|
||||
with io.open(README_FILE, encoding='utf-8') as f:
|
||||
with open(README_FILE, encoding='utf-8') as f:
|
||||
oldreadme = f.read()
|
||||
|
||||
header = oldreadme[:oldreadme.index('## General Options:')]
|
||||
|
@ -25,7 +21,7 @@ options = helptext[helptext.index(' General Options:'):]
|
|||
options = re.sub(r'(?m)^ (\w.+)$', r'## \1', options)
|
||||
options = options + '\n'
|
||||
|
||||
with io.open(README_FILE, 'w', encoding='utf-8') as f:
|
||||
with open(README_FILE, 'w', encoding='utf-8') as f:
|
||||
f.write(header)
|
||||
f.write(options)
|
||||
f.write(footer)
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
|
@ -23,11 +20,11 @@ def main():
|
|||
|
||||
def gen_ies_md(ies):
|
||||
for ie in ies:
|
||||
ie_md = '**{0}**'.format(ie.IE_NAME)
|
||||
ie_md = f'**{ie.IE_NAME}**'
|
||||
if ie.IE_DESC is False:
|
||||
continue
|
||||
if ie.IE_DESC is not None:
|
||||
ie_md += ': {0}'.format(ie.IE_DESC)
|
||||
ie_md += f': {ie.IE_DESC}'
|
||||
search_key = getattr(ie, 'SEARCH_KEY', None)
|
||||
if search_key is not None:
|
||||
ie_md += f'; "{ie.SEARCH_KEY}:" prefix'
|
||||
|
@ -40,7 +37,7 @@ def main():
|
|||
' - ' + md + '\n'
|
||||
for md in gen_ies_md(ies))
|
||||
|
||||
with io.open(outfile, 'w', encoding='utf-8') as outf:
|
||||
with open(outfile, 'w', encoding='utf-8') as outf:
|
||||
outf.write(out)
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import optparse
|
||||
import os.path
|
||||
import re
|
||||
|
@ -32,14 +29,14 @@ def main():
|
|||
|
||||
outfile, = args
|
||||
|
||||
with io.open(README_FILE, encoding='utf-8') as f:
|
||||
with open(README_FILE, encoding='utf-8') as f:
|
||||
readme = f.read()
|
||||
|
||||
readme = filter_excluded_sections(readme)
|
||||
readme = move_sections(readme)
|
||||
readme = filter_options(readme)
|
||||
|
||||
with io.open(outfile, 'w', encoding='utf-8') as outf:
|
||||
with open(outfile, 'w', encoding='utf-8') as outf:
|
||||
outf.write(PREFIX + readme)
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
@ -27,7 +25,7 @@ tarball_file = next(x for x in pypi_release['urls'] if x['filename'].endswith('.
|
|||
sha256sum = tarball_file['digests']['sha256']
|
||||
url = tarball_file['url']
|
||||
|
||||
with open(filename, 'r') as r:
|
||||
with open(filename) as r:
|
||||
formulae_text = r.read()
|
||||
|
||||
formulae_text = re.sub(r'sha256 "[0-9a-f]*?"', 'sha256 "%s"' % sha256sum, formulae_text)
|
||||
|
|
|
@ -4,7 +4,7 @@ import sys
|
|||
import subprocess
|
||||
|
||||
|
||||
with open('yt_dlp/version.py', 'rt') as f:
|
||||
with open('yt_dlp/version.py') as f:
|
||||
exec(compile(f.read(), 'yt_dlp/version.py', 'exec'))
|
||||
old_version = locals()['__version__']
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
from os.path import dirname as dirn
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, dirn(dirn((os.path.abspath(__file__)))))
|
||||
sys.path.insert(0, dirn(dirn(os.path.abspath(__file__))))
|
||||
import yt_dlp
|
||||
|
||||
ZSH_COMPLETION_FILE = "completions/zsh/_yt-dlp"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
|
|
1
setup.py
1
setup.py
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
import os.path
|
||||
import warnings
|
||||
import sys
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import errno
|
||||
import io
|
||||
import hashlib
|
||||
import json
|
||||
import os.path
|
||||
|
@ -35,10 +32,10 @@ def get_params(override=None):
|
|||
'parameters.json')
|
||||
LOCAL_PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'local_parameters.json')
|
||||
with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
|
||||
with open(PARAMETERS_FILE, encoding='utf-8') as pf:
|
||||
parameters = json.load(pf)
|
||||
if os.path.exists(LOCAL_PARAMETERS_FILE):
|
||||
with io.open(LOCAL_PARAMETERS_FILE, encoding='utf-8') as pf:
|
||||
with open(LOCAL_PARAMETERS_FILE, encoding='utf-8') as pf:
|
||||
parameters.update(json.load(pf))
|
||||
if override:
|
||||
parameters.update(override)
|
||||
|
@ -63,7 +60,7 @@ def report_warning(message):
|
|||
_msg_header = '\033[0;33mWARNING:\033[0m'
|
||||
else:
|
||||
_msg_header = 'WARNING:'
|
||||
output = '%s %s\n' % (_msg_header, message)
|
||||
output = f'{_msg_header} {message}\n'
|
||||
if 'b' in getattr(sys.stderr, 'mode', ''):
|
||||
output = output.encode(preferredencoding())
|
||||
sys.stderr.write(output)
|
||||
|
@ -74,7 +71,7 @@ class FakeYDL(YoutubeDL):
|
|||
# Different instances of the downloader can't share the same dictionary
|
||||
# some test set the "sublang" parameter, which would break the md5 checks.
|
||||
params = get_params(override=override)
|
||||
super(FakeYDL, self).__init__(params, auto_init=False)
|
||||
super().__init__(params, auto_init=False)
|
||||
self.result = []
|
||||
|
||||
def to_screen(self, s, skip_eol=None):
|
||||
|
@ -99,8 +96,7 @@ class FakeYDL(YoutubeDL):
|
|||
|
||||
def gettestcases(include_onlymatching=False):
|
||||
for ie in yt_dlp.extractor.gen_extractors():
|
||||
for tc in ie.get_testcases(include_onlymatching):
|
||||
yield tc
|
||||
yield from ie.get_testcases(include_onlymatching)
|
||||
|
||||
|
||||
md5 = lambda s: hashlib.md5(s.encode('utf-8')).hexdigest()
|
||||
|
@ -113,33 +109,30 @@ def expect_value(self, got, expected, field):
|
|||
|
||||
self.assertTrue(
|
||||
isinstance(got, compat_str),
|
||||
'Expected a %s object, but got %s for field %s' % (
|
||||
compat_str.__name__, type(got).__name__, field))
|
||||
f'Expected a {compat_str.__name__} object, but got {type(got).__name__} for field {field}')
|
||||
self.assertTrue(
|
||||
match_rex.match(got),
|
||||
'field %s (value: %r) should match %r' % (field, got, match_str))
|
||||
f'field {field} (value: {got!r}) should match {match_str!r}')
|
||||
elif isinstance(expected, compat_str) and expected.startswith('startswith:'):
|
||||
start_str = expected[len('startswith:'):]
|
||||
self.assertTrue(
|
||||
isinstance(got, compat_str),
|
||||
'Expected a %s object, but got %s for field %s' % (
|
||||
compat_str.__name__, type(got).__name__, field))
|
||||
f'Expected a {compat_str.__name__} object, but got {type(got).__name__} for field {field}')
|
||||
self.assertTrue(
|
||||
got.startswith(start_str),
|
||||
'field %s (value: %r) should start with %r' % (field, got, start_str))
|
||||
f'field {field} (value: {got!r}) should start with {start_str!r}')
|
||||
elif isinstance(expected, compat_str) and expected.startswith('contains:'):
|
||||
contains_str = expected[len('contains:'):]
|
||||
self.assertTrue(
|
||||
isinstance(got, compat_str),
|
||||
'Expected a %s object, but got %s for field %s' % (
|
||||
compat_str.__name__, type(got).__name__, field))
|
||||
f'Expected a {compat_str.__name__} object, but got {type(got).__name__} for field {field}')
|
||||
self.assertTrue(
|
||||
contains_str in got,
|
||||
'field %s (value: %r) should contain %r' % (field, got, contains_str))
|
||||
f'field {field} (value: {got!r}) should contain {contains_str!r}')
|
||||
elif isinstance(expected, type):
|
||||
self.assertTrue(
|
||||
isinstance(got, expected),
|
||||
'Expected type %r for field %s, but got value %r of type %r' % (expected, field, got, type(got)))
|
||||
f'Expected type {expected!r} for field {field}, but got value {got!r} of type {type(got)!r}')
|
||||
elif isinstance(expected, dict) and isinstance(got, dict):
|
||||
expect_dict(self, got, expected)
|
||||
elif isinstance(expected, list) and isinstance(got, list):
|
||||
|
@ -159,13 +152,12 @@ def expect_value(self, got, expected, field):
|
|||
if isinstance(expected, compat_str) and expected.startswith('md5:'):
|
||||
self.assertTrue(
|
||||
isinstance(got, compat_str),
|
||||
'Expected field %s to be a unicode object, but got value %r of type %r' % (field, got, type(got)))
|
||||
f'Expected field {field} to be a unicode object, but got value {got!r} of type {type(got)!r}')
|
||||
got = 'md5:' + md5(got)
|
||||
elif isinstance(expected, compat_str) and re.match(r'^(?:min|max)?count:\d+', expected):
|
||||
self.assertTrue(
|
||||
isinstance(got, (list, dict)),
|
||||
'Expected field %s to be a list or a dict, but it is of type %s' % (
|
||||
field, type(got).__name__))
|
||||
f'Expected field {field} to be a list or a dict, but it is of type {type(got).__name__}')
|
||||
op, _, expected_num = expected.partition(':')
|
||||
expected_num = int(expected_num)
|
||||
if op == 'mincount':
|
||||
|
@ -185,7 +177,7 @@ def expect_value(self, got, expected, field):
|
|||
return
|
||||
self.assertEqual(
|
||||
expected, got,
|
||||
'Invalid value for field %s, expected %r, got %r' % (field, expected, got))
|
||||
f'Invalid value for field {field}, expected {expected!r}, got {got!r}')
|
||||
|
||||
|
||||
def expect_dict(self, got_dict, expected_dict):
|
||||
|
@ -260,13 +252,13 @@ def expect_info_dict(self, got_dict, expected_dict):
|
|||
info_dict_str = ''
|
||||
if len(missing_keys) != len(expected_dict):
|
||||
info_dict_str += ''.join(
|
||||
' %s: %s,\n' % (_repr(k), _repr(v))
|
||||
f' {_repr(k)}: {_repr(v)},\n'
|
||||
for k, v in test_info_dict.items() if k not in missing_keys)
|
||||
|
||||
if info_dict_str:
|
||||
info_dict_str += '\n'
|
||||
info_dict_str += ''.join(
|
||||
' %s: %s,\n' % (_repr(k), _repr(test_info_dict[k]))
|
||||
f' {_repr(k)}: {_repr(test_info_dict[k])},\n'
|
||||
for k in missing_keys)
|
||||
write_string(
|
||||
'\n\'info_dict\': {\n' + info_dict_str + '},\n', out=sys.stderr)
|
||||
|
@ -295,21 +287,21 @@ def assertRegexpMatches(self, text, regexp, msg=None):
|
|||
def assertGreaterEqual(self, got, expected, msg=None):
|
||||
if not (got >= expected):
|
||||
if msg is None:
|
||||
msg = '%r not greater than or equal to %r' % (got, expected)
|
||||
msg = f'{got!r} not greater than or equal to {expected!r}'
|
||||
self.assertTrue(got >= expected, msg)
|
||||
|
||||
|
||||
def assertLessEqual(self, got, expected, msg=None):
|
||||
if not (got <= expected):
|
||||
if msg is None:
|
||||
msg = '%r not less than or equal to %r' % (got, expected)
|
||||
msg = f'{got!r} not less than or equal to {expected!r}'
|
||||
self.assertTrue(got <= expected, msg)
|
||||
|
||||
|
||||
def assertEqual(self, got, expected, msg=None):
|
||||
if not (got == expected):
|
||||
if msg is None:
|
||||
msg = '%r not equal to %r' % (got, expected)
|
||||
msg = f'{got!r} not equal to {expected!r}'
|
||||
self.assertTrue(got == expected, msg)
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
@ -1011,8 +1007,7 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
|||
]
|
||||
|
||||
for m3u8_file, m3u8_url, expected_formats, expected_subs in _TEST_CASES:
|
||||
with io.open('./test/testdata/m3u8/%s.m3u8' % m3u8_file,
|
||||
mode='r', encoding='utf-8') as f:
|
||||
with open('./test/testdata/m3u8/%s.m3u8' % m3u8_file, encoding='utf-8') as f:
|
||||
formats, subs = self.ie._parse_m3u8_formats_and_subtitles(
|
||||
f.read(), m3u8_url, ext='mp4')
|
||||
self.ie._sort_formats(formats)
|
||||
|
@ -1357,8 +1352,7 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
|||
]
|
||||
|
||||
for mpd_file, mpd_url, mpd_base_url, expected_formats, expected_subtitles in _TEST_CASES:
|
||||
with io.open('./test/testdata/mpd/%s.mpd' % mpd_file,
|
||||
mode='r', encoding='utf-8') as f:
|
||||
with open('./test/testdata/mpd/%s.mpd' % mpd_file, encoding='utf-8') as f:
|
||||
formats, subtitles = self.ie._parse_mpd_formats_and_subtitles(
|
||||
compat_etree_fromstring(f.read().encode('utf-8')),
|
||||
mpd_base_url=mpd_base_url, mpd_url=mpd_url)
|
||||
|
@ -1549,8 +1543,7 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
|||
]
|
||||
|
||||
for ism_file, ism_url, expected_formats, expected_subtitles in _TEST_CASES:
|
||||
with io.open('./test/testdata/ism/%s.Manifest' % ism_file,
|
||||
mode='r', encoding='utf-8') as f:
|
||||
with open('./test/testdata/ism/%s.Manifest' % ism_file, encoding='utf-8') as f:
|
||||
formats, subtitles = self.ie._parse_ism_formats_and_subtitles(
|
||||
compat_etree_fromstring(f.read().encode('utf-8')), ism_url=ism_url)
|
||||
self.ie._sort_formats(formats)
|
||||
|
@ -1576,8 +1569,7 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
|||
]
|
||||
|
||||
for f4m_file, f4m_url, expected_formats in _TEST_CASES:
|
||||
with io.open('./test/testdata/f4m/%s.f4m' % f4m_file,
|
||||
mode='r', encoding='utf-8') as f:
|
||||
with open('./test/testdata/f4m/%s.f4m' % f4m_file, encoding='utf-8') as f:
|
||||
formats = self.ie._parse_f4m_formats(
|
||||
compat_etree_fromstring(f.read().encode('utf-8')),
|
||||
f4m_url, None)
|
||||
|
@ -1624,8 +1616,7 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
|
|||
]
|
||||
|
||||
for xspf_file, xspf_url, expected_entries in _TEST_CASES:
|
||||
with io.open('./test/testdata/xspf/%s.xspf' % xspf_file,
|
||||
mode='r', encoding='utf-8') as f:
|
||||
with open('./test/testdata/xspf/%s.xspf' % xspf_file, encoding='utf-8') as f:
|
||||
entries = self.ie._parse_xspf(
|
||||
compat_etree_fromstring(f.read().encode('utf-8')),
|
||||
xspf_file, xspf_url=xspf_url, xspf_base_url=xspf_url)
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -25,7 +21,7 @@ TEST_URL = 'http://localhost/sample.mp4'
|
|||
|
||||
class YDL(FakeYDL):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(YDL, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.downloaded_info_dicts = []
|
||||
self.msgs = []
|
||||
|
||||
|
@ -551,11 +547,11 @@ class TestYoutubeDL(unittest.TestCase):
|
|||
def s_formats(lang, autocaption=False):
|
||||
return [{
|
||||
'ext': ext,
|
||||
'url': 'http://localhost/video.%s.%s' % (lang, ext),
|
||||
'url': f'http://localhost/video.{lang}.{ext}',
|
||||
'_auto': autocaption,
|
||||
} for ext in ['vtt', 'srt', 'ass']]
|
||||
subtitles = dict((l, s_formats(l)) for l in ['en', 'fr', 'es'])
|
||||
auto_captions = dict((l, s_formats(l, True)) for l in ['it', 'pt', 'es'])
|
||||
subtitles = {l: s_formats(l) for l in ['en', 'fr', 'es']}
|
||||
auto_captions = {l: s_formats(l, True) for l in ['it', 'pt', 'es']}
|
||||
info_dict = {
|
||||
'id': 'test',
|
||||
'title': 'Test',
|
||||
|
@ -580,7 +576,7 @@ class TestYoutubeDL(unittest.TestCase):
|
|||
result = get_info({'writesubtitles': True})
|
||||
subs = result['requested_subtitles']
|
||||
self.assertTrue(subs)
|
||||
self.assertEqual(set(subs.keys()), set(['en']))
|
||||
self.assertEqual(set(subs.keys()), {'en'})
|
||||
self.assertTrue(subs['en'].get('data') is None)
|
||||
self.assertEqual(subs['en']['ext'], 'ass')
|
||||
|
||||
|
@ -591,39 +587,39 @@ class TestYoutubeDL(unittest.TestCase):
|
|||
result = get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']})
|
||||
subs = result['requested_subtitles']
|
||||
self.assertTrue(subs)
|
||||
self.assertEqual(set(subs.keys()), set(['es', 'fr']))
|
||||
self.assertEqual(set(subs.keys()), {'es', 'fr'})
|
||||
|
||||
result = get_info({'writesubtitles': True, 'subtitleslangs': ['all', '-en']})
|
||||
subs = result['requested_subtitles']
|
||||
self.assertTrue(subs)
|
||||
self.assertEqual(set(subs.keys()), set(['es', 'fr']))
|
||||
self.assertEqual(set(subs.keys()), {'es', 'fr'})
|
||||
|
||||
result = get_info({'writesubtitles': True, 'subtitleslangs': ['en', 'fr', '-en']})
|
||||
subs = result['requested_subtitles']
|
||||
self.assertTrue(subs)
|
||||
self.assertEqual(set(subs.keys()), set(['fr']))
|
||||
self.assertEqual(set(subs.keys()), {'fr'})
|
||||
|
||||
result = get_info({'writesubtitles': True, 'subtitleslangs': ['-en', 'en']})
|
||||
subs = result['requested_subtitles']
|
||||
self.assertTrue(subs)
|
||||
self.assertEqual(set(subs.keys()), set(['en']))
|
||||
self.assertEqual(set(subs.keys()), {'en'})
|
||||
|
||||
result = get_info({'writesubtitles': True, 'subtitleslangs': ['e.+']})
|
||||
subs = result['requested_subtitles']
|
||||
self.assertTrue(subs)
|
||||
self.assertEqual(set(subs.keys()), set(['es', 'en']))
|
||||
self.assertEqual(set(subs.keys()), {'es', 'en'})
|
||||
|
||||
result = get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
|
||||
subs = result['requested_subtitles']
|
||||
self.assertTrue(subs)
|
||||
self.assertEqual(set(subs.keys()), set(['es', 'pt']))
|
||||
self.assertEqual(set(subs.keys()), {'es', 'pt'})
|
||||
self.assertFalse(subs['es']['_auto'])
|
||||
self.assertTrue(subs['pt']['_auto'])
|
||||
|
||||
result = get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
|
||||
subs = result['requested_subtitles']
|
||||
self.assertTrue(subs)
|
||||
self.assertEqual(set(subs.keys()), set(['es', 'pt']))
|
||||
self.assertEqual(set(subs.keys()), {'es', 'pt'})
|
||||
self.assertTrue(subs['es']['_auto'])
|
||||
self.assertTrue(subs['pt']['_auto'])
|
||||
|
||||
|
@ -1082,7 +1078,7 @@ class TestYoutubeDL(unittest.TestCase):
|
|||
|
||||
class _YDL(YDL):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(_YDL, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def trouble(self, s, tb=None):
|
||||
pass
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -81,11 +78,11 @@ class TestAllURLsMatching(unittest.TestCase):
|
|||
url = tc['url']
|
||||
for ie in ies:
|
||||
if type(ie).__name__ in ('GenericIE', tc['name'] + 'IE'):
|
||||
self.assertTrue(ie.suitable(url), '%s should match URL %r' % (type(ie).__name__, url))
|
||||
self.assertTrue(ie.suitable(url), f'{type(ie).__name__} should match URL {url!r}')
|
||||
else:
|
||||
self.assertFalse(
|
||||
ie.suitable(url),
|
||||
'%s should not match URL %r . That URL belongs to %s.' % (type(ie).__name__, url, tc['name']))
|
||||
f'{type(ie).__name__} should not match URL {url!r} . That URL belongs to {tc["name"]}.')
|
||||
|
||||
def test_keywords(self):
|
||||
self.assertMatch(':ytsubs', ['youtube:subscriptions'])
|
||||
|
@ -120,7 +117,7 @@ class TestAllURLsMatching(unittest.TestCase):
|
|||
for (ie_name, ie_list) in name_accu.items():
|
||||
self.assertEqual(
|
||||
len(ie_list), 1,
|
||||
'Multiple extractors with the same IE_NAME "%s" (%s)' % (ie_name, ', '.join(ie_list)))
|
||||
f'Multiple extractors with the same IE_NAME "{ie_name}" ({", ".join(ie_list)})')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import shutil
|
||||
|
||||
# Allow direct execution
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -48,7 +44,7 @@ class TestCompat(unittest.TestCase):
|
|||
all_names = yt_dlp.compat.__all__
|
||||
present_names = set(filter(
|
||||
lambda c: '_' in c and not c.startswith('_'),
|
||||
dir(yt_dlp.compat))) - set(['unicode_literals'])
|
||||
dir(yt_dlp.compat))) - {'unicode_literals'}
|
||||
self.assertEqual(all_names, sorted(present_names))
|
||||
|
||||
def test_compat_urllib_parse_unquote(self):
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -21,7 +18,6 @@ from test.helper import (
|
|||
|
||||
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import socket
|
||||
|
||||
|
@ -46,7 +42,7 @@ class YoutubeDL(yt_dlp.YoutubeDL):
|
|||
def __init__(self, *args, **kwargs):
|
||||
self.to_stderr = self.to_screen
|
||||
self.processed_info_dicts = []
|
||||
super(YoutubeDL, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def report_warning(self, message):
|
||||
# Don't accept warnings during tests
|
||||
|
@ -54,7 +50,7 @@ class YoutubeDL(yt_dlp.YoutubeDL):
|
|||
|
||||
def process_info(self, info_dict):
|
||||
self.processed_info_dicts.append(info_dict.copy())
|
||||
return super(YoutubeDL, self).process_info(info_dict)
|
||||
return super().process_info(info_dict)
|
||||
|
||||
|
||||
def _file_md5(fn):
|
||||
|
@ -80,7 +76,7 @@ class TestDownload(unittest.TestCase):
|
|||
|
||||
def strclass(cls):
|
||||
"""From 2.7's unittest; 2.6 had _strclass so we can't import it."""
|
||||
return '%s.%s' % (cls.__module__, cls.__name__)
|
||||
return f'{cls.__module__}.{cls.__name__}'
|
||||
|
||||
add_ie = getattr(self, self._testMethodName).add_ie
|
||||
return '%s (%s)%s:' % (self._testMethodName,
|
||||
|
@ -179,7 +175,7 @@ def generator(test_case, tname):
|
|||
report_warning('%s failed due to network errors, skipping...' % tname)
|
||||
return
|
||||
|
||||
print('Retrying: {0} failed tries\n\n##########\n\n'.format(try_num))
|
||||
print(f'Retrying: {try_num} failed tries\n\n##########\n\n')
|
||||
|
||||
try_num += 1
|
||||
else:
|
||||
|
@ -245,7 +241,7 @@ def generator(test_case, tname):
|
|||
self.assertTrue(
|
||||
os.path.exists(info_json_fn),
|
||||
'Missing info file %s' % info_json_fn)
|
||||
with io.open(info_json_fn, encoding='utf-8') as infof:
|
||||
with open(info_json_fn, encoding='utf-8') as infof:
|
||||
info_dict = json.load(infof)
|
||||
expect_info_dict(self, info_dict, tc.get('info_dict', {}))
|
||||
finally:
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import re
|
||||
|
@ -66,7 +63,7 @@ class HTTPTestRequestHandler(compat_http_server.BaseHTTPRequestHandler):
|
|||
assert False
|
||||
|
||||
|
||||
class FakeLogger(object):
|
||||
class FakeLogger:
|
||||
def debug(self, msg):
|
||||
pass
|
||||
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
import sys
|
||||
|
@ -45,7 +41,7 @@ class TestExecution(unittest.TestCase):
|
|||
finally:
|
||||
try:
|
||||
os.remove('yt_dlp/extractor/lazy_extractors.py')
|
||||
except (IOError, OSError):
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -41,7 +38,7 @@ class HTTPTestRequestHandler(compat_http_server.BaseHTTPRequestHandler):
|
|||
assert False
|
||||
|
||||
|
||||
class FakeLogger(object):
|
||||
class FakeLogger:
|
||||
def debug(self, msg):
|
||||
pass
|
||||
|
||||
|
@ -117,23 +114,23 @@ class TestProxy(unittest.TestCase):
|
|||
self.geo_proxy_thread.start()
|
||||
|
||||
def test_proxy(self):
|
||||
geo_proxy = '127.0.0.1:{0}'.format(self.geo_port)
|
||||
geo_proxy = f'127.0.0.1:{self.geo_port}'
|
||||
ydl = YoutubeDL({
|
||||
'proxy': '127.0.0.1:{0}'.format(self.port),
|
||||
'proxy': f'127.0.0.1:{self.port}',
|
||||
'geo_verification_proxy': geo_proxy,
|
||||
})
|
||||
url = 'http://foo.com/bar'
|
||||
response = ydl.urlopen(url).read().decode('utf-8')
|
||||
self.assertEqual(response, 'normal: {0}'.format(url))
|
||||
self.assertEqual(response, f'normal: {url}')
|
||||
|
||||
req = compat_urllib_request.Request(url)
|
||||
req.add_header('Ytdl-request-proxy', geo_proxy)
|
||||
response = ydl.urlopen(req).read().decode('utf-8')
|
||||
self.assertEqual(response, 'geo: {0}'.format(url))
|
||||
self.assertEqual(response, f'geo: {url}')
|
||||
|
||||
def test_proxy_with_idn(self):
|
||||
ydl = YoutubeDL({
|
||||
'proxy': '127.0.0.1:{0}'.format(self.port),
|
||||
'proxy': f'127.0.0.1:{self.port}',
|
||||
})
|
||||
url = 'http://中文.tw/'
|
||||
response = ydl.urlopen(url).read().decode('utf-8')
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -12,7 +9,7 @@ from test.helper import FakeYDL, is_download_test
|
|||
from yt_dlp.extractor import IqiyiIE
|
||||
|
||||
|
||||
class WarningLogger(object):
|
||||
class WarningLogger:
|
||||
def __init__(self):
|
||||
self.messages = []
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
from os.path import join
|
||||
import subprocess
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
@ -14,7 +11,7 @@ from yt_dlp.utils import DownloadError
|
|||
|
||||
class YoutubeDL(yt_dlp.YoutubeDL):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(YoutubeDL, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.to_stderr = self.to_screen
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -54,7 +52,7 @@ class BaseTestSubtitles(unittest.TestCase):
|
|||
if sub_info.get('data') is None:
|
||||
uf = self.DL.urlopen(sub_info['url'])
|
||||
sub_info['data'] = uf.read().decode('utf-8')
|
||||
return dict((l, sub_info['data']) for l, sub_info in subtitles.items())
|
||||
return {l: sub_info['data'] for l, sub_info in subtitles.items()}
|
||||
|
||||
|
||||
@is_download_test
|
||||
|
@ -163,7 +161,7 @@ class TestVimeoSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['de', 'en', 'es', 'fr']))
|
||||
self.assertEqual(set(subtitles.keys()), {'de', 'en', 'es', 'fr'})
|
||||
self.assertEqual(md5(subtitles['en']), '8062383cf4dec168fc40a088aa6d5888')
|
||||
self.assertEqual(md5(subtitles['fr']), 'b6191146a6c5d3a452244d853fde6dc8')
|
||||
|
||||
|
@ -186,7 +184,7 @@ class TestWallaSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['heb']))
|
||||
self.assertEqual(set(subtitles.keys()), {'heb'})
|
||||
self.assertEqual(md5(subtitles['heb']), 'e758c5d7cb982f6bef14f377ec7a3920')
|
||||
|
||||
def test_nosubtitles(self):
|
||||
|
@ -208,7 +206,7 @@ class TestCeskaTelevizeSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['cs']))
|
||||
self.assertEqual(set(subtitles.keys()), {'cs'})
|
||||
self.assertTrue(len(subtitles['cs']) > 20000)
|
||||
|
||||
def test_nosubtitles(self):
|
||||
|
@ -229,7 +227,7 @@ class TestLyndaSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['en']))
|
||||
self.assertEqual(set(subtitles.keys()), {'en'})
|
||||
self.assertEqual(md5(subtitles['en']), '09bbe67222259bed60deaa26997d73a7')
|
||||
|
||||
|
||||
|
@ -242,7 +240,7 @@ class TestNPOSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['nl']))
|
||||
self.assertEqual(set(subtitles.keys()), {'nl'})
|
||||
self.assertEqual(md5(subtitles['nl']), 'fc6435027572b63fb4ab143abd5ad3f4')
|
||||
|
||||
|
||||
|
@ -252,13 +250,13 @@ class TestMTVSubtitles(BaseTestSubtitles):
|
|||
IE = ComedyCentralIE
|
||||
|
||||
def getInfoDict(self):
|
||||
return super(TestMTVSubtitles, self).getInfoDict()['entries'][0]
|
||||
return super().getInfoDict()['entries'][0]
|
||||
|
||||
def test_allsubtitles(self):
|
||||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['en']))
|
||||
self.assertEqual(set(subtitles.keys()), {'en'})
|
||||
self.assertEqual(md5(subtitles['en']), '78206b8d8a0cfa9da64dc026eea48961')
|
||||
|
||||
|
||||
|
@ -271,7 +269,7 @@ class TestNRKSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['no']))
|
||||
self.assertEqual(set(subtitles.keys()), {'no'})
|
||||
self.assertEqual(md5(subtitles['no']), '544fa917d3197fcbee64634559221cc2')
|
||||
|
||||
|
||||
|
@ -284,7 +282,7 @@ class TestRaiPlaySubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['it']))
|
||||
self.assertEqual(set(subtitles.keys()), {'it'})
|
||||
self.assertEqual(md5(subtitles['it']), 'b1d90a98755126b61e667567a1f6680a')
|
||||
|
||||
def test_subtitles_array_key(self):
|
||||
|
@ -292,7 +290,7 @@ class TestRaiPlaySubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['it']))
|
||||
self.assertEqual(set(subtitles.keys()), {'it'})
|
||||
self.assertEqual(md5(subtitles['it']), '4b3264186fbb103508abe5311cfcb9cd')
|
||||
|
||||
|
||||
|
@ -305,7 +303,7 @@ class TestVikiSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['en']))
|
||||
self.assertEqual(set(subtitles.keys()), {'en'})
|
||||
self.assertEqual(md5(subtitles['en']), '53cb083a5914b2d84ef1ab67b880d18a')
|
||||
|
||||
|
||||
|
@ -320,7 +318,7 @@ class TestThePlatformSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['en']))
|
||||
self.assertEqual(set(subtitles.keys()), {'en'})
|
||||
self.assertEqual(md5(subtitles['en']), '97e7670cbae3c4d26ae8bcc7fdd78d4b')
|
||||
|
||||
|
||||
|
@ -333,7 +331,7 @@ class TestThePlatformFeedSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['en']))
|
||||
self.assertEqual(set(subtitles.keys()), {'en'})
|
||||
self.assertEqual(md5(subtitles['en']), '48649a22e82b2da21c9a67a395eedade')
|
||||
|
||||
|
||||
|
@ -348,7 +346,7 @@ class TestRtveSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['es']))
|
||||
self.assertEqual(set(subtitles.keys()), {'es'})
|
||||
self.assertEqual(md5(subtitles['es']), '69e70cae2d40574fb7316f31d6eb7fca')
|
||||
|
||||
|
||||
|
@ -361,7 +359,7 @@ class TestDemocracynowSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['en']))
|
||||
self.assertEqual(set(subtitles.keys()), {'en'})
|
||||
self.assertEqual(md5(subtitles['en']), 'acaca989e24a9e45a6719c9b3d60815c')
|
||||
|
||||
def test_subtitles_in_page(self):
|
||||
|
@ -369,7 +367,7 @@ class TestDemocracynowSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['en']))
|
||||
self.assertEqual(set(subtitles.keys()), {'en'})
|
||||
self.assertEqual(md5(subtitles['en']), 'acaca989e24a9e45a6719c9b3d60815c')
|
||||
|
||||
|
||||
|
@ -382,7 +380,7 @@ class TestPBSSubtitles(BaseTestSubtitles):
|
|||
self.DL.params['writesubtitles'] = True
|
||||
self.DL.params['allsubtitles'] = True
|
||||
subtitles = self.getSubtitles()
|
||||
self.assertEqual(set(subtitles.keys()), set(['en']))
|
||||
self.assertEqual(set(subtitles.keys()), {'en'})
|
||||
|
||||
def test_subtitles_dfxp_format(self):
|
||||
self.DL.params['writesubtitles'] = True
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -266,7 +262,7 @@ class TestUtil(unittest.TestCase):
|
|||
|
||||
def test_expand_path(self):
|
||||
def env(var):
|
||||
return '%{0}%'.format(var) if sys.platform == 'win32' else '${0}'.format(var)
|
||||
return f'%{var}%' if sys.platform == 'win32' else f'${var}'
|
||||
|
||||
compat_setenv('yt_dlp_EXPATH_PATH', 'expanded')
|
||||
self.assertEqual(expand_path(env('yt_dlp_EXPATH_PATH')), 'expanded')
|
||||
|
@ -666,8 +662,7 @@ class TestUtil(unittest.TestCase):
|
|||
def get_page(pagenum):
|
||||
firstid = pagenum * pagesize
|
||||
upto = min(size, pagenum * pagesize + pagesize)
|
||||
for i in range(firstid, upto):
|
||||
yield i
|
||||
yield from range(firstid, upto)
|
||||
|
||||
pl = OnDemandPagedList(get_page, pagesize)
|
||||
got = pl.getslice(*sliceargs)
|
||||
|
@ -736,7 +731,7 @@ class TestUtil(unittest.TestCase):
|
|||
multipart_encode({b'field': b'value'}, boundary='AAAAAA')[0],
|
||||
b'--AAAAAA\r\nContent-Disposition: form-data; name="field"\r\n\r\nvalue\r\n--AAAAAA--\r\n')
|
||||
self.assertEqual(
|
||||
multipart_encode({'欄位'.encode('utf-8'): '值'.encode('utf-8')}, boundary='AAAAAA')[0],
|
||||
multipart_encode({'欄位'.encode(): '值'.encode()}, boundary='AAAAAA')[0],
|
||||
b'--AAAAAA\r\nContent-Disposition: form-data; name="\xe6\xac\x84\xe4\xbd\x8d"\r\n\r\n\xe5\x80\xbc\r\n--AAAAAA--\r\n')
|
||||
self.assertRaises(
|
||||
ValueError, multipart_encode, {b'field': b'value'}, boundary='value')
|
||||
|
@ -1397,7 +1392,7 @@ ffmpeg version 2.4.4 Copyright (c) 2000-2014 the FFmpeg ...'''), '2.4.4')
|
|||
<p begin="3" dur="-1">Ignored, three</p>
|
||||
</div>
|
||||
</body>
|
||||
</tt>'''.encode('utf-8')
|
||||
</tt>'''.encode()
|
||||
srt_data = '''1
|
||||
00:00:00,000 --> 00:00:01,000
|
||||
The following line contains Chinese characters and special symbols
|
||||
|
@ -1415,14 +1410,14 @@ Line
|
|||
'''
|
||||
self.assertEqual(dfxp2srt(dfxp_data), srt_data)
|
||||
|
||||
dfxp_data_no_default_namespace = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
dfxp_data_no_default_namespace = b'''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tt xml:lang="en" xmlns:tts="http://www.w3.org/ns/ttml#parameter">
|
||||
<body>
|
||||
<div xml:lang="en">
|
||||
<p begin="0" end="1">The first line</p>
|
||||
</div>
|
||||
</body>
|
||||
</tt>'''.encode('utf-8')
|
||||
</tt>'''
|
||||
srt_data = '''1
|
||||
00:00:00,000 --> 00:00:01,000
|
||||
The first line
|
||||
|
@ -1430,7 +1425,7 @@ The first line
|
|||
'''
|
||||
self.assertEqual(dfxp2srt(dfxp_data_no_default_namespace), srt_data)
|
||||
|
||||
dfxp_data_with_style = '''<?xml version="1.0" encoding="utf-8"?>
|
||||
dfxp_data_with_style = b'''<?xml version="1.0" encoding="utf-8"?>
|
||||
<tt xmlns="http://www.w3.org/2006/10/ttaf1" xmlns:ttp="http://www.w3.org/2006/10/ttaf1#parameter" ttp:timeBase="media" xmlns:tts="http://www.w3.org/2006/10/ttaf1#style" xml:lang="en" xmlns:ttm="http://www.w3.org/2006/10/ttaf1#metadata">
|
||||
<head>
|
||||
<styling>
|
||||
|
@ -1448,7 +1443,7 @@ The first line
|
|||
<p style="s1" tts:textDecoration="underline" begin="00:00:09.56" id="p2" end="00:00:12.36"><span style="s2" tts:color="lime">inner<br /> </span>style</p>
|
||||
</div>
|
||||
</body>
|
||||
</tt>'''.encode('utf-8')
|
||||
</tt>'''
|
||||
srt_data = '''1
|
||||
00:00:02,080 --> 00:00:05,840
|
||||
<font color="white" face="sansSerif" size="16">default style<font color="red">custom style</font></font>
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
import sys
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
@ -21,7 +18,7 @@ import yt_dlp.extractor
|
|||
|
||||
class YoutubeDL(yt_dlp.YoutubeDL):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(YoutubeDL, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.to_stderr = self.to_screen
|
||||
|
||||
|
||||
|
@ -52,7 +49,7 @@ class TestAnnotations(unittest.TestCase):
|
|||
ydl.download([TEST_ID])
|
||||
self.assertTrue(os.path.exists(ANNOTATIONS_FILE))
|
||||
annoxml = None
|
||||
with io.open(ANNOTATIONS_FILE, 'r', encoding='utf-8') as annof:
|
||||
with open(ANNOTATIONS_FILE, 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()
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Allow direct execution
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
import io
|
||||
import re
|
||||
import string
|
||||
import urllib.request
|
||||
|
@ -149,7 +145,7 @@ def t_factory(name, sig_func, url_pattern):
|
|||
|
||||
if not os.path.exists(fn):
|
||||
urllib.request.urlretrieve(url, fn)
|
||||
with io.open(fn, encoding='utf-8') as testf:
|
||||
with open(fn, encoding='utf-8') as testf:
|
||||
jscode = testf.read()
|
||||
self.assertEqual(sig_func(jscode, sig_input), expected_sig)
|
||||
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import collections
|
||||
import contextlib
|
||||
import datetime
|
||||
|
@ -165,7 +161,7 @@ if compat_os_name == 'nt':
|
|||
import ctypes
|
||||
|
||||
|
||||
class YoutubeDL(object):
|
||||
class YoutubeDL:
|
||||
"""YoutubeDL class.
|
||||
|
||||
YoutubeDL objects are the ones responsible of downloading the
|
||||
|
@ -501,7 +497,7 @@ class YoutubeDL(object):
|
|||
care about HLS. (only for youtube)
|
||||
"""
|
||||
|
||||
_NUMERIC_FIELDS = set((
|
||||
_NUMERIC_FIELDS = {
|
||||
'width', 'height', 'tbr', 'abr', 'asr', 'vbr', 'fps', 'filesize', 'filesize_approx',
|
||||
'timestamp', 'release_timestamp',
|
||||
'duration', 'view_count', 'like_count', 'dislike_count', 'repost_count',
|
||||
|
@ -509,7 +505,7 @@ class YoutubeDL(object):
|
|||
'start_time', 'end_time',
|
||||
'chapter_number', 'season_number', 'episode_number',
|
||||
'track_number', 'disc_number', 'release_year',
|
||||
))
|
||||
}
|
||||
|
||||
_format_fields = {
|
||||
# NB: Keep in sync with the docstring of extractor/common.py
|
||||
|
@ -576,7 +572,7 @@ class YoutubeDL(object):
|
|||
|
||||
def check_deprecated(param, option, suggestion):
|
||||
if self.params.get(param) is not None:
|
||||
self.report_warning('%s is deprecated. Use %s instead' % (option, suggestion))
|
||||
self.report_warning(f'{option} is deprecated. Use {suggestion} instead')
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -693,7 +689,7 @@ class YoutubeDL(object):
|
|||
with locked_file(fn, 'r', encoding='utf-8') as archive_file:
|
||||
for line in archive_file:
|
||||
self.archive.add(line.strip())
|
||||
except IOError as ioe:
|
||||
except OSError as ioe:
|
||||
if ioe.errno != errno.ENOENT:
|
||||
raise
|
||||
return False
|
||||
|
@ -990,11 +986,9 @@ class YoutubeDL(object):
|
|||
outtmpl_dict.update({
|
||||
k: sanitize(v) for k, v in DEFAULT_OUTTMPL.items()
|
||||
if outtmpl_dict.get(k) is None})
|
||||
for key, val in outtmpl_dict.items():
|
||||
for _, val in outtmpl_dict.items():
|
||||
if isinstance(val, bytes):
|
||||
self.report_warning(
|
||||
'Parameter outtmpl is bytes, but should be a unicode string. '
|
||||
'Put from __future__ import unicode_literals at the top of your code file or consider switching to Python 3.x.')
|
||||
self.report_warning('Parameter outtmpl is bytes, but should be a unicode string')
|
||||
return outtmpl_dict
|
||||
|
||||
def get_output_path(self, dir_type='', filename=None):
|
||||
|
@ -1013,7 +1007,7 @@ class YoutubeDL(object):
|
|||
# '%%' intact for template dict substitution step. Working around
|
||||
# with boundary-alike separator hack.
|
||||
sep = ''.join([random.choice(ascii_letters) for _ in range(32)])
|
||||
outtmpl = outtmpl.replace('%%', '%{0}%'.format(sep)).replace('$$', '${0}$'.format(sep))
|
||||
outtmpl = outtmpl.replace('%%', f'%{sep}%').replace('$$', f'${sep}$')
|
||||
|
||||
# outtmpl should be expand_path'ed before template dict substitution
|
||||
# because meta fields may contain env variables we don't want to
|
||||
|
@ -1173,7 +1167,7 @@ class YoutubeDL(object):
|
|||
|
||||
fmt = outer_mobj.group('format')
|
||||
if fmt == 's' and value is not None and key in field_size_compat_map.keys():
|
||||
fmt = '0{:d}d'.format(field_size_compat_map[key])
|
||||
fmt = f'0{field_size_compat_map[key]:d}d'
|
||||
|
||||
value = default if value is None else value if replacement is None else replacement
|
||||
|
||||
|
@ -1188,7 +1182,7 @@ class YoutubeDL(object):
|
|||
value = map(str, variadic(value) if '#' in flags else [value])
|
||||
value, fmt = ' '.join(map(compat_shlex_quote, value)), str_fmt
|
||||
elif fmt[-1] == 'B': # bytes
|
||||
value = f'%{str_fmt}'.encode('utf-8') % str(value).encode('utf-8')
|
||||
value = f'%{str_fmt}'.encode() % str(value).encode('utf-8')
|
||||
value, fmt = value.decode('utf-8', 'ignore'), 's'
|
||||
elif fmt[-1] == 'U': # unicode normalized
|
||||
value, fmt = unicodedata.normalize(
|
||||
|
@ -1301,7 +1295,7 @@ class YoutubeDL(object):
|
|||
if date is not None:
|
||||
dateRange = self.params.get('daterange', DateRange())
|
||||
if date not in dateRange:
|
||||
return '%s upload date is not in range %s' % (date_from_str(date).isoformat(), dateRange)
|
||||
return f'{date_from_str(date).isoformat()} upload date is not in range {dateRange}'
|
||||
view_count = info_dict.get('view_count')
|
||||
if view_count is not None:
|
||||
min_views = self.params.get('min_views')
|
||||
|
@ -1765,14 +1759,14 @@ class YoutubeDL(object):
|
|||
|
||||
x_forwarded_for = ie_result.get('__x_forwarded_for_ip')
|
||||
|
||||
self.to_screen('[%s] playlist %s: %s' % (ie_result['extractor'], playlist, msg % n_entries))
|
||||
self.to_screen(f'[{ie_result["extractor"]}] playlist {playlist}: {msg % n_entries}')
|
||||
failures = 0
|
||||
max_failures = self.params.get('skip_playlist_after_errors') or float('inf')
|
||||
for i, entry_tuple in enumerate(entries, 1):
|
||||
playlist_index, entry = entry_tuple
|
||||
if 'playlist-index' in self.params.get('compat_opts', []):
|
||||
playlist_index = playlistitems[i - 1] if playlistitems else i + playliststart - 1
|
||||
self.to_screen('[download] Downloading video %s of %s' % (i, n_entries))
|
||||
self.to_screen(f'[download] Downloading video {i} of {n_entries}')
|
||||
# This __x_forwarded_for_ip thing is a bit ugly but requires
|
||||
# minimal changes
|
||||
if x_forwarded_for:
|
||||
|
@ -1940,7 +1934,7 @@ class YoutubeDL(object):
|
|||
def syntax_error(note, start):
|
||||
message = (
|
||||
'Invalid format specification: '
|
||||
'{0}\n\t{1}\n\t{2}^'.format(note, format_spec, ' ' * start[1]))
|
||||
'{}\n\t{}\n\t{}^'.format(note, format_spec, ' ' * start[1]))
|
||||
return SyntaxError(message)
|
||||
|
||||
PICKFIRST = 'PICKFIRST'
|
||||
|
@ -2044,7 +2038,7 @@ class YoutubeDL(object):
|
|||
raise syntax_error('Expected a selector', start)
|
||||
current_selector = FormatSelector(MERGE, (selector_1, selector_2), [])
|
||||
else:
|
||||
raise syntax_error('Operator not recognized: "{0}"'.format(string), start)
|
||||
raise syntax_error(f'Operator not recognized: "{string}"', start)
|
||||
elif type == tokenize.ENDMARKER:
|
||||
break
|
||||
if current_selector:
|
||||
|
@ -2244,7 +2238,7 @@ class YoutubeDL(object):
|
|||
except tokenize.TokenError:
|
||||
raise syntax_error('Missing closing/opening brackets or parenthesis', (0, len(format_spec)))
|
||||
|
||||
class TokenIterator(object):
|
||||
class TokenIterator:
|
||||
def __init__(self, tokens):
|
||||
self.tokens = tokens
|
||||
self.counter = 0
|
||||
|
@ -2644,7 +2638,7 @@ class YoutubeDL(object):
|
|||
if max_downloads_reached:
|
||||
break
|
||||
|
||||
write_archive = set(f.get('__write_download_archive', False) for f in formats_to_download)
|
||||
write_archive = {f.get('__write_download_archive', False) for f in formats_to_download}
|
||||
assert write_archive.issubset({True, False, 'ignore'})
|
||||
if True in write_archive and False not in write_archive:
|
||||
self.record_download_archive(info_dict)
|
||||
|
@ -2712,7 +2706,7 @@ class YoutubeDL(object):
|
|||
for lang in requested_langs:
|
||||
formats = available_subs.get(lang)
|
||||
if formats is None:
|
||||
self.report_warning('%s subtitles not available for %s' % (lang, video_id))
|
||||
self.report_warning(f'{lang} subtitles not available for {video_id}')
|
||||
continue
|
||||
for ext in formats_preference:
|
||||
if ext == 'best':
|
||||
|
@ -2755,7 +2749,7 @@ class YoutubeDL(object):
|
|||
tmpl = format_tmpl(tmpl)
|
||||
self.to_screen(f'[info] Writing {tmpl!r} to: {filename}')
|
||||
if self._ensure_dir_exists(filename):
|
||||
with io.open(filename, 'a', encoding='utf-8') as f:
|
||||
with open(filename, 'a', encoding='utf-8') as f:
|
||||
f.write(self.evaluate_outtmpl(tmpl, info_copy) + '\n')
|
||||
|
||||
def __forced_printings(self, info_dict, filename, incomplete):
|
||||
|
@ -2920,11 +2914,11 @@ class YoutubeDL(object):
|
|||
else:
|
||||
try:
|
||||
self.to_screen('[info] Writing video annotations to: ' + annofn)
|
||||
with io.open(encodeFilename(annofn), 'w', encoding='utf-8') as annofile:
|
||||
with open(encodeFilename(annofn), 'w', encoding='utf-8') as annofile:
|
||||
annofile.write(info_dict['annotations'])
|
||||
except (KeyError, TypeError):
|
||||
self.report_warning('There are no annotations to write.')
|
||||
except (OSError, IOError):
|
||||
except OSError:
|
||||
self.report_error('Cannot write annotations file: ' + annofn)
|
||||
return
|
||||
|
||||
|
@ -2943,13 +2937,13 @@ class YoutubeDL(object):
|
|||
return True
|
||||
try:
|
||||
self.to_screen(f'[info] Writing internet shortcut (.{link_type}) to: {linkfn}')
|
||||
with io.open(encodeFilename(to_high_limit_path(linkfn)), 'w', encoding='utf-8',
|
||||
newline='\r\n' if link_type == 'url' else '\n') as linkfile:
|
||||
with open(encodeFilename(to_high_limit_path(linkfn)), 'w', encoding='utf-8',
|
||||
newline='\r\n' if link_type == 'url' else '\n') as linkfile:
|
||||
template_vars = {'url': url}
|
||||
if link_type == 'desktop':
|
||||
template_vars['filename'] = linkfn[:-(len(link_type) + 1)]
|
||||
linkfile.write(LINK_TEMPLATES[link_type] % template_vars)
|
||||
except (OSError, IOError):
|
||||
except OSError:
|
||||
self.report_error(f'Cannot write internet shortcut {linkfn}')
|
||||
return False
|
||||
return True
|
||||
|
@ -3014,10 +3008,10 @@ class YoutubeDL(object):
|
|||
return False
|
||||
|
||||
# Check extension
|
||||
exts = set(format.get('ext') for format in formats)
|
||||
exts = {format.get('ext') for format in formats}
|
||||
COMPATIBLE_EXTS = (
|
||||
set(('mp3', 'mp4', 'm4a', 'm4p', 'm4b', 'm4r', 'm4v', 'ismv', 'isma')),
|
||||
set(('webm',)),
|
||||
{'mp3', 'mp4', 'm4a', 'm4p', 'm4b', 'm4r', 'm4v', 'ismv', 'isma'},
|
||||
{'webm'},
|
||||
)
|
||||
for ext_sets in COMPATIBLE_EXTS:
|
||||
if ext_sets.issuperset(exts):
|
||||
|
@ -3050,7 +3044,7 @@ class YoutubeDL(object):
|
|||
os.path.splitext(filename)[0]
|
||||
if filename_real_ext in (old_ext, new_ext)
|
||||
else filename)
|
||||
return '%s.%s' % (filename_wo_ext, ext)
|
||||
return f'{filename_wo_ext}.{ext}'
|
||||
|
||||
# Ensure filename always has a correct extension for successful merge
|
||||
full_filename = correct_ext(full_filename)
|
||||
|
@ -3135,10 +3129,10 @@ class YoutubeDL(object):
|
|||
except network_exceptions as err:
|
||||
self.report_error('unable to download video data: %s' % error_to_compat_str(err))
|
||||
return
|
||||
except (OSError, IOError) as err:
|
||||
except OSError as err:
|
||||
raise UnavailableVideoError(err)
|
||||
except (ContentTooShortError, ) as err:
|
||||
self.report_error('content too short (expected %s bytes and served %s)' % (err.expected, err.downloaded))
|
||||
self.report_error(f'content too short (expected {err.expected} bytes and served {err.downloaded})')
|
||||
return
|
||||
|
||||
if success and full_filename != '-':
|
||||
|
@ -3343,7 +3337,7 @@ class YoutubeDL(object):
|
|||
self.to_screen('Deleting original file %s (pass -k to keep)' % old_filename)
|
||||
try:
|
||||
os.remove(encodeFilename(old_filename))
|
||||
except (IOError, OSError):
|
||||
except OSError:
|
||||
self.report_warning('Unable to remove downloaded original file')
|
||||
if old_filename in infodict['__files_to_move']:
|
||||
del infodict['__files_to_move'][old_filename]
|
||||
|
@ -3388,7 +3382,7 @@ class YoutubeDL(object):
|
|||
break
|
||||
else:
|
||||
return
|
||||
return '%s %s' % (extractor.lower(), video_id)
|
||||
return f'{extractor.lower()} {video_id}'
|
||||
|
||||
def in_download_archive(self, info_dict):
|
||||
fn = self.params.get('download_archive')
|
||||
|
@ -3791,7 +3785,7 @@ class YoutubeDL(object):
|
|||
try:
|
||||
write_json_file(self.sanitize_info(ie_result, self.params.get('clean_infojson', True)), infofn)
|
||||
return True
|
||||
except (OSError, IOError):
|
||||
except OSError:
|
||||
self.report_error(f'Cannot write {label} metadata to JSON file {infofn}')
|
||||
return None
|
||||
|
||||
|
@ -3812,9 +3806,9 @@ class YoutubeDL(object):
|
|||
else:
|
||||
try:
|
||||
self.to_screen(f'[info] Writing {label} description to: {descfn}')
|
||||
with io.open(encodeFilename(descfn), 'w', encoding='utf-8') as descfile:
|
||||
with open(encodeFilename(descfn), 'w', encoding='utf-8') as descfile:
|
||||
descfile.write(ie_result['description'])
|
||||
except (OSError, IOError):
|
||||
except OSError:
|
||||
self.report_error(f'Cannot write {label} description file {descfn}')
|
||||
return None
|
||||
return True
|
||||
|
@ -3848,12 +3842,12 @@ class YoutubeDL(object):
|
|||
try:
|
||||
# Use newline='' to prevent conversion of newline characters
|
||||
# See https://github.com/ytdl-org/youtube-dl/issues/10268
|
||||
with io.open(sub_filename, 'w', encoding='utf-8', newline='') as subfile:
|
||||
with open(sub_filename, 'w', encoding='utf-8', newline='') as subfile:
|
||||
subfile.write(sub_info['data'])
|
||||
sub_info['filepath'] = sub_filename
|
||||
ret.append((sub_filename, sub_filename_final))
|
||||
continue
|
||||
except (OSError, IOError):
|
||||
except OSError:
|
||||
self.report_error(f'Cannot write video subtitles file {sub_filename}')
|
||||
return None
|
||||
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding: utf-8
|
||||
|
||||
f'You are using an unsupported version of Python. Only Python versions 3.6 and above are supported by yt-dlp' # noqa: F541
|
||||
|
||||
__license__ = 'Public Domain'
|
||||
|
||||
import io
|
||||
import itertools
|
||||
import os
|
||||
import random
|
||||
|
@ -67,13 +64,12 @@ def get_urls(urls, batchfile, verbose):
|
|||
'Ctrl+Z' if compat_os_name == 'nt' else 'Ctrl+D'))
|
||||
batchfd = sys.stdin
|
||||
else:
|
||||
batchfd = io.open(
|
||||
expand_path(batchfile),
|
||||
'r', encoding='utf-8', errors='ignore')
|
||||
batchfd = open(
|
||||
expand_path(batchfile), encoding='utf-8', errors='ignore')
|
||||
batch_urls = read_batch_urls(batchfd)
|
||||
if verbose:
|
||||
write_string('[debug] Batch file urls: ' + repr(batch_urls) + '\n')
|
||||
except IOError:
|
||||
except OSError:
|
||||
sys.exit('ERROR: batch file %s could not be read' % batchfile)
|
||||
_enc = preferredencoding()
|
||||
return [
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import unicode_literals
|
||||
|
||||
# Execute with
|
||||
# $ python -m yt_dlp
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from math import ceil
|
||||
|
||||
from .compat import (
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import errno
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
@ -15,7 +12,7 @@ from .utils import (
|
|||
)
|
||||
|
||||
|
||||
class Cache(object):
|
||||
class Cache:
|
||||
def __init__(self, ydl):
|
||||
self._ydl = ydl
|
||||
|
||||
|
@ -31,7 +28,7 @@ class Cache(object):
|
|||
'invalid section %r' % section
|
||||
assert re.match(r'^[a-zA-Z0-9_.-]+$', key), 'invalid key %r' % key
|
||||
return os.path.join(
|
||||
self._get_root_dir(), section, '%s.%s' % (key, dtype))
|
||||
self._get_root_dir(), section, f'{key}.{dtype}')
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
|
@ -54,8 +51,7 @@ class Cache(object):
|
|||
write_json_file(data, fn)
|
||||
except Exception:
|
||||
tb = traceback.format_exc()
|
||||
self._ydl.report_warning(
|
||||
'Writing cache to %r failed: %s' % (fn, tb))
|
||||
self._ydl.report_warning(f'Writing cache to {fn!r} failed: {tb}')
|
||||
|
||||
def load(self, section, key, dtype='json', default=None):
|
||||
assert dtype in ('json',)
|
||||
|
@ -66,17 +62,16 @@ class Cache(object):
|
|||
cache_fn = self._get_cache_fn(section, key, dtype)
|
||||
try:
|
||||
try:
|
||||
with io.open(cache_fn, 'r', encoding='utf-8') as cachef:
|
||||
with open(cache_fn, encoding='utf-8') as cachef:
|
||||
self._ydl.write_debug(f'Loading {section}.{key} from cache')
|
||||
return json.load(cachef)
|
||||
except ValueError:
|
||||
try:
|
||||
file_size = os.path.getsize(cache_fn)
|
||||
except (OSError, IOError) as oe:
|
||||
except OSError as oe:
|
||||
file_size = str(oe)
|
||||
self._ydl.report_warning(
|
||||
'Cache retrieval from %s failed (%s)' % (cache_fn, file_size))
|
||||
except IOError:
|
||||
self._ydl.report_warning(f'Cache retrieval from {cache_fn} failed ({file_size})')
|
||||
except OSError:
|
||||
pass # No cache available
|
||||
|
||||
return default
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
# coding: utf-8
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
import collections
|
||||
|
|
|
@ -125,7 +125,7 @@ def extract_cookies_from_browser(browser_name, profile=None, logger=YDLLogger(),
|
|||
elif browser_name in CHROMIUM_BASED_BROWSERS:
|
||||
return _extract_chrome_cookies(browser_name, profile, keyring, logger)
|
||||
else:
|
||||
raise ValueError('unknown browser: {}'.format(browser_name))
|
||||
raise ValueError(f'unknown browser: {browser_name}')
|
||||
|
||||
|
||||
def _extract_firefox_cookies(profile, logger):
|
||||
|
@ -144,8 +144,8 @@ def _extract_firefox_cookies(profile, logger):
|
|||
|
||||
cookie_database_path = _find_most_recently_used_file(search_root, 'cookies.sqlite', logger)
|
||||
if cookie_database_path is None:
|
||||
raise FileNotFoundError('could not find firefox cookies database in {}'.format(search_root))
|
||||
logger.debug('Extracting cookies from: "{}"'.format(cookie_database_path))
|
||||
raise FileNotFoundError(f'could not find firefox cookies database in {search_root}')
|
||||
logger.debug(f'Extracting cookies from: "{cookie_database_path}"')
|
||||
|
||||
with tempfile.TemporaryDirectory(prefix='yt_dlp') as tmpdir:
|
||||
cursor = None
|
||||
|
@ -164,7 +164,7 @@ def _extract_firefox_cookies(profile, logger):
|
|||
path=path, path_specified=bool(path), secure=is_secure, expires=expiry, discard=False,
|
||||
comment=None, comment_url=None, rest={})
|
||||
jar.set_cookie(cookie)
|
||||
logger.info('Extracted {} cookies from firefox'.format(len(jar)))
|
||||
logger.info(f'Extracted {len(jar)} cookies from firefox')
|
||||
return jar
|
||||
finally:
|
||||
if cursor is not None:
|
||||
|
@ -179,7 +179,7 @@ def _firefox_browser_dir():
|
|||
elif sys.platform == 'darwin':
|
||||
return os.path.expanduser('~/Library/Application Support/Firefox')
|
||||
else:
|
||||
raise ValueError('unsupported platform: {}'.format(sys.platform))
|
||||
raise ValueError(f'unsupported platform: {sys.platform}')
|
||||
|
||||
|
||||
def _get_chromium_based_browser_settings(browser_name):
|
||||
|
@ -219,7 +219,7 @@ def _get_chromium_based_browser_settings(browser_name):
|
|||
}[browser_name]
|
||||
|
||||
else:
|
||||
raise ValueError('unsupported platform: {}'.format(sys.platform))
|
||||
raise ValueError(f'unsupported platform: {sys.platform}')
|
||||
|
||||
# Linux keyring names can be determined by snooping on dbus while opening the browser in KDE:
|
||||
# dbus-monitor "interface='org.kde.KWallet'" "type=method_return"
|
||||
|
@ -242,7 +242,7 @@ def _get_chromium_based_browser_settings(browser_name):
|
|||
|
||||
|
||||
def _extract_chrome_cookies(browser_name, profile, keyring, logger):
|
||||
logger.info('Extracting cookies from {}'.format(browser_name))
|
||||
logger.info(f'Extracting cookies from {browser_name}')
|
||||
|
||||
if not SQLITE_AVAILABLE:
|
||||
logger.warning(('Cannot extract cookies from {} without sqlite3 support. '
|
||||
|
@ -260,13 +260,13 @@ def _extract_chrome_cookies(browser_name, profile, keyring, logger):
|
|||
if config['supports_profiles']:
|
||||
search_root = os.path.join(config['browser_dir'], profile)
|
||||
else:
|
||||
logger.error('{} does not support profiles'.format(browser_name))
|
||||
logger.error(f'{browser_name} does not support profiles')
|
||||
search_root = config['browser_dir']
|
||||
|
||||
cookie_database_path = _find_most_recently_used_file(search_root, 'Cookies', logger)
|
||||
if cookie_database_path is None:
|
||||
raise FileNotFoundError('could not find {} cookies database in "{}"'.format(browser_name, search_root))
|
||||
logger.debug('Extracting cookies from: "{}"'.format(cookie_database_path))
|
||||
raise FileNotFoundError(f'could not find {browser_name} cookies database in "{search_root}"')
|
||||
logger.debug(f'Extracting cookies from: "{cookie_database_path}"')
|
||||
|
||||
decryptor = get_cookie_decryptor(config['browser_dir'], config['keyring_name'], logger, keyring=keyring)
|
||||
|
||||
|
@ -295,13 +295,13 @@ def _extract_chrome_cookies(browser_name, profile, keyring, logger):
|
|||
unencrypted_cookies += 1
|
||||
jar.set_cookie(cookie)
|
||||
if failed_cookies > 0:
|
||||
failed_message = ' ({} could not be decrypted)'.format(failed_cookies)
|
||||
failed_message = f' ({failed_cookies} could not be decrypted)'
|
||||
else:
|
||||
failed_message = ''
|
||||
logger.info('Extracted {} cookies from {}{}'.format(len(jar), browser_name, failed_message))
|
||||
logger.info(f'Extracted {len(jar)} cookies from {browser_name}{failed_message}')
|
||||
counts = decryptor.cookie_counts.copy()
|
||||
counts['unencrypted'] = unencrypted_cookies
|
||||
logger.debug('cookie version breakdown: {}'.format(counts))
|
||||
logger.debug(f'cookie version breakdown: {counts}')
|
||||
return jar
|
||||
finally:
|
||||
if cursor is not None:
|
||||
|
@ -492,7 +492,7 @@ def _extract_safari_cookies(profile, logger):
|
|||
if profile is not None:
|
||||
logger.error('safari does not support profiles')
|
||||
if sys.platform != 'darwin':
|
||||
raise ValueError('unsupported platform: {}'.format(sys.platform))
|
||||
raise ValueError(f'unsupported platform: {sys.platform}')
|
||||
|
||||
cookies_path = os.path.expanduser('~/Library/Cookies/Cookies.binarycookies')
|
||||
|
||||
|
@ -506,7 +506,7 @@ def _extract_safari_cookies(profile, logger):
|
|||
cookies_data = f.read()
|
||||
|
||||
jar = parse_safari_cookies(cookies_data, logger=logger)
|
||||
logger.info('Extracted {} cookies from safari'.format(len(jar)))
|
||||
logger.info(f'Extracted {len(jar)} cookies from safari')
|
||||
return jar
|
||||
|
||||
|
||||
|
@ -522,7 +522,7 @@ class DataParser:
|
|||
|
||||
def read_bytes(self, num_bytes):
|
||||
if num_bytes < 0:
|
||||
raise ParserError('invalid read of {} bytes'.format(num_bytes))
|
||||
raise ParserError(f'invalid read of {num_bytes} bytes')
|
||||
end = self.cursor + num_bytes
|
||||
if end > len(self._data):
|
||||
raise ParserError('reached end of input')
|
||||
|
@ -533,7 +533,7 @@ class DataParser:
|
|||
def expect_bytes(self, expected_value, message):
|
||||
value = self.read_bytes(len(expected_value))
|
||||
if value != expected_value:
|
||||
raise ParserError('unexpected value: {} != {} ({})'.format(value, expected_value, message))
|
||||
raise ParserError(f'unexpected value: {value} != {expected_value} ({message})')
|
||||
|
||||
def read_uint(self, big_endian=False):
|
||||
data_format = '>I' if big_endian else '<I'
|
||||
|
@ -557,7 +557,7 @@ class DataParser:
|
|||
self._logger.debug('skipping {} bytes ({}): {}'.format(
|
||||
num_bytes, description, self.read_bytes(num_bytes)))
|
||||
elif num_bytes < 0:
|
||||
raise ParserError('invalid skip of {} bytes'.format(num_bytes))
|
||||
raise ParserError(f'invalid skip of {num_bytes} bytes')
|
||||
|
||||
def skip_to(self, offset, description='unknown'):
|
||||
self.skip(offset - self.cursor, description)
|
||||
|
@ -584,7 +584,7 @@ def _parse_safari_cookies_page(data, jar, logger):
|
|||
number_of_cookies = p.read_uint()
|
||||
record_offsets = [p.read_uint() for _ in range(number_of_cookies)]
|
||||
if number_of_cookies == 0:
|
||||
logger.debug('a cookies page of size {} has no cookies'.format(len(data)))
|
||||
logger.debug(f'a cookies page of size {len(data)} has no cookies')
|
||||
return
|
||||
|
||||
p.skip_to(record_offsets[0], 'unknown page header field')
|
||||
|
@ -730,7 +730,7 @@ def _choose_linux_keyring(logger):
|
|||
SelectBackend
|
||||
"""
|
||||
desktop_environment = _get_linux_desktop_environment(os.environ)
|
||||
logger.debug('detected desktop environment: {}'.format(desktop_environment.name))
|
||||
logger.debug(f'detected desktop environment: {desktop_environment.name}')
|
||||
if desktop_environment == _LinuxDesktopEnvironment.KDE:
|
||||
linux_keyring = _LinuxKeyring.KWALLET
|
||||
elif desktop_environment == _LinuxDesktopEnvironment.OTHER:
|
||||
|
@ -764,10 +764,10 @@ def _get_kwallet_network_wallet(logger):
|
|||
return default_wallet
|
||||
else:
|
||||
network_wallet = stdout.decode('utf-8').strip()
|
||||
logger.debug('NetworkWallet = "{}"'.format(network_wallet))
|
||||
logger.debug(f'NetworkWallet = "{network_wallet}"')
|
||||
return network_wallet
|
||||
except Exception as e:
|
||||
logger.warning('exception while obtaining NetworkWallet: {}'.format(e))
|
||||
logger.warning(f'exception while obtaining NetworkWallet: {e}')
|
||||
return default_wallet
|
||||
|
||||
|
||||
|
@ -785,8 +785,8 @@ def _get_kwallet_password(browser_keyring_name, logger):
|
|||
try:
|
||||
proc = Popen([
|
||||
'kwallet-query',
|
||||
'--read-password', '{} Safe Storage'.format(browser_keyring_name),
|
||||
'--folder', '{} Keys'.format(browser_keyring_name),
|
||||
'--read-password', f'{browser_keyring_name} Safe Storage',
|
||||
'--folder', f'{browser_keyring_name} Keys',
|
||||
network_wallet
|
||||
], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
|
||||
|
||||
|
@ -818,7 +818,7 @@ def _get_kwallet_password(browser_keyring_name, logger):
|
|||
|
||||
def _get_gnome_keyring_password(browser_keyring_name, logger):
|
||||
if not SECRETSTORAGE_AVAILABLE:
|
||||
logger.error('secretstorage not available {}'.format(SECRETSTORAGE_UNAVAILABLE_REASON))
|
||||
logger.error(f'secretstorage not available {SECRETSTORAGE_UNAVAILABLE_REASON}')
|
||||
return b''
|
||||
# the Gnome keyring does not seem to organise keys in the same way as KWallet,
|
||||
# using `dbus-monitor` during startup, it can be observed that chromium lists all keys
|
||||
|
@ -827,7 +827,7 @@ def _get_gnome_keyring_password(browser_keyring_name, logger):
|
|||
with contextlib.closing(secretstorage.dbus_init()) as con:
|
||||
col = secretstorage.get_default_collection(con)
|
||||
for item in col.get_all_items():
|
||||
if item.get_label() == '{} Safe Storage'.format(browser_keyring_name):
|
||||
if item.get_label() == f'{browser_keyring_name} Safe Storage':
|
||||
return item.get_secret()
|
||||
else:
|
||||
logger.error('failed to read from keyring')
|
||||
|
@ -861,7 +861,7 @@ def _get_mac_keyring_password(browser_keyring_name, logger):
|
|||
['security', 'find-generic-password',
|
||||
'-w', # write password to stdout
|
||||
'-a', browser_keyring_name, # match 'account'
|
||||
'-s', '{} Safe Storage'.format(browser_keyring_name)], # match 'service'
|
||||
'-s', f'{browser_keyring_name} Safe Storage'], # match 'service'
|
||||
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
|
||||
|
||||
stdout, stderr = proc.communicate_or_kill()
|
||||
|
@ -879,7 +879,7 @@ def _get_windows_v10_key(browser_root, logger):
|
|||
logger.error('could not find local state file')
|
||||
return None
|
||||
logger.debug(f'Found local state file at "{path}"')
|
||||
with open(path, 'r', encoding='utf8') as f:
|
||||
with open(path, encoding='utf8') as f:
|
||||
data = json.load(f)
|
||||
try:
|
||||
base64_key = data['os_crypt']['encrypted_key']
|
||||
|
@ -966,7 +966,7 @@ def _open_database_copy(database_path, tmpdir):
|
|||
|
||||
|
||||
def _get_column_names(cursor, table_name):
|
||||
table_info = cursor.execute('PRAGMA table_info({})'.format(table_name)).fetchall()
|
||||
table_info = cursor.execute(f'PRAGMA table_info({table_name})').fetchall()
|
||||
return [row[1].decode('utf-8') for row in table_info]
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from ..compat import compat_str
|
||||
from ..utils import (
|
||||
determine_protocol,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import division, unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
|
@ -25,7 +23,7 @@ from ..minicurses import (
|
|||
)
|
||||
|
||||
|
||||
class FileDownloader(object):
|
||||
class FileDownloader:
|
||||
"""File Downloader class.
|
||||
|
||||
File downloader objects are the ones responsible of downloading the
|
||||
|
@ -219,7 +217,7 @@ class FileDownloader(object):
|
|||
while True:
|
||||
try:
|
||||
return func(self, *args, **kwargs)
|
||||
except (IOError, OSError) as err:
|
||||
except OSError as err:
|
||||
retry = retry + 1
|
||||
if retry > file_access_retries or err.errno not in (errno.EACCES, errno.EINVAL):
|
||||
if not fatal:
|
||||
|
@ -486,4 +484,4 @@ class FileDownloader(object):
|
|||
if exe is None:
|
||||
exe = os.path.basename(str_args[0])
|
||||
|
||||
self.write_debug('%s command line: %s' % (exe, shell_quote(str_args)))
|
||||
self.write_debug(f'{exe} command line: {shell_quote(str_args)}')
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
import time
|
||||
|
||||
from ..downloader import get_suitable_downloader
|
||||
|
@ -46,7 +45,7 @@ class DashSegmentsFD(FragmentFD):
|
|||
|
||||
if real_downloader:
|
||||
self.to_screen(
|
||||
'[%s] Fragment downloads will be delegated to %s' % (self.FD_NAME, real_downloader.get_basename()))
|
||||
f'[{self.FD_NAME}] Fragment downloads will be delegated to {real_downloader.get_basename()}')
|
||||
info_dict['fragments'] = list(fragments_to_download)
|
||||
fd = real_downloader(self.ydl, self.params)
|
||||
return fd.real_download(filename, info_dict)
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
|
@ -56,7 +54,7 @@ class ExternalFD(FragmentFD):
|
|||
}
|
||||
if filename != '-':
|
||||
fsize = os.path.getsize(encodeFilename(tmpfilename))
|
||||
self.to_screen('\r[%s] Downloaded %s bytes' % (self.get_basename(), fsize))
|
||||
self.to_screen(f'\r[{self.get_basename()}] Downloaded {fsize} bytes')
|
||||
self.try_rename(tmpfilename, filename)
|
||||
status.update({
|
||||
'downloaded_bytes': fsize,
|
||||
|
@ -157,7 +155,7 @@ class ExternalFD(FragmentFD):
|
|||
fragment_filename = '%s-Frag%d' % (tmpfilename, frag_index)
|
||||
try:
|
||||
src, _ = self.sanitize_open(fragment_filename, 'rb')
|
||||
except IOError as err:
|
||||
except OSError as err:
|
||||
if skip_unavailable_fragments and frag_index > 1:
|
||||
self.report_skip_fragment(frag_index, err)
|
||||
continue
|
||||
|
@ -179,7 +177,7 @@ class CurlFD(ExternalFD):
|
|||
cmd = [self.exe, '--location', '-o', tmpfilename, '--compressed']
|
||||
if info_dict.get('http_headers') is not None:
|
||||
for key, val in info_dict['http_headers'].items():
|
||||
cmd += ['--header', '%s: %s' % (key, val)]
|
||||
cmd += ['--header', f'{key}: {val}']
|
||||
|
||||
cmd += self._bool_option('--continue-at', 'continuedl', '-', '0')
|
||||
cmd += self._valueless_option('--silent', 'noprogress')
|
||||
|
@ -216,7 +214,7 @@ class AxelFD(ExternalFD):
|
|||
cmd = [self.exe, '-o', tmpfilename]
|
||||
if info_dict.get('http_headers') is not None:
|
||||
for key, val in info_dict['http_headers'].items():
|
||||
cmd += ['-H', '%s: %s' % (key, val)]
|
||||
cmd += ['-H', f'{key}: {val}']
|
||||
cmd += self._configuration_args()
|
||||
cmd += ['--', info_dict['url']]
|
||||
return cmd
|
||||
|
@ -229,7 +227,7 @@ class WgetFD(ExternalFD):
|
|||
cmd = [self.exe, '-O', tmpfilename, '-nv', '--no-cookies', '--compression=auto']
|
||||
if info_dict.get('http_headers') is not None:
|
||||
for key, val in info_dict['http_headers'].items():
|
||||
cmd += ['--header', '%s: %s' % (key, val)]
|
||||
cmd += ['--header', f'{key}: {val}']
|
||||
cmd += self._option('--limit-rate', 'ratelimit')
|
||||
retry = self._option('--tries', 'retries')
|
||||
if len(retry) == 2:
|
||||
|
@ -240,7 +238,7 @@ class WgetFD(ExternalFD):
|
|||
proxy = self.params.get('proxy')
|
||||
if proxy:
|
||||
for var in ('http_proxy', 'https_proxy'):
|
||||
cmd += ['--execute', '%s=%s' % (var, proxy)]
|
||||
cmd += ['--execute', f'{var}={proxy}']
|
||||
cmd += self._valueless_option('--no-check-certificate', 'nocheckcertificate')
|
||||
cmd += self._configuration_args()
|
||||
cmd += ['--', info_dict['url']]
|
||||
|
@ -271,7 +269,7 @@ class Aria2cFD(ExternalFD):
|
|||
|
||||
if info_dict.get('http_headers') is not None:
|
||||
for key, val in info_dict['http_headers'].items():
|
||||
cmd += ['--header', '%s: %s' % (key, val)]
|
||||
cmd += ['--header', f'{key}: {val}']
|
||||
cmd += self._option('--max-overall-download-limit', 'ratelimit')
|
||||
cmd += self._option('--interface', 'source_address')
|
||||
cmd += self._option('--all-proxy', 'proxy')
|
||||
|
@ -289,10 +287,10 @@ class Aria2cFD(ExternalFD):
|
|||
dn = os.path.dirname(tmpfilename)
|
||||
if dn:
|
||||
if not os.path.isabs(dn):
|
||||
dn = '.%s%s' % (os.path.sep, dn)
|
||||
dn = f'.{os.path.sep}{dn}'
|
||||
cmd += ['--dir', dn + os.path.sep]
|
||||
if 'fragments' not in info_dict:
|
||||
cmd += ['--out', '.%s%s' % (os.path.sep, os.path.basename(tmpfilename))]
|
||||
cmd += ['--out', f'.{os.path.sep}{os.path.basename(tmpfilename)}']
|
||||
cmd += ['--auto-file-renaming=false']
|
||||
|
||||
if 'fragments' in info_dict:
|
||||
|
@ -320,7 +318,7 @@ class HttpieFD(ExternalFD):
|
|||
|
||||
if info_dict.get('http_headers') is not None:
|
||||
for key, val in info_dict['http_headers'].items():
|
||||
cmd += ['%s:%s' % (key, val)]
|
||||
cmd += [f'{key}:{val}']
|
||||
return cmd
|
||||
|
||||
|
||||
|
@ -393,7 +391,7 @@ class FFmpegFD(ExternalFD):
|
|||
headers = handle_youtubedl_headers(info_dict['http_headers'])
|
||||
args += [
|
||||
'-headers',
|
||||
''.join('%s: %s\r\n' % (key, val) for key, val in headers.items())]
|
||||
''.join(f'{key}: {val}\r\n' for key, val in headers.items())]
|
||||
|
||||
env = None
|
||||
proxy = self.params.get('proxy')
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import division, unicode_literals
|
||||
|
||||
import io
|
||||
import itertools
|
||||
import time
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import division, unicode_literals
|
||||
|
||||
import threading
|
||||
|
||||
from .common import FileDownloader
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import division, unicode_literals
|
||||
|
||||
import http.client
|
||||
import json
|
||||
import math
|
||||
|
@ -172,8 +170,7 @@ class FragmentFD(FileDownloader):
|
|||
total_frags_str += ' (not including %d ad)' % ad_frags
|
||||
else:
|
||||
total_frags_str = 'unknown (live)'
|
||||
self.to_screen(
|
||||
'[%s] Total fragments: %s' % (self.FD_NAME, total_frags_str))
|
||||
self.to_screen(f'[{self.FD_NAME}] Total fragments: {total_frags_str}')
|
||||
self.report_destination(ctx['filename'])
|
||||
dl = HttpQuietDownloader(
|
||||
self.ydl,
|
||||
|
@ -342,8 +339,7 @@ class FragmentFD(FileDownloader):
|
|||
total_frags_str += ' (not including %d ad)' % ad_frags
|
||||
else:
|
||||
total_frags_str = 'unknown (live)'
|
||||
self.to_screen(
|
||||
'[%s] Total fragments: %s' % (self.FD_NAME, total_frags_str))
|
||||
self.to_screen(f'[{self.FD_NAME}] Total fragments: {total_frags_str}')
|
||||
|
||||
tmpfilename = self.temp_name(ctx['filename'])
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
import io
|
||||
import binascii
|
||||
|
@ -102,8 +100,7 @@ class HlsFD(FragmentFD):
|
|||
if real_downloader and not real_downloader.supports_manifest(s):
|
||||
real_downloader = None
|
||||
if real_downloader:
|
||||
self.to_screen(
|
||||
'[%s] Fragment downloads will be delegated to %s' % (self.FD_NAME, real_downloader.get_basename()))
|
||||
self.to_screen(f'[{self.FD_NAME}] Fragment downloads will be delegated to {real_downloader.get_basename()}')
|
||||
|
||||
def is_ad_fragment_start(s):
|
||||
return (s.startswith('#ANVATO-SEGMENT-INFO') and 'type=ad' in s
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import ssl
|
||||
import time
|
||||
|
@ -221,10 +219,12 @@ class HttpFD(FileDownloader):
|
|||
min_data_len = self.params.get('min_filesize')
|
||||
max_data_len = self.params.get('max_filesize')
|
||||
if min_data_len is not None and data_len < min_data_len:
|
||||
self.to_screen('\r[download] File is smaller than min-filesize (%s bytes < %s bytes). Aborting.' % (data_len, min_data_len))
|
||||
self.to_screen(
|
||||
f'\r[download] File is smaller than min-filesize ({data_len} bytes < {min_data_len} bytes). Aborting.')
|
||||
return False
|
||||
if max_data_len is not None and data_len > max_data_len:
|
||||
self.to_screen('\r[download] File is larger than max-filesize (%s bytes > %s bytes). Aborting.' % (data_len, max_data_len))
|
||||
self.to_screen(
|
||||
f'\r[download] File is larger than max-filesize ({data_len} bytes > {max_data_len} bytes). Aborting.')
|
||||
return False
|
||||
|
||||
byte_counter = 0 + ctx.resume_len
|
||||
|
@ -265,7 +265,7 @@ class HttpFD(FileDownloader):
|
|||
assert ctx.stream is not None
|
||||
ctx.filename = self.undo_temp_name(ctx.tmpfilename)
|
||||
self.report_destination(ctx.filename)
|
||||
except (OSError, IOError) as err:
|
||||
except OSError as err:
|
||||
self.report_error('unable to open for writing: %s' % str(err))
|
||||
return False
|
||||
|
||||
|
@ -277,7 +277,7 @@ class HttpFD(FileDownloader):
|
|||
|
||||
try:
|
||||
ctx.stream.write(data_block)
|
||||
except (IOError, OSError) as err:
|
||||
except OSError as err:
|
||||
self.to_stderr('\n')
|
||||
self.report_error('unable to write data: %s' % str(err))
|
||||
return False
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import time
|
||||
import binascii
|
||||
import io
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import io
|
||||
import quopri
|
||||
import re
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import threading
|
||||
|
||||
from .common import FileDownloader
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
@ -32,7 +30,7 @@ class RtspFD(FileDownloader):
|
|||
retval = subprocess.call(args)
|
||||
if retval == 0:
|
||||
fsize = os.path.getsize(encodeFilename(tmpfilename))
|
||||
self.to_screen('\r[%s] %s bytes' % (args[0], fsize))
|
||||
self.to_screen(f'\r[{args[0]}] {fsize} bytes')
|
||||
self.try_rename(tmpfilename, filename)
|
||||
self._hook_progress({
|
||||
'downloaded_bytes': fsize,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import division, unicode_literals
|
||||
|
||||
import json
|
||||
import time
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import hashlib
|
||||
import hmac
|
||||
import re
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from .amp import AMPIE
|
||||
from .common import InfoExtractor
|
||||
from ..utils import (
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..compat import compat_str
|
||||
from ..utils import (
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from .common import InfoExtractor
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..utils import (
|
||||
clean_html,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import base64
|
||||
import binascii
|
||||
import json
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..compat import (
|
||||
compat_parse_qs,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import functools
|
||||
import re
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from .turner import TurnerBaseIE
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
from .theplatform import ThePlatformIE
|
||||
from ..utils import (
|
||||
ExtractorError,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import functools
|
||||
import re
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from .common import InfoExtractor
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..compat import compat_str
|
||||
from ..utils import (
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from .common import InfoExtractor
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..compat import compat_str
|
||||
from ..utils import (
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..utils import (
|
||||
parse_iso8601,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..utils import (
|
||||
clean_html,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from .common import InfoExtractor
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .common import InfoExtractor
|
||||
from .youtube import YoutubeIE
|
||||
from .vimeo import VimeoIE
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# coding: utf-8
|
||||
from .common import InfoExtractor
|
||||
from ..utils import int_or_none
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from .theplatform import ThePlatformIE
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from .common import InfoExtractor
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .common import InfoExtractor
|
||||
from ..utils import (
|
||||
determine_ext,
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from .common import InfoExtractor
|
||||
|
||||
from ..utils import (
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from .common import InfoExtractor
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
import urllib.parse
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from .nfl import NFLTokenGenerator
|
||||
|
||||
__all__ = [
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
|
||||
class TokenGenerator:
|
||||
def generate(self, anvack, mcp_id):
|
||||
raise NotImplementedError('This method must be implemented by subclasses')
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from .common import TokenGenerator
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from .yahoo import YahooIE
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# coding: utf-8
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import re
|
||||
|
||||
from .common import InfoExtractor
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue