1
0
mirror of https://github.com/ytdl-org/youtube-dl.git synced 2025-01-30 22:59:48 +00:00

Merge branch 'ytdl-org:master' into master

This commit is contained in:
bibiak 2023-06-13 07:10:17 +02:00 committed by GitHub
commit 7caa31f0f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 85 additions and 19 deletions

View File

@ -33,6 +33,55 @@ class TestJSInterpreter(unittest.TestCase):
jsi = JSInterpreter('function x4(a){return 2*a+1;}') jsi = JSInterpreter('function x4(a){return 2*a+1;}')
self.assertEqual(jsi.call_function('x4', 3), 7) self.assertEqual(jsi.call_function('x4', 3), 7)
def test_add(self):
jsi = JSInterpreter('function f(){return 42 + 7;}')
self.assertEqual(jsi.call_function('f'), 49)
jsi = JSInterpreter('function f(){return 42 + undefined;}')
self.assertTrue(math.isnan(jsi.call_function('f')))
jsi = JSInterpreter('function f(){return 42 + null;}')
self.assertEqual(jsi.call_function('f'), 42)
def test_sub(self):
jsi = JSInterpreter('function f(){return 42 - 7;}')
self.assertEqual(jsi.call_function('f'), 35)
jsi = JSInterpreter('function f(){return 42 - undefined;}')
self.assertTrue(math.isnan(jsi.call_function('f')))
jsi = JSInterpreter('function f(){return 42 - null;}')
self.assertEqual(jsi.call_function('f'), 42)
def test_mul(self):
jsi = JSInterpreter('function f(){return 42 * 7;}')
self.assertEqual(jsi.call_function('f'), 294)
jsi = JSInterpreter('function f(){return 42 * undefined;}')
self.assertTrue(math.isnan(jsi.call_function('f')))
jsi = JSInterpreter('function f(){return 42 * null;}')
self.assertEqual(jsi.call_function('f'), 0)
def test_div(self):
jsi = JSInterpreter('function f(a, b){return a / b;}')
self.assertTrue(math.isnan(jsi.call_function('f', 0, 0)))
self.assertTrue(math.isnan(jsi.call_function('f', JS_Undefined, 1)))
self.assertTrue(math.isinf(jsi.call_function('f', 2, 0)))
self.assertEqual(jsi.call_function('f', 0, 3), 0)
def test_mod(self):
jsi = JSInterpreter('function f(){return 42 % 7;}')
self.assertEqual(jsi.call_function('f'), 0)
jsi = JSInterpreter('function f(){return 42 % 0;}')
self.assertTrue(math.isnan(jsi.call_function('f')))
jsi = JSInterpreter('function f(){return 42 % undefined;}')
self.assertTrue(math.isnan(jsi.call_function('f')))
def test_exp(self):
jsi = JSInterpreter('function f(){return 42 ** 2;}')
self.assertEqual(jsi.call_function('f'), 1764)
jsi = JSInterpreter('function f(){return 42 ** undefined;}')
self.assertTrue(math.isnan(jsi.call_function('f')))
jsi = JSInterpreter('function f(){return 42 ** null;}')
self.assertEqual(jsi.call_function('f'), 1)
jsi = JSInterpreter('function f(){return undefined ** 42;}')
self.assertTrue(math.isnan(jsi.call_function('f')))
def test_empty_return(self): def test_empty_return(self):
jsi = JSInterpreter('function f(){return; y()}') jsi = JSInterpreter('function f(){return; y()}')
self.assertEqual(jsi.call_function('f'), None) self.assertEqual(jsi.call_function('f'), None)
@ -516,6 +565,9 @@ class TestJSInterpreter(unittest.TestCase):
jsi = JSInterpreter('function x(){return 42 << NaN}') jsi = JSInterpreter('function x(){return 42 << NaN}')
self.assertEqual(jsi.call_function('x'), 42) self.assertEqual(jsi.call_function('x'), 42)
jsi = JSInterpreter('function x(){return 42 << Infinity}')
self.assertEqual(jsi.call_function('x'), 42)
def test_32066(self): def test_32066(self):
jsi = JSInterpreter("function x(){return Math.pow(3, 5) + new Date('1970-01-01T08:01:42.000+08:00') / 1000 * -239 - -24205;}") jsi = JSInterpreter("function x(){return Math.pow(3, 5) + new Date('1970-01-01T08:01:42.000+08:00') / 1000 * -239 - -24205;}")
self.assertEqual(jsi.call_function('x'), 70) self.assertEqual(jsi.call_function('x'), 70)

View File

@ -143,6 +143,18 @@ _NSIG_TESTS = [
'https://www.youtube.com/s/player/dac945fd/player_ias.vflset/en_US/base.js', 'https://www.youtube.com/s/player/dac945fd/player_ias.vflset/en_US/base.js',
'o8BkRxXhuYsBCWi6RplPdP', '3Lx32v_hmzTm6A', 'o8BkRxXhuYsBCWi6RplPdP', '3Lx32v_hmzTm6A',
), ),
(
'https://www.youtube.com/s/player/6f20102c/player_ias.vflset/en_US/base.js',
'lE8DhoDmKqnmJJ', 'pJTTX6XyJP2BYw',
),
(
'https://www.youtube.com/s/player/cfa9e7cb/player_ias.vflset/en_US/base.js',
'qO0NiMtYQ7TeJnfFG2', 'k9cuJDHNS5O7kQ',
),
(
'https://www.youtube.com/s/player/8c7583ff/player_ias.vflset/en_US/base.js',
'E2AQVN6y_zM7uN9w8z', '9A2dbY5GDZrt9A',
),
] ]

View File

@ -102,6 +102,7 @@ from .utils import (
YoutubeDLCookieProcessor, YoutubeDLCookieProcessor,
YoutubeDLHandler, YoutubeDLHandler,
YoutubeDLRedirectHandler, YoutubeDLRedirectHandler,
ytdl_is_updateable,
) )
from .cache import Cache from .cache import Cache
from .extractor import get_info_extractor, gen_extractor_classes, _LAZY_LOADER from .extractor import get_info_extractor, gen_extractor_classes, _LAZY_LOADER
@ -2373,9 +2374,10 @@ class YoutubeDL(object):
self.get_encoding())) self.get_encoding()))
write_string(encoding_str, encoding=None) write_string(encoding_str, encoding=None)
self._write_string('[debug] youtube-dl version ' + __version__ + '\n') self._write_string('[debug] youtube-dl version ' + __version__ + (' (single file build)\n' if ytdl_is_updateable() else '\n'))
if _LAZY_LOADER: if _LAZY_LOADER:
self._write_string('[debug] Lazy loading extractors enabled' + '\n') self._write_string('[debug] Lazy loading extractors enabled\n')
writeln_debug = lambda *s: self._write_string('[debug] %s\n' % (''.join(s), )) # moved down for easier merge
try: try:
sp = subprocess.Popen( sp = subprocess.Popen(
['git', 'rev-parse', '--short', 'HEAD'], ['git', 'rev-parse', '--short', 'HEAD'],
@ -2384,7 +2386,7 @@ class YoutubeDL(object):
out, err = process_communicate_or_kill(sp) out, err = process_communicate_or_kill(sp)
out = out.decode().strip() out = out.decode().strip()
if re.match('[0-9a-f]+', out): if re.match('[0-9a-f]+', out):
self._write_string('[debug] Git HEAD: ' + out + '\n') writeln_debug('Git HEAD: ', out)
except Exception: except Exception:
try: try:
sys.exc_clear() sys.exc_clear()
@ -2403,13 +2405,15 @@ class YoutubeDL(object):
except OSError: # We may not have access to the executable except OSError: # We may not have access to the executable
return [] return []
self._write_string('[debug] Python %s (%s %s) - %s (%s%s)\n' % ( libc = join_nonempty(*libc_ver(), delim=' ')
writeln_debug('Python %s (%s %s %s) - %s - %s%s' % (
platform.python_version(), platform.python_version(),
python_implementation(), python_implementation(),
platform.machine(),
platform.architecture()[0], platform.architecture()[0],
platform_name(), platform_name(),
OPENSSL_VERSION, OPENSSL_VERSION,
', %s' % (join_nonempty(*libc_ver(), delim=' ') or '-'), (' - %s' % (libc, )) if libc else ''
)) ))
exe_versions = FFmpegPostProcessor.get_versions(self) exe_versions = FFmpegPostProcessor.get_versions(self)
@ -2422,17 +2426,17 @@ class YoutubeDL(object):
) )
if not exe_str: if not exe_str:
exe_str = 'none' exe_str = 'none'
self._write_string('[debug] exe versions: %s\n' % exe_str) writeln_debug('exe versions: %s' % (exe_str, ))
proxy_map = {} proxy_map = {}
for handler in self._opener.handlers: for handler in self._opener.handlers:
if hasattr(handler, 'proxies'): if hasattr(handler, 'proxies'):
proxy_map.update(handler.proxies) proxy_map.update(handler.proxies)
self._write_string('[debug] Proxy map: ' + compat_str(proxy_map) + '\n') writeln_debug('Proxy map: ', compat_str(proxy_map))
if self.params.get('call_home', False): if self.params.get('call_home', False):
ipaddr = self.urlopen('https://yt-dl.org/ip').read().decode('utf-8') ipaddr = self.urlopen('https://yt-dl.org/ip').read().decode('utf-8')
self._write_string('[debug] Public IP address: %s\n' % ipaddr) writeln_debug('Public IP address: %s' % (ipaddr, ))
latest_version = self.urlopen( latest_version = self.urlopen(
'https://yt-dl.org/latest/version').read().decode('utf-8') 'https://yt-dl.org/latest/version').read().decode('utf-8')
if version_tuple(latest_version) > version_tuple(__version__): if version_tuple(latest_version) > version_tuple(__version__):

View File

@ -1663,5 +1663,5 @@ def casefold(s):
__all__ = [ __all__ = [
casefold 'casefold',
] ]

View File

@ -59,7 +59,7 @@ class ITVBaseIE(InfoExtractor):
@staticmethod @staticmethod
def _vanilla_ua_header(): def _vanilla_ua_header():
return {'User-agent': 'Mozilla/5.0'} return {'User-Agent': 'Mozilla/5.0'}
def _download_webpage_handle(self, url, video_id, *args, **kwargs): def _download_webpage_handle(self, url, video_id, *args, **kwargs):
# specialised to (a) use vanilla UA (b) detect geo-block # specialised to (a) use vanilla UA (b) detect geo-block
@ -69,7 +69,7 @@ class ITVBaseIE(InfoExtractor):
'user_agent' not in params 'user_agent' not in params
and not any(re.match(r'(?i)user-agent\s*:', h) and not any(re.match(r'(?i)user-agent\s*:', h)
for h in (params.get('headers') or [])) for h in (params.get('headers') or []))
and 'User-agent' not in (kwargs.get('headers') or {})): and 'User-Agent' not in (kwargs.get('headers') or {})):
kwargs.setdefault('headers', {}) kwargs.setdefault('headers', {})
kwargs['headers'] = self._vanilla_ua_header() kwargs['headers'] = self._vanilla_ua_header()

View File

@ -2,7 +2,6 @@ from __future__ import unicode_literals
import itertools import itertools
import json import json
import math
import operator import operator
import re import re
@ -52,6 +51,10 @@ def wraps_op(op):
return update_and_rename_wrapper return update_and_rename_wrapper
# NB In principle NaN cannot be checked by membership.
# Here all NaN values are actually this one, so _NaN is _NaN,
# although _NaN != _NaN.
_NaN = float('nan') _NaN = float('nan')
@ -79,7 +82,7 @@ def _js_arith_op(op):
def _js_div(a, b): def _js_div(a, b):
if JS_Undefined in (a, b) or not (a and b): if JS_Undefined in (a, b) or not (a or b):
return _NaN return _NaN
return operator.truediv(a or 0, b) if b else float('inf') return operator.truediv(a or 0, b) if b else float('inf')
@ -126,13 +129,8 @@ def _js_comp_op(op):
def _js_ternary(cndn, if_true=True, if_false=False): def _js_ternary(cndn, if_true=True, if_false=False):
"""Simulate JS's ternary operator (cndn?if_true:if_false)""" """Simulate JS's ternary operator (cndn?if_true:if_false)"""
if cndn in (False, None, 0, '', JS_Undefined): if cndn in (False, None, 0, '', JS_Undefined, _NaN):
return if_false return if_false
try:
if math.isnan(cndn): # NB: NaN cannot be checked by membership
return if_false
except TypeError:
pass
return if_true return if_true