mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 06:35:12 +00:00 
			
		
		
		
	[update] Ability to set a maximum version for specific variants
This commit is contained in:
		
							
								
								
									
										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 json | |||||||
| 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 @@ from .utils import ( | |||||||
|     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 @@ from .utils import ( | |||||||
|     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 @@ class YoutubeDL: | |||||||
|                 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 hashlib | |||||||
| 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 @@ class Updater: | |||||||
|         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 @@ class Updater: | |||||||
|     @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 @@ class Updater: | |||||||
|         """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 @@ class Updater: | |||||||
|     @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 @@ class Updater: | |||||||
|             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 html.parser | |||||||
| 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 @@ class DateRange: | |||||||
| 
 | 
 | ||||||
| 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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 pukkandan
					pukkandan