Update MetadataFormatter

Several custom conversions (the s in {title!s}) have been created
u - str.upper()
l - str.casefold()
S - str.swapcase()
t - str.title()
c - str.Capitalize()

A new syntax has been added '{title+str}' and '{title-str}':
The + indicates an alternate value.
The - indicates a default value.

If the title of a comic is not set then
'{title-str}' will output 'str'
and
'{title+str} will output ''

If the title of a comic is 'hello' then
'{title+str}' will output 'str'
and
'{title-str}' will output 'hello'
This commit is contained in:
Timmy Welch 2022-10-04 16:15:20 -07:00
parent 4034123e6d
commit a6d55cd21a
No known key found for this signature in database
2 changed files with 100 additions and 0 deletions

View File

@ -79,12 +79,39 @@ class MetadataFormatter(string.Formatter):
return ""
return cast(str, super().format_field(value, format_spec))
def convert_field(self, value: Any, conversion: str) -> str:
if conversion == "u":
return str(value).upper()
if conversion == "l":
return str(value).casefold()
if conversion == "c":
return str(value).capitalize()
if conversion == "S":
return str(value).swapcase()
if conversion == "t":
return str(value).title()
return cast(str, super().convert_field(value, conversion))
def handle_replacements(self, string: str, replacements: list[Replacement]) -> str:
for find, replace, strict_only in replacements:
if self.is_strict() or not strict_only:
string = string.replace(find, replace)
return string
def none_replacement(self, value: Any, replacement: str, r: str) -> Any:
if r == "-" and value is None or value == "":
return replacement
if r == "+" and value is not None:
return replacement
return value
def split_replacement(self, field_name: str) -> tuple[str, str, str]:
if "-" in field_name:
return field_name.rpartition("-")
if "+" in field_name:
return field_name.rpartition("+")
return field_name, "", ""
def is_strict(self) -> bool:
return self.platform in [Platform.UNIVERSAL, Platform.WINDOWS]
@ -124,6 +151,7 @@ class MetadataFormatter(string.Formatter):
lstrip = False
# if there's a field, output it
if field_name is not None and field_name != "":
field_name, r, replacement = self.split_replacement(field_name)
field_name = field_name.casefold()
# this is some markup, find the object and do the formatting
@ -136,6 +164,8 @@ class MetadataFormatter(string.Formatter):
obj, arg_used = self.get_field(field_name, args, kwargs)
used_args.add(arg_used)
obj = self.none_replacement(obj, replacement, r)
# do any conversion on the resulting object
obj = self.convert_field(obj, conversion) # type: ignore

View File

@ -750,6 +750,76 @@ fnames = [
]
rnames = [
(
"{series!c} {price} {year}", # Capitalize
False,
"universal",
"Cory doctorow's futuristic tales of the here and now 2007.cbz",
does_not_raise(),
),
(
"{series!t} {price} {year}", # Title Case
False,
"universal",
"Cory Doctorow'S Futuristic Tales Of The Here And Now 2007.cbz",
does_not_raise(),
),
(
"{series!S} {price} {year}", # Swap Case
False,
"universal",
"cORY dOCTOROW'S fUTURISTIC tALES OF THE hERE AND nOW 2007.cbz",
does_not_raise(),
),
(
"{title!l} {price} {year}", # Lowercase
False,
"universal",
"anda's game 2007.cbz",
does_not_raise(),
),
(
"{title!u} {price} {year}", # Upper Case
False,
"universal",
"ANDA'S GAME 2007.cbz",
does_not_raise(),
),
(
"{title} {price} {year+}", # Empty alternate value
False,
"universal",
"Anda's Game.cbz",
does_not_raise(),
),
(
"{title} {price} {year+year!u}", # Alternate value Upper Case
False,
"universal",
"Anda's Game YEAR.cbz",
does_not_raise(),
),
(
"{title} {price} {year+year}", # Alternate Value
False,
"universal",
"Anda's Game year.cbz",
does_not_raise(),
),
(
"{title} {price-0} {year}", # Default value
False,
"universal",
"Anda's Game 0 2007.cbz",
does_not_raise(),
),
(
"{title} {price+0} {year}", # Alternate Value
False,
"universal",
"Anda's Game 2007.cbz",
does_not_raise(),
),
(
"{series} #{issue} - {title} ({year}) ({price})", # price should be none
False,