From 3d648c916a25173c7d8aa4a6cf19e5a7580b9939 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Tue, 17 Oct 2023 23:30:04 -0700 Subject: [PATCH] [FEATURE] No longer require a config.yaml --- src/ytdl_sub/cli/main.py | 11 +++++++++-- src/ytdl_sub/cli/main_args_parser.py | 6 ++++-- src/ytdl_sub/config/config_file.py | 1 - src/ytdl_sub/config/config_validator.py | 14 ++++++++------ tests/e2e/plugins/internal/test_view.py | 3 +-- tests/e2e/youtube/test_playlist.py | 5 ++--- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/ytdl_sub/cli/main.py b/src/ytdl_sub/cli/main.py index fbace307..709e3894 100644 --- a/src/ytdl_sub/cli/main.py +++ b/src/ytdl_sub/cli/main.py @@ -11,7 +11,7 @@ from colorama import Fore from yt_dlp.utils import sanitize_filename from ytdl_sub.cli.download_args_parser import DownloadArgsParser -from ytdl_sub.cli.main_args_parser import parser +from ytdl_sub.cli.main_args_parser import parser, DEFAULT_CONFIG_FILE_NAME from ytdl_sub.config.config_file import ConfigFile from ytdl_sub.subscriptions.subscription import Subscription from ytdl_sub.utils.exceptions import ExperimentalFeatureNotEnabled @@ -303,7 +303,14 @@ def main() -> List[Tuple[Subscription, FileHandlerTransactionLog]]: args, extra_args = parser.parse_known_args() # Load the config - config: ConfigFile = ConfigFile.from_file_path(args.config) + config: ConfigFile = ConfigFile(name="config", value={}) + if args.config: + config = ConfigFile.from_file_path(args.config) + elif os.path.isfile(DEFAULT_CONFIG_FILE_NAME): + config = ConfigFile.from_file_path(DEFAULT_CONFIG_FILE_NAME) + else: + logger.debug("No config specified, using defaults") + transaction_logs: List[Tuple[Subscription, FileHandlerTransactionLog]] = [] # If transaction log file is specified, make sure we can open it diff --git a/src/ytdl_sub/cli/main_args_parser.py b/src/ytdl_sub/cli/main_args_parser.py index 35f63849..d24f4aa1 100644 --- a/src/ytdl_sub/cli/main_args_parser.py +++ b/src/ytdl_sub/cli/main_args_parser.py @@ -5,6 +5,8 @@ from typing import List from ytdl_sub import __local_version__ from ytdl_sub.utils.logger import LoggerLevels +DEFAULT_CONFIG_FILE_NAME: str = "config.yaml" + @dataclasses.dataclass class CLIArgument: @@ -86,8 +88,8 @@ def _add_shared_arguments(arg_parser: argparse.ArgumentParser, suppress_defaults MainArguments.CONFIG.long, metavar="CONFIGPATH", type=str, - help="path to the config yaml, uses config.yaml if not provided", - default=argparse.SUPPRESS if suppress_defaults else "config.yaml", + # Default is set downstream + help=f"path to the config yaml, uses {DEFAULT_CONFIG_FILE_NAME} if not provided", ) arg_parser.add_argument( MainArguments.DRY_RUN.short, diff --git a/src/ytdl_sub/config/config_file.py b/src/ytdl_sub/config/config_file.py index b5981e51..70d662e9 100644 --- a/src/ytdl_sub/config/config_file.py +++ b/src/ytdl_sub/config/config_file.py @@ -11,7 +11,6 @@ from ytdl_sub.validators.file_path_validators import FilePathValidatorMixin class ConfigFile(ConfigValidator): - _required_keys = {"configuration", "presets"} def __init__(self, name: str, value: Any): super().__init__(name, value) diff --git a/src/ytdl_sub/config/config_validator.py b/src/ytdl_sub/config/config_validator.py index 20341088..2f324212 100644 --- a/src/ytdl_sub/config/config_validator.py +++ b/src/ytdl_sub/config/config_validator.py @@ -96,8 +96,8 @@ class PersistLogsValidator(StrictDictValidator): class ConfigOptions(StrictDictValidator): - _required_keys = {"working_directory"} _optional_keys = { + "working_directory", "umask", "dl_aliases", "persist_logs", @@ -112,8 +112,8 @@ class ConfigOptions(StrictDictValidator): def __init__(self, name: str, value: Any): super().__init__(name, value) - self._working_directory = self._validate_key( - key="working_directory", validator=StringValidator + self._working_directory = self._validate_key_if_present( + key="working_directory", validator=StringValidator, default=".ytdl-sub-temp-directory" ) self._umask = self._validate_key_if_present( key="umask", validator=StringValidator, default="022" @@ -244,14 +244,16 @@ class ConfigOptions(StrictDictValidator): class ConfigValidator(StrictDictValidator): - _required_keys = {"configuration", "presets"} + _optional_keys = {"configuration", "presets"} def __init__(self, name: str, value: Any): super().__init__(name, value) - self.config_options = self._validate_key("configuration", ConfigOptions) + self.config_options = self._validate_key_if_present( + "configuration", ConfigOptions, default={} + ) # Make sure presets is a dictionary. Will be validated in `PresetValidator` - self.presets = self._validate_key("presets", LiteralDictValidator) + self.presets = self._validate_key_if_present("presets", LiteralDictValidator, default={}) # Ensure custom presets do not collide with prebuilt presets for preset_name in self.presets.keys: diff --git a/tests/e2e/plugins/internal/test_view.py b/tests/e2e/plugins/internal/test_view.py index 590bfc6e..e3838e6f 100644 --- a/tests/e2e/plugins/internal/test_view.py +++ b/tests/e2e/plugins/internal/test_view.py @@ -10,12 +10,11 @@ class TestView: @pytest.mark.parametrize("split_chapters", [True, False]) def test_view_from_cli( self, - music_video_config_path, output_directory, split_chapters, ): - args = f"--config {music_video_config_path} view " + args = f"view " args += "--split-chapters " if split_chapters else "" args += f"https://www.youtube.com/playlist?list=PLBsm_SagFMmdWnCnrNtLjA9kzfrRkto4i" subscription_transaction_log = mock_run_from_cli(args=args) diff --git a/tests/e2e/youtube/test_playlist.py b/tests/e2e/youtube/test_playlist.py index f8899777..4ec810f9 100644 --- a/tests/e2e/youtube/test_playlist.py +++ b/tests/e2e/youtube/test_playlist.py @@ -150,19 +150,18 @@ class TestPlaylist: ) @pytest.mark.parametrize("dry_run", [True, False]) - def test_playlist_download_from_cli_sub( + def test_playlist_download_from_cli_sub_no_provided_config( self, preset_dict_to_subscription_yaml_generator, - music_video_config_for_cli, playlist_preset_dict, output_directory, dry_run, ): + # No config needed when using only prebuilt presets with preset_dict_to_subscription_yaml_generator( subscription_name="music_video_playlist_test", preset_dict=playlist_preset_dict ) as subscription_path: args = "--dry-run " if dry_run else "" - args += f"--config {music_video_config_for_cli} " args += f"sub {subscription_path}" subscription_transaction_log = mock_run_from_cli(args=args)