multi tag value for NFOs WIP

This commit is contained in:
Jesse Bannon 2022-09-06 16:59:58 -07:00
parent 6383d133dc
commit 56bae3f39a
4 changed files with 91 additions and 35 deletions

View file

@ -3,6 +3,7 @@ from abc import ABC
from pathlib import Path from pathlib import Path
from typing import Dict 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 typing import TypeVar
@ -95,23 +96,31 @@ class SharedNfoTagsPlugin(
Shared code between NFO tags and Ouptut Directory NFO Tags Shared code between NFO tags and Ouptut Directory NFO Tags
""" """
def _get_xml_element_dict(self, entry: Optional[Entry]) -> Dict[str, XmlElement]: def _get_xml_element_dict(self, entry: Optional[Entry]) -> Dict[str, List[XmlElement]]:
nfo_tags: Dict[str, XmlElement] = {} nfo_tags: Dict[str, List[XmlElement]] = {}
for key, string_tag in self.plugin_options.tags.string_tags.items(): for key, string_tags in self.plugin_options.tags.string_tags.items():
nfo_tags[key] = XmlElement( nfo_tags[key] = [
XmlElement(
text=self.overrides.apply_formatter(formatter=string_tag, entry=entry), text=self.overrides.apply_formatter(formatter=string_tag, entry=entry),
attributes={}, attributes={},
) )
for string_tag in string_tags
]
for key, attribute_tag in self.plugin_options.tags.attribute_tags.items(): for key, attribute_tags in self.plugin_options.tags.attribute_tags.items():
nfo_tags[key] = XmlElement( nfo_tags[key] = [
XmlElement(
text=self.overrides.apply_formatter(formatter=attribute_tag.tag, entry=entry), text=self.overrides.apply_formatter(formatter=attribute_tag.tag, entry=entry),
attributes={ attributes={
attr_name: self.overrides.apply_formatter(formatter=attr_formatter, entry=entry) attr_name: self.overrides.apply_formatter(
formatter=attr_formatter, entry=entry
)
for attr_name, attr_formatter in attribute_tag.attributes.dict.items() for attr_name, attr_formatter in attribute_tag.attributes.dict.items()
}, },
) )
for attribute_tag in attribute_tags
]
return nfo_tags return nfo_tags
@ -125,11 +134,14 @@ class SharedNfoTagsPlugin(
if self.plugin_options.kodi_safe: if self.plugin_options.kodi_safe:
nfo_root = to_max_3_byte_utf8_string(nfo_root) nfo_root = to_max_3_byte_utf8_string(nfo_root)
nfo_tags = { nfo_tags = {
to_max_3_byte_utf8_string(key): XmlElement( to_max_3_byte_utf8_string(key): [
XmlElement(
text=to_max_3_byte_utf8_string(xml_elem.text), text=to_max_3_byte_utf8_string(xml_elem.text),
attributes=to_max_3_byte_utf8_dict(xml_elem.attributes), attributes=to_max_3_byte_utf8_dict(xml_elem.attributes),
) )
for key, xml_elem in nfo_tags.items() for xml_elem in xml_elems
]
for key, xml_elems in nfo_tags.items()
} }
xml = to_xml(nfo_dict=nfo_tags, nfo_root=nfo_root) xml = to_xml(nfo_dict=nfo_tags, nfo_root=nfo_root)
@ -147,7 +159,14 @@ class SharedNfoTagsPlugin(
# Save the nfo file and log its metadata # Save the nfo file and log its metadata
nfo_metadata = FileMetadata.from_dict( nfo_metadata = FileMetadata.from_dict(
value_dict={ value_dict={
nfo_root: {key: xml_elem.to_dict_value() for key, xml_elem in nfo_tags.items()} nfo_root: {
key: (
xml_elems[0].to_dict_value()
if len(xml_elems) == 1
else [xml_elem.to_dict_value() for xml_elem in xml_elems]
)
for key, xml_elems in nfo_tags.items()
}
}, },
title="NFO tags:", title="NFO tags:",
) )

View file

@ -1,6 +1,8 @@
from abc import ABC from abc import ABC
from collections import defaultdict
from typing import Dict from typing import Dict
from typing import Generic from typing import Generic
from typing import List
from typing import Type from typing import Type
from typing import TypeVar from typing import TypeVar
@ -80,23 +82,34 @@ class SharedNfoTagsValidator(
def __init__(self, name, value): def __init__(self, name, value):
super().__init__(name, value) super().__init__(name, value)
self._string_tags: Dict[str, StringFormatterValidator] = {} self._string_tags: Dict[str, List[StringFormatterValidator]] = defaultdict(list)
self._attribute_tags: Dict[str, TNfoTagsWithAttributesValidator] = {} self._attribute_tags: Dict[str, List[TNfoTagsWithAttributesValidator]] = defaultdict(list)
for key, tag_value in self._dict.items(): for key, tag_value in self._dict.items():
if isinstance(tag_value, str): # Turn each value into a list if it's not
self._string_tags[key] = self._validate_key( if not isinstance(tag_value, list):
key=key, validator=self._tags_with_attributes_validator.formatter_validator tag_value = [tag_value]
# iterate each list, validate accordingly if it is a string tag or attribute tag
for tag_value_i in tag_value:
if isinstance(tag_value_i, str):
self._string_tags[key].append(
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( elif isinstance(tag_value_i, dict):
key=key, validator=self._tags_with_attributes_validator self._attribute_tags[key].append(
self._validate_key(key=key, validator=self._tags_with_attributes_validator)
) )
else: else:
raise self._validation_exception("must either be a string or attributes object") raise self._validation_exception(
"must either be a single or list of string/attribute object"
)
@property @property
def string_tags(self) -> Dict[str, StringFormatterValidator]: def string_tags(self) -> Dict[str, List[StringFormatterValidator]]:
""" """
Returns Returns
------- -------
@ -105,7 +118,7 @@ class SharedNfoTagsValidator(
return self._string_tags return self._string_tags
@property @property
def attribute_tags(self) -> Dict[str, TNfoTagsWithAttributesValidator]: def attribute_tags(self) -> Dict[str, List[TNfoTagsWithAttributesValidator]]:
""" """
Returns Returns
------- -------

View file

@ -241,3 +241,4 @@ class OverridesDictFormatterValidator(DictFormatterValidator):
""" """
_key_validator = OverridesStringFormatterValidator _key_validator = OverridesStringFormatterValidator

View file

@ -23,6 +23,17 @@ def subscription_dict(output_directory):
"attributes": {"🎸?": "value\nnewlines 🎸"}, "attributes": {"🎸?": "value\nnewlines 🎸"},
"tag": "the \n tag 🎸🎸", "tag": "the \n tag 🎸🎸",
}, },
"kodi_safe_multi_title 🎸": ["value 1 🎸", "value 2 🎸"],
"kodi_safe_multi_title_with_attrs": [
{
"attributes": {"🎸?": "value\nnewlines 🎸"},
"tag": "the \n tag 1 🎸🎸",
},
{
"attributes": {"🎸?": "value\nnewlines 🎸"},
"tag": "the \n tag 2 🎸🎸",
},
]
}, },
}, },
"output_directory_nfo_tags": { "output_directory_nfo_tags": {
@ -34,6 +45,17 @@ def subscription_dict(output_directory):
"attributes": {"🎸?": "value\nnewlines 🎸"}, "attributes": {"🎸?": "value\nnewlines 🎸"},
"tag": "the \n tag 🎸🎸", "tag": "the \n tag 🎸🎸",
}, },
"kodi_safe_multi_title 🎸": ["value 1 🎸", "value 2 🎸"],
"kodi_safe_multi_title_with_attrs": [
{
"attributes": {"🎸?": "value\nnewlines 🎸"},
"tag": "the \n tag 1 🎸🎸",
},
{
"attributes": {"🎸?": "value\nnewlines 🎸"},
"tag": "the \n tag 2 🎸🎸",
},
]
}, },
}, },
} }
@ -60,6 +82,7 @@ class TestNfoTagsPlugins:
output_directory=output_directory, output_directory=output_directory,
transaction_log=transaction_log, transaction_log=transaction_log,
transaction_log_summary_file_name=f"plugins/nfo_tags/{transaction_log_file_name}", transaction_log_summary_file_name=f"plugins/nfo_tags/{transaction_log_file_name}",
regenerate_transaction_log=True
) )
def test_source_variable_in_output_directory_nfo_tags_errors( def test_source_variable_in_output_directory_nfo_tags_errors(