diff --git a/README.md b/README.md index 0f9a7d556..e476c0084 100644 --- a/README.md +++ b/README.md @@ -1156,15 +1156,15 @@ # CONFIGURATION * `/etc/yt-dlp/config` * `/etc/yt-dlp/config.txt` -E.g. with the following configuration file, yt-dlp will always extract the audio, not copy the mtime, use a proxy and save all videos under `YouTube` directory in your home directory: +E.g. with the following configuration file, yt-dlp will always extract the audio, copy the mtime, use a proxy and save all videos under `YouTube` directory in your home directory: ``` # Lines starting with # are comments # Always extract audio -x -# Do not copy the mtime ---no-mtime +# Copy the mtime +--mtime # Use this proxy --proxy 127.0.0.1:3128 @@ -2262,6 +2262,7 @@ ### Differences in default behavior * yt-dlp uses modern http client backends such as `requests`. Use `--compat-options prefer-legacy-http-handler` to prefer the legacy http handler (`urllib`) to be used for standard http requests. * The sub-modules `swfinterp`, `casefold` are removed. * Passing `--simulate` (or calling `extract_info` with `download=False`) no longer alters the default format selection. See [#9843](https://github.com/yt-dlp/yt-dlp/issues/9843) for details. +* yt-dlp no longer applies the server modified time to downloaded files by default. Use `--mtime` or `--compat-options mtime-by-default` to revert this. For ease of use, a few more compat options are available: @@ -2271,7 +2272,7 @@ ### Differences in default behavior * `--compat-options 2021`: Same as `--compat-options 2022,no-certifi,filename-sanitization` * `--compat-options 2022`: Same as `--compat-options 2023,playlist-match-filter,no-external-downloader-progress,prefer-legacy-http-handler,manifest-filesize-approx` * `--compat-options 2023`: Same as `--compat-options 2024,prefer-vp9-sort` -* `--compat-options 2024`: Currently does nothing. Use this to enable all future compat options +* `--compat-options 2024`: Same as `--compat-options mtime-by-default`. Use this to enable all future compat options The following compat options restore vulnerable behavior from before security patches: diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 67ca90349..44a6696c0 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -482,7 +482,8 @@ class YoutubeDL: The following options do not work when used through the API: filename, abort-on-error, multistreams, no-live-chat, format-sort, no-clean-infojson, no-playlist-metafiles, - no-keep-subs, no-attach-info-json, allow-unsafe-ext, prefer-vp9-sort. + no-keep-subs, no-attach-info-json, allow-unsafe-ext, prefer-vp9-sort, + mtime-by-default. Refer __init__.py for their implementation progress_template: Dictionary of templates for progress outputs. Allowed keys are 'download', 'postprocess', diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index 714d9ad5c..2e7646b7e 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -159,6 +159,12 @@ def set_default_compat(compat_name, opt_name, default=True, remove_compat=True): elif 'prefer-vp9-sort' in opts.compat_opts: opts.format_sort.extend(FormatSorter._prefer_vp9_sort) + if 'mtime-by-default' in opts.compat_opts: + if opts.updatetime is None: + opts.updatetime = True + else: + _unused_compat_opt('mtime-by-default') + _video_multistreams_set = set_default_compat('multistreams', 'allow_multiple_video_streams', False, remove_compat=False) _audio_multistreams_set = set_default_compat('multistreams', 'allow_multiple_audio_streams', False, remove_compat=False) if _video_multistreams_set is False and _audio_multistreams_set is False: diff --git a/yt_dlp/downloader/fragment.py b/yt_dlp/downloader/fragment.py index 98784e703..7852ae90d 100644 --- a/yt_dlp/downloader/fragment.py +++ b/yt_dlp/downloader/fragment.py @@ -302,7 +302,7 @@ def _finish_frag_download(self, ctx, info_dict): elif to_file: self.try_rename(ctx['tmpfilename'], ctx['filename']) filetime = ctx.get('fragment_filetime') - if self.params.get('updatetime', True) and filetime: + if self.params.get('updatetime') and filetime: with contextlib.suppress(Exception): os.utime(ctx['filename'], (time.time(), filetime)) diff --git a/yt_dlp/downloader/http.py b/yt_dlp/downloader/http.py index 9c6dd8b79..90bfcaf55 100644 --- a/yt_dlp/downloader/http.py +++ b/yt_dlp/downloader/http.py @@ -348,7 +348,7 @@ def retry(e): self.try_rename(ctx.tmpfilename, ctx.filename) # Update file modification time - if self.params.get('updatetime', True): + if self.params.get('updatetime'): info_dict['filetime'] = self.try_utime(ctx.filename, ctx.data.headers.get('last-modified', None)) self._hook_progress({ diff --git a/yt_dlp/options.py b/yt_dlp/options.py index b4d3d4d66..13ba445df 100644 --- a/yt_dlp/options.py +++ b/yt_dlp/options.py @@ -529,14 +529,14 @@ def _preset_alias_callback(option, opt_str, value, parser): 'no-attach-info-json', 'embed-thumbnail-atomicparsley', 'no-external-downloader-progress', 'embed-metadata', 'seperate-video-versions', 'no-clean-infojson', 'no-keep-subs', 'no-certifi', 'no-youtube-channel-redirect', 'no-youtube-unavailable-videos', 'no-youtube-prefer-utc-upload-date', - 'prefer-legacy-http-handler', 'manifest-filesize-approx', 'allow-unsafe-ext', 'prefer-vp9-sort', + 'prefer-legacy-http-handler', 'manifest-filesize-approx', 'allow-unsafe-ext', 'prefer-vp9-sort', 'mtime-by-default', }, 'aliases': { 'youtube-dl': ['all', '-multistreams', '-playlist-match-filter', '-manifest-filesize-approx', '-allow-unsafe-ext', '-prefer-vp9-sort'], 'youtube-dlc': ['all', '-no-youtube-channel-redirect', '-no-live-chat', '-playlist-match-filter', '-manifest-filesize-approx', '-allow-unsafe-ext', '-prefer-vp9-sort'], '2021': ['2022', 'no-certifi', 'filename-sanitization'], '2022': ['2023', 'no-external-downloader-progress', 'playlist-match-filter', 'prefer-legacy-http-handler', 'manifest-filesize-approx'], '2023': ['2024', 'prefer-vp9-sort'], - '2024': [], + '2024': ['mtime-by-default'], }, }, help=( 'Options that can help keep compatibility with youtube-dl or youtube-dlc ' @@ -1466,12 +1466,12 @@ def _preset_alias_callback(option, opt_str, value, parser): help='Do not use .part files - write directly into output file') filesystem.add_option( '--mtime', - action='store_true', dest='updatetime', default=True, - help='Use the Last-modified header to set the file modification time (default)') + action='store_true', dest='updatetime', default=None, + help='Use the Last-modified header to set the file modification time') filesystem.add_option( '--no-mtime', action='store_false', dest='updatetime', - help='Do not use the Last-modified header to set the file modification time') + help='Do not use the Last-modified header to set the file modification time (default)') filesystem.add_option( '--write-description', action='store_true', dest='writedescription', default=False,