diff --git a/tests/unit/entries/conftest.py b/tests/unit/entries/conftest.py index a776e121..4864ad46 100644 --- a/tests/unit/entries/conftest.py +++ b/tests/unit/entries/conftest.py @@ -1,7 +1,7 @@ import pytest from ytdl_subscribe.entries.entry import Entry -from ytdl_subscribe.validators.base.string_formatter_validators import StringFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import StringFormatterValidator def _pad(num): diff --git a/tests/unit/validators/test_bool_validator.py b/tests/unit/validators/test_bool_validator.py index bbfee237..bc51f28e 100644 --- a/tests/unit/validators/test_bool_validator.py +++ b/tests/unit/validators/test_bool_validator.py @@ -1,7 +1,7 @@ import pytest -from ytdl_subscribe.validators.base.validators import BoolValidator -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.utils.exceptions import ValidationException +from ytdl_subscribe.validators.validators import BoolValidator @pytest.mark.parametrize("value", [True, False]) diff --git a/tests/unit/validators/test_dict_validator.py b/tests/unit/validators/test_dict_validator.py index d655c367..5ba5eda8 100644 --- a/tests/unit/validators/test_dict_validator.py +++ b/tests/unit/validators/test_dict_validator.py @@ -1,10 +1,10 @@ import pytest -from ytdl_subscribe.validators.base.validators import BoolValidator -from ytdl_subscribe.validators.base.validators import DictValidator -from ytdl_subscribe.validators.base.validators import LiteralDictValidator -from ytdl_subscribe.validators.base.validators import StringValidator -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.utils.exceptions import ValidationException +from ytdl_subscribe.validators.validators import BoolValidator +from ytdl_subscribe.validators.validators import DictValidator +from ytdl_subscribe.validators.validators import LiteralDictValidator +from ytdl_subscribe.validators.validators import StringValidator class TestDictValidator: diff --git a/tests/unit/validators/test_string_formatter_validator.py b/tests/unit/validators/test_string_formatter_validator.py index 837e05fc..9439da04 100644 --- a/tests/unit/validators/test_string_formatter_validator.py +++ b/tests/unit/validators/test_string_formatter_validator.py @@ -1,15 +1,11 @@ import pytest -from ytdl_subscribe.validators.base.string_formatter_validators import DictFormatterValidator -from ytdl_subscribe.validators.base.string_formatter_validators import ( - OverridesDictFormatterValidator, -) -from ytdl_subscribe.validators.base.string_formatter_validators import ( - OverridesStringFormatterValidator, -) -from ytdl_subscribe.validators.base.string_formatter_validators import StringFormatterValidator -from ytdl_subscribe.validators.exceptions import StringFormattingException -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.utils.exceptions import StringFormattingException +from ytdl_subscribe.utils.exceptions import ValidationException +from ytdl_subscribe.validators.string_formatter_validators import DictFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import OverridesDictFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import OverridesStringFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import StringFormatterValidator @pytest.fixture diff --git a/tests/unit/validators/test_string_validator.py b/tests/unit/validators/test_string_validator.py index 18906ccd..5755c716 100644 --- a/tests/unit/validators/test_string_validator.py +++ b/tests/unit/validators/test_string_validator.py @@ -1,7 +1,7 @@ import pytest -from ytdl_subscribe.validators.base.validators import StringValidator -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.utils.exceptions import ValidationException +from ytdl_subscribe.validators.validators import StringValidator @pytest.mark.parametrize("value", ["a", "unicode 💩", ""]) diff --git a/ytdl_subscribe/validators/base/__init__.py b/ytdl_subscribe/config/__init__.py similarity index 100% rename from ytdl_subscribe/validators/base/__init__.py rename to ytdl_subscribe/config/__init__.py diff --git a/ytdl_subscribe/validators/config/config_file_validator.py b/ytdl_subscribe/config/config_file_validator.py similarity index 77% rename from ytdl_subscribe/validators/config/config_file_validator.py rename to ytdl_subscribe/config/config_file_validator.py index 6e38ffe3..82009314 100644 --- a/ytdl_subscribe/validators/config/config_file_validator.py +++ b/ytdl_subscribe/config/config_file_validator.py @@ -2,11 +2,9 @@ from typing import Any import yaml -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.validators import LiteralDictValidator -from ytdl_subscribe.validators.config.config_options.config_options_validator import ( - ConfigOptionsValidator, -) +from ytdl_subscribe.config.config_options_validator import ConfigOptionsValidator +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator +from ytdl_subscribe.validators.validators import LiteralDictValidator class ConfigPresetsValidator(LiteralDictValidator): diff --git a/ytdl_subscribe/validators/config/config_options/config_options_validator.py b/ytdl_subscribe/config/config_options_validator.py similarity index 70% rename from ytdl_subscribe/validators/config/config_options/config_options_validator.py rename to ytdl_subscribe/config/config_options_validator.py index ea294495..caad9905 100644 --- a/ytdl_subscribe/validators/config/config_options/config_options_validator.py +++ b/ytdl_subscribe/config/config_options_validator.py @@ -1,7 +1,7 @@ from typing import Any -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.validators import StringValidator +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator +from ytdl_subscribe.validators.validators import StringValidator class ConfigOptionsValidator(StrictDictValidator): diff --git a/ytdl_subscribe/validators/config/source_options/download_strategy_validators.py b/ytdl_subscribe/config/download_strategy_validators.py similarity index 67% rename from ytdl_subscribe/validators/config/source_options/download_strategy_validators.py rename to ytdl_subscribe/config/download_strategy_validators.py index 5d8e6b63..8dfc7765 100644 --- a/ytdl_subscribe/validators/config/source_options/download_strategy_validators.py +++ b/ytdl_subscribe/config/download_strategy_validators.py @@ -4,21 +4,15 @@ from typing import Any from typing import Dict from typing import Type -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.validators import StringValidator -from ytdl_subscribe.validators.config.source_options.soundcloud_validators import ( +from ytdl_subscribe.downloaders.downloader import DownloaderValidator +from ytdl_subscribe.downloaders.soundcloud_downloader import ( SoundcloudAlbumsAndSinglesSourceValidator, ) -from ytdl_subscribe.validators.config.source_options.source_validators import SourceValidator -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubeChannelSourceValidator, -) -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubePlaylistSourceValidator, -) -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubeVideoSourceValidator, -) +from ytdl_subscribe.downloaders.youtube_downloader import YoutubeChannelDownloaderValidator +from ytdl_subscribe.downloaders.youtube_downloader import YoutubePlaylistDownloaderValidator +from ytdl_subscribe.downloaders.youtube_downloader import YoutubeVideoDownloaderValidator +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator +from ytdl_subscribe.validators.validators import StringValidator class DownloadStrategyValidator(StrictDictValidator, ABC): @@ -32,7 +26,7 @@ class DownloadStrategyValidator(StrictDictValidator, ABC): # Extra fields will be strict-validated using other StictDictValidators _allow_extra_keys = True - _download_strategy_to_source_mapping: Dict[str, Type[SourceValidator]] = {} + _download_strategy_to_source_mapping: Dict[str, Type[DownloaderValidator]] = {} def __init__(self, name: str, value: Any): super().__init__(name=name, value=value) @@ -68,7 +62,7 @@ class SoundcloudDownloadStrategyValidator(DownloadStrategyValidator): class YoutubeDownloadStrategyValidator(DownloadStrategyValidator): _download_strategy_to_source_mapping = { - "channel": YoutubeChannelSourceValidator, - "playlist": YoutubePlaylistSourceValidator, - "video": YoutubeVideoSourceValidator, + "channel": YoutubeChannelDownloaderValidator, + "playlist": YoutubePlaylistDownloaderValidator, + "video": YoutubeVideoDownloaderValidator, } diff --git a/ytdl_subscribe/validators/config/output_options/output_options_validator.py b/ytdl_subscribe/config/output_options_validator.py similarity index 82% rename from ytdl_subscribe/validators/config/output_options/output_options_validator.py rename to ytdl_subscribe/config/output_options_validator.py index 8e42337e..a31bc973 100644 --- a/ytdl_subscribe/validators/config/output_options/output_options_validator.py +++ b/ytdl_subscribe/config/output_options_validator.py @@ -1,9 +1,7 @@ -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.string_formatter_validators import ( - OverridesStringFormatterValidator, -) -from ytdl_subscribe.validators.base.string_formatter_validators import StringFormatterValidator -from ytdl_subscribe.validators.base.validators import BoolValidator +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator +from ytdl_subscribe.validators.string_formatter_validators import OverridesStringFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import StringFormatterValidator +from ytdl_subscribe.validators.validators import BoolValidator class OutputOptionsValidator(StrictDictValidator): diff --git a/ytdl_subscribe/validators/config/overrides/overrides_validator.py b/ytdl_subscribe/config/overrides_validator.py similarity index 86% rename from ytdl_subscribe/validators/config/overrides/overrides_validator.py rename to ytdl_subscribe/config/overrides_validator.py index 04ee54f4..5bf96e86 100644 --- a/ytdl_subscribe/validators/config/overrides/overrides_validator.py +++ b/ytdl_subscribe/config/overrides_validator.py @@ -3,8 +3,8 @@ from typing import Optional from yt_dlp.utils import sanitize_filename from ytdl_subscribe.entries.entry import Entry -from ytdl_subscribe.validators.base.string_formatter_validators import DictFormatterValidator -from ytdl_subscribe.validators.base.string_formatter_validators import StringFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import DictFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import StringFormatterValidator class OverridesValidator(DictFormatterValidator): diff --git a/ytdl_subscribe/validators/config/preset_validator.py b/ytdl_subscribe/config/preset_validator.py similarity index 73% rename from ytdl_subscribe/validators/config/preset_validator.py rename to ytdl_subscribe/config/preset_validator.py index 9117ab2e..bef626ab 100644 --- a/ytdl_subscribe/validators/config/preset_validator.py +++ b/ytdl_subscribe/config/preset_validator.py @@ -4,34 +4,19 @@ from typing import List from typing import Optional from typing import Type -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.string_formatter_validators import ( - OverridesStringFormatterValidator, -) -from ytdl_subscribe.validators.base.validators import DictValidator -from ytdl_subscribe.validators.base.validators import Validator -from ytdl_subscribe.validators.config.metadata_options.metadata_options_validator import ( - MetadataOptionsValidator, -) -from ytdl_subscribe.validators.config.output_options.output_options_validator import ( - OutputOptionsValidator, -) -from ytdl_subscribe.validators.config.overrides.overrides_validator import OverridesValidator -from ytdl_subscribe.validators.config.source_options.download_strategy_validators import ( - DownloadStrategyValidator, -) -from ytdl_subscribe.validators.config.source_options.download_strategy_validators import ( - SoundcloudDownloadStrategyValidator, -) -from ytdl_subscribe.validators.config.source_options.download_strategy_validators import ( - YoutubeDownloadStrategyValidator, -) -from ytdl_subscribe.validators.config.source_options.source_validators import SourceValidator -from ytdl_subscribe.validators.config.ytdl_options.ytdl_options_validator import ( - YTDLOptionsValidator, -) -from ytdl_subscribe.validators.exceptions import StringFormattingVariableNotFoundException -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.config.download_strategy_validators import DownloadStrategyValidator +from ytdl_subscribe.config.download_strategy_validators import SoundcloudDownloadStrategyValidator +from ytdl_subscribe.config.download_strategy_validators import YoutubeDownloadStrategyValidator +from ytdl_subscribe.config.output_options_validator import OutputOptionsValidator +from ytdl_subscribe.config.overrides_validator import OverridesValidator +from ytdl_subscribe.config.ytdl_options_validator import YTDLOptionsValidator +from ytdl_subscribe.downloaders.downloader import DownloaderValidator +from ytdl_subscribe.utils.exceptions import StringFormattingVariableNotFoundException +from ytdl_subscribe.utils.exceptions import ValidationException +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator +from ytdl_subscribe.validators.string_formatter_validators import OverridesStringFormatterValidator +from ytdl_subscribe.validators.validators import DictValidator +from ytdl_subscribe.validators.validators import Validator PRESET_SOURCE_VALIDATOR_MAPPING: Dict[str, Type[DownloadStrategyValidator]] = { "soundcloud": SoundcloudDownloadStrategyValidator, @@ -55,7 +40,7 @@ class PresetValidator(StrictDictValidator): def __available_sources(self) -> List[str]: return sorted(list(PRESET_SOURCE_VALIDATOR_MAPPING.keys())) - def __validate_and_get_subscription_source(self) -> SourceValidator: + def __validate_and_get_subscription_source(self) -> DownloaderValidator: download_strategy_validator: Optional[DownloadStrategyValidator] = None for key in self._keys: @@ -130,9 +115,8 @@ class PresetValidator(StrictDictValidator): key="output_options", validator=OutputOptionsValidator, ) - self.metadata_options = self._validate_key( - key="metadata_options", validator=MetadataOptionsValidator - ) + + # TODO: REPLACE METADATA OPTIONS WITH PLUGINS self.ytdl_options = self._validate_key( key="ytdl_options", validator=YTDLOptionsValidator, default={} diff --git a/ytdl_subscribe/validators/config/subscription_validator.py b/ytdl_subscribe/config/subscription_validator.py similarity index 78% rename from ytdl_subscribe/validators/config/subscription_validator.py rename to ytdl_subscribe/config/subscription_validator.py index c6d0185f..99bffde3 100644 --- a/ytdl_subscribe/validators/config/subscription_validator.py +++ b/ytdl_subscribe/config/subscription_validator.py @@ -8,30 +8,24 @@ from typing import Type import yaml from mergedeep import mergedeep +from ytdl_subscribe.config.config_file_validator import ConfigFileValidator +from ytdl_subscribe.config.overrides_validator import OverridesValidator +from ytdl_subscribe.config.preset_validator import PRESET_OPTIONAL_KEYS +from ytdl_subscribe.config.preset_validator import PRESET_REQUIRED_KEYS +from ytdl_subscribe.config.preset_validator import PresetValidator +from ytdl_subscribe.downloaders.soundcloud_downloader import ( + SoundcloudAlbumsAndSinglesSourceValidator, +) +from ytdl_subscribe.downloaders.youtube_downloader import YoutubeChannelDownloaderValidator +from ytdl_subscribe.downloaders.youtube_downloader import YoutubePlaylistDownloaderValidator +from ytdl_subscribe.downloaders.youtube_downloader import YoutubeVideoDownloaderValidator from ytdl_subscribe.subscriptions.soundcloud import SoundcloudAlbumsAndSinglesSubscription from ytdl_subscribe.subscriptions.subscription import Subscription from ytdl_subscribe.subscriptions.youtube import YoutubeChannelSubscription from ytdl_subscribe.subscriptions.youtube import YoutubePlaylistSubscription from ytdl_subscribe.subscriptions.youtube import YoutubeVideoSubscription -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.validators import StringValidator -from ytdl_subscribe.validators.config.config_file_validator import ConfigFileValidator -from ytdl_subscribe.validators.config.overrides.overrides_validator import OverridesValidator -from ytdl_subscribe.validators.config.preset_validator import PRESET_OPTIONAL_KEYS -from ytdl_subscribe.validators.config.preset_validator import PRESET_REQUIRED_KEYS -from ytdl_subscribe.validators.config.preset_validator import PresetValidator -from ytdl_subscribe.validators.config.source_options.soundcloud_validators import ( - SoundcloudAlbumsAndSinglesSourceValidator, -) -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubeChannelSourceValidator, -) -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubePlaylistSourceValidator, -) -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubeVideoSourceValidator, -) +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator +from ytdl_subscribe.validators.validators import StringValidator class SubscriptionValidator(StrictDictValidator): @@ -79,11 +73,11 @@ class SubscriptionValidator(StrictDictValidator): subscription_class: Optional[Type[Subscription]] = None if isinstance(self.preset.subscription_source, SoundcloudAlbumsAndSinglesSourceValidator): subscription_class = SoundcloudAlbumsAndSinglesSubscription - elif isinstance(self.preset.subscription_source, YoutubePlaylistSourceValidator): + elif isinstance(self.preset.subscription_source, YoutubePlaylistDownloaderValidator): subscription_class = YoutubePlaylistSubscription - elif isinstance(self.preset.subscription_source, YoutubeVideoSourceValidator): + elif isinstance(self.preset.subscription_source, YoutubeVideoDownloaderValidator): subscription_class = YoutubeVideoSubscription - elif isinstance(self.preset.subscription_source, YoutubeChannelSourceValidator): + elif isinstance(self.preset.subscription_source, YoutubeChannelDownloaderValidator): subscription_class = YoutubeChannelSubscription if subscription_class is None: raise ValueError("subscription source class not found") diff --git a/ytdl_subscribe/validators/config/ytdl_options/ytdl_options_validator.py b/ytdl_subscribe/config/ytdl_options_validator.py similarity index 55% rename from ytdl_subscribe/validators/config/ytdl_options/ytdl_options_validator.py rename to ytdl_subscribe/config/ytdl_options_validator.py index 1b76d0cc..07191e0e 100644 --- a/ytdl_subscribe/validators/config/ytdl_options/ytdl_options_validator.py +++ b/ytdl_subscribe/config/ytdl_options_validator.py @@ -1,4 +1,4 @@ -from ytdl_subscribe.validators.base.validators import LiteralDictValidator +from ytdl_subscribe.validators.validators import LiteralDictValidator class YTDLOptionsValidator(LiteralDictValidator): diff --git a/ytdl_subscribe/downloaders/downloader.py b/ytdl_subscribe/downloaders/downloader.py index 7639ff93..4bedc31c 100644 --- a/ytdl_subscribe/downloaders/downloader.py +++ b/ytdl_subscribe/downloaders/downloader.py @@ -1,3 +1,4 @@ +from abc import ABC from contextlib import contextmanager from pathlib import Path from typing import Dict @@ -5,6 +6,14 @@ from typing import Optional import yt_dlp as ytdl +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator + + +class DownloaderValidator(StrictDictValidator, ABC): + """ + Placeholder class to define downloader options + """ + class Downloader: """ diff --git a/ytdl_subscribe/downloaders/soundcloud_downloader.py b/ytdl_subscribe/downloaders/soundcloud_downloader.py index 8db2da1e..27295268 100644 --- a/ytdl_subscribe/downloaders/soundcloud_downloader.py +++ b/ytdl_subscribe/downloaders/soundcloud_downloader.py @@ -1,9 +1,27 @@ +from abc import ABC from typing import Dict from typing import List from ytdl_subscribe.downloaders.downloader import Downloader +from ytdl_subscribe.downloaders.downloader import DownloaderValidator from ytdl_subscribe.entries.soundcloud import SoundcloudAlbum from ytdl_subscribe.entries.soundcloud import SoundcloudTrack +from ytdl_subscribe.validators.validators import BoolValidator +from ytdl_subscribe.validators.validators import StringValidator + + +class SoundcloudDownloaderValidator(DownloaderValidator, ABC): + """ + Abstract source validator for all soundcloud sources. + """ + + _optional_keys = {"skip_premiere_tracks"} + + def __init__(self, name: str, value: dict): + super().__init__(name=name, value=value) + self.skip_premiere_tracks = self._validate_key( + "skip_premiere_tracks", BoolValidator, default=True + ) class SoundcloudDownloader(Downloader): @@ -48,3 +66,11 @@ class SoundcloudDownloader(Downloader): SoundcloudTrack(working_directory=self.working_directory, kwargs=e) for e in info["entries"] ] + + +class SoundcloudAlbumsAndSinglesSourceValidator(SoundcloudDownloaderValidator): + _required_keys = {"username"} + + def __init__(self, name, value): + super().__init__(name, value) + self.username = self._validate_key(key="username", validator=StringValidator) diff --git a/ytdl_subscribe/downloaders/youtube_downloader.py b/ytdl_subscribe/downloaders/youtube_downloader.py index 2b6a1337..4fc77041 100644 --- a/ytdl_subscribe/downloaders/youtube_downloader.py +++ b/ytdl_subscribe/downloaders/youtube_downloader.py @@ -1,12 +1,22 @@ import json import os +from abc import ABC from pathlib import Path from typing import List from yt_dlp.utils import RejectedVideoReached from ytdl_subscribe.downloaders.downloader import Downloader +from ytdl_subscribe.downloaders.downloader import DownloaderValidator from ytdl_subscribe.entries.youtube import YoutubeVideo +from ytdl_subscribe.validators.date_range_validator import DownloadDateRangeSource +from ytdl_subscribe.validators.validators import StringValidator + + +class YoutubeDownloaderValidator(DownloaderValidator, ABC): + """ + Abstract source validator for all soundcloud sources. + """ class YoutubeDownloader(Downloader): @@ -86,3 +96,29 @@ class YoutubeDownloader(Downloader): entries.append(YoutubeVideo(**json.load(file))) return entries + + +class YoutubePlaylistDownloaderValidator(YoutubeDownloaderValidator): + _required_keys = {"playlist_id"} + + def __init__(self, name, value): + super().__init__(name, value) + self.playlist_id = self._validate_key("playlist_id", StringValidator) + + +class YoutubeChannelDownloaderValidator(YoutubeDownloaderValidator, DownloadDateRangeSource): + _required_keys = {"channel_id"} + _optional_keys = {"before", "after"} + + def __init__(self, name, value): + YoutubeDownloaderValidator.__init__(self, name, value) + DownloadDateRangeSource.__init__(self, name, value) + self.channel_id = self._validate_key("channel_id", StringValidator) + + +class YoutubeVideoDownloaderValidator(YoutubeDownloaderValidator): + _required_keys = {"video_id"} + + def __init__(self, name, value): + super().__init__(name, value) + self.video_id = self._validate_key("video_id", StringValidator) diff --git a/ytdl_subscribe/main.py b/ytdl_subscribe/main.py index 5a979410..55e2a1ea 100644 --- a/ytdl_subscribe/main.py +++ b/ytdl_subscribe/main.py @@ -5,9 +5,9 @@ from typing import List from ytdl_subscribe.cli.download_args_parser import DownloadArgsParser from ytdl_subscribe.cli.main_args_parser import parser -from ytdl_subscribe.validators.config.config_file_validator import ConfigFileValidator -from ytdl_subscribe.validators.config.subscription_validator import SubscriptionValidator -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.config.config_file_validator import ConfigFileValidator +from ytdl_subscribe.config.subscription_validator import SubscriptionValidator +from ytdl_subscribe.utils.exceptions import ValidationException def _download_subscriptions_from_yaml_files( diff --git a/ytdl_subscribe/plugins/convert_thumbnail.py b/ytdl_subscribe/plugins/convert_thumbnail.py index b2538cff..4f2db5fc 100644 --- a/ytdl_subscribe/plugins/convert_thumbnail.py +++ b/ytdl_subscribe/plugins/convert_thumbnail.py @@ -5,7 +5,7 @@ from PIL.Image import Image from ytdl_subscribe.entries.entry import Entry from ytdl_subscribe.plugins.plugin import Plugin from ytdl_subscribe.plugins.plugin import PluginValidator -from ytdl_subscribe.validators.base.string_select_validator import StringSelectValidator +from ytdl_subscribe.validators.string_select_validator import StringSelectValidator class ThumbnailTypes(StringSelectValidator): diff --git a/ytdl_subscribe/plugins/music_tags.py b/ytdl_subscribe/plugins/music_tags.py index 972f2d8a..68f0e24f 100644 --- a/ytdl_subscribe/plugins/music_tags.py +++ b/ytdl_subscribe/plugins/music_tags.py @@ -3,8 +3,8 @@ import music_tag from ytdl_subscribe.entries.entry import Entry from ytdl_subscribe.plugins.plugin import Plugin from ytdl_subscribe.plugins.plugin import PluginValidator -from ytdl_subscribe.validators.base.string_formatter_validators import DictFormatterValidator -from ytdl_subscribe.validators.base.validators import StringValidator +from ytdl_subscribe.validators.string_formatter_validators import DictFormatterValidator +from ytdl_subscribe.validators.validators import StringValidator class MusicTagsValidator(PluginValidator): diff --git a/ytdl_subscribe/plugins/nfo_tags.py b/ytdl_subscribe/plugins/nfo_tags.py index 2cb8c6e2..3bcb7c26 100644 --- a/ytdl_subscribe/plugins/nfo_tags.py +++ b/ytdl_subscribe/plugins/nfo_tags.py @@ -5,8 +5,8 @@ import dicttoxml from ytdl_subscribe.entries.entry import Entry from ytdl_subscribe.plugins.plugin import Plugin from ytdl_subscribe.plugins.plugin import PluginValidator -from ytdl_subscribe.validators.base.string_formatter_validators import DictFormatterValidator -from ytdl_subscribe.validators.base.string_formatter_validators import StringFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import DictFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import StringFormatterValidator class NfoTagsValidator(PluginValidator): diff --git a/ytdl_subscribe/plugins/output_directory_nfo_tags.py b/ytdl_subscribe/plugins/output_directory_nfo_tags.py index cc994cfb..ea23cff5 100644 --- a/ytdl_subscribe/plugins/output_directory_nfo_tags.py +++ b/ytdl_subscribe/plugins/output_directory_nfo_tags.py @@ -4,12 +4,8 @@ import dicttoxml from ytdl_subscribe.plugins.plugin import Plugin from ytdl_subscribe.plugins.plugin import PluginValidator -from ytdl_subscribe.validators.base.string_formatter_validators import ( - OverridesDictFormatterValidator, -) -from ytdl_subscribe.validators.base.string_formatter_validators import ( - OverridesStringFormatterValidator, -) +from ytdl_subscribe.validators.string_formatter_validators import OverridesDictFormatterValidator +from ytdl_subscribe.validators.string_formatter_validators import OverridesStringFormatterValidator class OutputDirectoryNfoTagsValidator(PluginValidator): diff --git a/ytdl_subscribe/plugins/plugin.py b/ytdl_subscribe/plugins/plugin.py index 86f1b424..ec196042 100644 --- a/ytdl_subscribe/plugins/plugin.py +++ b/ytdl_subscribe/plugins/plugin.py @@ -1,13 +1,11 @@ from abc import ABC from typing import Generic -from typing import Optional from typing import TypeVar from typing import final +from ytdl_subscribe.config.overrides_validator import OverridesValidator from ytdl_subscribe.entries.entry import Entry -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.string_formatter_validators import StringFormatterValidator -from ytdl_subscribe.validators.config.overrides.overrides_validator import OverridesValidator +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator from ytdl_subscribe.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive diff --git a/ytdl_subscribe/subscriptions/soundcloud.py b/ytdl_subscribe/subscriptions/soundcloud.py index 9bfdc73f..15c9b55f 100644 --- a/ytdl_subscribe/subscriptions/soundcloud.py +++ b/ytdl_subscribe/subscriptions/soundcloud.py @@ -1,12 +1,12 @@ from typing import List +from ytdl_subscribe.downloaders.soundcloud_downloader import ( + SoundcloudAlbumsAndSinglesSourceValidator, +) from ytdl_subscribe.downloaders.soundcloud_downloader import SoundcloudDownloader from ytdl_subscribe.entries.soundcloud import SoundcloudAlbum from ytdl_subscribe.entries.soundcloud import SoundcloudTrack from ytdl_subscribe.subscriptions.subscription import Subscription -from ytdl_subscribe.validators.config.source_options.soundcloud_validators import ( - SoundcloudAlbumsAndSinglesSourceValidator, -) class SoundcloudAlbumsAndSinglesSubscription( diff --git a/ytdl_subscribe/subscriptions/subscription.py b/ytdl_subscribe/subscriptions/subscription.py index f0d4fce1..f1ee74b7 100644 --- a/ytdl_subscribe/subscriptions/subscription.py +++ b/ytdl_subscribe/subscriptions/subscription.py @@ -11,21 +11,17 @@ from typing import Optional from typing import Type from typing import TypeVar +from ytdl_subscribe.config.config_options_validator import ConfigOptionsValidator +from ytdl_subscribe.config.output_options_validator import OutputOptionsValidator +from ytdl_subscribe.config.overrides_validator import OverridesValidator +from ytdl_subscribe.config.preset_validator import PresetValidator from ytdl_subscribe.downloaders.downloader import Downloader +from ytdl_subscribe.downloaders.downloader import DownloaderValidator from ytdl_subscribe.entries.entry import Entry -from ytdl_subscribe.validators.config.config_options.config_options_validator import ( - ConfigOptionsValidator, -) -from ytdl_subscribe.validators.config.output_options.output_options_validator import ( - OutputOptionsValidator, -) -from ytdl_subscribe.validators.config.overrides.overrides_validator import OverridesValidator -from ytdl_subscribe.validators.config.preset_validator import PresetValidator -from ytdl_subscribe.validators.config.source_options.mixins import DownloadDateRangeSource -from ytdl_subscribe.validators.config.source_options.source_validators import SourceValidator +from ytdl_subscribe.validators.date_range_validator import DownloadDateRangeSource from ytdl_subscribe.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive -SourceT = TypeVar("SourceT", bound=SourceValidator) +SourceT = TypeVar("SourceT", bound=DownloaderValidator) EntryT = TypeVar("EntryT", bound=Entry) DownloaderT = TypeVar("DownloaderT", bound=Downloader) diff --git a/ytdl_subscribe/subscriptions/youtube.py b/ytdl_subscribe/subscriptions/youtube.py index 6cf080a3..5e100341 100644 --- a/ytdl_subscribe/subscriptions/youtube.py +++ b/ytdl_subscribe/subscriptions/youtube.py @@ -1,20 +1,14 @@ from typing import List +from ytdl_subscribe.downloaders.youtube_downloader import YoutubeChannelDownloaderValidator from ytdl_subscribe.downloaders.youtube_downloader import YoutubeDownloader +from ytdl_subscribe.downloaders.youtube_downloader import YoutubePlaylistDownloaderValidator +from ytdl_subscribe.downloaders.youtube_downloader import YoutubeVideoDownloaderValidator from ytdl_subscribe.entries.youtube import YoutubeVideo from ytdl_subscribe.subscriptions.subscription import Subscription -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubeChannelSourceValidator, -) -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubePlaylistSourceValidator, -) -from ytdl_subscribe.validators.config.source_options.youtube_validators import ( - YoutubeVideoSourceValidator, -) -class YoutubePlaylistSubscription(Subscription[YoutubePlaylistSourceValidator, YoutubeVideo]): +class YoutubePlaylistSubscription(Subscription[YoutubePlaylistDownloaderValidator, YoutubeVideo]): """ Youtube subscription to download videos from a playlist """ @@ -25,7 +19,7 @@ class YoutubePlaylistSubscription(Subscription[YoutubePlaylistSourceValidator, Y ) -class YoutubeChannelSubscription(Subscription[YoutubeChannelSourceValidator, YoutubeVideo]): +class YoutubeChannelSubscription(Subscription[YoutubeChannelDownloaderValidator, YoutubeVideo]): """ Youtube subscription to download videos from a channel """ @@ -40,7 +34,7 @@ class YoutubeChannelSubscription(Subscription[YoutubeChannelSourceValidator, You return downloader.download_channel(channel_id=self.source_options.channel_id.value) -class YoutubeVideoSubscription(Subscription[YoutubeVideoSourceValidator, YoutubeVideo]): +class YoutubeVideoSubscription(Subscription[YoutubeVideoDownloaderValidator, YoutubeVideo]): """ Youtube subscription to download a single video """ diff --git a/ytdl_subscribe/validators/config/__init__.py b/ytdl_subscribe/utils/__init__.py similarity index 100% rename from ytdl_subscribe/validators/config/__init__.py rename to ytdl_subscribe/utils/__init__.py diff --git a/ytdl_subscribe/validators/exceptions.py b/ytdl_subscribe/utils/exceptions.py similarity index 100% rename from ytdl_subscribe/validators/exceptions.py rename to ytdl_subscribe/utils/exceptions.py diff --git a/ytdl_subscribe/validators/config/config_options/__init__.py b/ytdl_subscribe/validators/config/config_options/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ytdl_subscribe/validators/config/metadata_options/__init__.py b/ytdl_subscribe/validators/config/metadata_options/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ytdl_subscribe/validators/config/metadata_options/metadata_options_validator.py b/ytdl_subscribe/validators/config/metadata_options/metadata_options_validator.py deleted file mode 100644 index 8b7e78ff..00000000 --- a/ytdl_subscribe/validators/config/metadata_options/metadata_options_validator.py +++ /dev/null @@ -1,18 +0,0 @@ -from ytdl_subscribe.plugins.music_tags import MusicTagsValidator -from ytdl_subscribe.plugins.nfo_tags import NfoTagsValidator -from ytdl_subscribe.plugins.output_directory_nfo_tags import OutputDirectoryNfoTagsValidator -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator - - -class MetadataOptionsValidator(StrictDictValidator): - _optional_keys = {"id3", "nfo", "output_directory_nfo"} - - def __init__(self, name, value): - super().__init__(name, value) - - self.id3 = self._validate_key_if_present(key="id3", validator=MusicTagsValidator) - self.nfo = self._validate_key_if_present(key="nfo", validator=NfoTagsValidator) - - self.output_directory_nfo = self._validate_key_if_present( - key="output_directory_nfo", validator=OutputDirectoryNfoTagsValidator - ) diff --git a/ytdl_subscribe/validators/config/output_options/__init__.py b/ytdl_subscribe/validators/config/output_options/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ytdl_subscribe/validators/config/overrides/__init__.py b/ytdl_subscribe/validators/config/overrides/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ytdl_subscribe/validators/config/source_options/__init__.py b/ytdl_subscribe/validators/config/source_options/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ytdl_subscribe/validators/config/source_options/soundcloud_validators.py b/ytdl_subscribe/validators/config/source_options/soundcloud_validators.py deleted file mode 100644 index 6bc589f3..00000000 --- a/ytdl_subscribe/validators/config/source_options/soundcloud_validators.py +++ /dev/null @@ -1,12 +0,0 @@ -from ytdl_subscribe.validators.base.validators import StringValidator -from ytdl_subscribe.validators.config.source_options.source_validators import ( - SoundcloudSourceValidator, -) - - -class SoundcloudAlbumsAndSinglesSourceValidator(SoundcloudSourceValidator): - _required_keys = {"username"} - - def __init__(self, name, value): - super().__init__(name, value) - self.username = self._validate_key(key="username", validator=StringValidator) diff --git a/ytdl_subscribe/validators/config/source_options/source_validators.py b/ytdl_subscribe/validators/config/source_options/source_validators.py deleted file mode 100644 index 64b1bcb8..00000000 --- a/ytdl_subscribe/validators/config/source_options/source_validators.py +++ /dev/null @@ -1,30 +0,0 @@ -from abc import ABC - -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.validators import BoolValidator - - -class SourceValidator(StrictDictValidator): - """ - Abstract class for any source validator - """ - - -class SoundcloudSourceValidator(SourceValidator, ABC): - """ - Abstract source validator for all soundcloud sources. - """ - - _optional_keys = {"skip_premiere_tracks"} - - def __init__(self, name: str, value: dict): - super().__init__(name=name, value=value) - self.skip_premiere_tracks = self._validate_key( - "skip_premiere_tracks", BoolValidator, default=True - ) - - -class YoutubeSourceValidator(SourceValidator, ABC): - """ - Abstract source validator for all soundcloud sources. - """ diff --git a/ytdl_subscribe/validators/config/source_options/youtube_validators.py b/ytdl_subscribe/validators/config/source_options/youtube_validators.py deleted file mode 100644 index c1f8bdfe..00000000 --- a/ytdl_subscribe/validators/config/source_options/youtube_validators.py +++ /dev/null @@ -1,30 +0,0 @@ -from ytdl_subscribe.validators.base.string_datetime import StringDatetimeValidator -from ytdl_subscribe.validators.base.validators import StringValidator -from ytdl_subscribe.validators.config.source_options.mixins import DownloadDateRangeSource -from ytdl_subscribe.validators.config.source_options.source_validators import YoutubeSourceValidator - - -class YoutubePlaylistSourceValidator(YoutubeSourceValidator): - _required_keys = {"playlist_id"} - - def __init__(self, name, value): - super().__init__(name, value) - self.playlist_id = self._validate_key("playlist_id", StringValidator) - - -class YoutubeVideoSourceValidator(YoutubeSourceValidator): - _required_keys = {"video_id"} - - def __init__(self, name, value): - super().__init__(name, value) - self.video_id = self._validate_key("video_id", StringValidator) - - -class YoutubeChannelSourceValidator(YoutubeSourceValidator, DownloadDateRangeSource): - _required_keys = {"channel_id"} - _optional_keys = {"before", "after"} - - def __init__(self, name, value): - YoutubeSourceValidator.__init__(self, name, value) - DownloadDateRangeSource.__init__(self, name, value) - self.channel_id = self._validate_key("channel_id", StringValidator) diff --git a/ytdl_subscribe/validators/config/ytdl_options/__init__.py b/ytdl_subscribe/validators/config/ytdl_options/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/ytdl_subscribe/validators/config/source_options/mixins.py b/ytdl_subscribe/validators/date_range_validator.py similarity index 81% rename from ytdl_subscribe/validators/config/source_options/mixins.py rename to ytdl_subscribe/validators/date_range_validator.py index d46fc5b4..564dbce9 100644 --- a/ytdl_subscribe/validators/config/source_options/mixins.py +++ b/ytdl_subscribe/validators/date_range_validator.py @@ -3,8 +3,8 @@ from typing import Optional from yt_dlp import DateRange -from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator -from ytdl_subscribe.validators.base.string_datetime import StringDatetimeValidator +from ytdl_subscribe.validators.strict_dict_validator import StrictDictValidator +from ytdl_subscribe.validators.string_datetime import StringDatetimeValidator class DownloadDateRangeSource(StrictDictValidator, ABC): diff --git a/ytdl_subscribe/validators/base/strict_dict_validator.py b/ytdl_subscribe/validators/strict_dict_validator.py similarity index 93% rename from ytdl_subscribe/validators/base/strict_dict_validator.py rename to ytdl_subscribe/validators/strict_dict_validator.py index 22f8c193..ddf78ec1 100644 --- a/ytdl_subscribe/validators/base/strict_dict_validator.py +++ b/ytdl_subscribe/validators/strict_dict_validator.py @@ -1,8 +1,8 @@ from typing import List from typing import Set -from ytdl_subscribe.validators.base.validators import DictValidator -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.utils.exceptions import ValidationException +from ytdl_subscribe.validators.validators import DictValidator class StrictDictValidator(DictValidator): diff --git a/ytdl_subscribe/validators/base/string_datetime.py b/ytdl_subscribe/validators/string_datetime.py similarity index 81% rename from ytdl_subscribe/validators/base/string_datetime.py rename to ytdl_subscribe/validators/string_datetime.py index 56b26004..043a9bd3 100644 --- a/ytdl_subscribe/validators/base/string_datetime.py +++ b/ytdl_subscribe/validators/string_datetime.py @@ -1,7 +1,7 @@ from yt_dlp.utils import datetime_from_str -from ytdl_subscribe.validators.base.validators import Validator -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.utils.exceptions import ValidationException +from ytdl_subscribe.validators.validators import Validator class StringDatetimeValidator(Validator): diff --git a/ytdl_subscribe/validators/base/string_formatter_validators.py b/ytdl_subscribe/validators/string_formatter_validators.py similarity index 94% rename from ytdl_subscribe/validators/base/string_formatter_validators.py rename to ytdl_subscribe/validators/string_formatter_validators.py index 034c74ab..7d752301 100644 --- a/ytdl_subscribe/validators/base/string_formatter_validators.py +++ b/ytdl_subscribe/validators/string_formatter_validators.py @@ -5,10 +5,10 @@ from typing import Dict from typing import List from typing import final -from ytdl_subscribe.validators.base.validators import LiteralDictValidator -from ytdl_subscribe.validators.base.validators import Validator -from ytdl_subscribe.validators.exceptions import StringFormattingException -from ytdl_subscribe.validators.exceptions import StringFormattingVariableNotFoundException +from ytdl_subscribe.utils.exceptions import StringFormattingException +from ytdl_subscribe.utils.exceptions import StringFormattingVariableNotFoundException +from ytdl_subscribe.validators.validators import LiteralDictValidator +from ytdl_subscribe.validators.validators import Validator class StringFormatterValidator(Validator): diff --git a/ytdl_subscribe/validators/base/string_select_validator.py b/ytdl_subscribe/validators/string_select_validator.py similarity index 87% rename from ytdl_subscribe/validators/base/string_select_validator.py rename to ytdl_subscribe/validators/string_select_validator.py index 8e88c3e3..fd06b6cd 100644 --- a/ytdl_subscribe/validators/base/string_select_validator.py +++ b/ytdl_subscribe/validators/string_select_validator.py @@ -1,6 +1,6 @@ from typing import Set -from ytdl_subscribe.validators.base.validators import StringValidator +from ytdl_subscribe.validators.validators import StringValidator class StringSelectValidator(StringValidator): diff --git a/ytdl_subscribe/validators/base/validators.py b/ytdl_subscribe/validators/validators.py similarity index 98% rename from ytdl_subscribe/validators/base/validators.py rename to ytdl_subscribe/validators/validators.py index a7142467..114682b3 100644 --- a/ytdl_subscribe/validators/base/validators.py +++ b/ytdl_subscribe/validators/validators.py @@ -8,7 +8,7 @@ from typing import Type from typing import TypeVar from typing import final -from ytdl_subscribe.validators.exceptions import ValidationException +from ytdl_subscribe.utils.exceptions import ValidationException V = TypeVar("V", bound=ValidationException)