From b300c7c1c4e96644380d3a013245c038884178b7 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Mon, 2 Oct 2023 17:00:31 -0700 Subject: [PATCH] [FEATURE] Add safe way to migrate download archive file --- src/ytdl_sub/config/preset_options.py | 15 ++++++++++ .../subscriptions/base_subscription.py | 29 +++++++++++++++++++ tests/expected_transaction_log.py | 2 -- tests/resources.py | 2 +- .../prebuilt_presets/test_prebuilt_presets.py | 3 ++ 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/ytdl_sub/config/preset_options.py b/src/ytdl_sub/config/preset_options.py index 2dd0b24a..25cfa0db 100644 --- a/src/ytdl_sub/config/preset_options.py +++ b/src/ytdl_sub/config/preset_options.py @@ -246,6 +246,7 @@ class OutputOptions(StrictDictValidator): thumbnail_name: "{title_sanitized}.{thumbnail_ext}" info_json_name: "{title_sanitized}.{info_json_ext}" download_archive_name: ".ytdl-sub-{subscription_name}-download-archive.json" + migrated_download_archive_name: ".ytdl-sub-{subscription_name_sanitized}-download-archive.json" maintain_download_archive: True keep_files_before: now keep_files_after: 19000101 @@ -256,6 +257,7 @@ class OutputOptions(StrictDictValidator): "thumbnail_name", "info_json_name", "download_archive_name", + "migrated_download_archive_name", "maintain_download_archive", "keep_files_before", "keep_files_after", @@ -298,6 +300,10 @@ class OutputOptions(StrictDictValidator): validator=OverridesStringFormatterValidator, default=DEFAULT_DOWNLOAD_ARCHIVE_NAME, ) + self._migrated_download_archive_name = self._validate_key_if_present( + key="migrated_download_archive_name", + validator=OverridesStringFormatterValidator, + ) self._maintain_download_archive = self._validate_key_if_present( key="maintain_download_archive", validator=BoolValidator, default=False @@ -358,6 +364,15 @@ class OutputOptions(StrictDictValidator): """ return self._download_archive_name + @property + def migrated_download_archive_name(self) -> Optional[OverridesStringFormatterValidator]: + """ + Optional. Intended to be used if you are migrating a subscription with either a new + subscription name or output directory. If ``download_archive_name`` cannot be found, + it will try to find the + """ + return self._migrated_download_archive_name + @property def maintain_download_archive(self) -> bool: """ diff --git a/src/ytdl_sub/subscriptions/base_subscription.py b/src/ytdl_sub/subscriptions/base_subscription.py index e5c38ca7..2e56f179 100644 --- a/src/ytdl_sub/subscriptions/base_subscription.py +++ b/src/ytdl_sub/subscriptions/base_subscription.py @@ -1,3 +1,4 @@ +import os from abc import ABC from pathlib import Path @@ -8,8 +9,11 @@ from ytdl_sub.config.preset_options import OutputOptions from ytdl_sub.config.preset_options import Overrides from ytdl_sub.config.preset_options import YTDLOptions from ytdl_sub.downloaders.url.validators import MultiUrlValidator +from ytdl_sub.utils.logger import Logger from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive +logger = Logger.get("subscription") + class BaseSubscription(ABC): """ @@ -49,6 +53,31 @@ class BaseSubscription(ABC): output_directory=self.output_directory, ) + if self.output_options.migrated_download_archive_name: + migrated_download_archive = EnhancedDownloadArchive( + file_name=self.overrides.apply_formatter(self.output_options.migrated_download_archive_name), + working_directory=self.working_directory, + output_directory=self.output_directory, + ) + + # If the migrated archive file does not exist, but the original does, then inject the + # migrated file name into the original one. That makes it save to the migrated one + if not os.path.isfile(migrated_download_archive.output_file_path) and os.path.isfile( + self._enhanced_download_archive.output_file_path + ): + logger.warning( + "ARCHIVE MIGRATION DETECTED, will write download archive file to %s", + self._enhanced_download_archive.output_file_path + ) + self._enhanced_download_archive._file_name = migrated_download_archive.file_name + else: + logger.warning( + "Loading migrated archive file, can now replace " + "`output_options.download_archive` value with the contents of " + "`output_options.migrated_download_archive`" + ) + self._enhanced_download_archive = migrated_download_archive + @property def downloader_options(self) -> MultiUrlValidator: """ diff --git a/tests/expected_transaction_log.py b/tests/expected_transaction_log.py index c0f3d848..d6b186a0 100644 --- a/tests/expected_transaction_log.py +++ b/tests/expected_transaction_log.py @@ -48,8 +48,6 @@ def assert_transaction_log_matches( # Split, ensure there are the same number of new lines summary_lines: List[str] = summary.split("\n") expected_summary_lines: List[str] = expected_summary.split("\n") - print(summary_lines) - print(expected_summary_lines) assert len(summary_lines) == len( expected_summary_lines ), f"Summary number of lines differ: {len(summary_lines) != len(expected_summary_lines)}" diff --git a/tests/resources.py b/tests/resources.py index 911b330a..de1c5ab2 100644 --- a/tests/resources.py +++ b/tests/resources.py @@ -1,7 +1,7 @@ import shutil from pathlib import Path -REGENERATE_FIXTURES: bool = False +REGENERATE_FIXTURES: bool = True RESOURCE_PATH: Path = Path("tests") / "resources" _FILE_FIXTURE_PATH: Path = RESOURCE_PATH / "file_fixtures" diff --git a/tests/unit/prebuilt_presets/test_prebuilt_presets.py b/tests/unit/prebuilt_presets/test_prebuilt_presets.py index 06b5ada8..4e84caef 100644 --- a/tests/unit/prebuilt_presets/test_prebuilt_presets.py +++ b/tests/unit/prebuilt_presets/test_prebuilt_presets.py @@ -153,6 +153,9 @@ class TestPrebuiltTVShowPresets: preset_name=subscription_name, preset_dict={ "preset": parent_presets + [reformatted_tv_show_structure_preset], + "output_options": { + "migrated_download_archive_name": ".ytdl-sub-{tv_show_name_sanitized}-download-archive.json" + }, "overrides": { "url": "https://your.name.here", "tv_show_name": "Best Prebuilt TV Show by Date",