Refactor ruff (#1155)

* Refactored to make ruff happy

* Refactored tests, fixed bug in Mojave path_raw
This commit is contained in:
Rhet Turnbull 2023-08-12 20:24:46 -06:00 committed by GitHub
parent e53d223f2d
commit 8be71243d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 192 additions and 204 deletions

View File

@ -53,10 +53,10 @@ _PHOTOS_8_MODEL_VERSION = [16000, 16999] # Ventura dev preview: 16119
_PHOTOS_9_MODEL_VERSION = [17000, 17999] # Sonoma dev preview: 17120 _PHOTOS_9_MODEL_VERSION = [17000, 17999] # Sonoma dev preview: 17120
# the preview versions of 12.0.0 had a difference schema for syndication info so need to check model version before processing # the preview versions of 12.0.0 had a difference schema for syndication info so need to check model version before processing
_PHOTOS_SYNDICATION_MODEL_VERSION = 15323 # 12.0.1 _PHOTOS_SYNDICATION_MODEL_VERSION = 15323 # 12.0.1
# shared iCloud library versions; dev preview doesn't contain same columns as release version # shared iCloud library versions; dev preview doesn't contain same columns as release version
_PHOTOS_SHARED_LIBRARY_VERSION = 16320 # 13.0 _PHOTOS_SHARED_LIBRARY_VERSION = 16320 # 13.0
# some table names differ between Photos 5 and later versions # some table names differ between Photos 5 and later versions
_DB_TABLE_NAMES = { _DB_TABLE_NAMES = {

View File

@ -362,7 +362,7 @@ def set_photo_metadata(
photo.title = normalize_unicode(metadata.title) photo.title = normalize_unicode(metadata.title)
photo.description = normalize_unicode(metadata.description) photo.description = normalize_unicode(metadata.description)
keywords = metadata.keywords.copy() keywords = metadata.keywords.copy()
keywords =normalize_unicode(keywords) keywords = normalize_unicode(keywords)
if merge_keywords: if merge_keywords:
if old_keywords := normalize_unicode(photo.keywords): if old_keywords := normalize_unicode(photo.keywords):
keywords.extend(old_keywords) keywords.extend(old_keywords)

View File

@ -273,7 +273,7 @@ def format_flags(photo: PhotoInfo) -> str:
if photo.shared: if photo.shared:
flags.append("shared") flags.append("shared")
if photo.syndicated: if photo.syndicated:
flags.append("syndicated") # sourcery skip flags.append("syndicated") # sourcery skip
flags.append( flags.append(
"saved to library" if photo.saved_to_library else "not saved to library" "saved to library" if photo.saved_to_library else "not saved to library"
) )

View File

@ -52,7 +52,9 @@ MACOS_OPTIONS = make_click_option_decorator(
@click.command() @click.command()
@DB_OPTION @DB_OPTION
@JSON_OPTION @JSON_OPTION
@click.option("--count", is_flag=True, help="Print count of photos matching query and exit.") @click.option(
"--count", is_flag=True, help="Print count of photos matching query and exit."
)
@QUERY_OPTIONS @QUERY_OPTIONS
@DELETED_OPTIONS @DELETED_OPTIONS
@MACOS_OPTIONS @MACOS_OPTIONS

View File

@ -219,7 +219,7 @@ def _verbose_print_function(
styled_args = [] styled_args = []
timestamp_str = f"{str(datetime.now())} -- " if timestamp else "" timestamp_str = f"{str(datetime.now())} -- " if timestamp else ""
for arg in args: for arg in args:
if type(arg) == str: if isinstance(arg, str):
arg = timestamp_str + arg arg = timestamp_str + arg
if "error" in arg.lower(): if "error" in arg.lower():
arg = click.style(arg, fg=CLI_COLOR_ERROR) arg = click.style(arg, fg=CLI_COLOR_ERROR)
@ -236,7 +236,7 @@ def _verbose_print_function(
timestamp_str = time_stamp() if timestamp else "" timestamp_str = time_stamp() if timestamp else ""
new_args = [] new_args = []
for arg in args: for arg in args:
if type(arg) == str: if isinstance(arg, str):
if "error" in arg.lower(): if "error" in arg.lower():
arg = f"[error]{arg}" arg = f"[error]{arg}"
if ERROR_EMOJI: if ERROR_EMOJI:
@ -257,7 +257,7 @@ def _verbose_print_function(
timestamp_str = time_stamp() if timestamp else "" timestamp_str = time_stamp() if timestamp else ""
new_args = [] new_args = []
for arg in args: for arg in args:
if type(arg) == str: if isinstance(arg, str):
if "error" in arg.lower(): if "error" in arg.lower():
arg = f"[error]{arg}" arg = f"[error]{arg}"
if ERROR_EMOJI: if ERROR_EMOJI:

View File

@ -58,7 +58,7 @@ def exiftool_can_write(suffix: str) -> bool:
def escape_str(s): def escape_str(s):
"""escape string for use with exiftool -E""" """escape string for use with exiftool -E"""
if type(s) != str: if not isinstance(s, str):
return s return s
s = html.escape(s) s = html.escape(s)
s = s.replace("\n", "
") s = s.replace("\n", "
")
@ -69,7 +69,7 @@ def escape_str(s):
def unescape_str(s): def unescape_str(s):
"""unescape an HTML string returned by exiftool -E""" """unescape an HTML string returned by exiftool -E"""
if type(s) != str: if not isinstance(s, str):
return s return s
# avoid " in values which result in json.loads() throwing an exception, #636 # avoid " in values which result in json.loads() throwing an exception, #636
s = s.replace(""", '\\"') s = s.replace(""", '\\"')

View File

@ -355,10 +355,10 @@ class _IgnoreRule:
if os.altsep is not None: if os.altsep is not None:
_all_seps_expr = f"[{re.escape(os.sep)}{re.escape(os.altsep)}]" _all_seps_expr = f"[{re.escape(os.sep)}{re.escape(os.altsep)}]"
_path_split = lambda path: re.split(_all_seps_expr, path) # noqa: E731 _path_split = lambda path: re.split(_all_seps_expr, path) # noqa: E731
else: else:
_path_split = lambda path: path.split(os.sep) # noqa: E731 _path_split = lambda path: path.split(os.sep) # noqa: E731
def _fnmatch_pathname_to_regexp(pattern, anchored, directory_only): def _fnmatch_pathname_to_regexp(pattern, anchored, directory_only):

View File

@ -552,6 +552,7 @@ class PhotoInfo:
f"MISSING PATH: RAW photo for UUID {self._uuid} should be at {photopath} but does not appear to exist" f"MISSING PATH: RAW photo for UUID {self._uuid} should be at {photopath} but does not appear to exist"
) )
photopath = None photopath = None
return photopath
@property @property
def description(self): def description(self):

View File

@ -4,4 +4,8 @@ Processes a Photos.app library database to extract information about photos
""" """
from .photosdb import PhotosDB from .photosdb import PhotosDB
from .photosdb_utils import get_photos_version_from_model, get_db_version, get_model_version from .photosdb_utils import (
get_db_version,
get_model_version,
get_photos_version_from_model,
)

View File

@ -464,7 +464,7 @@ class PhotoTemplate:
([rendered_strings], [unmatched]): tuple of list of rendered strings and list of unmatched template values ([rendered_strings], [unmatched]): tuple of list of rendered strings and list of unmatched template values
""" """
if type(template) is not str: if not isinstance(template, str):
raise TypeError(f"template must be type str, not {type(template)}") raise TypeError(f"template must be type str, not {type(template)}")
self.options = options self.options = options
@ -1395,7 +1395,7 @@ class PhotoTemplate:
# if no uuid, then template is being validated but not actually run # if no uuid, then template is being validated but not actually run
# so don't run the function # so don't run the function
values = [] values = []
elif caller in ["export", "query"]: elif caller in {"export", "query"}:
# function signature is: # function signature is:
# def example(photo: PhotoInfo, options: ExportOptions, args: Optional[str] = None, **kwargs) -> Union[List, str]: # def example(photo: PhotoInfo, options: ExportOptions, args: Optional[str] = None, **kwargs) -> Union[List, str]:
values = template_func(self.photo, options=self.options, args=field_arg) values = template_func(self.photo, options=self.options, args=field_arg)
@ -1411,7 +1411,7 @@ class PhotoTemplate:
raise TypeError( raise TypeError(
f"Invalid return type for function {funcname}: expected str or list" f"Invalid return type for function {funcname}: expected str or list"
) )
if type(values) == str: if isinstance(values, str):
values = [values] values = [values]
# sanitize directory names if needed # sanitize directory names if needed

View File

@ -40,7 +40,7 @@ def sqlgrep(
for row_num, row in enumerate(cursor): for row_num, row in enumerate(cursor):
for field in row.keys(): for field in row.keys():
field_value = row[field] field_value = row[field]
if not field_value or type(field_value) == bytes: if not field_value or isinstance(field_value, bytes):
# don't search binary blobs # don't search binary blobs
next next
field_value = str(field_value) field_value = str(field_value)

View File

@ -253,8 +253,6 @@ def list_photo_libraries():
return lib_list return lib_list
# def findfiles(pattern, path): # def findfiles(pattern, path):
# """Returns list of filenames from path matched by pattern # """Returns list of filenames from path matched by pattern
# shell pattern. Matching is case-insensitive. # shell pattern. Matching is case-insensitive.

18
pyproject.toml Normal file
View File

@ -0,0 +1,18 @@
[tool.ruff]
# Docs: https://beta.ruff.rs/docs/
# Rules: https://beta.ruff.rs/docs/rules/
target-version = "py39"
line-length = 366
ignore = ["E402","E722","E741","F401","F403","F405","F541","F822","F841"]
# Exclude a variety of commonly ignored directories.
exclude = [
".git",
".mypy_cache",
".pre-commit-cache",
".ruff_cache",
".tox",
".venv",
"venv",
"docs",
"__pycache",
]

View File

@ -22,7 +22,7 @@ class TempDiskImage:
TypeError if size is not int TypeError if size is not int
RunTimeError if not on MacOS RunTimeError if not on MacOS
""" """
if type(size) != int: if not isinstance(size, int):
raise TypeError("size must be int") raise TypeError("size must be int")
system = platform.system() system = platform.system()

View File

@ -111,7 +111,7 @@ def test_attributes(photosdb):
assert p.path.endswith( assert p.path.endswith(
"/tests/Test-10.12.6.photoslibrary/Masters/2019/08/24/20190824-030824/Pumkins2.jpg" "/tests/Test-10.12.6.photoslibrary/Masters/2019/08/24/20190824-030824/Pumkins2.jpg"
) )
assert p.ismissing == False assert not p.ismissing
def test_missing(photosdb): def test_missing(photosdb):
@ -119,7 +119,7 @@ def test_missing(photosdb):
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.path is None assert p.path is None
assert p.ismissing == True assert p.ismissing
def test_count(photosdb): def test_count(photosdb):

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -76,7 +76,7 @@ UUID_DOWNLOAD_MISSING = "C6C712C5-9316-408D-A3C3-125661422DA9" # IMG_8844.JPG
UUID_FILE = "tests/uuid_from_file.txt" UUID_FILE = "tests/uuid_from_file.txt"
SKIP_UUID_FILE = "tests/skip_uuid_from_file.txt" SKIP_UUID_FILE = "tests/skip_uuid_from_file.txt"
CLI_OUTPUT_QUERY_UUID = '[{"uuid": "D79B8D77-BFFC-460B-9312-034F2877D35B", "filename": "D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg", "original_filename": "Pumkins2.jpg", "date": "2018-09-28T16:07:07-04:00", "description": "Girl holding pumpkin", "title": "I found one!", "keywords": ["Kids"], "albums": ["Pumpkin Farm", "Test Album", "Multi Keyword"], "persons": ["Katie"], "path": "/tests/Test-10.15.7.photoslibrary/originals/D/D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg", "ismissing": false, "hasadjustments": false, "external_edit": false, "favorite": false, "hidden": false, "latitude": 41.256566, "longitude": -95.940257, "path_edited": null, "shared": false, "isphoto": true, "ismovie": false, "uti": "public.jpeg", "burst": false, "live_photo": false, "path_live_photo": null, "iscloudasset": false, "incloud": null}]' CLI_OUTPUT_QUERY_UUID = '[{"uuid": "D79B8D77-BFFC-460B-9312-034F2877D35B", "filename": "D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg", "original_filename": "Pumkins2.jpg", "date": "2018-09-28T16:07:07-04:00", "description": "Girl holding pumpkin", "title": "I found one!", "keywords": ["Kids"], "albums": ["Pumpkin Farm", "Test Album", "Multi Keyword"], "persons": ["Katie"], "path": "/tests/Test-10.15.7.photoslibrary/originals/D/D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg", "ismissing": false, "hasadjustments": false, "external_edit": false, "favorite": false, "hidden": false, "latitude": 41.256566, "longitude": -95.940257, "path_edited": null, "shared": false, "isphoto": true, "ismovie": false, "uti": "public.jpeg", "burst": false, "live_photo": false, "path_live_photo": null, "iscloudasset": false, "incloud": null}]' # noqa: E501
CLI_EXPORT_FILENAMES = _normalize_fs_paths( CLI_EXPORT_FILENAMES = _normalize_fs_paths(
[ [

View File

@ -537,7 +537,10 @@ def test_import_keyword_merge():
photo_1 = Photo(uuid_1) photo_1 = Photo(uuid_1)
assert photo_1.filename == file_1 assert photo_1.filename == file_1
assert sorted(photo_1.keywords) == sorted(list(set(["Bar", "Foo"] + TEST_DATA[TEST_IMAGE_1]["keywords"]))) assert sorted(photo_1.keywords) == sorted(
list(set(["Bar", "Foo"] + TEST_DATA[TEST_IMAGE_1]["keywords"]))
)
@pytest.mark.skipif(exiftool_path is None, reason="exiftool not installed") @pytest.mark.skipif(exiftool_path is None, reason="exiftool not installed")
@pytest.mark.test_import @pytest.mark.test_import
@ -574,7 +577,9 @@ def test_import_keyword_merge_unicode():
photo_1 = Photo(uuid_1) photo_1 = Photo(uuid_1)
assert photo_1.filename == file_1 assert photo_1.filename == file_1
assert sorted(photo_1.keywords) == sorted(list(set(["Bar", "Foo"] + TEST_DATA[TEST_IMAGE_1]["keywords"]))) assert sorted(photo_1.keywords) == sorted(
list(set(["Bar", "Foo"] + TEST_DATA[TEST_IMAGE_1]["keywords"]))
)
@pytest.mark.test_import @pytest.mark.test_import

View File

@ -19,7 +19,7 @@ def test_init():
cfg = ConfigOptions("test", VARS) cfg = ConfigOptions("test", VARS)
assert isinstance(cfg, ConfigOptions) assert isinstance(cfg, ConfigOptions)
assert cfg.foo == "bar" assert cfg.foo == "bar"
assert cfg.bar == False assert not cfg.bar
assert type(cfg.test1) == tuple assert type(cfg.test1) == tuple
@ -67,7 +67,7 @@ def test_asdict():
cfg = ConfigOptions("test", VARS) cfg = ConfigOptions("test", VARS)
cfg_dict = cfg.asdict() cfg_dict = cfg.asdict()
assert cfg_dict["foo"] == "bar" assert cfg_dict["foo"] == "bar"
assert cfg_dict["bar"] == False assert not cfg_dict["bar"]
assert cfg_dict["test1"] == () assert cfg_dict["test1"] == ()

View File

@ -18,14 +18,14 @@ from osxphotos.export_db import (
) )
from osxphotos.export_db_utils import export_db_get_version from osxphotos.export_db_utils import export_db_get_version
EXIF_DATA = """[{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", "EXIF:ImageDescription": "\u2068Elder Park\u2069, \u2068Adelaide\u2069, \u2068Australia\u2069", "XMP:Description": "\u2068Elder Park\u2069, \u2068Adelaide\u2069, \u2068Australia\u2069", "XMP:Title": "Elder Park", "EXIF:GPSLatitude": "34 deg 55' 8.01\" S", "EXIF:GPSLongitude": "138 deg 35' 48.70\" E", "Composite:GPSPosition": "34 deg 55' 8.01\" S, 138 deg 35' 48.70\" E", "EXIF:GPSLatitudeRef": "South", "EXIF:GPSLongitudeRef": "East", "EXIF:DateTimeOriginal": "2017:06:20 17:18:56", "EXIF:OffsetTimeOriginal": "+09:30", "EXIF:ModifyDate": "2020:05:18 14:42:04"}]""" EXIF_DATA = """[{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", "EXIF:ImageDescription": "\u2068Elder Park\u2069, \u2068Adelaide\u2069, \u2068Australia\u2069", "XMP:Description": "\u2068Elder Park\u2069, \u2068Adelaide\u2069, \u2068Australia\u2069", "XMP:Title": "Elder Park", "EXIF:GPSLatitude": "34 deg 55' 8.01\" S", "EXIF:GPSLongitude": "138 deg 35' 48.70\" E", "Composite:GPSPosition": "34 deg 55' 8.01\" S, 138 deg 35' 48.70\" E", "EXIF:GPSLatitudeRef": "South", "EXIF:GPSLongitudeRef": "East", "EXIF:DateTimeOriginal": "2017:06:20 17:18:56", "EXIF:OffsetTimeOriginal": "+09:30", "EXIF:ModifyDate": "2020:05:18 14:42:04"}]""" # noqa: E501
INFO_DATA = """{"uuid": "3DD2C897-F19E-4CA6-8C22-B027D5A71907", "filename": "3DD2C897-F19E-4CA6-8C22-B027D5A71907.jpeg", "original_filename": "IMG_4547.jpg", "date": "2017-06-20T17:18:56.518000+09:30", "description": "\u2068Elder Park\u2069, \u2068Adelaide\u2069, \u2068Australia\u2069", "title": "Elder Park", "keywords": [], "labels": ["Statue", "Art"], "albums": ["AlbumInFolder"], "folders": {"AlbumInFolder": ["Folder1", "SubFolder2"]}, "persons": [], "path": "/Users/rhet/Pictures/Test-10.15.4.photoslibrary/originals/3/3DD2C897-F19E-4CA6-8C22-B027D5A71907.jpeg", "ismissing": false, "hasadjustments": true, "external_edit": false, "favorite": false, "hidden": false, "latitude": -34.91889167000001, "longitude": 138.59686167, "path_edited": "/Users/rhet/Pictures/Test-10.15.4.photoslibrary/resources/renders/3/3DD2C897-F19E-4CA6-8C22-B027D5A71907_1_201_a.jpeg", "shared": false, "isphoto": true, "ismovie": false, "uti": "public.jpeg", "burst": false, "live_photo": false, "path_live_photo": null, "iscloudasset": false, "incloud": null, "date_modified": "2020-05-18T14:42:04.608664+09:30", "portrait": false, "screenshot": false, "slow_mo": false, "time_lapse": false, "hdr": false, "selfie": false, "panorama": false, "has_raw": false, "uti_raw": null, "path_raw": null, "place": {"name": "Elder Park, Adelaide, South Australia, Australia, River Torrens", "names": {"field0": [], "country": ["Australia"], "state_province": ["South Australia"], "sub_administrative_area": ["Adelaide"], "city": ["Adelaide", "Adelaide"], "field5": [], "additional_city_info": ["Adelaide CBD", "Tarndanya"], "ocean": [], "area_of_interest": ["Elder Park", ""], "inland_water": ["River Torrens", "River Torrens"], "field10": [], "region": [], "sub_throughfare": [], "field13": [], "postal_code": [], "field15": [], "field16": [], "street_address": [], "body_of_water": ["River Torrens", "River Torrens"]}, "country_code": "AU", "ishome": false, "address_str": "River Torrens, Adelaide SA, Australia", "address": {"street": null, "sub_locality": "Tarndanya", "city": "Adelaide", "sub_administrative_area": "Adelaide", "state_province": "SA", "postal_code": null, "country": "Australia", "iso_country_code": "AU"}}, "exif": {"flash_fired": false, "iso": 320, "metering_mode": 3, "sample_rate": null, "track_format": null, "white_balance": 0, "aperture": 2.2, "bit_rate": null, "duration": null, "exposure_bias": 0.0, "focal_length": 4.15, "fps": null, "latitude": null, "longitude": null, "shutter_speed": 0.058823529411764705, "camera_make": "Apple", "camera_model": "iPhone 6s", "codec": null, "lens_model": "iPhone 6s back camera 4.15mm f/2.2"}}""" INFO_DATA = """{"uuid": "3DD2C897-F19E-4CA6-8C22-B027D5A71907", "filename": "3DD2C897-F19E-4CA6-8C22-B027D5A71907.jpeg", "original_filename": "IMG_4547.jpg", "date": "2017-06-20T17:18:56.518000+09:30", "description": "\u2068Elder Park\u2069, \u2068Adelaide\u2069, \u2068Australia\u2069", "title": "Elder Park", "keywords": [], "labels": ["Statue", "Art"], "albums": ["AlbumInFolder"], "folders": {"AlbumInFolder": ["Folder1", "SubFolder2"]}, "persons": [], "path": "/Users/rhet/Pictures/Test-10.15.4.photoslibrary/originals/3/3DD2C897-F19E-4CA6-8C22-B027D5A71907.jpeg", "ismissing": false, "hasadjustments": true, "external_edit": false, "favorite": false, "hidden": false, "latitude": -34.91889167000001, "longitude": 138.59686167, "path_edited": "/Users/rhet/Pictures/Test-10.15.4.photoslibrary/resources/renders/3/3DD2C897-F19E-4CA6-8C22-B027D5A71907_1_201_a.jpeg", "shared": false, "isphoto": true, "ismovie": false, "uti": "public.jpeg", "burst": false, "live_photo": false, "path_live_photo": null, "iscloudasset": false, "incloud": null, "date_modified": "2020-05-18T14:42:04.608664+09:30", "portrait": false, "screenshot": false, "slow_mo": false, "time_lapse": false, "hdr": false, "selfie": false, "panorama": false, "has_raw": false, "uti_raw": null, "path_raw": null, "place": {"name": "Elder Park, Adelaide, South Australia, Australia, River Torrens", "names": {"field0": [], "country": ["Australia"], "state_province": ["South Australia"], "sub_administrative_area": ["Adelaide"], "city": ["Adelaide", "Adelaide"], "field5": [], "additional_city_info": ["Adelaide CBD", "Tarndanya"], "ocean": [], "area_of_interest": ["Elder Park", ""], "inland_water": ["River Torrens", "River Torrens"], "field10": [], "region": [], "sub_throughfare": [], "field13": [], "postal_code": [], "field15": [], "field16": [], "street_address": [], "body_of_water": ["River Torrens", "River Torrens"]}, "country_code": "AU", "ishome": false, "address_str": "River Torrens, Adelaide SA, Australia", "address": {"street": null, "sub_locality": "Tarndanya", "city": "Adelaide", "sub_administrative_area": "Adelaide", "state_province": "SA", "postal_code": null, "country": "Australia", "iso_country_code": "AU"}}, "exif": {"flash_fired": false, "iso": 320, "metering_mode": 3, "sample_rate": null, "track_format": null, "white_balance": 0, "aperture": 2.2, "bit_rate": null, "duration": null, "exposure_bias": 0.0, "focal_length": 4.15, "fps": null, "latitude": null, "longitude": null, "shutter_speed": 0.058823529411764705, "camera_make": "Apple", "camera_model": "iPhone 6s", "codec": null, "lens_model": "iPhone 6s back camera 4.15mm f/2.2"}}""" # noqa: E501
SIDECAR_DATA = """FOO_BAR""" SIDECAR_DATA = """FOO_BAR"""
METADATA_DATA = "FIZZ" METADATA_DATA = "FIZZ"
DIGEST_DATA = "FIZZ" DIGEST_DATA = "FIZZ"
EXIF_DATA2 = """[{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", "XMP:Title": "St. James's Park", "XMP:TagsList": ["London 2018", "St. James's Park", "England", "United Kingdom", "UK", "London"], "IPTC:Keywords": ["London 2018", "St. James's Park", "England", "United Kingdom", "UK", "London"], "XMP:Subject": ["London 2018", "St. James's Park", "England", "United Kingdom", "UK", "London"], "EXIF:GPSLatitude": "51 deg 30' 12.86\" N", "EXIF:GPSLongitude": "0 deg 7' 54.50\" W", "Composite:GPSPosition": "51 deg 30' 12.86\" N, 0 deg 7' 54.50\" W", "EXIF:GPSLatitudeRef": "North", "EXIF:GPSLongitudeRef": "West", "EXIF:DateTimeOriginal": "2018:10:13 09:18:12", "EXIF:OffsetTimeOriginal": "-04:00", "EXIF:ModifyDate": "2019:12:08 14:06:44"}]""" EXIF_DATA2 = """[{"_CreatedBy": "osxphotos, https://github.com/RhetTbull/osxphotos", "XMP:Title": "St. James's Park", "XMP:TagsList": ["London 2018", "St. James's Park", "England", "United Kingdom", "UK", "London"], "IPTC:Keywords": ["London 2018", "St. James's Park", "England", "United Kingdom", "UK", "London"], "XMP:Subject": ["London 2018", "St. James's Park", "England", "United Kingdom", "UK", "London"], "EXIF:GPSLatitude": "51 deg 30' 12.86\" N", "EXIF:GPSLongitude": "0 deg 7' 54.50\" W", "Composite:GPSPosition": "51 deg 30' 12.86\" N, 0 deg 7' 54.50\" W", "EXIF:GPSLatitudeRef": "North", "EXIF:GPSLongitudeRef": "West", "EXIF:DateTimeOriginal": "2018:10:13 09:18:12", "EXIF:OffsetTimeOriginal": "-04:00", "EXIF:ModifyDate": "2019:12:08 14:06:44"}]""" # noqa: E501
INFO_DATA2 = """{"uuid": "F2BB3F98-90F0-4E4C-A09B-25C6822A4529", "filename": "F2BB3F98-90F0-4E4C-A09B-25C6822A4529.jpeg", "original_filename": "IMG_8440.JPG", "date": "2019-06-11T11:42:06.711805-07:00", "description": null, "title": null, "keywords": [], "labels": ["Sky", "Cloudy", "Fence", "Land", "Outdoor", "Park", "Amusement Park", "Roller Coaster"], "albums": [], "folders": {}, "persons": [], "path": "/Volumes/MacBook Catalina - Data/Users/rhet/Pictures/Photos Library.photoslibrary/originals/F/F2BB3F98-90F0-4E4C-A09B-25C6822A4529.jpeg", "ismissing": false, "hasadjustments": false, "external_edit": false, "favorite": false, "hidden": false, "latitude": 33.81558666666667, "longitude": -117.99298, "path_edited": null, "shared": false, "isphoto": true, "ismovie": false, "uti": "public.jpeg", "burst": false, "live_photo": false, "path_live_photo": null, "iscloudasset": true, "incloud": true, "date_modified": "2019-10-14T00:51:47.141950-07:00", "portrait": false, "screenshot": false, "slow_mo": false, "time_lapse": false, "hdr": false, "selfie": false, "panorama": false, "has_raw": false, "uti_raw": null, "path_raw": null, "place": {"name": "Adventure City, Stanton, California, United States", "names": {"field0": [], "country": ["United States"], "state_province": ["California"], "sub_administrative_area": ["Orange"], "city": ["Stanton", "Anaheim", "Anaheim"], "field5": [], "additional_city_info": ["West Anaheim"], "ocean": [], "area_of_interest": ["Adventure City", "Adventure City"], "inland_water": [], "field10": [], "region": [], "sub_throughfare": [], "field13": [], "postal_code": [], "field15": [], "field16": [], "street_address": [], "body_of_water": []}, "country_code": "US", "ishome": false, "address_str": "Adventure City, 1240 S Beach Blvd, Anaheim, CA 92804, United States", "address": {"street": "1240 S Beach Blvd", "sub_locality": "West Anaheim", "city": "Stanton", "sub_administrative_area": "Orange", "state_province": "CA", "postal_code": "92804", "country": "United States", "iso_country_code": "US"}}, "exif": {"flash_fired": false, "iso": 25, "metering_mode": 5, "sample_rate": null, "track_format": null, "white_balance": 0, "aperture": 2.2, "bit_rate": null, "duration": null, "exposure_bias": 0.0, "focal_length": 4.15, "fps": null, "latitude": null, "longitude": null, "shutter_speed": 0.0004940711462450593, "camera_make": "Apple", "camera_model": "iPhone 6s", "codec": null, "lens_model": "iPhone 6s back camera 4.15mm f/2.2"}}""" INFO_DATA2 = """{"uuid": "F2BB3F98-90F0-4E4C-A09B-25C6822A4529", "filename": "F2BB3F98-90F0-4E4C-A09B-25C6822A4529.jpeg", "original_filename": "IMG_8440.JPG", "date": "2019-06-11T11:42:06.711805-07:00", "description": null, "title": null, "keywords": [], "labels": ["Sky", "Cloudy", "Fence", "Land", "Outdoor", "Park", "Amusement Park", "Roller Coaster"], "albums": [], "folders": {}, "persons": [], "path": "/Volumes/MacBook Catalina - Data/Users/rhet/Pictures/Photos Library.photoslibrary/originals/F/F2BB3F98-90F0-4E4C-A09B-25C6822A4529.jpeg", "ismissing": false, "hasadjustments": false, "external_edit": false, "favorite": false, "hidden": false, "latitude": 33.81558666666667, "longitude": -117.99298, "path_edited": null, "shared": false, "isphoto": true, "ismovie": false, "uti": "public.jpeg", "burst": false, "live_photo": false, "path_live_photo": null, "iscloudasset": true, "incloud": true, "date_modified": "2019-10-14T00:51:47.141950-07:00", "portrait": false, "screenshot": false, "slow_mo": false, "time_lapse": false, "hdr": false, "selfie": false, "panorama": false, "has_raw": false, "uti_raw": null, "path_raw": null, "place": {"name": "Adventure City, Stanton, California, United States", "names": {"field0": [], "country": ["United States"], "state_province": ["California"], "sub_administrative_area": ["Orange"], "city": ["Stanton", "Anaheim", "Anaheim"], "field5": [], "additional_city_info": ["West Anaheim"], "ocean": [], "area_of_interest": ["Adventure City", "Adventure City"], "inland_water": [], "field10": [], "region": [], "sub_throughfare": [], "field13": [], "postal_code": [], "field15": [], "field16": [], "street_address": [], "body_of_water": []}, "country_code": "US", "ishome": false, "address_str": "Adventure City, 1240 S Beach Blvd, Anaheim, CA 92804, United States", "address": {"street": "1240 S Beach Blvd", "sub_locality": "West Anaheim", "city": "Stanton", "sub_administrative_area": "Orange", "state_province": "CA", "postal_code": "92804", "country": "United States", "iso_country_code": "US"}}, "exif": {"flash_fired": false, "iso": 25, "metering_mode": 5, "sample_rate": null, "track_format": null, "white_balance": 0, "aperture": 2.2, "bit_rate": null, "duration": null, "exposure_bias": 0.0, "focal_length": 4.15, "fps": null, "latitude": null, "longitude": null, "shutter_speed": 0.0004940711462450593, "camera_make": "Apple", "camera_model": "iPhone 6s", "codec": null, "lens_model": "iPhone 6s back camera 4.15mm f/2.2"}}""" # noqa: E501
DIGEST_DATA2 = "BUZZ" DIGEST_DATA2 = "BUZZ"
EXPORT_DATABASE_V1 = "tests/export_db_version1.db" EXPORT_DATABASE_V1 = "tests/export_db_version1.db"

View File

@ -108,7 +108,7 @@ def test_attributes(photosdb):
assert p.path.endswith( assert p.path.endswith(
"/tests/Test-10.13.6.photoslibrary/Masters/2019/07/26/20190726-203227/Pumkins2.jpg" "/tests/Test-10.13.6.photoslibrary/Masters/2019/07/26/20190726-203227/Pumkins2.jpg"
) )
assert p.ismissing == False assert not p.ismissing
def test_missing(photosdb): def test_missing(photosdb):

View File

@ -270,7 +270,7 @@ def test_attributes(photosdb):
assert p.path.endswith( assert p.path.endswith(
"/tests/Test-10.14.6.photoslibrary/Masters/2019/07/27/20190727-131650/Pumkins2.jpg" "/tests/Test-10.14.6.photoslibrary/Masters/2019/07/27/20190727-131650/Pumkins2.jpg"
) )
assert p.ismissing == False assert not p.ismissing
def test_attributes_2(photosdb): def test_attributes_2(photosdb):
@ -321,28 +321,28 @@ def test_favorite(photosdb):
photos = photosdb.photos(uuid=[UUID_DICT["favorite"]]) photos = photosdb.photos(uuid=[UUID_DICT["favorite"]])
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.favorite == True assert p.favorite
def test_not_favorite(photosdb): def test_not_favorite(photosdb):
photos = photosdb.photos(uuid=["od0fmC7NQx+ayVr+%i06XA"]) photos = photosdb.photos(uuid=["od0fmC7NQx+ayVr+%i06XA"])
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.favorite == False assert not p.favorite
def test_hidden(photosdb): def test_hidden(photosdb):
photos = photosdb.photos(uuid=[UUID_DICT["hidden"]]) photos = photosdb.photos(uuid=[UUID_DICT["hidden"]])
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.hidden == True assert p.hidden
def test_not_hidden(photosdb): def test_not_hidden(photosdb):
photos = photosdb.photos(uuid=[UUID_DICT["not_hidden"]]) photos = photosdb.photos(uuid=[UUID_DICT["not_hidden"]])
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.hidden == False assert not p.hidden
def test_visible(photosdb): def test_visible(photosdb):
@ -382,11 +382,11 @@ def test_location_2(photosdb):
def test_hasadjustments1(photosdb): def test_hasadjustments1(photosdb):
# test hasadjustments == True # test hasadjustments
photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]]) photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]])
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.hasadjustments == True assert p.hasadjustments
def test_hasadjustments2(photosdb): def test_hasadjustments2(photosdb):
@ -394,7 +394,7 @@ def test_hasadjustments2(photosdb):
photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]]) photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]])
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.hasadjustments == False assert not p.hasadjustments
def test_external_edit1(photosdb): def test_external_edit1(photosdb):
@ -403,7 +403,7 @@ def test_external_edit1(photosdb):
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.external_edit == True assert p.external_edit
def test_external_edit2(photosdb): def test_external_edit2(photosdb):
@ -412,7 +412,7 @@ def test_external_edit2(photosdb):
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.external_edit == False assert not p.external_edit
def test_path_edited1(photosdb): def test_path_edited1(photosdb):
@ -646,7 +646,7 @@ def test_raw(photosdb):
assert photo.path_raw is None assert photo.path_raw is None
def test_raw(): def test_raw_properties():
"""Test various raw properties""" """Test various raw properties"""
import osxphotos import osxphotos

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -68,22 +68,22 @@ def test_attributes():
assert p.path.endswith( assert p.path.endswith(
"tests/Test-Movie-4_0.photoslibrary/Masters/2019/12/28/20191228-202119/IMG_0670B_NOGPS.MOV" "tests/Test-Movie-4_0.photoslibrary/Masters/2019/12/28/20191228-202119/IMG_0670B_NOGPS.MOV"
) )
assert p.ismissing == False assert not p.ismissing
assert p.hasadjustments == True assert p.hasadjustments
assert p.path_edited.endswith( assert p.path_edited.endswith(
"tests/Test-Movie-4_0.photoslibrary/resources/media/version/00/00/fullsizeoutput_7.mov" "tests/Test-Movie-4_0.photoslibrary/resources/media/version/00/00/fullsizeoutput_7.mov"
) )
def test_hasadjustments1(): def test_hasadjustments1():
# test hasadjustments == True # test hasadjustments
import osxphotos import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
photos = photosdb.photos(uuid=[UUID_DICT["movie"]], movies=True) photos = photosdb.photos(uuid=[UUID_DICT["movie"]], movies=True)
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.hasadjustments == True assert p.hasadjustments
def test_path_edited1(): def test_path_edited1():

View File

@ -71,22 +71,22 @@ def test_attributes():
assert p.path.endswith( assert p.path.endswith(
"tests/Test-Movie-5_0.photoslibrary/originals/4/423C0683-672D-4DDD-979C-23A6A53D7256.mov" "tests/Test-Movie-5_0.photoslibrary/originals/4/423C0683-672D-4DDD-979C-23A6A53D7256.mov"
) )
assert p.ismissing == False assert not p.ismissing
assert p.hasadjustments == True assert p.hasadjustments
assert p.path_edited.endswith( assert p.path_edited.endswith(
"tests/Test-Movie-5_0.photoslibrary/resources/renders/4/423C0683-672D-4DDD-979C-23A6A53D7256_2_0_a.mov" "tests/Test-Movie-5_0.photoslibrary/resources/renders/4/423C0683-672D-4DDD-979C-23A6A53D7256_2_0_a.mov"
) )
def test_hasadjustments1(): def test_hasadjustments1():
# test hasadjustments == True # test hasadjustments
import osxphotos import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB) photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
photos = photosdb.photos(uuid=[UUID_DICT["movie"]], movies=True) photos = photosdb.photos(uuid=[UUID_DICT["movie"]], movies=True)
assert len(photos) == 1 assert len(photos) == 1
p = photos[0] p = photos[0]
assert p.hasadjustments == True assert p.hasadjustments
def test_path_edited1(): def test_path_edited1():

View File

@ -12,8 +12,8 @@ from osxphotos.placeinfo import (
PLRevGeoMapItemAdditionalPlaceInfo, PLRevGeoMapItemAdditionalPlaceInfo,
) )
REVERSE_GEO_LOC_DATA_1 = b'bplist00\xd4\x01\x02\x03\x04\x05\x06\x07\nX$versionY$archiverT$topX$objects\x12\x00\x01\x86\xa0_\x10\x0fNSKeyedArchiver\xd1\x08\tTroot\x80\x01\xaf\x10,\x0b\x0c!)4>?@GLMNSTUZ[`aefglmnru{\x7f\x80\x85\x86\x8a\x8b\x8f\xa1\xa2\xa3\xa4\xa5\xa6\xa9\xaa\xabU$null\xda\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1a\x1f VisHomeV$class]postalAddress_\x10\x16compoundSecondaryNames[countryCode]addressStringWversion]compoundNames_\x10\x12geoServiceProviderWmapItem\x08\x80+\x80"\x80\x00\x80 \x80)\x10\r\x80\x00\x80*\x80\x02\xd4\x0e"#$%&\'(_\x10\x0ffinalPlaceInfos_\x10\x10sortedPlaceInfos_\x10\x10backupPlaceInfos\x80!\x80\x1a\x80\x03\x80\x19\xd2*\x0e+3ZNS.objects\xa7,-./012\x80\x04\x80\x08\x80\x0b\x80\x0e\x80\x10\x80\x12\x80\x15\x80\x18\xd55\x0e6789:;<=_\x10\x11dominantOrderTypeTareaTnameYplaceType\x10\x00\x80\x07#\x00\x00\x00\x00\x00\x00\x00\x00\x80\x05\x80\x06_\x10\x0f2038 18th St NW\x10\x11\xd2ABCDZ$classnameX$classes_\x10"PLRevGeoMapItemAdditionalPlaceInfo\xa2EF_\x10"PLRevGeoMapItemAdditionalPlaceInfoXNSObject\xd55\x0e6789:IJK\x80\x07#A/M\x81\xe0\x00\x00\x00\x80\t\x80\n\\Adams Morgan\x10\x06\xd55\x0e6789:PQR\x80\x07#AIo;@\x00\x00\x00\x80\x0c\x80\rZWashington\x10\x04\xd55\x0e6789:WXR\x80\x07#A\xa4\x91\xc0@\x00\x00\x00\x80\x0f\x80\rZWashington\xd55\x0e6789:]^R\x80\x07#A\xa5 \xd9`\x00\x00\x00\x80\x11\x80\rZWashington\xd55\x0e6789:]cd\x80\x07\x80\x13\x80\x14_\x10\x14District of Columbia\x10\x02\xd55\x0e6789:ijk\x80\x07#B\xa2\xc3\xf5`\x00\x00\x00\x80\x16\x80\x17]United States\x10\x01\xd2ABop^NSMutableArray\xa3oqFWNSArray\xd2*\x0es3\xa0\x80\x18\xd2*\x0ev3\xa3wxy\x80\x1b\x80\x1d\x80\x1f\x80\x18\xd55\x0e678f:;}=\x80\x07\x80\x1c\x80\x06Z18th St NW\xd55\x0e678\x81:;\x83=\x10\x0b\x80\x07\x80\x1e\x80\x06RDC\xd55\x0e678\x1d:;\x1b=\x80\x07\x80 \x80\x06RUS\xd2AB\x8c\x8d_\x10\x0fPLRevGeoMapItem\xa2\x8eF_\x10\x0fPLRevGeoMapItem\xd9\x90\x0e\x91\x92\x93\x94\x95\x96\x97\x83\x99\x9a\x9b\x9c\x9d\x1a\x9f\x1bV_stateU_cityW_street[_postalCodeX_country_\x10\x16_subAdministrativeArea\\_subLocality_\x10\x0f_ISOCountryCode\x80\x1e\x80(\x80%\x80#\x80&\x80\'\x80\x00\x80$\x80 _\x10\x0f2038 18th St NW\\Adams MorganZWashingtonU20009]United States\xd2AB\xa7\xa8_\x10\x0fCNPostalAddress\xa2\xa7F_\x1052038 18th St NW, Washington, DC 20009, United StatesT7618\xd2AB\xac\xad_\x10\x14PLRevGeoLocationInfo\xa2\xaeF_\x10\x14PLRevGeoLocationInfo\x00\x08\x00\x11\x00\x1a\x00$\x00)\x002\x007\x00I\x00L\x00Q\x00S\x00\x82\x00\x88\x00\x9d\x00\xa4\x00\xab\x00\xb9\x00\xd2\x00\xde\x00\xec\x00\xf4\x01\x02\x01\x17\x01\x1f\x01 \x01"\x01$\x01&\x01(\x01*\x01,\x01.\x010\x012\x01;\x01M\x01`\x01s\x01u\x01w\x01y\x01{\x01\x80\x01\x8b\x01\x93\x01\x95\x01\x97\x01\x99\x01\x9b\x01\x9d\x01\x9f\x01\xa1\x01\xa3\x01\xae\x01\xc2\x01\xc7\x01\xcc\x01\xd6\x01\xd8\x01\xda\x01\xe3\x01\xe5\x01\xe7\x01\xf9\x01\xfb\x02\x00\x02\x0b\x02\x14\x029\x02<\x02a\x02j\x02u\x02w\x02\x80\x02\x82\x02\x84\x02\x91\x02\x93\x02\x9e\x02\xa0\x02\xa9\x02\xab\x02\xad\x02\xb8\x02\xba\x02\xc5\x02\xc7\x02\xd0\x02\xd2\x02\xd4\x02\xdf\x02\xea\x02\xec\x02\xf5\x02\xf7\x02\xf9\x03\x04\x03\x0f\x03\x11\x03\x13\x03\x15\x03,\x03.\x039\x03;\x03D\x03F\x03H\x03V\x03X\x03]\x03l\x03p\x03x\x03}\x03~\x03\x80\x03\x85\x03\x89\x03\x8b\x03\x8d\x03\x8f\x03\x91\x03\x9c\x03\x9e\x03\xa0\x03\xa2\x03\xad\x03\xb8\x03\xba\x03\xbc\x03\xbe\x03\xc0\x03\xc3\x03\xce\x03\xd0\x03\xd2\x03\xd4\x03\xd7\x03\xdc\x03\xee\x03\xf1\x04\x03\x04\x16\x04\x1d\x04#\x04+\x047\x04@\x04Y\x04f\x04x\x04z\x04|\x04~\x04\x80\x04\x82\x04\x84\x04\x86\x04\x88\x04\x8a\x04\x9c\x04\xa9\x04\xb4\x04\xba\x04\xc8\x04\xcd\x04\xdf\x04\xe2\x05\x1a\x05\x1f\x05$\x05;\x05>\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05U' REVERSE_GEO_LOC_DATA_1 = b'bplist00\xd4\x01\x02\x03\x04\x05\x06\x07\nX$versionY$archiverT$topX$objects\x12\x00\x01\x86\xa0_\x10\x0fNSKeyedArchiver\xd1\x08\tTroot\x80\x01\xaf\x10,\x0b\x0c!)4>?@GLMNSTUZ[`aefglmnru{\x7f\x80\x85\x86\x8a\x8b\x8f\xa1\xa2\xa3\xa4\xa5\xa6\xa9\xaa\xabU$null\xda\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1a\x1f VisHomeV$class]postalAddress_\x10\x16compoundSecondaryNames[countryCode]addressStringWversion]compoundNames_\x10\x12geoServiceProviderWmapItem\x08\x80+\x80"\x80\x00\x80 \x80)\x10\r\x80\x00\x80*\x80\x02\xd4\x0e"#$%&\'(_\x10\x0ffinalPlaceInfos_\x10\x10sortedPlaceInfos_\x10\x10backupPlaceInfos\x80!\x80\x1a\x80\x03\x80\x19\xd2*\x0e+3ZNS.objects\xa7,-./012\x80\x04\x80\x08\x80\x0b\x80\x0e\x80\x10\x80\x12\x80\x15\x80\x18\xd55\x0e6789:;<=_\x10\x11dominantOrderTypeTareaTnameYplaceType\x10\x00\x80\x07#\x00\x00\x00\x00\x00\x00\x00\x00\x80\x05\x80\x06_\x10\x0f2038 18th St NW\x10\x11\xd2ABCDZ$classnameX$classes_\x10"PLRevGeoMapItemAdditionalPlaceInfo\xa2EF_\x10"PLRevGeoMapItemAdditionalPlaceInfoXNSObject\xd55\x0e6789:IJK\x80\x07#A/M\x81\xe0\x00\x00\x00\x80\t\x80\n\\Adams Morgan\x10\x06\xd55\x0e6789:PQR\x80\x07#AIo;@\x00\x00\x00\x80\x0c\x80\rZWashington\x10\x04\xd55\x0e6789:WXR\x80\x07#A\xa4\x91\xc0@\x00\x00\x00\x80\x0f\x80\rZWashington\xd55\x0e6789:]^R\x80\x07#A\xa5 \xd9`\x00\x00\x00\x80\x11\x80\rZWashington\xd55\x0e6789:]cd\x80\x07\x80\x13\x80\x14_\x10\x14District of Columbia\x10\x02\xd55\x0e6789:ijk\x80\x07#B\xa2\xc3\xf5`\x00\x00\x00\x80\x16\x80\x17]United States\x10\x01\xd2ABop^NSMutableArray\xa3oqFWNSArray\xd2*\x0es3\xa0\x80\x18\xd2*\x0ev3\xa3wxy\x80\x1b\x80\x1d\x80\x1f\x80\x18\xd55\x0e678f:;}=\x80\x07\x80\x1c\x80\x06Z18th St NW\xd55\x0e678\x81:;\x83=\x10\x0b\x80\x07\x80\x1e\x80\x06RDC\xd55\x0e678\x1d:;\x1b=\x80\x07\x80 \x80\x06RUS\xd2AB\x8c\x8d_\x10\x0fPLRevGeoMapItem\xa2\x8eF_\x10\x0fPLRevGeoMapItem\xd9\x90\x0e\x91\x92\x93\x94\x95\x96\x97\x83\x99\x9a\x9b\x9c\x9d\x1a\x9f\x1bV_stateU_cityW_street[_postalCodeX_country_\x10\x16_subAdministrativeArea\\_subLocality_\x10\x0f_ISOCountryCode\x80\x1e\x80(\x80%\x80#\x80&\x80\'\x80\x00\x80$\x80 _\x10\x0f2038 18th St NW\\Adams MorganZWashingtonU20009]United States\xd2AB\xa7\xa8_\x10\x0fCNPostalAddress\xa2\xa7F_\x1052038 18th St NW, Washington, DC 20009, United StatesT7618\xd2AB\xac\xad_\x10\x14PLRevGeoLocationInfo\xa2\xaeF_\x10\x14PLRevGeoLocationInfo\x00\x08\x00\x11\x00\x1a\x00$\x00)\x002\x007\x00I\x00L\x00Q\x00S\x00\x82\x00\x88\x00\x9d\x00\xa4\x00\xab\x00\xb9\x00\xd2\x00\xde\x00\xec\x00\xf4\x01\x02\x01\x17\x01\x1f\x01 \x01"\x01$\x01&\x01(\x01*\x01,\x01.\x010\x012\x01;\x01M\x01`\x01s\x01u\x01w\x01y\x01{\x01\x80\x01\x8b\x01\x93\x01\x95\x01\x97\x01\x99\x01\x9b\x01\x9d\x01\x9f\x01\xa1\x01\xa3\x01\xae\x01\xc2\x01\xc7\x01\xcc\x01\xd6\x01\xd8\x01\xda\x01\xe3\x01\xe5\x01\xe7\x01\xf9\x01\xfb\x02\x00\x02\x0b\x02\x14\x029\x02<\x02a\x02j\x02u\x02w\x02\x80\x02\x82\x02\x84\x02\x91\x02\x93\x02\x9e\x02\xa0\x02\xa9\x02\xab\x02\xad\x02\xb8\x02\xba\x02\xc5\x02\xc7\x02\xd0\x02\xd2\x02\xd4\x02\xdf\x02\xea\x02\xec\x02\xf5\x02\xf7\x02\xf9\x03\x04\x03\x0f\x03\x11\x03\x13\x03\x15\x03,\x03.\x039\x03;\x03D\x03F\x03H\x03V\x03X\x03]\x03l\x03p\x03x\x03}\x03~\x03\x80\x03\x85\x03\x89\x03\x8b\x03\x8d\x03\x8f\x03\x91\x03\x9c\x03\x9e\x03\xa0\x03\xa2\x03\xad\x03\xb8\x03\xba\x03\xbc\x03\xbe\x03\xc0\x03\xc3\x03\xce\x03\xd0\x03\xd2\x03\xd4\x03\xd7\x03\xdc\x03\xee\x03\xf1\x04\x03\x04\x16\x04\x1d\x04#\x04+\x047\x04@\x04Y\x04f\x04x\x04z\x04|\x04~\x04\x80\x04\x82\x04\x84\x04\x86\x04\x88\x04\x8a\x04\x9c\x04\xa9\x04\xb4\x04\xba\x04\xc8\x04\xcd\x04\xdf\x04\xe2\x05\x1a\x05\x1f\x05$\x05;\x05>\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\xaf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05U' # noqa: E501
REVERSE_GEO_LOC_DATA_2 = b'bplist00\xd4\x01\x02\x03\x04\x05\x06\x07\nX$versionY$archiverT$topX$objects\x12\x00\x01\x86\xa0_\x10\x0fNSKeyedArchiver\xd1\x08\tTroot\x80\x01\xaf\x10+\x0b\x0c!)5?@AHMNOTUZ_`afglmnstuy|\x82\x86\x87\x8b\x8c\x90\x91\x95\xa7\xa8\xa9\xaa\xad\xae\xafU$null\xda\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1a\x1f VisHomeV$class]postalAddress_\x10\x16compoundSecondaryNames[countryCode]addressStringWversion]compoundNames_\x10\x12geoServiceProviderWmapItem\x08\x80*\x80#\x80\x00\x80!\x80(\x10\r\x80\x00\x80)\x80\x02\xd4\x0e"#$%&\'(_\x10\x0ffinalPlaceInfos_\x10\x10sortedPlaceInfos_\x10\x10backupPlaceInfos\x80"\x80\x1b\x80\x03\x80\x1a\xd2*\x0e+4ZNS.objects\xa8,-./0123\x80\x04\x80\x08\x80\x0b\x80\r\x80\x0e\x80\x11\x80\x13\x80\x16\x80\x19\xd56\x0e789:;<=>_\x10\x11dominantOrderTypeTareaTnameYplaceType\x10\x00\x80\x07#\x00\x00\x00\x00\x00\x00\x00\x00\x80\x05\x80\x06_\x10\x153700 Wailea Alanui Dr\x10\x11\xd2BCDEZ$classnameX$classes_\x10"PLRevGeoMapItemAdditionalPlaceInfo\xa2FG_\x10"PLRevGeoMapItemAdditionalPlaceInfoXNSObject\xd56\x0e789:;JKL\x80\x07#Az\xab?`\x00\x00\x00\x80\t\x80\nVWailea\x10\x04\xd56\x0e789:;QRL\x80\x07#A\x97K\xd2\xc0\x00\x00\x00\x80\x0c\x80\nUKihei\xd56\x0e789:;WRL\x80\x07#A\x97\xd0\x14\xc0\x00\x00\x00\x80\x0c\x80\n\xd56\x0e789:;\\]^\x80\x07#A\xdc+\x84\x00\x00\x00\x00\x80\x0f\x80\x10TMaui\x10\x0b\xd56\x0e789:;c]e\x80\x07#A\xf7A\xae@\x00\x00\x00\x80\x0f\x80\x12\x10\x03\xd56\x0e789:;ijk\x80\x07#B\x1a\x97\xca\xe0\x00\x00\x00\x80\x14\x80\x15WHawai\'i\x10\x02\xd56\x0e789:;pqr\x80\x07#B\xa2\xc3\xf5`\x00\x00\x00\x80\x17\x80\x18]United States\x10\x01\xd2BCvw^NSMutableArray\xa3vxGWNSArray\xd2*\x0ez4\xa0\x80\x19\xd2*\x0e}4\xa3~\x7f\x80\x80\x1c\x80\x1e\x80 \x80\x19\xd56\x0e789m;<\x84>\x80\x07\x80\x1d\x80\x06_\x10\x10Wailea Alanui Dr\xd56\x0e789`;<\x89>\x80\x07\x80\x1f\x80\x06RHI\xd56\x0e789\x1d;<\x1b>\x80\x07\x80!\x80\x06RUS\xd2BC\x92\x93_\x10\x0fPLRevGeoMapItem\xa2\x94G_\x10\x0fPLRevGeoMapItem\xd9\x96\x0e\x97\x98\x99\x9a\x9b\x9c\x9d\x89\x9fR\xa1\xa2\xa3]\x1a\x1bV_stateU_cityW_street[_postalCodeX_country_\x10\x16_subAdministrativeArea\\_subLocality_\x10\x0f_ISOCountryCode\x80\x1f\x80\'\x80\x0c\x80$\x80%\x80&\x80\x0f\x80\x00\x80!_\x10\x153700 Wailea Alanui DrU96753]United States\xd2BC\xab\xac_\x10\x0fCNPostalAddress\xa2\xabG_\x1063700 Wailea Alanui Dr, Kihei, HI 96753, United StatesT7618\xd2BC\xb0\xb1_\x10\x14PLRevGeoLocationInfo\xa2\xb2G_\x10\x14PLRevGeoLocationInfo\x00\x08\x00\x11\x00\x1a\x00$\x00)\x002\x007\x00I\x00L\x00Q\x00S\x00\x81\x00\x87\x00\x9c\x00\xa3\x00\xaa\x00\xb8\x00\xd1\x00\xdd\x00\xeb\x00\xf3\x01\x01\x01\x16\x01\x1e\x01\x1f\x01!\x01#\x01%\x01\'\x01)\x01+\x01-\x01/\x011\x01:\x01L\x01_\x01r\x01t\x01v\x01x\x01z\x01\x7f\x01\x8a\x01\x93\x01\x95\x01\x97\x01\x99\x01\x9b\x01\x9d\x01\x9f\x01\xa1\x01\xa3\x01\xa5\x01\xb0\x01\xc4\x01\xc9\x01\xce\x01\xd8\x01\xda\x01\xdc\x01\xe5\x01\xe7\x01\xe9\x02\x01\x02\x03\x02\x08\x02\x13\x02\x1c\x02A\x02D\x02i\x02r\x02}\x02\x7f\x02\x88\x02\x8a\x02\x8c\x02\x93\x02\x95\x02\xa0\x02\xa2\x02\xab\x02\xad\x02\xaf\x02\xb5\x02\xc0\x02\xc2\x02\xcb\x02\xcd\x02\xcf\x02\xda\x02\xdc\x02\xe5\x02\xe7\x02\xe9\x02\xee\x02\xf0\x02\xfb\x02\xfd\x03\x06\x03\x08\x03\n\x03\x0c\x03\x17\x03\x19\x03"\x03$\x03&\x03.\x030\x03;\x03=\x03F\x03H\x03J\x03X\x03Z\x03_\x03n\x03r\x03z\x03\x7f\x03\x80\x03\x82\x03\x87\x03\x8b\x03\x8d\x03\x8f\x03\x91\x03\x93\x03\x9e\x03\xa0\x03\xa2\x03\xa4\x03\xb7\x03\xc2\x03\xc4\x03\xc6\x03\xc8\x03\xcb\x03\xd6\x03\xd8\x03\xda\x03\xdc\x03\xdf\x03\xe4\x03\xf6\x03\xf9\x04\x0b\x04\x1e\x04%\x04+\x043\x04?\x04H\x04a\x04n\x04\x80\x04\x82\x04\x84\x04\x86\x04\x88\x04\x8a\x04\x8c\x04\x8e\x04\x90\x04\x92\x04\xaa\x04\xb0\x04\xbe\x04\xc3\x04\xd5\x04\xd8\x05\x11\x05\x16\x05\x1b\x052\x055\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05L' REVERSE_GEO_LOC_DATA_2 = b'bplist00\xd4\x01\x02\x03\x04\x05\x06\x07\nX$versionY$archiverT$topX$objects\x12\x00\x01\x86\xa0_\x10\x0fNSKeyedArchiver\xd1\x08\tTroot\x80\x01\xaf\x10+\x0b\x0c!)5?@AHMNOTUZ_`afglmnstuy|\x82\x86\x87\x8b\x8c\x90\x91\x95\xa7\xa8\xa9\xaa\xad\xae\xafU$null\xda\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1a\x1f VisHomeV$class]postalAddress_\x10\x16compoundSecondaryNames[countryCode]addressStringWversion]compoundNames_\x10\x12geoServiceProviderWmapItem\x08\x80*\x80#\x80\x00\x80!\x80(\x10\r\x80\x00\x80)\x80\x02\xd4\x0e"#$%&\'(_\x10\x0ffinalPlaceInfos_\x10\x10sortedPlaceInfos_\x10\x10backupPlaceInfos\x80"\x80\x1b\x80\x03\x80\x1a\xd2*\x0e+4ZNS.objects\xa8,-./0123\x80\x04\x80\x08\x80\x0b\x80\r\x80\x0e\x80\x11\x80\x13\x80\x16\x80\x19\xd56\x0e789:;<=>_\x10\x11dominantOrderTypeTareaTnameYplaceType\x10\x00\x80\x07#\x00\x00\x00\x00\x00\x00\x00\x00\x80\x05\x80\x06_\x10\x153700 Wailea Alanui Dr\x10\x11\xd2BCDEZ$classnameX$classes_\x10"PLRevGeoMapItemAdditionalPlaceInfo\xa2FG_\x10"PLRevGeoMapItemAdditionalPlaceInfoXNSObject\xd56\x0e789:;JKL\x80\x07#Az\xab?`\x00\x00\x00\x80\t\x80\nVWailea\x10\x04\xd56\x0e789:;QRL\x80\x07#A\x97K\xd2\xc0\x00\x00\x00\x80\x0c\x80\nUKihei\xd56\x0e789:;WRL\x80\x07#A\x97\xd0\x14\xc0\x00\x00\x00\x80\x0c\x80\n\xd56\x0e789:;\\]^\x80\x07#A\xdc+\x84\x00\x00\x00\x00\x80\x0f\x80\x10TMaui\x10\x0b\xd56\x0e789:;c]e\x80\x07#A\xf7A\xae@\x00\x00\x00\x80\x0f\x80\x12\x10\x03\xd56\x0e789:;ijk\x80\x07#B\x1a\x97\xca\xe0\x00\x00\x00\x80\x14\x80\x15WHawai\'i\x10\x02\xd56\x0e789:;pqr\x80\x07#B\xa2\xc3\xf5`\x00\x00\x00\x80\x17\x80\x18]United States\x10\x01\xd2BCvw^NSMutableArray\xa3vxGWNSArray\xd2*\x0ez4\xa0\x80\x19\xd2*\x0e}4\xa3~\x7f\x80\x80\x1c\x80\x1e\x80 \x80\x19\xd56\x0e789m;<\x84>\x80\x07\x80\x1d\x80\x06_\x10\x10Wailea Alanui Dr\xd56\x0e789`;<\x89>\x80\x07\x80\x1f\x80\x06RHI\xd56\x0e789\x1d;<\x1b>\x80\x07\x80!\x80\x06RUS\xd2BC\x92\x93_\x10\x0fPLRevGeoMapItem\xa2\x94G_\x10\x0fPLRevGeoMapItem\xd9\x96\x0e\x97\x98\x99\x9a\x9b\x9c\x9d\x89\x9fR\xa1\xa2\xa3]\x1a\x1bV_stateU_cityW_street[_postalCodeX_country_\x10\x16_subAdministrativeArea\\_subLocality_\x10\x0f_ISOCountryCode\x80\x1f\x80\'\x80\x0c\x80$\x80%\x80&\x80\x0f\x80\x00\x80!_\x10\x153700 Wailea Alanui DrU96753]United States\xd2BC\xab\xac_\x10\x0fCNPostalAddress\xa2\xabG_\x1063700 Wailea Alanui Dr, Kihei, HI 96753, United StatesT7618\xd2BC\xb0\xb1_\x10\x14PLRevGeoLocationInfo\xa2\xb2G_\x10\x14PLRevGeoLocationInfo\x00\x08\x00\x11\x00\x1a\x00$\x00)\x002\x007\x00I\x00L\x00Q\x00S\x00\x81\x00\x87\x00\x9c\x00\xa3\x00\xaa\x00\xb8\x00\xd1\x00\xdd\x00\xeb\x00\xf3\x01\x01\x01\x16\x01\x1e\x01\x1f\x01!\x01#\x01%\x01\'\x01)\x01+\x01-\x01/\x011\x01:\x01L\x01_\x01r\x01t\x01v\x01x\x01z\x01\x7f\x01\x8a\x01\x93\x01\x95\x01\x97\x01\x99\x01\x9b\x01\x9d\x01\x9f\x01\xa1\x01\xa3\x01\xa5\x01\xb0\x01\xc4\x01\xc9\x01\xce\x01\xd8\x01\xda\x01\xdc\x01\xe5\x01\xe7\x01\xe9\x02\x01\x02\x03\x02\x08\x02\x13\x02\x1c\x02A\x02D\x02i\x02r\x02}\x02\x7f\x02\x88\x02\x8a\x02\x8c\x02\x93\x02\x95\x02\xa0\x02\xa2\x02\xab\x02\xad\x02\xaf\x02\xb5\x02\xc0\x02\xc2\x02\xcb\x02\xcd\x02\xcf\x02\xda\x02\xdc\x02\xe5\x02\xe7\x02\xe9\x02\xee\x02\xf0\x02\xfb\x02\xfd\x03\x06\x03\x08\x03\n\x03\x0c\x03\x17\x03\x19\x03"\x03$\x03&\x03.\x030\x03;\x03=\x03F\x03H\x03J\x03X\x03Z\x03_\x03n\x03r\x03z\x03\x7f\x03\x80\x03\x82\x03\x87\x03\x8b\x03\x8d\x03\x8f\x03\x91\x03\x93\x03\x9e\x03\xa0\x03\xa2\x03\xa4\x03\xb7\x03\xc2\x03\xc4\x03\xc6\x03\xc8\x03\xcb\x03\xd6\x03\xd8\x03\xda\x03\xdc\x03\xdf\x03\xe4\x03\xf6\x03\xf9\x04\x0b\x04\x1e\x04%\x04+\x043\x04?\x04H\x04a\x04n\x04\x80\x04\x82\x04\x84\x04\x86\x04\x88\x04\x8a\x04\x8c\x04\x8e\x04\x90\x04\x92\x04\xaa\x04\xb0\x04\xbe\x04\xc3\x04\xd5\x04\xd8\x05\x11\x05\x16\x05\x1b\x052\x055\x00\x00\x00\x00\x00\x00\x02\x01\x00\x00\x00\x00\x00\x00\x00\xb3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05L' # noqa: E501
# below is just test data, not accurate representation of actual values # below is just test data, not accurate representation of actual values
PLACE_4_INFO_1 = [ PLACE_4_INFO_1 = [

View File

@ -138,16 +138,3 @@ def test_place_place_info_asdict():
assert isinstance(photo.place, osxphotos.placeinfo.PlaceInfo) assert isinstance(photo.place, osxphotos.placeinfo.PlaceInfo)
assert photo.place.asdict() == MAUI_DICT assert photo.place.asdict() == MAUI_DICT
# def test_place_str():
# # test __str__
# import osxphotos
# photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
# photo = photosdb.photos(uuid=[UUID_DICT["place_dc"]])[0]
# assert (
# str(photo.place)
# == "PlaceInfo(name='2038 18th St NW', names='['2038 18th St NW', 'Adams Morgan', 'Washington', 'Washington', 'Washington', 'District of Columbia', 'United States']', country_code='US', ishome='False', address_str='2038 18th St NW, Washington, DC 20009, United States', address='PostalAddress(street='2038 18th St NW', sub_locality='Adams Morgan', city='Washington', sub_administrative_area=None, state='DC', postal_code='20009', country='United States', iso_country_code='US')')"
# )

View File

@ -102,7 +102,7 @@ def test_albums_1(photosdb):
@pytest.mark.parametrize("album_name,album_uuids", ALBUM_PHOTO_DATA) @pytest.mark.parametrize("album_name,album_uuids", ALBUM_PHOTO_DATA)
def test_photoinfo_albums(photosdb, album_name, album_uuids): def test_photoinfo_albums_1(photosdb, album_name, album_uuids):
"""Test PhotoInfo.albums""" """Test PhotoInfo.albums"""
photos = photosdb.photos(uuid=album_uuids) photos = photosdb.photos(uuid=album_uuids)
@ -111,7 +111,7 @@ def test_photoinfo_albums(photosdb, album_name, album_uuids):
@pytest.mark.parametrize("uuid,expected_albums", PHOTO_ALBUM_DATA.items()) @pytest.mark.parametrize("uuid,expected_albums", PHOTO_ALBUM_DATA.items())
def test_photoinfo_albums(photosdb, uuid, expected_albums): def test_photoinfo_albums_2(photosdb, uuid, expected_albums):
"""Test PhotoInfo.albums""" """Test PhotoInfo.albums"""
photo = photosdb.get_photo(uuid) photo = photosdb.get_photo(uuid)

View File

@ -11,23 +11,6 @@ TOP_LEVEL_FOLDERS = ["Folder1", "iPhoto Events"]
ALBUM_NAMES = ["Album1", "Pumpkin Farm", "Event 1"] ALBUM_NAMES = ["Album1", "Pumpkin Farm", "Event 1"]
ALBUM_PHOTO_DATA = [
(
"Pumpkin Farm",
[
"FO2q5khAS9y4O9CkjpuYaw",
"47wXm7h6RfGRACCdcbLiCA",
"ZXV0MzbOSf65q82evn6G7g",
],
),
(
"Album1",
[
"ZXV0MzbOSf65q82evn6G7g",
],
),
]
PHOTO_ALBUM_DATA = { PHOTO_ALBUM_DATA = {
"FO2q5khAS9y4O9CkjpuYaw": ["Pumpkin Farm", "Album1", "Event 1"], "FO2q5khAS9y4O9CkjpuYaw": ["Pumpkin Farm", "Album1", "Event 1"],
"ZXV0MzbOSf65q82evn6G7g": ["Pumpkin Farm", "Event 1"], "ZXV0MzbOSf65q82evn6G7g": ["Pumpkin Farm", "Event 1"],
@ -101,15 +84,6 @@ def test_albums_1(photosdb):
assert sorted(album_names) == sorted(ALBUM_NAMES) assert sorted(album_names) == sorted(ALBUM_NAMES)
@pytest.mark.parametrize("album_name,album_uuids", ALBUM_PHOTO_DATA)
def test_photoinfo_albums(photosdb, album_name, album_uuids):
"""Test PhotoInfo.albums"""
photos = photosdb.photos(uuid=album_uuids)
albums = photos[0].albums
assert album_name in albums
@pytest.mark.parametrize("uuid,expected_albums", PHOTO_ALBUM_DATA.items()) @pytest.mark.parametrize("uuid,expected_albums", PHOTO_ALBUM_DATA.items())
def test_photoinfo_albums(photosdb, uuid, expected_albums): def test_photoinfo_albums(photosdb, uuid, expected_albums):
"""Test PhotoInfo.albums""" """Test PhotoInfo.albums"""

File diff suppressed because one or more lines are too long

View File

@ -379,7 +379,6 @@ UUID_CONDITIONAL = {
"{title contains Park?YES,NO}": ["YES"], "{title contains Park?YES,NO}": ["YES"],
"{title not contains Park?YES,NO}": ["NO"], "{title not contains Park?YES,NO}": ["NO"],
"{title matches Park?YES,NO}": ["NO"], "{title matches Park?YES,NO}": ["NO"],
"{title matches Elder Park?YES,NO}": ["YES"],
"{title == Elder Park?YES,NO}": ["YES"], "{title == Elder Park?YES,NO}": ["YES"],
"{title != Elder Park?YES,NO}": ["NO"], "{title != Elder Park?YES,NO}": ["NO"],
"{title[ ,] == ElderPark?YES,NO}": ["YES"], "{title[ ,] == ElderPark?YES,NO}": ["YES"],
@ -389,7 +388,6 @@ UUID_CONDITIONAL = {
"{title endswith Elder?YES,NO}": ["NO"], "{title endswith Elder?YES,NO}": ["NO"],
"{title startswith Elder?YES,NO}": ["YES"], "{title startswith Elder?YES,NO}": ["YES"],
"{title startswith Elder|endswith Park?YES,NO}": ["YES"], "{title startswith Elder|endswith Park?YES,NO}": ["YES"],
"{title endswith Elder?YES,NO}": ["NO"],
"{photo.place.name contains Adelaide?YES,NO}": ["YES"], "{photo.place.name contains Adelaide?YES,NO}": ["YES"],
"{photo.place.name|lower contains adelaide?YES,NO}": ["YES"], "{photo.place.name|lower contains adelaide?YES,NO}": ["YES"],
"{photo.place.name|lower contains adelaide|australia?YES,NO}": ["YES"], "{photo.place.name|lower contains adelaide|australia?YES,NO}": ["YES"],
@ -1136,7 +1134,8 @@ def test_nested_template(photosdb):
assert rendered == ["My Title"] assert rendered == ["My Title"]
def test_punctuation(photosdb): def test_punctuation_1(photosdb):
"""Test punctuation template fields"""
from osxphotos.phototemplate import PUNCTUATION from osxphotos.phototemplate import PUNCTUATION
photo = photosdb.get_photo(UUID_MULTI_KEYWORDS) photo = photosdb.get_photo(UUID_MULTI_KEYWORDS)
@ -1145,6 +1144,19 @@ def test_punctuation(photosdb):
assert rendered[0] == PUNCTUATION[punc] assert rendered[0] == PUNCTUATION[punc]
def test_punctuation_2():
"""Test punctuation template fields"""
template_string = ""
expected_string = ""
for field, value in PUNCTUATION.items():
template_string += "{" + field + "}"
expected_string += f"{value}"
template = PhotoTemplate(PhotoInfoNone())
options = RenderOptions()
rendered, _ = template.render(template_string, options)
assert rendered == [expected_string]
def test_photo_template(photosdb): def test_photo_template(photosdb):
for uuid in UUID_PHOTO: for uuid in UUID_PHOTO:
photo = photosdb.get_photo(uuid) photo = photosdb.get_photo(uuid)
@ -1361,16 +1373,3 @@ def test_bad_sslice(photosdb):
# bad function raises ValueError # bad function raises ValueError
with pytest.raises((SyntaxError, ValueError)): with pytest.raises((SyntaxError, ValueError)):
rendered, _ = photo.render_template("{photo.original_filename|sslice(1:2:3:4)}") rendered, _ = photo.render_template("{photo.original_filename|sslice(1:2:3:4)}")
def test_punctuation():
"""Test punctuation template fields"""
template_string = ""
expected_string = ""
for field, value in PUNCTUATION.items():
template_string += "{" + field + "}"
expected_string += f"{value}"
template = PhotoTemplate(PhotoInfoNone())
options = RenderOptions()
rendered, _ = template.render(template_string, options)
assert rendered == [expected_string]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long