ytdl-sub/ytdl_subscribe/validators/config/preset_validator.py
2022-04-05 07:50:43 +00:00

112 lines
3.6 KiB
Python

from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from typing import Type
import sanitize_filename
from ytdl_subscribe.validators.base.strict_dict_validator import StrictDictValidator
from ytdl_subscribe.validators.base.string_formatter_validator import (
DictFormatterValidator,
)
from ytdl_subscribe.validators.base.validators import LiteralDictValidator
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.sources.soundcloud_validators import (
SoundcloudSourceValidator,
)
from ytdl_subscribe.validators.config.sources.source_validator import SourceValidator
from ytdl_subscribe.validators.config.sources.youtube_validators import (
YoutubeSourceValidator,
)
from ytdl_subscribe.validators.exceptions import ValidationException
class YTDLOptionsValidator(LiteralDictValidator):
"""Ensures `ytdl_options` is a dict"""
pass
class OverridesValidator(DictFormatterValidator):
"""Ensures `overrides` is a dict"""
def __init__(self, name, value):
super().__init__(name, value)
for key in self._keys:
self._value[f"sanitized_{key}"] = sanitize_filename.sanitize(
self._value[key]
)
PRESET_SOURCE_VALIDATOR_MAPPING: Dict[str, Type[SourceValidator]] = {
"soundcloud": SoundcloudSourceValidator,
"youtube": YoutubeSourceValidator,
}
PRESET_REQUIRED_KEYS = {"output_options"}
PRESET_OPTIONAL_KEYS = {
"metadata_options",
"ytdl_options",
"overrides",
*PRESET_SOURCE_VALIDATOR_MAPPING.keys(),
}
class PresetValidator(StrictDictValidator):
_required_keys = PRESET_REQUIRED_KEYS
_optional_keys = PRESET_OPTIONAL_KEYS
@property
def __available_sources(self) -> List[str]:
return sorted(list(PRESET_SOURCE_VALIDATOR_MAPPING.keys()))
def __validate_and_get_subscription_source(self) -> SourceValidator:
subscription_source: Optional[SourceValidator] = None
for key in self._keys:
if key in self.__available_sources and subscription_source:
raise ValidationException(
f"'{self._name}' can only have one of the following sources: "
f"{', '.join(self.__available_sources)}"
)
if key in PRESET_SOURCE_VALIDATOR_MAPPING:
subscription_source = self._validate_key(
key=key, validator=PRESET_SOURCE_VALIDATOR_MAPPING[key]
)
# If subscription source was not set, error
if not subscription_source:
raise ValidationException(
f"'{self._name} must have one of the following sources: "
f"{', '.join(self.__available_sources)}"
)
return subscription_source
def __init__(self, name: str, value: Any):
super().__init__(name=name, value=value)
self.subscription_source = self.__validate_and_get_subscription_source()
self.output_options = self._validate_key(
key="output_options",
validator=OutputOptionsValidator,
)
self.metadata_options = self._validate_key(
key="metadata_options", validator=MetadataOptionsValidator
)
self.ytdl_options = self._validate_key(
key="ytdl_options", validator=YTDLOptionsValidator, default={}
)
self.overrides = self._validate_key(
key="overrides", validator=OverridesValidator, default={}
)