diff --git a/osxphotos/_version.py b/osxphotos/_version.py index 89faf7fb..e33bb353 100644 --- a/osxphotos/_version.py +++ b/osxphotos/_version.py @@ -1,3 +1,3 @@ """ version info """ -__version__ = "0.28.5" +__version__ = "0.28.6" diff --git a/osxphotos/template.py b/osxphotos/template.py index 1de4d96f..551181db 100644 --- a/osxphotos/template.py +++ b/osxphotos/template.py @@ -10,6 +10,7 @@ # This code isn't elegant but it seems to work well. PRs gladly accepted. import datetime +import locale import os import pathlib import re @@ -18,6 +19,9 @@ from typing import Tuple, List # pylint: disable=syntax-error from .photoinfo import PhotoInfo from ._constants import _UNKNOWN_PERSON +# ensure locale set to user's locale +locale.setlocale(locale.LC_ALL, "") + # Permitted substitutions (each of these returns a single value or None) TEMPLATE_SUBSTITUTIONS = { "{name}": "Filename of the photo", diff --git a/tests/test_cli.py b/tests/test_cli.py index b5cbf2dd..4d6eb56a 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -71,6 +71,12 @@ CLI_EXPORTED_DIRECTORY_TEMPLATE_FILENAMES1 = [ "2018/September/Pumkins1.jpg", ] +CLI_EXPORTED_DIRECTORY_TEMPLATE_FILENAMES_LOCALE = [ + "2019/September/IMG_9975.JPEG", + "2020/Februar/IMG_1064.JPEG", + "2016/März/IMG_3984.JPEG", +] + CLI_EXPORTED_DIRECTORY_TEMPLATE_FILENAMES_ALBUM1 = [ "Multi Keyword/wedding.jpg", "_/Tulips.jpg", @@ -595,6 +601,45 @@ def test_export_directory_template_album_2(): assert os.path.isfile(os.path.join(workdir, filepath)) +def test_export_directory_template_locale(): + # test export using directory template in user locale non-US + import os + import glob + import locale + import os.path + + import osxphotos + from osxphotos.__main__ import export + + runner = CliRunner() + cwd = os.getcwd() + # pylint: disable=not-context-manager + with runner.isolated_filesystem(): + # set locale environment + os.environ["LANG"] = "de_DE.UTF-8" + os.environ["LC_COLLATE"] = "de_DE.UTF-8" + os.environ["LC_CTYPE"] = "de_DE.UTF-8" + os.environ["LC_MESSAGES"] = "de_DE.UTF-8" + os.environ["LC_MONETARY"] = "de_DE.UTF-8" + os.environ["LC_NUMERIC"] = "de_DE.UTF-8" + os.environ["LC_TIME"] = "de_DE.UTF-8" + locale.setlocale(locale.LC_ALL, "") + result = runner.invoke( + export, + [ + os.path.join(cwd, PLACES_PHOTOS_DB), + ".", + "-V", + "--directory", + "{created.year}/{created.month}", + ], + ) + assert result.exit_code == 0 + workdir = os.getcwd() + for filepath in CLI_EXPORTED_DIRECTORY_TEMPLATE_FILENAMES_LOCALE: + assert os.path.isfile(os.path.join(workdir, filepath)) + + def test_places(): import json import os diff --git a/tests/test_template.py b/tests/test_template.py index 81242795..ca4cbcae 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -53,6 +53,41 @@ TEMPLATE_VALUES = { } +TEMPLATE_VALUES_DEU = { + "{name}": "128FB4C6-0B16-4E7D-9108-FB2E90DA1546", + "{original_name}": "IMG_1064", + "{title}": "Glen Ord", + "{descr}": "Jack Rose Dining Saloon", + "{created.date}": "2020-02-04", + "{created.year}": "2020", + "{created.yy}": "20", + "{created.mm}": "02", + "{created.month}": "Februar", + "{created.mon}": "Feb", + "{created.doy}": "035", + "{modified.date}": "2020-03-21", + "{modified.year}": "2020", + "{modified.yy}": "20", + "{modified.mm}": "03", + "{modified.month}": "März", + "{modified.mon}": "Mär", + "{modified.doy}": "081", + "{place.name}": "Washington, District of Columbia, United States", + "{place.country_code}": "US", + "{place.name.country}": "United States", + "{place.name.state_province}": "District of Columbia", + "{place.name.city}": "Washington", + "{place.name.area_of_interest}": "_", + "{place.address}": "2038 18th St NW, Washington, DC 20009, United States", + "{place.address.street}": "2038 18th St NW", + "{place.address.city}": "Washington", + "{place.address.state_province}": "DC", + "{place.address.postal_code}": "20009", + "{place.address.country}": "United States", + "{place.address.country_code}": "US", +} + + def test_lookup(): """ Test that a lookup is returned for every possible value """ import re @@ -87,6 +122,49 @@ def test_subst(): assert rendered[0] == TEMPLATE_VALUES[template] +def test_subst_locale_1(): + """ Test that substitutions are correct in user locale""" + import locale + import osxphotos + + # osxphotos.template sets local on load so set the environment first + # set locale to DE + locale.setlocale(locale.LC_ALL, "de_DE.UTF-8") + from osxphotos.template import render_filepath_template + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB_PLACES) + photo = photosdb.photos(uuid=[UUID_DICT["place_dc"]])[0] + + for template in TEMPLATE_VALUES_DEU: + rendered, _ = render_filepath_template(template, photo) + assert rendered[0] == TEMPLATE_VALUES_DEU[template] + + +def test_subst_locale_2(): + """ Test that substitutions are correct in user locale""" + import locale + import os + import osxphotos + + # osxphotos.template sets local on load so set the environment first + os.environ["LANG"] = "de_DE.UTF-8" + os.environ["LC_COLLATE"] = "de_DE.UTF-8" + os.environ["LC_CTYPE"] = "de_DE.UTF-8" + os.environ["LC_MESSAGES"] = "de_DE.UTF-8" + os.environ["LC_MONETARY"] = "de_DE.UTF-8" + os.environ["LC_NUMERIC"] = "de_DE.UTF-8" + os.environ["LC_TIME"] = "de_DE.UTF-8" + + from osxphotos.template import render_filepath_template + + photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB_PLACES) + photo = photosdb.photos(uuid=[UUID_DICT["place_dc"]])[0] + + for template in TEMPLATE_VALUES_DEU: + rendered, _ = render_filepath_template(template, photo) + assert rendered[0] == TEMPLATE_VALUES_DEU[template] + + def test_subst_default_val(): """ Test substitution with default value specified """ import locale