download strategy validate
This commit is contained in:
parent
d3c2c14452
commit
c33f0d84ee
7 changed files with 109 additions and 13 deletions
|
|
@ -114,6 +114,11 @@ class DownloadStrategyValidator(StrictDictValidator):
|
|||
Returns
|
||||
-------
|
||||
The downloader class
|
||||
|
||||
Raises
|
||||
------
|
||||
ValidationException
|
||||
If the download strategy is invalid
|
||||
"""
|
||||
try:
|
||||
return DownloadStrategyMapping.get(
|
||||
|
|
@ -129,15 +134,46 @@ class Preset(StrictDictValidator):
|
|||
# and ensure required keys are present.
|
||||
_optional_keys = PRESET_KEYS
|
||||
|
||||
@classmethod
|
||||
def _validate_download_strategy(cls, name: str, value: Dict) -> None:
|
||||
sources: List[str] = []
|
||||
for source_name in DownloadStrategyMapping.sources():
|
||||
if source_name in value:
|
||||
sources.append(source_name)
|
||||
|
||||
if len(sources) > 1:
|
||||
raise validation_exception(
|
||||
name=name,
|
||||
error_message=f"Contains the sources {', '.join(sources)} but can only have one",
|
||||
)
|
||||
|
||||
# If no sources, nothing more to validate
|
||||
if not sources:
|
||||
return
|
||||
|
||||
source_name = sources[0]
|
||||
source_dict = copy.deepcopy(value[source_name])
|
||||
|
||||
downloader = DownloadStrategyValidator(name=f"{name}.{source_name}", value=source_dict).get(
|
||||
downloader_source=source_name
|
||||
)
|
||||
del source_dict["download_strategy"]
|
||||
|
||||
downloader.downloader_options_type.partial_validate(
|
||||
name=f"{name}.{source_name}", value=source_dict
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def preset_partial_validate(cls, config: ConfigValidator, name: str, value: Any) -> None:
|
||||
# Ensure value is a dict
|
||||
_ = DictValidator(name=name, value=value)
|
||||
assert isinstance(value, dict)
|
||||
|
||||
cls._validate_download_strategy(name, value)
|
||||
cls._partial_validate_key(name, value, "output_options", OutputOptions)
|
||||
cls._partial_validate_key(name, value, "ytdl_options", YTDLOptions)
|
||||
cls._partial_validate_key(name, value, "overrides", Overrides)
|
||||
|
||||
for plugin_name in PluginMapping.plugins():
|
||||
cls._partial_validate_key(
|
||||
name,
|
||||
|
|
|
|||
|
|
@ -156,6 +156,12 @@ class CollectionValidator(StrictDictValidator, AddsVariablesMixin):
|
|||
|
||||
_required_keys = {"urls"}
|
||||
|
||||
@classmethod
|
||||
def partial_validate(cls, name: str, value: Any) -> None:
|
||||
if isinstance(value, dict):
|
||||
value["urls"] = value.get("urls", [{"url": "placeholder"}])
|
||||
_ = cls(name, value)
|
||||
|
||||
def __init__(self, name, value):
|
||||
super().__init__(name, value)
|
||||
self._urls = self._validate_key(key="urls", validator=CollectionUrlListValidator)
|
||||
|
|
|
|||
|
|
@ -41,9 +41,13 @@ class SharedNfoTagsOptions(PluginOptions):
|
|||
def __init__(self, name, value):
|
||||
super().__init__(name, value)
|
||||
|
||||
self._nfo_name = self._validate_key(key="nfo_name", validator=StringFormatterValidator)
|
||||
self._nfo_root = self._validate_key(key="nfo_root", validator=StringFormatterValidator)
|
||||
self._tags = self._validate_key(key="tags", validator=NfoTagsValidator)
|
||||
self._nfo_name = self._validate_key_if_present(
|
||||
key="nfo_name", validator=StringFormatterValidator
|
||||
)
|
||||
self._nfo_root = self._validate_key_if_present(
|
||||
key="nfo_root", validator=StringFormatterValidator
|
||||
)
|
||||
self._tags = self._validate_key_if_present(key="tags", validator=NfoTagsValidator)
|
||||
self._kodi_safe = self._validate_key_if_present(
|
||||
key="kodi_safe", validator=BoolValidator, default=False
|
||||
).value
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
presets:
|
||||
|
||||
kodi-music-videos:
|
||||
preset:
|
||||
- "jellyfin-music-videos"
|
||||
- "kodi-safe"
|
||||
|
|
@ -3,7 +3,7 @@ presets:
|
|||
kodi_music_video:
|
||||
generic:
|
||||
download_strategy: "source"
|
||||
music_video_url: "{music_video_url}"
|
||||
url: "{music_video_url}"
|
||||
|
||||
output_options:
|
||||
output_directory: "{music_video_directory}"
|
||||
|
|
@ -18,6 +18,7 @@ presets:
|
|||
|
||||
collection_season_1:
|
||||
generic:
|
||||
download_strategy: "collection"
|
||||
urls:
|
||||
- url: "{collection_season_1_url}"
|
||||
variables:
|
||||
|
|
@ -42,6 +43,7 @@ presets:
|
|||
|
||||
collection_season_2:
|
||||
generic:
|
||||
download_strategy: "collection"
|
||||
urls:
|
||||
- url: "{collection_season_2_url}"
|
||||
variables:
|
||||
|
|
@ -60,6 +62,7 @@ presets:
|
|||
|
||||
collection_season_3:
|
||||
generic:
|
||||
download_strategy: "collection"
|
||||
urls:
|
||||
- url: "{collection_season_3_url}"
|
||||
variables:
|
||||
|
|
@ -78,6 +81,7 @@ presets:
|
|||
|
||||
collection_season_4:
|
||||
generic:
|
||||
download_strategy: "collection"
|
||||
urls:
|
||||
- url: "{collection_season_4_url}"
|
||||
variables:
|
||||
|
|
@ -96,6 +100,7 @@ presets:
|
|||
|
||||
collection_season_5:
|
||||
generic:
|
||||
download_strategy: "collection"
|
||||
urls:
|
||||
- url: "{collection_season_5_url}"
|
||||
variables:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from typing import Dict
|
|||
|
||||
import pytest
|
||||
|
||||
from ytdl_sub.config.config_file import ConfigFile
|
||||
from ytdl_sub.config.preset import Preset
|
||||
from ytdl_sub.plugins.nfo_tags import NfoTagsOptions
|
||||
from ytdl_sub.utils.exceptions import StringFormattingVariableNotFoundException
|
||||
|
|
@ -203,6 +204,56 @@ class TestPreset:
|
|||
},
|
||||
)
|
||||
|
||||
def test_partial_validate(self, config_file):
|
||||
for preset_name, preset_dict in config_file.presets.dict.items():
|
||||
Preset.preset_partial_validate(config_file, preset_name, preset_dict)
|
||||
|
||||
class TestPresetPartialValidate:
|
||||
@pytest.mark.parametrize(
|
||||
"preset_dict",
|
||||
[
|
||||
{"nfo_tags": {"tags": {"key-1": "preset_0"}}},
|
||||
{"output_directory_nfo_tags": {"nfo_root": "test"}},
|
||||
{"output_directory": {"file_name": "test"}},
|
||||
{"output_directory": {"keep_files_after": "today"}},
|
||||
{"ytdl_options": {"format": "best"}},
|
||||
],
|
||||
)
|
||||
def test_partial_validate(self, preset_dict):
|
||||
_ = ConfigFile(
|
||||
name="test_partial_validate",
|
||||
value={
|
||||
"configuration": {"working_directory": "."},
|
||||
"presets": {"partial_preset": preset_dict},
|
||||
},
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"preset_dict",
|
||||
[
|
||||
{"youtube": {}, "generic": {}}, # multiple sources
|
||||
],
|
||||
)
|
||||
def test_partial_validate__bad_sources(self, preset_dict):
|
||||
with pytest.raises(ValidationException):
|
||||
_ = ConfigFile(
|
||||
name="test_partial_validate",
|
||||
value={
|
||||
"configuration": {"working_directory": "."},
|
||||
"presets": {"partial_preset": preset_dict},
|
||||
},
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"preset_dict",
|
||||
[
|
||||
{"nfo_tags": {"tags": {"key-1": {"attributes": {"test": "2"}}}}},
|
||||
{"generic": {"urls": {"variables_to_set": {"name": "value"}}}},
|
||||
],
|
||||
)
|
||||
def test_partial_validate__incomplete_list_item(self, preset_dict):
|
||||
with pytest.raises(ValidationException):
|
||||
_ = ConfigFile(
|
||||
name="test_partial_validate",
|
||||
value={
|
||||
"configuration": {"working_directory": "."},
|
||||
"presets": {"partial_preset": preset_dict},
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue