full dates in serialization. remainder in square brackets. tests for serializer
This commit is contained in:
parent
4b9015878d
commit
439a904c54
@ -105,10 +105,14 @@ _MONTH_NUMERIC_RE_EXP = r"(?P<month>0?\d|1[0-2]?)"
|
|||||||
_MONTH_RE_EXP = r"(" + _MONTH_ALPHA_RE_EXP + r"|" + _MONTH_NUMERIC_RE_EXP + r")"
|
_MONTH_RE_EXP = r"(" + _MONTH_ALPHA_RE_EXP + r"|" + _MONTH_NUMERIC_RE_EXP + r")"
|
||||||
_ALPHA_MONTH_RANGE = (
|
_ALPHA_MONTH_RANGE = (
|
||||||
r"\b"
|
r"\b"
|
||||||
+ r"(" + r"|".join(MONTHS) + r")"
|
+ r"("
|
||||||
|
+ r"|".join(MONTHS)
|
||||||
|
+ r")"
|
||||||
+ r"("
|
+ r"("
|
||||||
+ r"\.?-"
|
+ r"\.?-"
|
||||||
+ r"(" + r"|".join(MONTHS) + r")"
|
+ r"("
|
||||||
|
+ r"|".join(MONTHS)
|
||||||
|
+ r")"
|
||||||
+ r")\b"
|
+ r")\b"
|
||||||
)
|
)
|
||||||
print(_ALPHA_MONTH_RANGE)
|
print(_ALPHA_MONTH_RANGE)
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
"""Unparse comic filenames."""
|
"""Unparse comic filenames."""
|
||||||
from collections.abc import Callable, Mapping
|
from collections.abc import Callable, Mapping, Sequence
|
||||||
|
from contextlib import suppress
|
||||||
|
from calendar import month_abbr
|
||||||
|
from types import MappingProxyType
|
||||||
|
|
||||||
|
|
||||||
def issue_formatter(issue: str) -> str:
|
def issue_formatter(issue: str) -> str:
|
||||||
@ -18,18 +21,39 @@ _PAREN_FMT: str = "({})"
|
|||||||
_FILENAME_FORMAT_TAGS: tuple[tuple[str, str | Callable], ...] = (
|
_FILENAME_FORMAT_TAGS: tuple[tuple[str, str | Callable], ...] = (
|
||||||
("series", "{}"),
|
("series", "{}"),
|
||||||
("volume", "v{}"),
|
("volume", "v{}"),
|
||||||
|
("volume_count", "(of {:03})"),
|
||||||
("issue", issue_formatter),
|
("issue", issue_formatter),
|
||||||
("issue_count", "(of {:03})"),
|
("issue_count", "(of {:03})"),
|
||||||
("year", _PAREN_FMT),
|
("date", _PAREN_FMT),
|
||||||
("title", "{}"),
|
("title", "{}"),
|
||||||
|
("publisher", _PAREN_FMT),
|
||||||
("original_format", _PAREN_FMT),
|
("original_format", _PAREN_FMT),
|
||||||
("scan_info", _PAREN_FMT),
|
("scan_info", _PAREN_FMT),
|
||||||
)
|
)
|
||||||
_EMPTY_VALUES: tuple[None, str] = (None, "")
|
_EMPTY_VALUES: tuple[None, str] = (None, "")
|
||||||
_DEFAULT_EXT = "cbz"
|
_DEFAULT_EXT = "cbz"
|
||||||
|
_DATE_KEYS = ("year", "month", "day")
|
||||||
|
|
||||||
|
|
||||||
class ComicFilenameSerializer:
|
class ComicFilenameSerializer:
|
||||||
|
def _add_date(self) -> None:
|
||||||
|
if "date" in self.metadata:
|
||||||
|
return
|
||||||
|
parts = []
|
||||||
|
for key in _DATE_KEYS:
|
||||||
|
if part := self.metadata.get(key):
|
||||||
|
if key == "month" and not parts:
|
||||||
|
with suppress(TypeError):
|
||||||
|
part = month_abbr[int(part)]
|
||||||
|
|
||||||
|
parts.append(part)
|
||||||
|
if key == "month" and not parts:
|
||||||
|
# noop if only day.
|
||||||
|
break
|
||||||
|
if parts:
|
||||||
|
date = "-".join(parts)
|
||||||
|
self.metadata = MappingProxyType({**self.metadata, "date": date})
|
||||||
|
|
||||||
def _tokenize_tag(self, tag: str, fmt: str | Callable) -> str:
|
def _tokenize_tag(self, tag: str, fmt: str | Callable) -> str:
|
||||||
val = self.metadata.get(tag)
|
val = self.metadata.get(tag)
|
||||||
if val in _EMPTY_VALUES:
|
if val in _EMPTY_VALUES:
|
||||||
@ -38,22 +62,30 @@ class ComicFilenameSerializer:
|
|||||||
token = final_fmt.format(val).strip()
|
token = final_fmt.format(val).strip()
|
||||||
return token
|
return token
|
||||||
|
|
||||||
|
def _add_remainder(self) -> str:
|
||||||
|
if remainders := self.metadata.get("remainders"):
|
||||||
|
if isinstance(remainders, Sequence):
|
||||||
|
remainder = " ".join(remainders)
|
||||||
|
else:
|
||||||
|
remainder = str(remainders)
|
||||||
|
return f"[{remainder}]"
|
||||||
|
return ""
|
||||||
|
|
||||||
def serialize(self) -> str:
|
def serialize(self) -> str:
|
||||||
"""Get our preferred basename from a metadata dict."""
|
"""Get our preferred basename from a metadata dict."""
|
||||||
|
self._add_date()
|
||||||
|
|
||||||
tokens = []
|
tokens = []
|
||||||
for tag, fmt in _FILENAME_FORMAT_TAGS:
|
for tag, fmt in _FILENAME_FORMAT_TAGS:
|
||||||
if token := self._tokenize_tag(tag, fmt):
|
if token := self._tokenize_tag(tag, fmt):
|
||||||
tokens.append(token)
|
tokens.append(token)
|
||||||
fn = " ".join(tokens)
|
fn = " ".join(tokens)
|
||||||
|
|
||||||
if remainders := self.metadata.get("remainders"):
|
fn += self._add_remainder()
|
||||||
# TODO make token and add before join?
|
|
||||||
remainder = " ".join(remainders)
|
|
||||||
# TODO oh this is the - delineated remainder :(
|
|
||||||
fn += f" - {remainder}"
|
|
||||||
|
|
||||||
if self._ext:
|
if self._ext:
|
||||||
fn += "." + self.metadata.get("ext", _DEFAULT_EXT)
|
ext = self.metadata.get("ext", _DEFAULT_EXT)
|
||||||
|
fn += f".{ext}"
|
||||||
|
|
||||||
return fn
|
return fn
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
"""Test filenames with human parsed correct results."""
|
"""Test filenames with human parsed correct results."""
|
||||||
|
|
||||||
|
from types import MappingProxyType
|
||||||
|
|
||||||
|
|
||||||
TEST_COMIC_FIELDS = {
|
TEST_COMIC_FIELDS = {
|
||||||
"series": "Long Series Name",
|
"series": "Long Series Name",
|
||||||
"issue": "001",
|
"issue": "001",
|
||||||
@ -30,7 +33,7 @@ TEST_COMIC_VOL_ONLY = {
|
|||||||
"ext": "cbr",
|
"ext": "cbr",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Working with 0.1.0
|
# Tests for 0.1.0
|
||||||
FNS = {
|
FNS = {
|
||||||
"Night of 1000 Wolves 001 (2013).cbz": {
|
"Night of 1000 Wolves 001 (2013).cbz": {
|
||||||
"series": "Night of 1000 Wolves",
|
"series": "Night of 1000 Wolves",
|
||||||
@ -239,7 +242,7 @@ FNS = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fixed with 0.2.0
|
# Tests for 0.2.0
|
||||||
FNS.update(
|
FNS.update(
|
||||||
{
|
{
|
||||||
# Philosopy change regarding dashes.
|
# Philosopy change regarding dashes.
|
||||||
@ -442,6 +445,34 @@ FNS.update(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
PARSE_FNS = MappingProxyType(FNS)
|
||||||
|
|
||||||
|
SERIALIZE_FNS = MappingProxyType(
|
||||||
|
{
|
||||||
|
"Long Series Name #001 (2000) Title (TPB) (Releaser).cbz": TEST_COMIC_FIELDS,
|
||||||
|
"Long Series Name v1 #001 "
|
||||||
|
"(2000) Title (TPB) (Releaser & Releaser-Releaser).cbr": TEST_COMIC_VOL_ONLY,
|
||||||
|
"Series Name (2000-12-31).cbz": {
|
||||||
|
"series": "Series Name",
|
||||||
|
"year": "2000",
|
||||||
|
"month": "12",
|
||||||
|
"day": "31",
|
||||||
|
"ext": "cbz",
|
||||||
|
},
|
||||||
|
"Series Name (2000-12).cbz": {
|
||||||
|
"series": "Series Name",
|
||||||
|
"year": "2000",
|
||||||
|
"month": "12",
|
||||||
|
"ext": "cbz",
|
||||||
|
},
|
||||||
|
"Series Name (Dec-31).cbz": {
|
||||||
|
"series": "Series Name",
|
||||||
|
"month": "12",
|
||||||
|
"day": "31",
|
||||||
|
"ext": "cbz",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# first_key, first_val = NEW.popitem()
|
# first_key, first_val = NEW.popitem()
|
||||||
# FNS[first_key] = first_val
|
# FNS[first_key] = first_val
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
"""Tests for filename parsing."""
|
"""Tests for filename parsing."""
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
from types import MappingProxyType
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from deepdiff.diff import DeepDiff
|
from deepdiff.diff import DeepDiff
|
||||||
|
|
||||||
from comicfn2dict import ComicFilenameParser
|
from comicfn2dict import ComicFilenameParser
|
||||||
from tests.comic_filenames import FNS
|
from tests.comic_filenames import PARSE_FNS
|
||||||
|
|
||||||
ALL_FIELDS = frozenset({"series", "volume", "issue", "issue_count", "year", "ext"})
|
|
||||||
FIELD_SCHEMA = MappingProxyType({key: None for key in ALL_FIELDS})
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("item", FNS.items())
|
@pytest.mark.parametrize("item", PARSE_FNS.items())
|
||||||
def test_parse_filename(item):
|
def test_parse_filename(item):
|
||||||
"""Test filename parsing."""
|
"""Test filename parsing."""
|
||||||
fn, defined_fields = item
|
fn, defined_fields = item
|
||||||
|
13
tests/test_dict2comicfn.py
Normal file
13
tests/test_dict2comicfn.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
"""Tests for filename parsing."""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from comicfn2dict import ComicFilenameSerializer
|
||||||
|
from tests.comic_filenames import SERIALIZE_FNS
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("item", SERIALIZE_FNS.items())
|
||||||
|
def test_serialize_dict(item):
|
||||||
|
"""Test metadata serialization."""
|
||||||
|
test_fn, md = item
|
||||||
|
fn = ComicFilenameSerializer(md).serialize()
|
||||||
|
assert test_fn == fn
|
Loading…
Reference in New Issue
Block a user