restructured manifest and plugins loading; updated plugins
This commit is contained in:
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import atexit
|
||||
import contextlib
|
||||
import datetime as dt
|
||||
import functools
|
||||
import hashlib
|
||||
import json
|
||||
@@ -57,27 +58,40 @@ def _get_variant_and_executable_path():
|
||||
"""@returns (variant, executable_path)"""
|
||||
if getattr(sys, 'frozen', False):
|
||||
path = sys.executable
|
||||
|
||||
# py2exe: No longer officially supported, but still identify it to block updates
|
||||
if not hasattr(sys, '_MEIPASS'):
|
||||
return 'py2exe', path
|
||||
elif sys._MEIPASS == os.path.dirname(path):
|
||||
return f'{sys.platform}_dir', path
|
||||
elif sys.platform == 'darwin':
|
||||
|
||||
# staticx builds: sys.executable returns a /tmp/ path
|
||||
# No longer officially supported, but still identify them to block updates
|
||||
# Ref: https://staticx.readthedocs.io/en/latest/usage.html#run-time-information
|
||||
if static_exe_path := os.getenv('STATICX_PROG_PATH'):
|
||||
return 'linux_static_exe', static_exe_path
|
||||
|
||||
# We know it's a PyInstaller bundle, but is it "onedir" or "onefile"?
|
||||
suffix = 'dir' if sys._MEIPASS == os.path.dirname(path) else 'exe'
|
||||
system_platform = remove_end(sys.platform, '32')
|
||||
|
||||
if system_platform == 'darwin':
|
||||
# darwin_legacy_exe is no longer supported, but still identify it to block updates
|
||||
machine = '_legacy' if version_tuple(platform.mac_ver()[0]) < (10, 15) else ''
|
||||
else:
|
||||
machine = f'_{platform.machine().lower()}'
|
||||
is_64bits = sys.maxsize > 2**32
|
||||
# Ref: https://en.wikipedia.org/wiki/Uname#Examples
|
||||
if machine[1:] in ('x86', 'x86_64', 'amd64', 'i386', 'i686'):
|
||||
machine = '_x86' if not is_64bits else ''
|
||||
# platform.machine() on 32-bit raspbian OS may return 'aarch64', so check "64-bitness"
|
||||
# See: https://github.com/yt-dlp/yt-dlp/issues/11813
|
||||
elif machine[1:] == 'aarch64' and not is_64bits:
|
||||
machine = '_armv7l'
|
||||
# sys.executable returns a /tmp/ path for staticx builds (linux_static)
|
||||
# Ref: https://staticx.readthedocs.io/en/latest/usage.html#run-time-information
|
||||
if static_exe_path := os.getenv('STATICX_PROG_PATH'):
|
||||
path = static_exe_path
|
||||
return f'{remove_end(sys.platform, "32")}{machine}_exe', path
|
||||
return f'darwin{machine}_{suffix}', path
|
||||
|
||||
if system_platform == 'linux' and platform.libc_ver()[0] != 'glibc':
|
||||
system_platform = 'musllinux'
|
||||
|
||||
machine = f'_{platform.machine().lower()}'
|
||||
is_64bits = sys.maxsize > 2**32
|
||||
# Ref: https://en.wikipedia.org/wiki/Uname#Examples
|
||||
if machine[1:] in ('x86', 'x86_64', 'amd64', 'i386', 'i686'):
|
||||
machine = '_x86' if not is_64bits else ''
|
||||
# platform.machine() on 32-bit raspbian OS may return 'aarch64', so check "64-bitness"
|
||||
# See: https://github.com/yt-dlp/yt-dlp/issues/11813
|
||||
elif machine[1:] == 'aarch64' and not is_64bits:
|
||||
machine = '_armv7l'
|
||||
|
||||
return f'{system_platform}{machine}_{suffix}', path
|
||||
|
||||
path = os.path.dirname(__file__)
|
||||
if isinstance(__loader__, zipimporter):
|
||||
@@ -109,11 +123,12 @@ _FILE_SUFFIXES = {
|
||||
'zip': '',
|
||||
'win_exe': '.exe',
|
||||
'win_x86_exe': '_x86.exe',
|
||||
'win_arm64_exe': '_arm64.exe',
|
||||
'darwin_exe': '_macos',
|
||||
'darwin_legacy_exe': '_macos_legacy',
|
||||
'linux_exe': '_linux',
|
||||
'linux_aarch64_exe': '_linux_aarch64',
|
||||
'linux_armv7l_exe': '_linux_armv7l',
|
||||
'musllinux_exe': '_musllinux',
|
||||
'musllinux_aarch64_exe': '_musllinux_aarch64',
|
||||
}
|
||||
|
||||
_NON_UPDATEABLE_REASONS = {
|
||||
@@ -139,7 +154,7 @@ def _get_binary_name():
|
||||
|
||||
|
||||
def _get_system_deprecation():
|
||||
MIN_SUPPORTED, MIN_RECOMMENDED = (3, 9), (3, 9)
|
||||
MIN_SUPPORTED, MIN_RECOMMENDED = (3, 10), (3, 10)
|
||||
|
||||
if sys.version_info > MIN_RECOMMENDED:
|
||||
return None
|
||||
@@ -153,6 +168,22 @@ def _get_system_deprecation():
|
||||
return f'Support for Python version {major}.{minor} has been deprecated. {PYTHON_MSG}'
|
||||
|
||||
|
||||
def _get_outdated_warning():
|
||||
# Only yt-dlp guarantees a stable release at least every 90 days
|
||||
if not ORIGIN.startswith('yt-dlp/'):
|
||||
return None
|
||||
|
||||
with contextlib.suppress(Exception):
|
||||
last_updated = dt.date(*version_tuple(__version__)[:3])
|
||||
if last_updated < dt.datetime.now(dt.timezone.utc).date() - dt.timedelta(days=90):
|
||||
return ('\n '.join((
|
||||
f'Your yt-dlp version ({__version__}) is older than 90 days!',
|
||||
'It is strongly recommended to always use the latest version.',
|
||||
f'{is_non_updateable() or """Run "yt-dlp --update" or "yt-dlp -U" to update"""}.',
|
||||
'To suppress this warning, add --no-update to your command/config.')))
|
||||
return None
|
||||
|
||||
|
||||
def _sha256_file(path):
|
||||
h = hashlib.sha256()
|
||||
mv = memoryview(bytearray(128 * 1024))
|
||||
@@ -163,16 +194,14 @@ def _sha256_file(path):
|
||||
|
||||
|
||||
def _make_label(origin, tag, version=None):
|
||||
if '/' in origin:
|
||||
channel = _INVERSE_UPDATE_SOURCES.get(origin, origin)
|
||||
else:
|
||||
channel = origin
|
||||
label = f'{channel}@{tag}'
|
||||
if version and version != tag:
|
||||
label += f' build {version}'
|
||||
if channel != origin:
|
||||
label += f' from {origin}'
|
||||
return label
|
||||
if tag != version:
|
||||
if version:
|
||||
return f'{origin}@{tag} build {version}'
|
||||
return f'{origin}@{tag}'
|
||||
|
||||
if channel := _INVERSE_UPDATE_SOURCES.get(origin):
|
||||
return f'{channel}@{tag} from {origin}'
|
||||
return f'{origin}@{tag}'
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -530,11 +559,9 @@ class Updater:
|
||||
@functools.cached_property
|
||||
def cmd(self):
|
||||
"""The command-line to run the executable, if known"""
|
||||
argv = None
|
||||
# There is no sys.orig_argv in py < 3.10. Also, it can be [] when frozen
|
||||
if getattr(sys, 'orig_argv', None):
|
||||
argv = sys.orig_argv
|
||||
elif getattr(sys, 'frozen', False):
|
||||
argv = sys.orig_argv
|
||||
# sys.orig_argv can be [] when frozen
|
||||
if not argv and getattr(sys, 'frozen', False):
|
||||
argv = sys.argv
|
||||
# linux_static exe's argv[0] will be /tmp/staticx-NNNN/yt-dlp_linux if we don't fixup here
|
||||
if argv and os.getenv('STATICX_PROG_PATH'):
|
||||
@@ -543,7 +570,7 @@ class Updater:
|
||||
|
||||
def restart(self):
|
||||
"""Restart the executable"""
|
||||
assert self.cmd, 'Must be frozen or Py >= 3.10'
|
||||
assert self.cmd, 'Unable to determine argv'
|
||||
self.ydl.write_debug(f'Restarting: {shell_quote(self.cmd)}')
|
||||
_, _, returncode = Popen.run(self.cmd)
|
||||
return returncode
|
||||
|
||||
Reference in New Issue
Block a user