Template system now supports default values

This commit is contained in:
Rhet Turnbull
2020-03-28 09:57:48 -07:00
parent 427c4c0bc4
commit 67a9a9e21b
9 changed files with 357 additions and 119 deletions

View File

@@ -81,11 +81,11 @@ class ExportCommand(click.Command):
formatter.write_text(
"With the --directory option, you may specify a template for the "
+ "export directory. This directory will be appended to the export path specified "
+ " in the export DEST argument to export. For example, if template is "
+ "in the export DEST argument to export. For example, if template is "
+ "'{created.year}/{created.month}', and export desitnation DEST is "
+ "'/Users/maria/Pictures/export', "
+ " the actual export directory for a photo would be '/Users/maria/Pictures/export/2020/March' "
+ " if the photo was created in March 2020. "
+ "the actual export directory for a photo would be '/Users/maria/Pictures/export/2020/March' "
+ "if the photo was created in March 2020. "
)
formatter.write("\n")
formatter.write_text(
@@ -104,16 +104,22 @@ class ExportCommand(click.Command):
)
formatter.write("\n")
formatter.write_text(
"In the current implementation, substitutions which have no value "
+ "will be replaced by '_', "
+ "for example, your template looked like '{created.year}/{place.address}' "
"You may specify an optional default value to use if the substitution does not contain a value "
+ "(e.g. the value is null) "
+ "by specifying the default value after a ',' in the template string: "
+ "for example, if template is '{created.year}/{place.address,'NO_ADDRESS'}' "
+ "but there was no address associated with the photo, the resulting output would be: "
+ "'2020/_/photoname.jpg' "
+ "'2020/NO_ADDRESS/photoname.jpg'. "
+ "If specified, the default value may not contain a brace symbol ('{' or '}')."
)
formatter.write("\n")
formatter.write_text(
"I plan to add the option to specify the value to be used for missing "
+ "subsitutions in a future version. I also plan to extend the templating system "
"If you do not specify a default value and the template substitution "
+ "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"
)
formatter.write_text(
"I plan to eventually extend the templating system "
+ "to the exported filename so you can specify the filename using a template."
)
@@ -817,8 +823,8 @@ def query(
"--directory",
metavar="DIRECTORY",
default=None,
help="Optional template for specifying name of output directory. "
"See below for additional details on templating system",
help="Optional template for specifying name of output directory in the form '{name,DEFAULT}'. "
"See below for additional details on templating system.",
)
@DB_ARGUMENT
@click.argument("dest", nargs=1, type=click.Path(exists=True))

View File

@@ -1,3 +1,3 @@
""" version info """
__version__ = "0.24.0"
__version__ = "0.24.1"

View File

@@ -25,17 +25,17 @@ TEMPLATE_SUBSTITUTIONS = {
"{modified.mon}": "Month abbreviation in the user's locale of the file modification time",
"{modified.doy}": "3-digit day of year (e.g Julian day) of file modification time, starting from 1 (zero padded)",
"{place.name}": "Place name from the photo's reverse geolocation data, as displayed in Photos",
"{place.names.country}": "Country name from the photo's reverse geolocation data",
"{place.names.state_province}": "State or province name from the photo's reverse geolocation data",
"{place.names.city}": "City or locality name from the photo's reverse geolocation data",
"{place.names.area_of_interest}": "Area of interest name (e.g. landmark or public place) from the photo's reverse geolocation data",
"{place.name.country}": "Country name from the photo's reverse geolocation data",
"{place.name.state_province}": "State or province name from the photo's reverse geolocation data",
"{place.name.city}": "City or locality name from the photo's reverse geolocation data",
"{place.name.area_of_interest}": "Area of interest name (e.g. landmark or public place) from the photo's reverse geolocation data",
"{place.address}": "Postal address from the photo's reverse geolocation data, e.g. '2007 18th St NW, Washington, DC 20009, United States'",
"{place.street}": "Street part of the postal address, e.g. '2007 18th St NW'",
"{place.city}": "City part of the postal address, e.g. 'Washington'",
"{place.state_province}": "State/province part of the postal address, e.g. 'DC'",
"{place.postal_code}": "Postal code part of the postal address, e.g. '20009'",
"{place.country}": "Country name of the postal address, e.g. 'United States'",
"{place.country_code}": "ISO country code of the postal address, e.g. 'US'",
"{place.address.street}": "Street part of the postal address, e.g. '2007 18th St NW'",
"{place.address.city}": "City part of the postal address, e.g. 'Washington'",
"{place.address.state_province}": "State/province part of the postal address, e.g. 'DC'",
"{place.address.postal_code}": "Postal code part of the postal address, e.g. '20009'",
"{place.address.country}": "Country name of the postal address, e.g. 'United States'",
"{place.address.country_code}": "ISO country code of the postal address, e.g. 'US'",
}
@@ -119,34 +119,81 @@ def get_template_value(lookup, photo):
if lookup == "place.name":
return photo.place.name if photo.place else None
if lookup == "place.names.country":
if lookup == "place.name.country":
return (
photo.place.names.country[0]
if photo.place and photo.place.names.country
else None
)
if lookup == "place.names.state_province":
if lookup == "place.name.state_province":
return (
photo.place.names.state_province[0]
if photo.place and photo.place.names.state_province
else None
)
if lookup == "place.names.city":
if lookup == "place.name.city":
return (
photo.place.names.city[0]
if photo.place and photo.place.names.city
else None
)
if lookup == "place.names.area_of_interest":
if lookup == "place.name.area_of_interest":
return (
photo.place.names.area_of_interest[0]
if photo.place and photo.place.names.area_of_interest
else None
)
if lookup == "place.address":
return (
photo.place.address_str if photo.place and photo.place.address_str else None
)
if lookup == "place.address.street":
return (
photo.place.address.street
if photo.place and photo.place.address.street
else None
)
if lookup == "place.address.city":
return (
photo.place.address.city
if photo.place and photo.place.address.city
else None
)
if lookup == "place.address.state_province":
return (
photo.place.address.state_province
if photo.place and photo.place.address.state_province
else None
)
if lookup == "place.address.postal_code":
return (
photo.place.address.postal_code
if photo.place and photo.place.address.postal_code
else None
)
if lookup == "place.address.country":
return (
photo.place.address.country
if photo.place and photo.place.address.country
else None
)
if lookup == "place.address.country_code":
return (
photo.place.address.iso_country_code
if photo.place and photo.place.address.iso_country_code
else None
)
# if here, didn't get a match
raise KeyError(f"No rule for processing {lookup}")