Refactored regex in phototemplate
This commit is contained in:
@@ -208,7 +208,11 @@ class ExportCommand(click.Command):
|
|||||||
+ "has no value, '_' (underscore) will be used as the default value. For example, in the "
|
+ "has no value, '_' (underscore) will be used as the default value. For example, in the "
|
||||||
+ "above example, this would result in '2020/_/photoname.jpg' if address was null."
|
+ "above example, this would result in '2020/_/photoname.jpg' if address was null."
|
||||||
)
|
)
|
||||||
|
formatter.write("\n")
|
||||||
|
formatter.write_text(
|
||||||
|
'You may specify a null default (e.g. "" or empty string) by omitting the value after '
|
||||||
|
+ 'the comma, e.g. {title,} which would render to "" if title had no value.'
|
||||||
|
)
|
||||||
formatter.write("\n")
|
formatter.write("\n")
|
||||||
templ_tuples = [("Substitution", "Description")]
|
templ_tuples = [("Substitution", "Description")]
|
||||||
templ_tuples.extend((k, v) for k, v in TEMPLATE_SUBSTITUTIONS.items())
|
templ_tuples.extend((k, v) for k, v in TEMPLATE_SUBSTITUTIONS.items())
|
||||||
|
|||||||
@@ -174,9 +174,9 @@ class PhotoTemplate:
|
|||||||
# there would be 6 possible renderings (2 albums x 3 persons)
|
# there would be 6 possible renderings (2 albums x 3 persons)
|
||||||
|
|
||||||
# regex to find {template_field,optional_default} in strings
|
# regex to find {template_field,optional_default} in strings
|
||||||
# for explanation of regex see https://regex101.com/r/4JJg42/1
|
# for explanation of regex see https://regex101.com/r/MbOlJV/4
|
||||||
# pylint: disable=anomalous-backslash-in-string
|
# pylint: disable=anomalous-backslash-in-string
|
||||||
regex = r"(?<!\{)\{([^\\,}]+)(,{0,1}(([\w\-\%. ]+))?)(?=\}(?!\}))\}"
|
regex = r"(?<!\{)\{([^}]*\+)?([^\\,}+]+)(,{0,1}([\w\-\%. ]+)?)(?=\}(?!\}))\}"
|
||||||
if type(template) is not str:
|
if type(template) is not str:
|
||||||
raise TypeError(f"template must be type str, not {type(template)}")
|
raise TypeError(f"template must be type str, not {type(template)}")
|
||||||
|
|
||||||
@@ -198,17 +198,25 @@ class PhotoTemplate:
|
|||||||
def subst(matchobj):
|
def subst(matchobj):
|
||||||
groups = len(matchobj.groups())
|
groups = len(matchobj.groups())
|
||||||
if groups == 4:
|
if groups == 4:
|
||||||
|
delim = matchobj.group(1)
|
||||||
|
field = matchobj.group(2)
|
||||||
|
default = matchobj.group(3)
|
||||||
|
default_val = matchobj.group(4)
|
||||||
try:
|
try:
|
||||||
val = get_func(matchobj.group(1), matchobj.group(3))
|
val = get_func(field, default_val)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return matchobj.group(0)
|
return matchobj.group(0)
|
||||||
|
|
||||||
if val is None:
|
if val is None:
|
||||||
val = (
|
# field valid but didn't match a value
|
||||||
matchobj.group(3)
|
if default == ",":
|
||||||
if matchobj.group(3) is not None
|
val = ""
|
||||||
else none_str
|
else:
|
||||||
)
|
val = (
|
||||||
|
default_val
|
||||||
|
if default_val is not None
|
||||||
|
else none_str
|
||||||
|
)
|
||||||
|
|
||||||
return val
|
return val
|
||||||
else:
|
else:
|
||||||
@@ -249,7 +257,7 @@ class PhotoTemplate:
|
|||||||
rendered_strings = [rendered]
|
rendered_strings = [rendered]
|
||||||
for field in MULTI_VALUE_SUBSTITUTIONS:
|
for field in MULTI_VALUE_SUBSTITUTIONS:
|
||||||
# Build a regex that matches only the field being processed
|
# Build a regex that matches only the field being processed
|
||||||
re_str = r"(?<!\\)\{(" + field + r")(,(([\w\-\%. ]{0,})))?\}"
|
re_str = r"(?<!\{)\{([^}]*\+)?(" + field + r")(,{0,1}([\w\-\%. ]+)?)(?=\}(?!\}))\}"
|
||||||
regex_multi = re.compile(re_str)
|
regex_multi = re.compile(re_str)
|
||||||
|
|
||||||
# holds each of the new rendered_strings, dict to avoid repeats (dict.keys())
|
# holds each of the new rendered_strings, dict to avoid repeats (dict.keys())
|
||||||
@@ -319,9 +327,9 @@ class PhotoTemplate:
|
|||||||
for rendered_str in rendered_strings:
|
for rendered_str in rendered_strings:
|
||||||
unmatched.extend(
|
unmatched.extend(
|
||||||
[
|
[
|
||||||
no_match[0]
|
no_match[1]
|
||||||
for no_match in re.findall(regex, rendered_str)
|
for no_match in re.findall(regex, rendered_str)
|
||||||
if no_match[0] not in unmatched
|
if no_match[1] not in unmatched
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ def test_subst_default_val_2():
|
|||||||
|
|
||||||
template = "{place.name.area_of_interest,}"
|
template = "{place.name.area_of_interest,}"
|
||||||
rendered, _ = photo.render_template(template)
|
rendered, _ = photo.render_template(template)
|
||||||
assert rendered[0] == "_"
|
assert rendered[0] == ""
|
||||||
|
|
||||||
|
|
||||||
def test_subst_unknown_val():
|
def test_subst_unknown_val():
|
||||||
@@ -284,10 +284,6 @@ def test_subst_unknown_val():
|
|||||||
assert rendered[0] == "2020/{foo}"
|
assert rendered[0] == "2020/{foo}"
|
||||||
assert unknown == ["foo"]
|
assert unknown == ["foo"]
|
||||||
|
|
||||||
template = "{place.name.area_of_interest,}"
|
|
||||||
rendered, _ = photo.render_template(template)
|
|
||||||
assert rendered[0] == "_"
|
|
||||||
|
|
||||||
|
|
||||||
def test_subst_double_brace():
|
def test_subst_double_brace():
|
||||||
""" Test substitution with double brace {{ which should be ignored """
|
""" Test substitution with double brace {{ which should be ignored """
|
||||||
|
|||||||
Reference in New Issue
Block a user