mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-14 21:23:05 +00:00
Compare commits
2 Commits
2516cafb28
...
e5458d1d88
Author | SHA1 | Date | |
---|---|---|---|
|
e5458d1d88 | ||
|
b5e7a2e69d |
@ -11,13 +11,16 @@ from ..utils import (
|
|||||||
|
|
||||||
# These bloat the lazy_extractors, so allow them to passthrough silently
|
# These bloat the lazy_extractors, so allow them to passthrough silently
|
||||||
ALLOWED_CLASSMETHODS = {'get_testcases', 'extract_from_webpage'}
|
ALLOWED_CLASSMETHODS = {'get_testcases', 'extract_from_webpage'}
|
||||||
|
_WARNED = False
|
||||||
|
|
||||||
|
|
||||||
class LazyLoadMetaClass(type):
|
class LazyLoadMetaClass(type):
|
||||||
def __getattr__(cls, name):
|
def __getattr__(cls, name):
|
||||||
if '_real_class' not in cls.__dict__ and name not in ALLOWED_CLASSMETHODS:
|
global _WARNED
|
||||||
write_string(
|
if ('_real_class' not in cls.__dict__
|
||||||
'WARNING: Falling back to normal extractor since lazy extractor '
|
and name not in ALLOWED_CLASSMETHODS and not _WARNED):
|
||||||
|
_WARNED = True
|
||||||
|
write_string('WARNING: Falling back to normal extractor since lazy extractor '
|
||||||
f'{cls.__name__} does not have attribute {name}{bug_reports_message()}\n')
|
f'{cls.__name__} does not have attribute {name}{bug_reports_message()}\n')
|
||||||
return getattr(cls.real_class, name)
|
return getattr(cls.real_class, name)
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ from inspect import getsource
|
|||||||
from devscripts.utils import get_filename_args, read_file, write_file
|
from devscripts.utils import get_filename_args, read_file, write_file
|
||||||
|
|
||||||
NO_ATTR = object()
|
NO_ATTR = object()
|
||||||
STATIC_CLASS_PROPERTIES = ['IE_NAME', 'IE_DESC', 'SEARCH_KEY', '_VALID_URL', '_WORKING', '_NETRC_MACHINE', 'age_limit']
|
STATIC_CLASS_PROPERTIES = [
|
||||||
|
'IE_NAME', 'IE_DESC', 'SEARCH_KEY', '_VALID_URL', '_WORKING', '_ENABLED', '_NETRC_MACHINE', 'age_limit'
|
||||||
|
]
|
||||||
CLASS_METHODS = [
|
CLASS_METHODS = [
|
||||||
'ie_key', 'working', 'description', 'suitable', '_match_valid_url', '_match_id', 'get_temp_id', 'is_suitable'
|
'ie_key', 'working', 'description', 'suitable', '_match_valid_url', '_match_id', 'get_temp_id', 'is_suitable'
|
||||||
]
|
]
|
||||||
|
@ -11,41 +11,46 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|||||||
import contextlib
|
import contextlib
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from yt_dlp.utils import encodeArgument
|
from yt_dlp.utils import Popen
|
||||||
|
|
||||||
rootDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
rootDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
LAZY_EXTRACTORS = 'yt_dlp/extractor/lazy_extractors.py'
|
||||||
|
|
||||||
try:
|
|
||||||
_DEV_NULL = subprocess.DEVNULL
|
|
||||||
except AttributeError:
|
|
||||||
_DEV_NULL = open(os.devnull, 'wb')
|
|
||||||
|
|
||||||
|
|
||||||
class TestExecution(unittest.TestCase):
|
class TestExecution(unittest.TestCase):
|
||||||
def test_import(self):
|
def run_yt_dlp(self, exe=(sys.executable, 'yt_dlp/__main__.py'), opts=('--version', )):
|
||||||
subprocess.check_call([sys.executable, '-c', 'import yt_dlp'], cwd=rootDir)
|
stdout, stderr, returncode = Popen.run(
|
||||||
|
[*exe, '--ignore-config', *opts], cwd=rootDir, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
def test_module_exec(self):
|
print(stderr, file=sys.stderr)
|
||||||
subprocess.check_call([sys.executable, '-m', 'yt_dlp', '--ignore-config', '--version'], cwd=rootDir, stdout=_DEV_NULL)
|
self.assertEqual(returncode, 0)
|
||||||
|
return stdout.strip(), stderr.strip()
|
||||||
|
|
||||||
def test_main_exec(self):
|
def test_main_exec(self):
|
||||||
subprocess.check_call([sys.executable, 'yt_dlp/__main__.py', '--ignore-config', '--version'], cwd=rootDir, stdout=_DEV_NULL)
|
self.run_yt_dlp()
|
||||||
|
|
||||||
|
def test_import(self):
|
||||||
|
self.run_yt_dlp(exe=(sys.executable, '-c', 'import yt_dlp'))
|
||||||
|
|
||||||
|
def test_module_exec(self):
|
||||||
|
self.run_yt_dlp(exe=(sys.executable, '-m', 'yt_dlp'))
|
||||||
|
|
||||||
def test_cmdline_umlauts(self):
|
def test_cmdline_umlauts(self):
|
||||||
p = subprocess.Popen(
|
_, stderr = self.run_yt_dlp(opts=('ä', '--version'))
|
||||||
[sys.executable, 'yt_dlp/__main__.py', '--ignore-config', encodeArgument('ä'), '--version'],
|
|
||||||
cwd=rootDir, stdout=_DEV_NULL, stderr=subprocess.PIPE)
|
|
||||||
_, stderr = p.communicate()
|
|
||||||
self.assertFalse(stderr)
|
self.assertFalse(stderr)
|
||||||
|
|
||||||
def test_lazy_extractors(self):
|
def test_lazy_extractors(self):
|
||||||
try:
|
try:
|
||||||
subprocess.check_call([sys.executable, 'devscripts/make_lazy_extractors.py', 'yt_dlp/extractor/lazy_extractors.py'], cwd=rootDir, stdout=_DEV_NULL)
|
subprocess.check_call([sys.executable, 'devscripts/make_lazy_extractors.py', LAZY_EXTRACTORS],
|
||||||
subprocess.check_call([sys.executable, 'test/test_all_urls.py'], cwd=rootDir, stdout=_DEV_NULL)
|
cwd=rootDir, stdout=subprocess.DEVNULL)
|
||||||
|
self.assertTrue(os.path.exists(LAZY_EXTRACTORS))
|
||||||
|
|
||||||
|
_, stderr = self.run_yt_dlp(opts=('-s', 'test:'))
|
||||||
|
self.assertFalse(stderr)
|
||||||
|
|
||||||
|
subprocess.check_call([sys.executable, 'test/test_all_urls.py'], cwd=rootDir, stdout=subprocess.DEVNULL)
|
||||||
finally:
|
finally:
|
||||||
with contextlib.suppress(OSError):
|
with contextlib.suppress(OSError):
|
||||||
os.remove('yt_dlp/extractor/lazy_extractors.py')
|
os.remove(LAZY_EXTRACTORS)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -48,7 +48,7 @@ from .postprocessor import (
|
|||||||
get_postprocessor,
|
get_postprocessor,
|
||||||
)
|
)
|
||||||
from .postprocessor.ffmpeg import resolve_mapping as resolve_recode_mapping
|
from .postprocessor.ffmpeg import resolve_mapping as resolve_recode_mapping
|
||||||
from .update import detect_variant
|
from .update import REPOSITORY, current_git_head, detect_variant
|
||||||
from .utils import (
|
from .utils import (
|
||||||
DEFAULT_OUTTMPL,
|
DEFAULT_OUTTMPL,
|
||||||
IDENTITY,
|
IDENTITY,
|
||||||
@ -3314,6 +3314,12 @@ class YoutubeDL:
|
|||||||
return info_dict
|
return info_dict
|
||||||
info_dict.setdefault('epoch', int(time.time()))
|
info_dict.setdefault('epoch', int(time.time()))
|
||||||
info_dict.setdefault('_type', 'video')
|
info_dict.setdefault('_type', 'video')
|
||||||
|
info_dict.setdefault('_version', {
|
||||||
|
'version': __version__,
|
||||||
|
'current_git_head': current_git_head(),
|
||||||
|
'release_git_head': RELEASE_GIT_HEAD,
|
||||||
|
'repository': REPOSITORY,
|
||||||
|
})
|
||||||
|
|
||||||
if remove_private_keys:
|
if remove_private_keys:
|
||||||
reject = lambda k, v: v is None or k.startswith('__') or k in {
|
reject = lambda k, v: v is None or k.startswith('__') or k in {
|
||||||
@ -3678,7 +3684,8 @@ class YoutubeDL:
|
|||||||
if VARIANT not in (None, 'pip'):
|
if VARIANT not in (None, 'pip'):
|
||||||
source += '*'
|
source += '*'
|
||||||
write_debug(join_nonempty(
|
write_debug(join_nonempty(
|
||||||
'yt-dlp version', __version__,
|
f'{"yt-dlp" if REPOSITORY == "yt-dlp/yt-dlp" else REPOSITORY} version',
|
||||||
|
__version__,
|
||||||
f'[{RELEASE_GIT_HEAD}]' if RELEASE_GIT_HEAD else '',
|
f'[{RELEASE_GIT_HEAD}]' if RELEASE_GIT_HEAD else '',
|
||||||
'' if source == 'unknown' else f'({source})',
|
'' if source == 'unknown' else f'({source})',
|
||||||
delim=' '))
|
delim=' '))
|
||||||
@ -3694,18 +3701,8 @@ class YoutubeDL:
|
|||||||
if self.params['compat_opts']:
|
if self.params['compat_opts']:
|
||||||
write_debug('Compatibility options: %s' % ', '.join(self.params['compat_opts']))
|
write_debug('Compatibility options: %s' % ', '.join(self.params['compat_opts']))
|
||||||
|
|
||||||
if source == 'source':
|
if current_git_head():
|
||||||
try:
|
write_debug(f'Git HEAD: {current_git_head()}')
|
||||||
stdout, _, _ = Popen.run(
|
|
||||||
['git', 'rev-parse', '--short', 'HEAD'],
|
|
||||||
text=True, cwd=os.path.dirname(os.path.abspath(__file__)),
|
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
||||||
if re.fullmatch('[0-9a-f]+', stdout.strip()):
|
|
||||||
write_debug(f'Git HEAD: {stdout.strip()}')
|
|
||||||
except Exception:
|
|
||||||
with contextlib.suppress(Exception):
|
|
||||||
sys.exc_clear()
|
|
||||||
|
|
||||||
write_debug(system_identifier())
|
write_debug(system_identifier())
|
||||||
|
|
||||||
exe_versions, ffmpeg_features = FFmpegPostProcessor.get_versions_and_features(self)
|
exe_versions, ffmpeg_features = FFmpegPostProcessor.get_versions_and_features(self)
|
||||||
|
@ -8,12 +8,14 @@ class TestURLIE(InfoExtractor):
|
|||||||
""" Allows addressing of the test cases as test:yout.*be_1 """
|
""" Allows addressing of the test cases as test:yout.*be_1 """
|
||||||
|
|
||||||
IE_DESC = False # Do not list
|
IE_DESC = False # Do not list
|
||||||
_VALID_URL = r'test(?:url)?:(?P<extractor>.+?)(?:_(?P<num>[0-9]+))?$'
|
_VALID_URL = r'test(?:url)?:(?P<extractor>.*?)(?:_(?P<num>[0-9]+))?$'
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
from . import gen_extractor_classes
|
from . import gen_extractor_classes
|
||||||
|
|
||||||
extractor_id, num = self._match_valid_url(url).group('extractor', 'num')
|
extractor_id, num = self._match_valid_url(url).group('extractor', 'num')
|
||||||
|
if not extractor_id:
|
||||||
|
return {'id': ':test', 'title': '', 'url': url}
|
||||||
|
|
||||||
rex = re.compile(extractor_id, flags=re.IGNORECASE)
|
rex = re.compile(extractor_id, flags=re.IGNORECASE)
|
||||||
matching_extractors = [e for e in gen_extractor_classes() if rex.search(e.IE_NAME)]
|
matching_extractors = [e for e in gen_extractor_classes() if rex.search(e.IE_NAME)]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import atexit
|
import atexit
|
||||||
|
import contextlib
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
@ -50,6 +51,19 @@ def detect_variant():
|
|||||||
return VARIANT or _get_variant_and_executable_path()[0]
|
return VARIANT or _get_variant_and_executable_path()[0]
|
||||||
|
|
||||||
|
|
||||||
|
@functools.cache
|
||||||
|
def current_git_head():
|
||||||
|
if detect_variant() != 'source':
|
||||||
|
return
|
||||||
|
with contextlib.suppress(Exception):
|
||||||
|
stdout, _, _ = Popen.run(
|
||||||
|
['git', 'rev-parse', '--short', 'HEAD'],
|
||||||
|
text=True, cwd=os.path.dirname(os.path.abspath(__file__)),
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
if re.fullmatch('[0-9a-f]+', stdout.strip()):
|
||||||
|
return stdout.strip()
|
||||||
|
|
||||||
|
|
||||||
_FILE_SUFFIXES = {
|
_FILE_SUFFIXES = {
|
||||||
'zip': '',
|
'zip': '',
|
||||||
'py2exe': '_min.exe',
|
'py2exe': '_min.exe',
|
||||||
|
Loading…
Reference in New Issue
Block a user