mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-03 08:19:57 +01:00
[update] Ability to set a maximum version for specific variants
This commit is contained in:
parent
c2c8921b41
commit
b1f94422cc
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@ -449,6 +449,19 @@ jobs:
|
|||||||
asset_name: SHA2-512SUMS
|
asset_name: SHA2-512SUMS
|
||||||
asset_content_type: text/plain
|
asset_content_type: text/plain
|
||||||
|
|
||||||
|
- name: Make Update spec
|
||||||
|
run: |
|
||||||
|
echo "# This file is used for regulating self-update" >> _update_spec
|
||||||
|
- name: Upload update spec
|
||||||
|
uses: actions/upload-release-asset@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||||
|
asset_path: ./_update_spec
|
||||||
|
asset_name: _update_spec
|
||||||
|
asset_content_type: text/plain
|
||||||
|
|
||||||
- name: Finalize release
|
- name: Finalize release
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
import locale
|
import locale
|
||||||
import operator
|
import operator
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
@ -110,7 +109,6 @@
|
|||||||
number_of_digits,
|
number_of_digits,
|
||||||
orderedSet,
|
orderedSet,
|
||||||
parse_filesize,
|
parse_filesize,
|
||||||
platform_name,
|
|
||||||
preferredencoding,
|
preferredencoding,
|
||||||
prepend_extension,
|
prepend_extension,
|
||||||
register_socks_protocols,
|
register_socks_protocols,
|
||||||
@ -126,6 +124,7 @@
|
|||||||
strftime_or_none,
|
strftime_or_none,
|
||||||
subtitles_filename,
|
subtitles_filename,
|
||||||
supports_terminal_sequences,
|
supports_terminal_sequences,
|
||||||
|
system_identifier,
|
||||||
timetuple_from_msec,
|
timetuple_from_msec,
|
||||||
to_high_limit_path,
|
to_high_limit_path,
|
||||||
traverse_obj,
|
traverse_obj,
|
||||||
@ -3656,17 +3655,7 @@ def get_encoding(stream):
|
|||||||
with contextlib.suppress(Exception):
|
with contextlib.suppress(Exception):
|
||||||
sys.exc_clear()
|
sys.exc_clear()
|
||||||
|
|
||||||
def python_implementation():
|
write_debug(system_identifier())
|
||||||
impl_name = platform.python_implementation()
|
|
||||||
if impl_name == 'PyPy' and hasattr(sys, 'pypy_version_info'):
|
|
||||||
return impl_name + ' version %d.%d.%d' % sys.pypy_version_info[:3]
|
|
||||||
return impl_name
|
|
||||||
|
|
||||||
write_debug('Python version %s (%s %s) - %s' % (
|
|
||||||
platform.python_version(),
|
|
||||||
python_implementation(),
|
|
||||||
platform.architecture()[0],
|
|
||||||
platform_name()))
|
|
||||||
|
|
||||||
exe_versions, ffmpeg_features = FFmpegPostProcessor.get_versions_and_features(self)
|
exe_versions, ffmpeg_features = FFmpegPostProcessor.get_versions_and_features(self)
|
||||||
ffmpeg_features = {key for key, val in ffmpeg_features.items() if val}
|
ffmpeg_features = {key for key, val in ffmpeg_features.items() if val}
|
||||||
|
@ -3,17 +3,25 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from zipimport import zipimporter
|
from zipimport import zipimporter
|
||||||
|
|
||||||
from .compat import functools # isort: split
|
from .compat import functools # isort: split
|
||||||
from .compat import compat_realpath
|
from .compat import compat_realpath
|
||||||
from .utils import Popen, shell_quote, traverse_obj, version_tuple
|
from .utils import (
|
||||||
|
Popen,
|
||||||
|
cached_method,
|
||||||
|
shell_quote,
|
||||||
|
system_identifier,
|
||||||
|
traverse_obj,
|
||||||
|
version_tuple,
|
||||||
|
)
|
||||||
from .version import __version__
|
from .version import __version__
|
||||||
|
|
||||||
REPOSITORY = 'yt-dlp/yt-dlp'
|
REPOSITORY = 'yt-dlp/yt-dlp'
|
||||||
API_URL = f'https://api.github.com/repos/{REPOSITORY}/releases/latest'
|
API_URL = f'https://api.github.com/repos/{REPOSITORY}/releases'
|
||||||
|
|
||||||
|
|
||||||
@functools.cache
|
@functools.cache
|
||||||
@ -79,9 +87,20 @@ def __init__(self, ydl):
|
|||||||
self.ydl = ydl
|
self.ydl = ydl
|
||||||
|
|
||||||
@functools.cached_property
|
@functools.cached_property
|
||||||
def _new_version_info(self):
|
def _tag(self):
|
||||||
self.ydl.write_debug(f'Fetching release info: {API_URL}')
|
identifier = f'{detect_variant()} {system_identifier()}'
|
||||||
return json.loads(self.ydl.urlopen(API_URL).read().decode())
|
for line in self._download('_update_spec', 'latest').decode().splitlines():
|
||||||
|
if not line.startswith('lock '):
|
||||||
|
continue
|
||||||
|
_, tag, pattern = line.split(' ', 2)
|
||||||
|
if re.match(pattern, identifier):
|
||||||
|
return f'tags/{tag}'
|
||||||
|
return 'latest'
|
||||||
|
|
||||||
|
@cached_method
|
||||||
|
def _get_version_info(self, tag):
|
||||||
|
self.ydl.write_debug(f'Fetching release info: {API_URL}/{tag}')
|
||||||
|
return json.loads(self.ydl.urlopen(f'{API_URL}/{tag}').read().decode())
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_version(self):
|
def current_version(self):
|
||||||
@ -91,7 +110,7 @@ def current_version(self):
|
|||||||
@property
|
@property
|
||||||
def new_version(self):
|
def new_version(self):
|
||||||
"""Version of the latest release"""
|
"""Version of the latest release"""
|
||||||
return self._new_version_info['tag_name']
|
return self._get_version_info(self._tag)['tag_name']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_update(self):
|
def has_update(self):
|
||||||
@ -103,9 +122,8 @@ def filename(self):
|
|||||||
"""Filename of the executable"""
|
"""Filename of the executable"""
|
||||||
return compat_realpath(_get_variant_and_executable_path()[1])
|
return compat_realpath(_get_variant_and_executable_path()[1])
|
||||||
|
|
||||||
def _download(self, name=None):
|
def _download(self, name, tag):
|
||||||
name = name or self.release_name
|
url = traverse_obj(self._get_version_info(tag), (
|
||||||
url = traverse_obj(self._new_version_info, (
|
|
||||||
'assets', lambda _, v: v['name'] == name, 'browser_download_url'), get_all=False)
|
'assets', lambda _, v: v['name'] == name, 'browser_download_url'), get_all=False)
|
||||||
if not url:
|
if not url:
|
||||||
raise Exception('Unable to find download URL')
|
raise Exception('Unable to find download URL')
|
||||||
@ -123,7 +141,7 @@ def release_name(self):
|
|||||||
@functools.cached_property
|
@functools.cached_property
|
||||||
def release_hash(self):
|
def release_hash(self):
|
||||||
"""Hash of the latest release"""
|
"""Hash of the latest release"""
|
||||||
hash_data = dict(ln.split()[::-1] for ln in self._download('SHA2-256SUMS').decode().splitlines())
|
hash_data = dict(ln.split()[::-1] for ln in self._download('SHA2-256SUMS', self._tag).decode().splitlines())
|
||||||
return hash_data[self.release_name]
|
return hash_data[self.release_name]
|
||||||
|
|
||||||
def _report_error(self, msg, expected=False):
|
def _report_error(self, msg, expected=False):
|
||||||
@ -176,7 +194,7 @@ def update(self):
|
|||||||
return self._report_error('Unable to remove the old version')
|
return self._report_error('Unable to remove the old version')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
newcontent = self._download()
|
newcontent = self._download(self.release_name, self._tag)
|
||||||
except OSError:
|
except OSError:
|
||||||
return self._report_network_error('download latest version')
|
return self._report_network_error('download latest version')
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
import http.client
|
import http.client
|
||||||
import http.cookiejar
|
import http.cookiejar
|
||||||
import importlib.util
|
import importlib.util
|
||||||
|
import inspect
|
||||||
import io
|
import io
|
||||||
import itertools
|
import itertools
|
||||||
import json
|
import json
|
||||||
@ -1909,12 +1910,23 @@ def __str__(self):
|
|||||||
|
|
||||||
def platform_name():
|
def platform_name():
|
||||||
""" Returns the platform name as a str """
|
""" Returns the platform name as a str """
|
||||||
res = platform.platform()
|
write_string('DeprecationWarning: yt_dlp.utils.platform_name is deprecated, use platform.platform instead')
|
||||||
if isinstance(res, bytes):
|
return platform.platform()
|
||||||
res = res.decode(preferredencoding())
|
|
||||||
|
|
||||||
assert isinstance(res, str)
|
|
||||||
return res
|
@functools.cache
|
||||||
|
def system_identifier():
|
||||||
|
python_implementation = platform.python_implementation()
|
||||||
|
if python_implementation == 'PyPy' and hasattr(sys, 'pypy_version_info'):
|
||||||
|
python_implementation += ' version %d.%d.%d' % sys.pypy_version_info[:3]
|
||||||
|
|
||||||
|
return 'Python %s (%s %s) - %s %s' % (
|
||||||
|
platform.python_version(),
|
||||||
|
python_implementation,
|
||||||
|
platform.architecture()[0],
|
||||||
|
platform.platform(),
|
||||||
|
format_field(join_nonempty(*platform.libc_ver(), delim=' '), None, '(%s)'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@functools.cache
|
@functools.cache
|
||||||
@ -5544,8 +5556,27 @@ def merge_headers(*dicts):
|
|||||||
return {k.title(): v for k, v in itertools.chain.from_iterable(map(dict.items, dicts))}
|
return {k.title(): v for k, v in itertools.chain.from_iterable(map(dict.items, dicts))}
|
||||||
|
|
||||||
|
|
||||||
|
def cached_method(f):
|
||||||
|
"""Cache a method"""
|
||||||
|
signature = inspect.signature(f)
|
||||||
|
|
||||||
|
@functools.wraps(f)
|
||||||
|
def wrapper(self, *args, **kwargs):
|
||||||
|
bound_args = signature.bind(self, *args, **kwargs)
|
||||||
|
bound_args.apply_defaults()
|
||||||
|
key = tuple(bound_args.arguments.values())
|
||||||
|
|
||||||
|
if not hasattr(self, '__cached_method__cache'):
|
||||||
|
self.__cached_method__cache = {}
|
||||||
|
cache = self.__cached_method__cache.setdefault(f.__name__, {})
|
||||||
|
if key not in cache:
|
||||||
|
cache[key] = f(self, *args, **kwargs)
|
||||||
|
return cache[key]
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class classproperty:
|
class classproperty:
|
||||||
"""classmethod(property(func)) that works in py < 3.9"""
|
"""property access for class methods"""
|
||||||
|
|
||||||
def __init__(self, func):
|
def __init__(self, func):
|
||||||
functools.update_wrapper(self, func)
|
functools.update_wrapper(self, func)
|
||||||
|
Loading…
Reference in New Issue
Block a user