ytdl-sub/ytdl_subscribe/validators/config/preset_validator.py
2022-04-05 06:45:26 +00:00

115 lines
3.7 KiB
Python

import copy
from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from typing import Tuple
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 DictValidator
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={}
)