xml-att working
This commit is contained in:
parent
90ed66ffac
commit
fd80b93597
4 changed files with 243 additions and 138 deletions
|
|
@ -1,97 +1,26 @@
|
||||||
import os
|
import os
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Dict
|
||||||
from typing import Generic
|
from typing import Generic
|
||||||
from typing import List
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
from typing import Type
|
from typing import Type
|
||||||
from typing import TypeVar
|
|
||||||
|
|
||||||
from ytdl_sub.entries.entry import Entry
|
from ytdl_sub.entries.entry import Entry
|
||||||
from ytdl_sub.plugins.plugin import Plugin
|
from ytdl_sub.plugins.plugin import Plugin
|
||||||
from ytdl_sub.plugins.plugin import PluginOptions
|
from ytdl_sub.plugins.plugin import PluginOptions
|
||||||
from ytdl_sub.utils.file_handler import FileMetadata
|
from ytdl_sub.utils.file_handler import FileMetadata
|
||||||
|
from ytdl_sub.utils.xml import XmlElement
|
||||||
from ytdl_sub.utils.xml import to_max_3_byte_utf8_dict
|
from ytdl_sub.utils.xml import to_max_3_byte_utf8_dict
|
||||||
from ytdl_sub.utils.xml import to_max_3_byte_utf8_string
|
from ytdl_sub.utils.xml import to_max_3_byte_utf8_string
|
||||||
from ytdl_sub.utils.xml import to_xml
|
from ytdl_sub.utils.xml import to_xml
|
||||||
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
|
from ytdl_sub.validators.nfo_validators import NfoTagsValidator
|
||||||
|
from ytdl_sub.validators.nfo_validators import SharedNfoTagsValidator
|
||||||
|
from ytdl_sub.validators.nfo_validators import TDictFormatterValidator
|
||||||
|
from ytdl_sub.validators.nfo_validators import TStringFormatterValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
||||||
from ytdl_sub.validators.validators import BoolValidator
|
from ytdl_sub.validators.validators import BoolValidator
|
||||||
from ytdl_sub.validators.validators import DictValidator
|
|
||||||
|
|
||||||
TStringFormatterValidator = TypeVar("TStringFormatterValidator", bound=StringFormatterValidator)
|
|
||||||
TDictFormatterValidator = TypeVar("TDictFormatterValidator", bound=DictFormatterValidator)
|
|
||||||
|
|
||||||
|
|
||||||
class NfoTagsWithAttributesValidator(
|
|
||||||
StrictDictValidator, Generic[TStringFormatterValidator, TDictFormatterValidator], ABC
|
|
||||||
):
|
|
||||||
|
|
||||||
_required_keys = {"attributes", "tag"}
|
|
||||||
|
|
||||||
formatter_validator: Type[TStringFormatterValidator]
|
|
||||||
dict_formatter_validator: Type[TDictFormatterValidator]
|
|
||||||
|
|
||||||
def __init__(self, name, value):
|
|
||||||
super().__init__(name, value)
|
|
||||||
self._attributes = self._validate_key(
|
|
||||||
key="attributes", validator=self.dict_formatter_validator
|
|
||||||
)
|
|
||||||
self._tag = self._validate_key(key="tag", validator=self.formatter_validator)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def attributes(self) -> TDictFormatterValidator:
|
|
||||||
"""
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
The attributes for this NFO tag
|
|
||||||
"""
|
|
||||||
return self._attributes
|
|
||||||
|
|
||||||
@property
|
|
||||||
def tag(self) -> TStringFormatterValidator:
|
|
||||||
"""
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
The value for this NFO tag
|
|
||||||
"""
|
|
||||||
return self._tag
|
|
||||||
|
|
||||||
|
|
||||||
_TagsWithAttributesValidator = NfoTagsWithAttributesValidator[
|
|
||||||
TStringFormatterValidator, TDictFormatterValidator
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class NfoTagsValidator(
|
|
||||||
DictValidator, Generic[TStringFormatterValidator, TDictFormatterValidator], ABC
|
|
||||||
):
|
|
||||||
|
|
||||||
_tags_with_attributes_validator: Type[_TagsWithAttributesValidator]
|
|
||||||
|
|
||||||
def __init__(self, name, value):
|
|
||||||
super().__init__(name, value)
|
|
||||||
|
|
||||||
self.tags: List[TStringFormatterValidator] = []
|
|
||||||
self.tags_with_attributes: List[_TagsWithAttributesValidator] = []
|
|
||||||
|
|
||||||
for key in self._keys:
|
|
||||||
if isinstance(value, str):
|
|
||||||
validated = self._validate_key(
|
|
||||||
key=key, validator=self._tags_with_attributes_validator.formatter_validator
|
|
||||||
)
|
|
||||||
self.tags.append(validated)
|
|
||||||
elif isinstance(value, dict):
|
|
||||||
validated = self._validate_key(
|
|
||||||
key=key, validator=self._tags_with_attributes_validator
|
|
||||||
)
|
|
||||||
self.tags_with_attributes.append(validated)
|
|
||||||
else:
|
|
||||||
raise self._validation_exception("must either be a string or attributes object")
|
|
||||||
|
|
||||||
|
|
||||||
_TagsValidator = NfoTagsValidator[TStringFormatterValidator, TDictFormatterValidator]
|
|
||||||
|
|
||||||
|
|
||||||
class SharedNfoTagsOptions(
|
class SharedNfoTagsOptions(
|
||||||
|
|
@ -102,7 +31,9 @@ class SharedNfoTagsOptions(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_formatter_validator: Type[TStringFormatterValidator]
|
_formatter_validator: Type[TStringFormatterValidator]
|
||||||
_tags_validator: Type[_TagsValidator]
|
_tags_validator: Type[
|
||||||
|
SharedNfoTagsValidator[TStringFormatterValidator, TDictFormatterValidator]
|
||||||
|
]
|
||||||
|
|
||||||
_required_keys = {"nfo_name", "nfo_root", "tags"}
|
_required_keys = {"nfo_name", "nfo_root", "tags"}
|
||||||
_optional_keys = {"kodi_safe"}
|
_optional_keys = {"kodi_safe"}
|
||||||
|
|
@ -117,20 +48,78 @@ class SharedNfoTagsOptions(
|
||||||
key="kodi_safe", validator=BoolValidator, default=False
|
key="kodi_safe", validator=BoolValidator, default=False
|
||||||
).value
|
).value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def nfo_name(self) -> StringFormatterValidator:
|
||||||
|
"""
|
||||||
|
The NFO file name.
|
||||||
|
"""
|
||||||
|
return self._nfo_name
|
||||||
|
|
||||||
TSharedNfoTagsOptions = TypeVar("TSharedNfoTagsOptions", bound=SharedNfoTagsOptions)
|
@property
|
||||||
|
def nfo_root(self) -> StringFormatterValidator:
|
||||||
|
"""
|
||||||
|
The root tag of the NFO's XML. In the usage above, it would look like
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<episodedetails>
|
||||||
|
</episodedetails>
|
||||||
|
"""
|
||||||
|
return self._nfo_root
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tags(self) -> SharedNfoTagsValidator[TStringFormatterValidator, TDictFormatterValidator]:
|
||||||
|
"""
|
||||||
|
Tags within the nfo_root tag. In the usage above, it would look like
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<episodedetails>
|
||||||
|
<title>Awesome Youtube Video</title>
|
||||||
|
<season>2022</season>
|
||||||
|
<episode>502</episode>
|
||||||
|
</episodedetails>
|
||||||
|
"""
|
||||||
|
return self._tags
|
||||||
|
|
||||||
|
@property
|
||||||
|
def kodi_safe(self) -> Optional[bool]:
|
||||||
|
"""
|
||||||
|
Optional. Kodi does not support > 3-byte unicode characters, which include emojis and some
|
||||||
|
foreign language characters. Setting this to True will replace those characters with '□'.
|
||||||
|
Defaults to False.
|
||||||
|
"""
|
||||||
|
return self._kodi_safe
|
||||||
|
|
||||||
|
|
||||||
class SharedNfoTagsPlugin(Plugin[TSharedNfoTagsOptions], Generic[TSharedNfoTagsOptions], ABC):
|
class SharedNfoTagsPlugin(
|
||||||
|
Plugin[SharedNfoTagsOptions[TStringFormatterValidator, TDictFormatterValidator]],
|
||||||
|
Generic[TStringFormatterValidator, TDictFormatterValidator],
|
||||||
|
ABC,
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Shared code between NFO tags and Ouptut Directory NFO Tags
|
Shared code between NFO tags and Ouptut Directory NFO Tags
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _create_nfo(self, entry: Optional[Entry] = None) -> None:
|
def _create_nfo(self, entry: Optional[Entry] = None) -> None:
|
||||||
nfo = {}
|
nfo_tags: Dict[str, XmlElement] = {}
|
||||||
|
|
||||||
for tag, tag_formatter in sorted(self.plugin_options.tags.dict.items()):
|
for key, string_tag in self.plugin_options.tags.string_tags.items():
|
||||||
nfo[tag] = self.overrides.apply_formatter(formatter=tag_formatter, entry=entry)
|
nfo_tags[key] = XmlElement(
|
||||||
|
text=self.overrides.apply_formatter(formatter=string_tag, entry=entry),
|
||||||
|
attributes={},
|
||||||
|
)
|
||||||
|
|
||||||
|
for key, attribute_tag in self.plugin_options.tags.attribute_tags.items():
|
||||||
|
nfo_tags[key] = XmlElement(
|
||||||
|
text=self.overrides.apply_formatter(formatter=attribute_tag.tag, entry=entry),
|
||||||
|
attributes={
|
||||||
|
attr_name: self.overrides.apply_formatter(formatter=attr_formatter, entry=entry)
|
||||||
|
for attr_name, attr_formatter in attribute_tag.attributes.dict.items()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
# Write the nfo tags to XML with the nfo_root
|
# Write the nfo tags to XML with the nfo_root
|
||||||
nfo_root = self.overrides.apply_formatter(
|
nfo_root = self.overrides.apply_formatter(
|
||||||
|
|
@ -138,10 +127,14 @@ class SharedNfoTagsPlugin(Plugin[TSharedNfoTagsOptions], Generic[TSharedNfoTagsO
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.plugin_options.kodi_safe:
|
if self.plugin_options.kodi_safe:
|
||||||
nfo = to_max_3_byte_utf8_dict(nfo)
|
|
||||||
nfo_root = to_max_3_byte_utf8_string(nfo_root)
|
nfo_root = to_max_3_byte_utf8_string(nfo_root)
|
||||||
|
for key, xml_elem in nfo_tags.items():
|
||||||
|
nfo_tags[key] = XmlElement(
|
||||||
|
text=to_max_3_byte_utf8_string(xml_elem.text),
|
||||||
|
attributes=to_max_3_byte_utf8_dict(xml_elem.attributes),
|
||||||
|
)
|
||||||
|
|
||||||
xml = to_xml(nfo_dict=nfo, nfo_root=nfo_root)
|
xml = to_xml(nfo_dict=nfo_tags, nfo_root=nfo_root)
|
||||||
|
|
||||||
nfo_file_name = self.overrides.apply_formatter(
|
nfo_file_name = self.overrides.apply_formatter(
|
||||||
formatter=self.plugin_options.nfo_name, entry=entry
|
formatter=self.plugin_options.nfo_name, entry=entry
|
||||||
|
|
@ -154,7 +147,12 @@ class SharedNfoTagsPlugin(Plugin[TSharedNfoTagsOptions], Generic[TSharedNfoTagsO
|
||||||
nfo_file.write(xml)
|
nfo_file.write(xml)
|
||||||
|
|
||||||
# Save the nfo file and log its metadata
|
# Save the nfo file and log its metadata
|
||||||
nfo_metadata = FileMetadata.from_dict(value_dict={nfo_root: nfo}, title="NFO tags:")
|
nfo_metadata = FileMetadata.from_dict(
|
||||||
|
value_dict={
|
||||||
|
nfo_root: {key: xml_elem.to_dict_value() for key, xml_elem in nfo_tags.items()}
|
||||||
|
},
|
||||||
|
title="NFO tags:",
|
||||||
|
)
|
||||||
self.save_file(file_name=nfo_file_name, file_metadata=nfo_metadata, entry=entry)
|
self.save_file(file_name=nfo_file_name, file_metadata=nfo_metadata, entry=entry)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -183,54 +181,10 @@ class NfoTagsOptions(SharedNfoTagsOptions[StringFormatterValidator, DictFormatte
|
||||||
|
|
||||||
_formatter_validator = StringFormatterValidator
|
_formatter_validator = StringFormatterValidator
|
||||||
_dict_formatter_validator = DictFormatterValidator
|
_dict_formatter_validator = DictFormatterValidator
|
||||||
|
_tags_validator = NfoTagsValidator
|
||||||
@property
|
|
||||||
def nfo_name(self) -> StringFormatterValidator:
|
|
||||||
"""
|
|
||||||
The NFO file name.
|
|
||||||
"""
|
|
||||||
return self._nfo_name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def nfo_root(self) -> StringFormatterValidator:
|
|
||||||
"""
|
|
||||||
The root tag of the NFO's XML. In the usage above, it would look like
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<episodedetails>
|
|
||||||
</episodedetails>
|
|
||||||
"""
|
|
||||||
return self._nfo_root
|
|
||||||
|
|
||||||
@property
|
|
||||||
def tags(self) -> NfoTagsValidator[StringFormatterValidator, DictFormatterValidator]:
|
|
||||||
"""
|
|
||||||
Tags within the nfo_root tag. In the usage above, it would look like
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<episodedetails>
|
|
||||||
<title>Awesome Youtube Video</title>
|
|
||||||
<season>2022</season>
|
|
||||||
<episode>502</episode>
|
|
||||||
</episodedetails>
|
|
||||||
"""
|
|
||||||
return self._tags
|
|
||||||
|
|
||||||
@property
|
|
||||||
def kodi_safe(self) -> Optional[bool]:
|
|
||||||
"""
|
|
||||||
Optional. Kodi does not support > 3-byte unicode characters, which include emojis and some
|
|
||||||
foreign language characters. Setting this to True will replace those characters with '□'.
|
|
||||||
Defaults to False.
|
|
||||||
"""
|
|
||||||
return self._kodi_safe
|
|
||||||
|
|
||||||
|
|
||||||
class NfoTagsPlugin(SharedNfoTagsPlugin[NfoTagsOptions]):
|
class NfoTagsPlugin(SharedNfoTagsPlugin[StringFormatterValidator, DictFormatterValidator]):
|
||||||
plugin_options_type = NfoTagsOptions
|
plugin_options_type = NfoTagsOptions
|
||||||
|
|
||||||
def post_process_entry(self, entry: Entry) -> None:
|
def post_process_entry(self, entry: Entry) -> None:
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from typing import Optional
|
||||||
from ytdl_sub.plugins.nfo_tags import NfoTagsValidator
|
from ytdl_sub.plugins.nfo_tags import NfoTagsValidator
|
||||||
from ytdl_sub.plugins.nfo_tags import SharedNfoTagsOptions
|
from ytdl_sub.plugins.nfo_tags import SharedNfoTagsOptions
|
||||||
from ytdl_sub.plugins.nfo_tags import SharedNfoTagsPlugin
|
from ytdl_sub.plugins.nfo_tags import SharedNfoTagsPlugin
|
||||||
|
from ytdl_sub.validators.nfo_validators import NfoOverrideTagsValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import OverridesDictFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import OverridesDictFormatterValidator
|
||||||
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
||||||
|
|
||||||
|
|
@ -32,6 +33,7 @@ class OutputDirectoryNfoTagsOptions(
|
||||||
|
|
||||||
_formatter_validator = OverridesStringFormatterValidator
|
_formatter_validator = OverridesStringFormatterValidator
|
||||||
_dict_formatter_validator = OverridesDictFormatterValidator
|
_dict_formatter_validator = OverridesDictFormatterValidator
|
||||||
|
_tags_validator = NfoOverrideTagsValidator
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def nfo_name(self) -> OverridesStringFormatterValidator:
|
def nfo_name(self) -> OverridesStringFormatterValidator:
|
||||||
|
|
@ -56,7 +58,7 @@ class OutputDirectoryNfoTagsOptions(
|
||||||
@property
|
@property
|
||||||
def tags(
|
def tags(
|
||||||
self,
|
self,
|
||||||
) -> NfoTagsValidator[OverridesStringFormatterValidator, OverridesDictFormatterValidator]:
|
) -> NfoTagsValidator:
|
||||||
"""
|
"""
|
||||||
Tags within the nfo_root tag. In the usage above, it would look like
|
Tags within the nfo_root tag. In the usage above, it would look like
|
||||||
|
|
||||||
|
|
@ -79,7 +81,9 @@ class OutputDirectoryNfoTagsOptions(
|
||||||
return self._kodi_safe
|
return self._kodi_safe
|
||||||
|
|
||||||
|
|
||||||
class OutputDirectoryNfoTagsPlugin(SharedNfoTagsPlugin[OutputDirectoryNfoTagsOptions]):
|
class OutputDirectoryNfoTagsPlugin(
|
||||||
|
SharedNfoTagsPlugin[OverridesStringFormatterValidator, OverridesDictFormatterValidator]
|
||||||
|
):
|
||||||
plugin_options_type = OutputDirectoryNfoTagsOptions
|
plugin_options_type = OutputDirectoryNfoTagsOptions
|
||||||
|
|
||||||
def post_process_subscription(self):
|
def post_process_subscription(self):
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,27 @@
|
||||||
import xml.etree.ElementTree as et
|
import xml.etree.ElementTree as et
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Any
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class XmlElement:
|
||||||
|
text: str
|
||||||
|
attributes: Dict[str, str]
|
||||||
|
|
||||||
|
def to_dict_value(self) -> Union[str, Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Only the tag if no attributes, otherwise a dict containing both attributes and the tag
|
||||||
|
"""
|
||||||
|
if not self.attributes:
|
||||||
|
return self.text
|
||||||
|
return {
|
||||||
|
"attributes": self.attributes,
|
||||||
|
"tag": self.text,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _to_max_3_byte_utf8_char(char: str) -> str:
|
def _to_max_3_byte_utf8_char(char: str) -> str:
|
||||||
|
|
@ -37,7 +59,7 @@ def to_max_3_byte_utf8_dict(string_dict: Dict[str, str]) -> Dict[str, str]:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def to_xml(nfo_dict: Dict[str, str], nfo_root: str) -> bytes:
|
def to_xml(nfo_dict: Dict[str, XmlElement], nfo_root: str) -> bytes:
|
||||||
"""
|
"""
|
||||||
Transforms a dict to XML
|
Transforms a dict to XML
|
||||||
|
|
||||||
|
|
@ -53,9 +75,10 @@ def to_xml(nfo_dict: Dict[str, str], nfo_root: str) -> bytes:
|
||||||
XML bytes
|
XML bytes
|
||||||
"""
|
"""
|
||||||
xml_root = et.Element(nfo_root)
|
xml_root = et.Element(nfo_root)
|
||||||
for key, value in nfo_dict.items():
|
for key, xml_elem in sorted(nfo_dict.items()):
|
||||||
sub_element = et.SubElement(xml_root, key)
|
sorted_attr = dict(sorted(xml_elem.attributes.items()))
|
||||||
sub_element.text = value
|
sub_element = et.SubElement(xml_root, key, sorted_attr)
|
||||||
|
sub_element.text = xml_elem.text
|
||||||
|
|
||||||
et.indent(tree=xml_root, space=" ", level=0)
|
et.indent(tree=xml_root, space=" ", level=0)
|
||||||
return et.tostring(element=xml_root, encoding="utf-8", xml_declaration=True)
|
return et.tostring(element=xml_root, encoding="utf-8", xml_declaration=True)
|
||||||
|
|
|
||||||
124
src/ytdl_sub/validators/nfo_validators.py
Normal file
124
src/ytdl_sub/validators/nfo_validators.py
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
from abc import ABC
|
||||||
|
from typing import Dict
|
||||||
|
from typing import Generic
|
||||||
|
from typing import Type
|
||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
|
||||||
|
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
|
||||||
|
from ytdl_sub.validators.string_formatter_validators import OverridesDictFormatterValidator
|
||||||
|
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
|
||||||
|
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
|
||||||
|
from ytdl_sub.validators.validators import DictValidator
|
||||||
|
|
||||||
|
TStringFormatterValidator = TypeVar("TStringFormatterValidator", bound=StringFormatterValidator)
|
||||||
|
TDictFormatterValidator = TypeVar("TDictFormatterValidator", bound=DictFormatterValidator)
|
||||||
|
|
||||||
|
|
||||||
|
class _NfoTagsWithAttributesValidator(
|
||||||
|
StrictDictValidator, Generic[TStringFormatterValidator, TDictFormatterValidator], ABC
|
||||||
|
):
|
||||||
|
|
||||||
|
_required_keys = {"attributes", "tag"}
|
||||||
|
|
||||||
|
formatter_validator: Type[TStringFormatterValidator]
|
||||||
|
dict_formatter_validator: Type[TDictFormatterValidator]
|
||||||
|
|
||||||
|
def __init__(self, name, value):
|
||||||
|
super().__init__(name, value)
|
||||||
|
self._attributes = self._validate_key(
|
||||||
|
key="attributes", validator=self.dict_formatter_validator
|
||||||
|
)
|
||||||
|
self._tag = self._validate_key(key="tag", validator=self.formatter_validator)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def attributes(self) -> TDictFormatterValidator:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
The attributes for this NFO tag
|
||||||
|
"""
|
||||||
|
return self._attributes
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tag(self) -> TStringFormatterValidator:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
The value for this NFO tag
|
||||||
|
"""
|
||||||
|
return self._tag
|
||||||
|
|
||||||
|
|
||||||
|
class NfoTagsWithAttributesValidator(
|
||||||
|
_NfoTagsWithAttributesValidator[StringFormatterValidator, DictFormatterValidator]
|
||||||
|
):
|
||||||
|
formatter_validator = StringFormatterValidator
|
||||||
|
dict_formatter_validator = DictFormatterValidator
|
||||||
|
|
||||||
|
|
||||||
|
class NfoOverrideTagsWithAttributesValidator(
|
||||||
|
_NfoTagsWithAttributesValidator[
|
||||||
|
OverridesStringFormatterValidator, OverridesDictFormatterValidator
|
||||||
|
]
|
||||||
|
):
|
||||||
|
formatter_validator = OverridesStringFormatterValidator
|
||||||
|
dict_formatter_validator = OverridesDictFormatterValidator
|
||||||
|
|
||||||
|
|
||||||
|
TNfoTagsWithAttributesValidator = _NfoTagsWithAttributesValidator[
|
||||||
|
TStringFormatterValidator, TDictFormatterValidator
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class SharedNfoTagsValidator(
|
||||||
|
DictValidator, Generic[TStringFormatterValidator, TDictFormatterValidator], ABC
|
||||||
|
):
|
||||||
|
|
||||||
|
_tags_with_attributes_validator: Type[TNfoTagsWithAttributesValidator]
|
||||||
|
|
||||||
|
def __init__(self, name, value):
|
||||||
|
super().__init__(name, value)
|
||||||
|
|
||||||
|
self._string_tags: Dict[str, StringFormatterValidator] = {}
|
||||||
|
self._attribute_tags: Dict[str, TNfoTagsWithAttributesValidator] = {}
|
||||||
|
|
||||||
|
for key, tag_value in self._dict.items():
|
||||||
|
if isinstance(tag_value, str):
|
||||||
|
self._string_tags[key] = self._validate_key(
|
||||||
|
key=key, validator=self._tags_with_attributes_validator.formatter_validator
|
||||||
|
)
|
||||||
|
elif isinstance(tag_value, dict):
|
||||||
|
self._attribute_tags[key] = self._validate_key(
|
||||||
|
key=key, validator=self._tags_with_attributes_validator
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise self._validation_exception("must either be a string or attributes object")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def string_tags(self) -> Dict[str, StringFormatterValidator]:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Tags with no attributes
|
||||||
|
"""
|
||||||
|
return self._string_tags
|
||||||
|
|
||||||
|
@property
|
||||||
|
def attribute_tags(self) -> Dict[str, TNfoTagsWithAttributesValidator]:
|
||||||
|
"""
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Tags with attributes
|
||||||
|
"""
|
||||||
|
return self._attribute_tags
|
||||||
|
|
||||||
|
|
||||||
|
class NfoTagsValidator(SharedNfoTagsValidator[StringFormatterValidator, DictFormatterValidator]):
|
||||||
|
_tags_with_attributes_validator = NfoTagsWithAttributesValidator
|
||||||
|
|
||||||
|
|
||||||
|
class NfoOverrideTagsValidator(
|
||||||
|
SharedNfoTagsValidator[OverridesStringFormatterValidator, OverridesDictFormatterValidator]
|
||||||
|
):
|
||||||
|
_tags_with_attributes_validator = NfoOverrideTagsWithAttributesValidator
|
||||||
Loading…
Reference in a new issue