Refactored PhotoInfo to use properties instead of methods--major update
This commit is contained in:
44
README.md
44
README.md
@@ -30,7 +30,7 @@
|
|||||||
- [`original_filename()`](#original_filename)
|
- [`original_filename()`](#original_filename)
|
||||||
- [`date()`](#date)
|
- [`date()`](#date)
|
||||||
- [`description()`](#description)
|
- [`description()`](#description)
|
||||||
- [`name()`](#name)
|
- [`title()`](#title)
|
||||||
- [`keywords()`](#keywords)
|
- [`keywords()`](#keywords)
|
||||||
- [`albums()`](#albums)
|
- [`albums()`](#albums)
|
||||||
- [`persons()`](#persons)
|
- [`persons()`](#persons)
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
- [`favorite()`](#favorite)
|
- [`favorite()`](#favorite)
|
||||||
- [`hidden()`](#hidden)
|
- [`hidden()`](#hidden)
|
||||||
- [`location()`](#location)
|
- [`location()`](#location)
|
||||||
- [`to_json()`](#to_json)
|
- [`json()`](#json)
|
||||||
- [`export(dest, *filename, edited=False, overwrite=False, increment=True)`](#exportdest-filename-editedfalse-overwritefalse-incrementtrue)
|
- [`export(dest, *filename, edited=False, overwrite=False, increment=True)`](#exportdest-filename-editedfalse-overwritefalse-incrementtrue)
|
||||||
+ [Utility Functions](#utility-functions)
|
+ [Utility Functions](#utility-functions)
|
||||||
- [```get_system_library_path()```](#get_system_library_path)
|
- [```get_system_library_path()```](#get_system_library_path)
|
||||||
@@ -121,11 +121,11 @@ Options:
|
|||||||
--person TEXT Search for person(s).
|
--person TEXT Search for person(s).
|
||||||
--album TEXT Search for album(s).
|
--album TEXT Search for album(s).
|
||||||
--uuid TEXT Search for UUID(s).
|
--uuid TEXT Search for UUID(s).
|
||||||
--name TEXT Search for TEXT in name of photo.
|
--title TEXT Search for TEXT in title of photo.
|
||||||
--no-name Search for photos with no name.
|
--no-title Search for photos with no title.
|
||||||
--description TEXT Search for TEXT in description of photo.
|
--description TEXT Search for TEXT in description of photo.
|
||||||
--no-description Search for photos with no description.
|
--no-description Search for photos with no description.
|
||||||
-i, --ignore-case Case insensitive search for name or description. Does
|
-i, --ignore-case Case insensitive search for title or description. Does
|
||||||
not apply to keyword, person, or album.
|
not apply to keyword, person, or album.
|
||||||
--edited Search for photos that have been edited.
|
--edited Search for photos that have been edited.
|
||||||
--external-edit Search for photos edited in external editor.
|
--external-edit Search for photos edited in external editor.
|
||||||
@@ -167,15 +167,15 @@ def main():
|
|||||||
for p in photos:
|
for p in photos:
|
||||||
print(
|
print(
|
||||||
p.uuid,
|
p.uuid,
|
||||||
p.filename(),
|
p.filename,
|
||||||
p.original_filename(),
|
p.original_filename,
|
||||||
p.date(),
|
p.date,
|
||||||
p.description(),
|
p.description,
|
||||||
p.name(),
|
p.title,
|
||||||
p.keywords(),
|
p.keywords,
|
||||||
p.albums(),
|
p.albums,
|
||||||
p.persons(),
|
p.persons,
|
||||||
p.path(),
|
p.path,
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@@ -191,6 +191,7 @@ import os.path
|
|||||||
|
|
||||||
import osxphotos
|
import osxphotos
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
photosdb = osxphotos.PhotosDB()
|
photosdb = osxphotos.PhotosDB()
|
||||||
photos = photosdb.photos()
|
photos = photosdb.photos()
|
||||||
@@ -198,14 +199,15 @@ def main():
|
|||||||
export_path = os.path.expanduser("~/Desktop/export")
|
export_path = os.path.expanduser("~/Desktop/export")
|
||||||
|
|
||||||
for p in photos:
|
for p in photos:
|
||||||
if not p.ismissing():
|
if not p.ismissing:
|
||||||
if p.hasadjustments():
|
if p.hasadjustments:
|
||||||
exported = p.export(export_path, edited=True)
|
exported = p.export(export_path, edited=True)
|
||||||
else:
|
else:
|
||||||
exported = p.export(export_path)
|
exported = p.export(export_path)
|
||||||
print(f"Exported {p.filename()} to {exported}")
|
print(f"Exported {p.filename} to {exported}")
|
||||||
else:
|
else:
|
||||||
print(f"Skipping missing photo: {p.filename()}")
|
print(f"Skipping missing photo: {p.filename}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
@@ -438,8 +440,8 @@ Returns the date of the photo as a datetime.datetime object
|
|||||||
#### `description()`
|
#### `description()`
|
||||||
Returns the description of the photo
|
Returns the description of the photo
|
||||||
|
|
||||||
#### `name()`
|
#### `title()`
|
||||||
Returns the name (or the title as Photos calls it) of the photo
|
Returns the title of the photo
|
||||||
|
|
||||||
#### `keywords()`
|
#### `keywords()`
|
||||||
Returns a list of keywords (e.g. tags) applied to the photo
|
Returns a list of keywords (e.g. tags) applied to the photo
|
||||||
@@ -474,7 +476,7 @@ Returns `True` if the picture has been marked as hidden, otherwise `False`
|
|||||||
#### `location()`
|
#### `location()`
|
||||||
Returns latitude and longitude as a tuple of floats (latitude, longitude). If location is not set, latitude and longitude are returned as `None`
|
Returns latitude and longitude as a tuple of floats (latitude, longitude). If location is not set, latitude and longitude are returned as `None`
|
||||||
|
|
||||||
#### `to_json()`
|
#### `json()`
|
||||||
Returns a JSON representation of all photo info
|
Returns a JSON representation of all photo info
|
||||||
|
|
||||||
#### `export(dest, *filename, edited=False, overwrite=False, increment=True)`
|
#### `export(dest, *filename, edited=False, overwrite=False, increment=True)`
|
||||||
|
|||||||
@@ -29,17 +29,17 @@ def main():
|
|||||||
photos = photosdb.photos()
|
photos = photosdb.photos()
|
||||||
for p in photos:
|
for p in photos:
|
||||||
print(
|
print(
|
||||||
p.uuid(),
|
p.uuid,
|
||||||
p.filename(),
|
p.filename,
|
||||||
p.date(),
|
p.date,
|
||||||
p.description(),
|
p.description,
|
||||||
p.name(),
|
p.title,
|
||||||
p.keywords(),
|
p.keywords,
|
||||||
p.albums(),
|
p.albums,
|
||||||
p.persons(),
|
p.persons,
|
||||||
p.path(),
|
p.path,
|
||||||
p.ismissing(),
|
p.ismissing,
|
||||||
p.hasadjustments(),
|
p.hasadjustments,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import os.path
|
|||||||
|
|
||||||
import osxphotos
|
import osxphotos
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
photosdb = osxphotos.PhotosDB()
|
photosdb = osxphotos.PhotosDB()
|
||||||
photos = photosdb.photos()
|
photos = photosdb.photos()
|
||||||
@@ -13,14 +14,15 @@ def main():
|
|||||||
export_path = os.path.expanduser("~/Desktop/export")
|
export_path = os.path.expanduser("~/Desktop/export")
|
||||||
|
|
||||||
for p in photos:
|
for p in photos:
|
||||||
if not p.ismissing():
|
if not p.ismissing:
|
||||||
if p.hasadjustments():
|
if p.hasadjustments:
|
||||||
exported = p.export(export_path, edited=True)
|
exported = p.export(export_path, edited=True)
|
||||||
else:
|
else:
|
||||||
exported = p.export(export_path)
|
exported = p.export(export_path)
|
||||||
print(f"Exported {p.filename()} to {exported}")
|
print(f"Exported {p.filename} to {exported}")
|
||||||
else:
|
else:
|
||||||
print(f"Skipping missing photo: {p.filename()}")
|
print(f"Skipping missing photo: {p.filename}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
@@ -9,7 +9,7 @@ import osxphotos
|
|||||||
|
|
||||||
from ._version import __version__
|
from ._version import __version__
|
||||||
|
|
||||||
# TODO: add "--any" to search any field (e.g. keyword, description, name contains "wedding") (add case insensitive option)
|
# TODO: add "--any" to search any field (e.g. keyword, description, title contains "wedding") (add case insensitive option)
|
||||||
|
|
||||||
|
|
||||||
class CLI_Obj:
|
class CLI_Obj:
|
||||||
@@ -169,9 +169,9 @@ def list_libraries(cli_obj):
|
|||||||
@click.option("--album", default=None, multiple=True, help="Search for album(s).")
|
@click.option("--album", default=None, multiple=True, help="Search for album(s).")
|
||||||
@click.option("--uuid", default=None, multiple=True, help="Search for UUID(s).")
|
@click.option("--uuid", default=None, multiple=True, help="Search for UUID(s).")
|
||||||
@click.option(
|
@click.option(
|
||||||
"--name", default=None, multiple=True, help="Search for TEXT in name of photo."
|
"--title", default=None, multiple=True, help="Search for TEXT in title of photo."
|
||||||
)
|
)
|
||||||
@click.option("--no-name", is_flag=True, help="Search for photos with no name.")
|
@click.option("--no-title", is_flag=True, help="Search for photos with no title.")
|
||||||
@click.option(
|
@click.option(
|
||||||
"--description",
|
"--description",
|
||||||
default=None,
|
default=None,
|
||||||
@@ -185,7 +185,7 @@ def list_libraries(cli_obj):
|
|||||||
"-i",
|
"-i",
|
||||||
"--ignore-case",
|
"--ignore-case",
|
||||||
is_flag=True,
|
is_flag=True,
|
||||||
help="Case insensitive search for name or description. Does not apply to keyword, person, or album.",
|
help="Case insensitive search for title or description. Does not apply to keyword, person, or album.",
|
||||||
)
|
)
|
||||||
@click.option("--edited", is_flag=True, help="Search for photos that have been edited.")
|
@click.option("--edited", is_flag=True, help="Search for photos that have been edited.")
|
||||||
@click.option(
|
@click.option(
|
||||||
@@ -219,8 +219,8 @@ def query(
|
|||||||
person,
|
person,
|
||||||
album,
|
album,
|
||||||
uuid,
|
uuid,
|
||||||
name,
|
title,
|
||||||
no_name,
|
no_title,
|
||||||
description,
|
description,
|
||||||
no_description,
|
no_description,
|
||||||
ignore_case,
|
ignore_case,
|
||||||
@@ -246,8 +246,8 @@ def query(
|
|||||||
person,
|
person,
|
||||||
album,
|
album,
|
||||||
uuid,
|
uuid,
|
||||||
name,
|
title,
|
||||||
no_name,
|
no_title,
|
||||||
description,
|
description,
|
||||||
no_description,
|
no_description,
|
||||||
edited,
|
edited,
|
||||||
@@ -274,8 +274,8 @@ def query(
|
|||||||
# can't search for both missing and notmissing
|
# can't search for both missing and notmissing
|
||||||
click.echo(cli.commands["query"].get_help(ctx))
|
click.echo(cli.commands["query"].get_help(ctx))
|
||||||
return
|
return
|
||||||
elif name and no_name:
|
elif title and no_title:
|
||||||
# can't search for both name and no_name
|
# can't search for both title and no_title
|
||||||
click.echo(cli.commands["query"].get_help(ctx))
|
click.echo(cli.commands["query"].get_help(ctx))
|
||||||
return
|
return
|
||||||
elif description and no_description:
|
elif description and no_description:
|
||||||
@@ -288,19 +288,19 @@ def query(
|
|||||||
keywords=keyword, persons=person, albums=album, uuid=uuid
|
keywords=keyword, persons=person, albums=album, uuid=uuid
|
||||||
)
|
)
|
||||||
|
|
||||||
if name:
|
if title:
|
||||||
# search name field for text
|
# search title field for text
|
||||||
# if more than one, find photos with all name values in in name
|
# if more than one, find photos with all title values in title
|
||||||
if ignore_case:
|
if ignore_case:
|
||||||
# case-insensitive
|
# case-insensitive
|
||||||
for n in name:
|
for t in title:
|
||||||
n = n.lower()
|
t = t.lower()
|
||||||
photos = [p for p in photos if p.name() and n in p.name().lower()]
|
photos = [p for p in photos if p.title and t in p.title.lower()]
|
||||||
else:
|
else:
|
||||||
for n in name:
|
for t in title:
|
||||||
photos = [p for p in photos if p.name() and n in p.name()]
|
photos = [p for p in photos if p.title and t in p.title]
|
||||||
elif no_name:
|
elif no_title:
|
||||||
photos = [p for p in photos if not p.name()]
|
photos = [p for p in photos if not p.title]
|
||||||
|
|
||||||
if description:
|
if description:
|
||||||
# search description field for text
|
# search description field for text
|
||||||
@@ -361,7 +361,7 @@ def print_photo_info(photos, json=False):
|
|||||||
if json:
|
if json:
|
||||||
dump = []
|
dump = []
|
||||||
for p in photos:
|
for p in photos:
|
||||||
dump.append(p.to_json())
|
dump.append(p.json())
|
||||||
click.echo(f"[{', '.join(dump)}]")
|
click.echo(f"[{', '.join(dump)}]")
|
||||||
else:
|
else:
|
||||||
# dump as CSV
|
# dump as CSV
|
||||||
@@ -377,7 +377,7 @@ def print_photo_info(photos, json=False):
|
|||||||
"original_filename",
|
"original_filename",
|
||||||
"date",
|
"date",
|
||||||
"description",
|
"description",
|
||||||
"name",
|
"title",
|
||||||
"keywords",
|
"keywords",
|
||||||
"albums",
|
"albums",
|
||||||
"persons",
|
"persons",
|
||||||
@@ -395,24 +395,24 @@ def print_photo_info(photos, json=False):
|
|||||||
for p in photos:
|
for p in photos:
|
||||||
dump.append(
|
dump.append(
|
||||||
[
|
[
|
||||||
p.uuid(),
|
p.uuid,
|
||||||
p.filename(),
|
p.filename,
|
||||||
p.original_filename(),
|
p.original_filename,
|
||||||
str(p.date()),
|
str(p.date),
|
||||||
p.description(),
|
p.description,
|
||||||
p.name(),
|
p.title,
|
||||||
", ".join(p.keywords()),
|
", ".join(p.keywords),
|
||||||
", ".join(p.albums()),
|
", ".join(p.albums),
|
||||||
", ".join(p.persons()),
|
", ".join(p.persons),
|
||||||
p.path(),
|
p.path,
|
||||||
p.ismissing(),
|
p.ismissing,
|
||||||
p.hasadjustments(),
|
p.hasadjustments,
|
||||||
p.external_edit(),
|
p.external_edit,
|
||||||
p.favorite(),
|
p.favorite,
|
||||||
p.hidden(),
|
p.hidden,
|
||||||
p._latitude(),
|
p._latitude,
|
||||||
p._longitude(),
|
p._longitude,
|
||||||
p.path_edited(),
|
p.path_edited,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
for row in dump:
|
for row in dump:
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
""" version info """
|
""" version info """
|
||||||
|
|
||||||
__version__ = "0.16.02"
|
__version__ = "0.17.00"
|
||||||
|
|||||||
@@ -30,15 +30,18 @@ class PhotoInfo:
|
|||||||
self._info = info
|
self._info = info
|
||||||
self._db = db
|
self._db = db
|
||||||
|
|
||||||
|
@property
|
||||||
def filename(self):
|
def filename(self):
|
||||||
""" filename of the picture """
|
""" filename of the picture """
|
||||||
return self._info["filename"]
|
return self._info["filename"]
|
||||||
|
|
||||||
|
@property
|
||||||
def original_filename(self):
|
def original_filename(self):
|
||||||
""" original filename of the picture """
|
""" original filename of the picture """
|
||||||
""" Photos 5 mangles filenames upon import """
|
""" Photos 5 mangles filenames upon import """
|
||||||
return self._info["originalFilename"]
|
return self._info["originalFilename"]
|
||||||
|
|
||||||
|
@property
|
||||||
def date(self):
|
def date(self):
|
||||||
""" image creation date as timezone aware datetime object """
|
""" image creation date as timezone aware datetime object """
|
||||||
imagedate = self._info["imageDate"]
|
imagedate = self._info["imageDate"]
|
||||||
@@ -48,10 +51,12 @@ class PhotoInfo:
|
|||||||
imagedate_utc = imagedate.astimezone(tz=tz)
|
imagedate_utc = imagedate.astimezone(tz=tz)
|
||||||
return imagedate_utc
|
return imagedate_utc
|
||||||
|
|
||||||
|
@property
|
||||||
def tzoffset(self):
|
def tzoffset(self):
|
||||||
""" timezone offset from UTC in seconds """
|
""" timezone offset from UTC in seconds """
|
||||||
return self._info["imageTimeZoneOffsetSeconds"]
|
return self._info["imageTimeZoneOffsetSeconds"]
|
||||||
|
|
||||||
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
""" absolute path on disk of the original picture """
|
""" absolute path on disk of the original picture """
|
||||||
photopath = ""
|
photopath = ""
|
||||||
@@ -93,6 +98,7 @@ class PhotoInfo:
|
|||||||
|
|
||||||
return photopath
|
return photopath
|
||||||
|
|
||||||
|
@property
|
||||||
def path_edited(self):
|
def path_edited(self):
|
||||||
""" absolute path on disk of the edited picture """
|
""" absolute path on disk of the edited picture """
|
||||||
""" None if photo has not been edited """
|
""" None if photo has not been edited """
|
||||||
@@ -165,14 +171,17 @@ class PhotoInfo:
|
|||||||
|
|
||||||
return photopath
|
return photopath
|
||||||
|
|
||||||
|
@property
|
||||||
def description(self):
|
def description(self):
|
||||||
""" long / extended description of picture """
|
""" long / extended description of picture """
|
||||||
return self._info["extendedDescription"]
|
return self._info["extendedDescription"]
|
||||||
|
|
||||||
|
@property
|
||||||
def persons(self):
|
def persons(self):
|
||||||
""" list of persons in picture """
|
""" list of persons in picture """
|
||||||
return self._info["persons"]
|
return self._info["persons"]
|
||||||
|
|
||||||
|
@property
|
||||||
def albums(self):
|
def albums(self):
|
||||||
""" list of albums picture is contained in """
|
""" list of albums picture is contained in """
|
||||||
albums = []
|
albums = []
|
||||||
@@ -180,24 +189,23 @@ class PhotoInfo:
|
|||||||
albums.append(self._db._dbalbum_details[album]["title"])
|
albums.append(self._db._dbalbum_details[album]["title"])
|
||||||
return albums
|
return albums
|
||||||
|
|
||||||
|
@property
|
||||||
def keywords(self):
|
def keywords(self):
|
||||||
""" list of keywords for picture """
|
""" list of keywords for picture """
|
||||||
return self._info["keywords"]
|
return self._info["keywords"]
|
||||||
|
|
||||||
def name(self):
|
@property
|
||||||
""" (deprecated) name / title of picture """
|
|
||||||
# TODO: add warning on deprecation
|
|
||||||
return self._info["name"]
|
|
||||||
|
|
||||||
def title(self):
|
def title(self):
|
||||||
""" name / title of picture """
|
""" name / title of picture """
|
||||||
# TODO: Update documentation and tests to use title
|
# TODO: Update documentation and tests to use title
|
||||||
return self._info["name"]
|
return self._info["name"]
|
||||||
|
|
||||||
|
@property
|
||||||
def uuid(self):
|
def uuid(self):
|
||||||
""" UUID of picture """
|
""" UUID of picture """
|
||||||
return self._uuid
|
return self._uuid
|
||||||
|
|
||||||
|
@property
|
||||||
def ismissing(self):
|
def ismissing(self):
|
||||||
""" returns true if photo is missing from disk (which means it's not been downloaded from iCloud)
|
""" returns true if photo is missing from disk (which means it's not been downloaded from iCloud)
|
||||||
NOTE: the photos.db database uses an asynchrounous write-ahead log so changes in Photos
|
NOTE: the photos.db database uses an asynchrounous write-ahead log so changes in Photos
|
||||||
@@ -210,10 +218,12 @@ class PhotoInfo:
|
|||||||
"""
|
"""
|
||||||
return True if self._info["isMissing"] == 1 else False
|
return True if self._info["isMissing"] == 1 else False
|
||||||
|
|
||||||
|
@property
|
||||||
def hasadjustments(self):
|
def hasadjustments(self):
|
||||||
""" True if picture has adjustments / edits """
|
""" True if picture has adjustments / edits """
|
||||||
return True if self._info["hasAdjustments"] == 1 else False
|
return True if self._info["hasAdjustments"] == 1 else False
|
||||||
|
|
||||||
|
@property
|
||||||
def external_edit(self):
|
def external_edit(self):
|
||||||
""" Returns True if picture was edited outside of Photos using external editor """
|
""" Returns True if picture was edited outside of Photos using external editor """
|
||||||
return (
|
return (
|
||||||
@@ -222,17 +232,20 @@ class PhotoInfo:
|
|||||||
else False
|
else False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
def favorite(self):
|
def favorite(self):
|
||||||
""" True if picture is marked as favorite """
|
""" True if picture is marked as favorite """
|
||||||
return True if self._info["favorite"] == 1 else False
|
return True if self._info["favorite"] == 1 else False
|
||||||
|
|
||||||
|
@property
|
||||||
def hidden(self):
|
def hidden(self):
|
||||||
""" True if picture is hidden """
|
""" True if picture is hidden """
|
||||||
return True if self._info["hidden"] == 1 else False
|
return True if self._info["hidden"] == 1 else False
|
||||||
|
|
||||||
|
@property
|
||||||
def location(self):
|
def location(self):
|
||||||
""" returns (latitude, longitude) as float in degrees or None """
|
""" returns (latitude, longitude) as float in degrees or None """
|
||||||
return (self._latitude(), self._longitude())
|
return (self._latitude, self._longitude)
|
||||||
|
|
||||||
def export(
|
def export(
|
||||||
self,
|
self,
|
||||||
@@ -278,43 +291,43 @@ class PhotoInfo:
|
|||||||
# need to use file extension from edited file as Photos saves a jpeg once edited
|
# need to use file extension from edited file as Photos saves a jpeg once edited
|
||||||
if edited:
|
if edited:
|
||||||
# verify we have a valid path_edited and use that to get filename
|
# verify we have a valid path_edited and use that to get filename
|
||||||
if not self.path_edited():
|
if not self.path_edited:
|
||||||
raise FileNotFoundError(
|
raise FileNotFoundError(
|
||||||
f"edited=True but path_edited is none; hasadjustments: {self.hasadjustments()}"
|
f"edited=True but path_edited is none; hasadjustments: {self.hasadjustments}"
|
||||||
)
|
)
|
||||||
edited_name = Path(self.path_edited()).name
|
edited_name = Path(self.path_edited).name
|
||||||
edited_suffix = Path(edited_name).suffix
|
edited_suffix = Path(edited_name).suffix
|
||||||
filename = Path(self.filename()).stem + "_edited" + edited_suffix
|
filename = Path(self.filename).stem + "_edited" + edited_suffix
|
||||||
else:
|
else:
|
||||||
filename = self.filename()
|
filename = self.filename
|
||||||
|
|
||||||
# get path to source file and verify it's not None and is valid file
|
# get path to source file and verify it's not None and is valid file
|
||||||
# TODO: how to handle ismissing or not hasadjustments and edited=True cases?
|
# TODO: how to handle ismissing or not hasadjustments and edited=True cases?
|
||||||
if edited:
|
if edited:
|
||||||
if not self.hasadjustments():
|
if not self.hasadjustments:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
"Attempting to export edited photo but hasadjustments=False"
|
"Attempting to export edited photo but hasadjustments=False"
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.path_edited() is not None:
|
if self.path_edited is not None:
|
||||||
src = self.path_edited()
|
src = self.path_edited
|
||||||
else:
|
else:
|
||||||
raise FileNotFoundError(
|
raise FileNotFoundError(
|
||||||
f"edited=True but path_edited is none; hasadjustments: {self.hasadjustments()}"
|
f"edited=True but path_edited is none; hasadjustments: {self.hasadjustments}"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
if self.ismissing():
|
if self.ismissing:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"Attempting to export photo with ismissing=True: path = {self.path()}"
|
f"Attempting to export photo with ismissing=True: path = {self.path}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.path() is None:
|
if self.path is None:
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"Attempting to export photo but path is None: ismissing = {self.ismissing()}"
|
f"Attempting to export photo but path is None: ismissing = {self.ismissing}"
|
||||||
)
|
)
|
||||||
raise FileNotFoundError("Cannot export photo if path is None")
|
raise FileNotFoundError("Cannot export photo if path is None")
|
||||||
else:
|
else:
|
||||||
src = self.path()
|
src = self.path
|
||||||
|
|
||||||
if not os.path.isfile(src):
|
if not os.path.isfile(src):
|
||||||
raise FileNotFoundError(f"{src} does not appear to exist")
|
raise FileNotFoundError(f"{src} does not appear to exist")
|
||||||
@@ -368,25 +381,25 @@ class PhotoInfo:
|
|||||||
def _exiftool_json_sidecar(self):
|
def _exiftool_json_sidecar(self):
|
||||||
""" return json string of EXIF details in exiftool sidecar format """
|
""" return json string of EXIF details in exiftool sidecar format """
|
||||||
exif = {}
|
exif = {}
|
||||||
exif["FileName"] = self.filename()
|
exif["FileName"] = self.filename
|
||||||
|
|
||||||
if self.description():
|
if self.description:
|
||||||
exif["ImageDescription"] = self.description()
|
exif["ImageDescription"] = self.description
|
||||||
exif["Description"] = self.description()
|
exif["Description"] = self.description
|
||||||
|
|
||||||
if self.title():
|
if self.title:
|
||||||
exif["Title"] = self.title()
|
exif["Title"] = self.title
|
||||||
|
|
||||||
if self.keywords():
|
if self.keywords:
|
||||||
exif["TagsList"] = exif["Keywords"] = self.keywords()
|
exif["TagsList"] = exif["Keywords"] = self.keywords
|
||||||
|
|
||||||
if self.persons():
|
if self.persons:
|
||||||
exif["PersonInImage"] = self.persons()
|
exif["PersonInImage"] = self.persons
|
||||||
|
|
||||||
# if self.favorite():
|
# if self.favorite():
|
||||||
# exif["Rating"] = 5
|
# exif["Rating"] = 5
|
||||||
|
|
||||||
(lat, lon) = self.location()
|
(lat, lon) = self.location
|
||||||
if lat is not None and lon is not None:
|
if lat is not None and lon is not None:
|
||||||
lat_str, lon_str = dd_to_dms_str(lat, lon)
|
lat_str, lon_str = dd_to_dms_str(lat, lon)
|
||||||
exif["GPSLatitude"] = lat_str
|
exif["GPSLatitude"] = lat_str
|
||||||
@@ -398,7 +411,7 @@ class PhotoInfo:
|
|||||||
exif["GPSLongitudeRef"] = lon_ref
|
exif["GPSLongitudeRef"] = lon_ref
|
||||||
|
|
||||||
# process date/time and timezone offset
|
# process date/time and timezone offset
|
||||||
date = self.date()
|
date = self.date
|
||||||
# exiftool expects format to "2015:01:18 12:00:00"
|
# exiftool expects format to "2015:01:18 12:00:00"
|
||||||
datetimeoriginal = date.strftime("%Y:%m:%d %H:%M:%S")
|
datetimeoriginal = date.strftime("%Y:%m:%d %H:%M:%S")
|
||||||
offsettime = date.strftime("%z")
|
offsettime = date.strftime("%z")
|
||||||
@@ -425,10 +438,12 @@ class PhotoInfo:
|
|||||||
f.write(json_str)
|
f.write(json_str)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
@property
|
||||||
def _longitude(self):
|
def _longitude(self):
|
||||||
""" Returns longitude, in degrees """
|
""" Returns longitude, in degrees """
|
||||||
return self._info["longitude"]
|
return self._info["longitude"]
|
||||||
|
|
||||||
|
@property
|
||||||
def _latitude(self):
|
def _latitude(self):
|
||||||
""" Returns latitude, in degrees """
|
""" Returns latitude, in degrees """
|
||||||
return self._info["latitude"]
|
return self._info["latitude"]
|
||||||
@@ -439,49 +454,49 @@ class PhotoInfo:
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
info = {
|
info = {
|
||||||
"uuid": self.uuid(),
|
"uuid": self.uuid,
|
||||||
"filename": self.filename(),
|
"filename": self.filename,
|
||||||
"original_filename": self.original_filename(),
|
"original_filename": self.original_filename,
|
||||||
"date": str(self.date()),
|
"date": str(self.date),
|
||||||
"description": self.description(),
|
"description": self.description,
|
||||||
"name": self.name(),
|
"name": self.name,
|
||||||
"keywords": self.keywords(),
|
"keywords": self.keywords,
|
||||||
"albums": self.albums(),
|
"albums": self.albums,
|
||||||
"persons": self.persons(),
|
"persons": self.persons,
|
||||||
"path": self.path(),
|
"path": self.path,
|
||||||
"ismissing": self.ismissing(),
|
"ismissing": self.ismissing,
|
||||||
"hasadjustments": self.hasadjustments(),
|
"hasadjustments": self.hasadjustments,
|
||||||
"external_edit": self.external_edit(),
|
"external_edit": self.external_edit,
|
||||||
"favorite": self.favorite(),
|
"favorite": self.favorite,
|
||||||
"hidden": self.hidden(),
|
"hidden": self.hidden,
|
||||||
"latitude": self._latitude(),
|
"latitude": self._latitude,
|
||||||
"longitude": self._longitude(),
|
"longitude": self._longitude,
|
||||||
"path_edited": self.path_edited(),
|
"path_edited": self.path_edited,
|
||||||
}
|
}
|
||||||
return yaml.dump(info, sort_keys=False)
|
return yaml.dump(info, sort_keys=False)
|
||||||
|
|
||||||
def to_json(self):
|
def json(self):
|
||||||
""" return JSON representation """
|
""" return JSON representation """
|
||||||
# TODO: Add additional details here
|
# TODO: Add additional details here
|
||||||
pic = {
|
pic = {
|
||||||
"uuid": self.uuid(),
|
"uuid": self.uuid,
|
||||||
"filename": self.filename(),
|
"filename": self.filename,
|
||||||
"original_filename": self.original_filename(),
|
"original_filename": self.original_filename,
|
||||||
"date": str(self.date()),
|
"date": str(self.date),
|
||||||
"description": self.description(),
|
"description": self.description,
|
||||||
"name": self.name(),
|
"title": self.title,
|
||||||
"keywords": self.keywords(),
|
"keywords": self.keywords,
|
||||||
"albums": self.albums(),
|
"albums": self.albums,
|
||||||
"persons": self.persons(),
|
"persons": self.persons,
|
||||||
"path": self.path(),
|
"path": self.path,
|
||||||
"ismissing": self.ismissing(),
|
"ismissing": self.ismissing,
|
||||||
"hasadjustments": self.hasadjustments(),
|
"hasadjustments": self.hasadjustments,
|
||||||
"external_edit": self.external_edit(),
|
"external_edit": self.external_edit,
|
||||||
"favorite": self.favorite(),
|
"favorite": self.favorite,
|
||||||
"hidden": self.hidden(),
|
"hidden": self.hidden,
|
||||||
"latitude": self._latitude(),
|
"latitude": self._latitude,
|
||||||
"longitude": self._longitude(),
|
"longitude": self._longitude,
|
||||||
"path_edited": self.path_edited(),
|
"path_edited": self.path_edited,
|
||||||
}
|
}
|
||||||
return json.dumps(pic)
|
return json.dumps(pic)
|
||||||
|
|
||||||
|
|||||||
@@ -116,20 +116,20 @@ def test_attributes():
|
|||||||
photos = photosdb.photos(uuid=["sE5LlfekS8ykEE7o0cuMVA"])
|
photos = photosdb.photos(uuid=["sE5LlfekS8ykEE7o0cuMVA"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.keywords() == ["Kids"]
|
assert p.keywords == ["Kids"]
|
||||||
assert p.original_filename() == "Pumkins2.jpg"
|
assert p.original_filename == "Pumkins2.jpg"
|
||||||
assert p.filename() == "Pumkins2.jpg"
|
assert p.filename == "Pumkins2.jpg"
|
||||||
assert p.date() == datetime.datetime(
|
assert p.date == datetime.datetime(
|
||||||
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
||||||
)
|
)
|
||||||
assert p.description() == "Girl holding pumpkin"
|
assert p.description == "Girl holding pumpkin"
|
||||||
assert p.name() == "I found one!"
|
assert p.title == "I found one!"
|
||||||
assert p.albums() == ["Pumpkin Farm"]
|
assert p.albums == ["Pumpkin Farm"]
|
||||||
assert p.persons() == ["Katie"]
|
assert p.persons == ["Katie"]
|
||||||
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 p.ismissing == False
|
||||||
|
|
||||||
|
|
||||||
def test_missing():
|
def test_missing():
|
||||||
@@ -139,8 +139,8 @@ def test_missing():
|
|||||||
photos = photosdb.photos(uuid=["Pj99JmYjQkeezdY2OFuSaw"])
|
photos = photosdb.photos(uuid=["Pj99JmYjQkeezdY2OFuSaw"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.path() == None
|
assert p.path == None
|
||||||
assert p.ismissing() == True
|
assert p.ismissing == True
|
||||||
|
|
||||||
|
|
||||||
def test_count():
|
def test_count():
|
||||||
@@ -169,4 +169,4 @@ def test_keyword_not_in_album():
|
|||||||
photos2 = photosdb.photos(keywords=["Kids"])
|
photos2 = photosdb.photos(keywords=["Kids"])
|
||||||
photos3 = [p for p in photos2 if p not in photos1]
|
photos3 = [p for p in photos2 if p not in photos1]
|
||||||
assert len(photos3) == 1
|
assert len(photos3) == 1
|
||||||
assert photos3[0].uuid() == "Pj99JmYjQkeezdY2OFuSaw"
|
assert photos3[0].uuid == "Pj99JmYjQkeezdY2OFuSaw"
|
||||||
|
|||||||
@@ -193,20 +193,20 @@ def test_attributes():
|
|||||||
photos = photosdb.photos(uuid=["D79B8D77-BFFC-460B-9312-034F2877D35B"])
|
photos = photosdb.photos(uuid=["D79B8D77-BFFC-460B-9312-034F2877D35B"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.keywords() == ["Kids"]
|
assert p.keywords == ["Kids"]
|
||||||
assert p.original_filename() == "Pumkins2.jpg"
|
assert p.original_filename == "Pumkins2.jpg"
|
||||||
assert p.filename() == "D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg"
|
assert p.filename == "D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg"
|
||||||
assert p.date() == datetime.datetime(
|
assert p.date == datetime.datetime(
|
||||||
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
||||||
)
|
)
|
||||||
assert p.description() == "Girl holding pumpkin"
|
assert p.description == "Girl holding pumpkin"
|
||||||
assert p.name() == "I found one!"
|
assert p.title == "I found one!"
|
||||||
assert p.albums() == ["Pumpkin Farm", "Test Album"]
|
assert p.albums == ["Pumpkin Farm", "Test Album"]
|
||||||
assert p.persons() == ["Katie"]
|
assert p.persons == ["Katie"]
|
||||||
assert p.path().endswith(
|
assert p.path.endswith(
|
||||||
"tests/Test-10.15.1.photoslibrary/originals/D/D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg"
|
"tests/Test-10.15.1.photoslibrary/originals/D/D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg"
|
||||||
)
|
)
|
||||||
assert p.ismissing() == False
|
assert p.ismissing == False
|
||||||
|
|
||||||
|
|
||||||
def test_missing():
|
def test_missing():
|
||||||
@@ -216,8 +216,8 @@ def test_missing():
|
|||||||
photos = photosdb.photos(uuid=[UUID_DICT["missing"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["missing"]])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.path() == None
|
assert p.path == None
|
||||||
assert p.ismissing() == True
|
assert p.ismissing == True
|
||||||
|
|
||||||
|
|
||||||
def test_favorite():
|
def test_favorite():
|
||||||
@@ -227,7 +227,7 @@ def test_favorite():
|
|||||||
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 == True
|
||||||
|
|
||||||
|
|
||||||
def test_not_favorite():
|
def test_not_favorite():
|
||||||
@@ -237,7 +237,7 @@ def test_not_favorite():
|
|||||||
photos = photosdb.photos(uuid=[UUID_DICT["not_favorite"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["not_favorite"]])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.favorite() == False
|
assert p.favorite == False
|
||||||
|
|
||||||
|
|
||||||
def test_hidden():
|
def test_hidden():
|
||||||
@@ -247,7 +247,7 @@ def test_hidden():
|
|||||||
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 == True
|
||||||
|
|
||||||
|
|
||||||
def test_not_hidden():
|
def test_not_hidden():
|
||||||
@@ -257,7 +257,7 @@ def test_not_hidden():
|
|||||||
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 p.hidden == False
|
||||||
|
|
||||||
|
|
||||||
def test_location_1():
|
def test_location_1():
|
||||||
@@ -268,7 +268,7 @@ def test_location_1():
|
|||||||
photos = photosdb.photos(uuid=[UUID_DICT["location"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["location"]])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
lat, lon = p.location()
|
lat, lon = p.location
|
||||||
assert lat == pytest.approx(51.50357167)
|
assert lat == pytest.approx(51.50357167)
|
||||||
assert lon == pytest.approx(-0.1318055)
|
assert lon == pytest.approx(-0.1318055)
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ def test_location_2():
|
|||||||
photos = photosdb.photos(uuid=[UUID_DICT["no_location"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["no_location"]])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
lat, lon = p.location()
|
lat, lon = p.location
|
||||||
assert lat is None
|
assert lat is None
|
||||||
assert lon is None
|
assert lon is None
|
||||||
|
|
||||||
@@ -294,7 +294,7 @@ def test_hasadjustments1():
|
|||||||
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 == True
|
||||||
|
|
||||||
|
|
||||||
def test_hasadjustments2():
|
def test_hasadjustments2():
|
||||||
@@ -305,7 +305,7 @@ def test_hasadjustments2():
|
|||||||
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 p.hasadjustments == False
|
||||||
|
|
||||||
|
|
||||||
def test_external_edit1():
|
def test_external_edit1():
|
||||||
@@ -317,7 +317,7 @@ def test_external_edit1():
|
|||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
|
|
||||||
assert p.external_edit() == True
|
assert p.external_edit == True
|
||||||
|
|
||||||
|
|
||||||
def test_external_edit2():
|
def test_external_edit2():
|
||||||
@@ -329,7 +329,7 @@ def test_external_edit2():
|
|||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
|
|
||||||
assert p.external_edit() == False
|
assert p.external_edit == False
|
||||||
|
|
||||||
|
|
||||||
def test_path_edited1():
|
def test_path_edited1():
|
||||||
@@ -340,7 +340,7 @@ def test_path_edited1():
|
|||||||
photos = photosdb.photos(uuid=["E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51"])
|
photos = photosdb.photos(uuid=["E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
path = p.path_edited()
|
path = p.path_edited
|
||||||
assert path.endswith(
|
assert path.endswith(
|
||||||
"resources/renders/E/E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51_1_201_a.jpeg"
|
"resources/renders/E/E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51_1_201_a.jpeg"
|
||||||
)
|
)
|
||||||
@@ -354,7 +354,7 @@ def test_path_edited2():
|
|||||||
photos = photosdb.photos(uuid=["6191423D-8DB8-4D4C-92BE-9BBBA308AAC4"])
|
photos = photosdb.photos(uuid=["6191423D-8DB8-4D4C-92BE-9BBBA308AAC4"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
path = p.path_edited()
|
path = p.path_edited
|
||||||
assert path is None
|
assert path is None
|
||||||
|
|
||||||
|
|
||||||
@@ -384,7 +384,7 @@ def test_keyword_not_in_album():
|
|||||||
photos2 = photosdb.photos(keywords=["Kids"])
|
photos2 = photosdb.photos(keywords=["Kids"])
|
||||||
photos3 = [p for p in photos2 if p not in photos1]
|
photos3 = [p for p in photos2 if p not in photos1]
|
||||||
assert len(photos3) == 1
|
assert len(photos3) == 1
|
||||||
assert photos3[0].uuid() == "A1DD1F98-2ECD-431F-9AC9-5AFEFE2D3A5C"
|
assert photos3[0].uuid == "A1DD1F98-2ECD-431F-9AC9-5AFEFE2D3A5C"
|
||||||
|
|
||||||
|
|
||||||
def test_get_db_path():
|
def test_get_db_path():
|
||||||
@@ -416,7 +416,7 @@ def test_export_1():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
|
|
||||||
@@ -465,7 +465,7 @@ def test_export_3():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
filename2 = pathlib.Path(filename)
|
filename2 = pathlib.Path(filename)
|
||||||
filename2 = f"{filename2.stem} (1){filename2.suffix}"
|
filename2 = f"{filename2.stem} (1){filename2.suffix}"
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
@@ -526,7 +526,7 @@ def test_export_5():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
@@ -583,7 +583,7 @@ def test_export_7():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
@@ -609,7 +609,7 @@ def test_export_8():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["missing"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["missing"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
@@ -630,7 +630,7 @@ def test_export_9():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
@@ -698,9 +698,9 @@ def test_export_12():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]])
|
||||||
|
|
||||||
edited_name = pathlib.Path(photos[0].path_edited()).name
|
edited_name = pathlib.Path(photos[0].path_edited).name
|
||||||
edited_suffix = pathlib.Path(edited_name).suffix
|
edited_suffix = pathlib.Path(edited_name).suffix
|
||||||
filename = pathlib.Path(photos[0].filename()).stem + "_edited" + edited_suffix
|
filename = pathlib.Path(photos[0].filename).stem + "_edited" + edited_suffix
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest, edited=True)
|
got_dest = photos[0].export(dest, edited=True)
|
||||||
@@ -730,7 +730,7 @@ def test_export_13():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ def test_export_1():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ def test_export_3():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
filename2 = pathlib.Path(filename)
|
filename2 = pathlib.Path(filename)
|
||||||
filename2 = f"{filename2.stem} (1){filename2.suffix}"
|
filename2 = f"{filename2.stem} (1){filename2.suffix}"
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
@@ -182,7 +182,7 @@ def test_export_5():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
@@ -239,7 +239,7 @@ def test_export_7():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
@@ -265,7 +265,7 @@ def test_export_8():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["missing"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["missing"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
@@ -286,7 +286,7 @@ def test_export_9():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
@@ -354,9 +354,9 @@ def test_export_12():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]])
|
||||||
|
|
||||||
edited_name = pathlib.Path(photos[0].path_edited()).name
|
edited_name = pathlib.Path(photos[0].path_edited).name
|
||||||
edited_suffix = pathlib.Path(edited_name).suffix
|
edited_suffix = pathlib.Path(edited_name).suffix
|
||||||
filename = pathlib.Path(photos[0].filename()).stem + "_edited" + edited_suffix
|
filename = pathlib.Path(photos[0].filename).stem + "_edited" + edited_suffix
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest, edited=True)
|
got_dest = photos[0].export(dest, edited=True)
|
||||||
@@ -386,7 +386,7 @@ def test_export_13():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ def test_export_1():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ def test_export_3():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
filename2 = pathlib.Path(filename)
|
filename2 = pathlib.Path(filename)
|
||||||
filename2 = f"{filename2.stem} (1){filename2.suffix}"
|
filename2 = f"{filename2.stem} (1){filename2.suffix}"
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
@@ -168,7 +168,7 @@ def test_export_5():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
@@ -225,7 +225,7 @@ def test_export_7():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest)
|
got_dest = photos[0].export(dest)
|
||||||
@@ -251,7 +251,7 @@ def test_export_8():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["missing"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["missing"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
@@ -272,7 +272,7 @@ def test_export_9():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["no_adjustments"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
@@ -340,9 +340,9 @@ def test_export_12():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["has_adjustments"]])
|
||||||
|
|
||||||
edited_name = pathlib.Path(photos[0].path_edited()).name
|
edited_name = pathlib.Path(photos[0].path_edited).name
|
||||||
edited_suffix = pathlib.Path(edited_name).suffix
|
edited_suffix = pathlib.Path(edited_name).suffix
|
||||||
filename = pathlib.Path(photos[0].filename()).stem + "_edited" + edited_suffix
|
filename = pathlib.Path(photos[0].filename).stem + "_edited" + edited_suffix
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
got_dest = photos[0].export(dest, edited=True)
|
got_dest = photos[0].export(dest, edited=True)
|
||||||
@@ -372,7 +372,7 @@ def test_export_13():
|
|||||||
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB)
|
||||||
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
photos = photosdb.photos(uuid=[UUID_DICT["export"]])
|
||||||
|
|
||||||
filename = photos[0].filename()
|
filename = photos[0].filename
|
||||||
expected_dest = os.path.join(dest, filename)
|
expected_dest = os.path.join(dest, filename)
|
||||||
|
|
||||||
with pytest.raises(Exception) as e:
|
with pytest.raises(Exception) as e:
|
||||||
|
|||||||
@@ -115,20 +115,20 @@ def test_attributes():
|
|||||||
photos = photosdb.photos(uuid=["RWmFYiDjSyKjeK8Pfna0Eg"])
|
photos = photosdb.photos(uuid=["RWmFYiDjSyKjeK8Pfna0Eg"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.keywords() == ["Kids"]
|
assert p.keywords == ["Kids"]
|
||||||
assert p.original_filename() == "Pumkins2.jpg"
|
assert p.original_filename == "Pumkins2.jpg"
|
||||||
assert p.filename() == "Pumkins2.jpg"
|
assert p.filename == "Pumkins2.jpg"
|
||||||
assert p.date() == datetime.datetime(
|
assert p.date == datetime.datetime(
|
||||||
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
||||||
)
|
)
|
||||||
assert p.description() == "Girl holding pumpkin"
|
assert p.description == "Girl holding pumpkin"
|
||||||
assert p.name() == "I found one!"
|
assert p.title == "I found one!"
|
||||||
assert p.albums() == ["Pumpkin Farm"]
|
assert p.albums == ["Pumpkin Farm"]
|
||||||
assert p.persons() == ["Katie"]
|
assert p.persons == ["Katie"]
|
||||||
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 p.ismissing == False
|
||||||
|
|
||||||
|
|
||||||
def test_missing():
|
def test_missing():
|
||||||
@@ -138,8 +138,8 @@ def test_missing():
|
|||||||
photos = photosdb.photos(uuid=["6iAZJP7ZQ5iXxapoJb3ytA"])
|
photos = photosdb.photos(uuid=["6iAZJP7ZQ5iXxapoJb3ytA"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.path() == None
|
assert p.path == None
|
||||||
assert p.ismissing() == True
|
assert p.ismissing == True
|
||||||
|
|
||||||
|
|
||||||
def test_count():
|
def test_count():
|
||||||
@@ -168,4 +168,4 @@ def test_keyword_not_in_album():
|
|||||||
photos2 = photosdb.photos(keywords=["Kids"])
|
photos2 = photosdb.photos(keywords=["Kids"])
|
||||||
photos3 = [p for p in photos2 if p not in photos1]
|
photos3 = [p for p in photos2 if p not in photos1]
|
||||||
assert len(photos3) == 1
|
assert len(photos3) == 1
|
||||||
assert photos3[0].uuid() == "6iAZJP7ZQ5iXxapoJb3ytA"
|
assert photos3[0].uuid == "6iAZJP7ZQ5iXxapoJb3ytA"
|
||||||
|
|||||||
@@ -115,20 +115,20 @@ def test_attributes():
|
|||||||
photos = photosdb.photos(uuid=["15uNd7%8RguTEgNPKHfTWw"])
|
photos = photosdb.photos(uuid=["15uNd7%8RguTEgNPKHfTWw"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.keywords() == ["Kids"]
|
assert p.keywords == ["Kids"]
|
||||||
assert p.original_filename() == "Pumkins2.jpg"
|
assert p.original_filename == "Pumkins2.jpg"
|
||||||
assert p.filename() == "Pumkins2.jpg"
|
assert p.filename == "Pumkins2.jpg"
|
||||||
assert p.date() == datetime.datetime(
|
assert p.date == datetime.datetime(
|
||||||
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
||||||
)
|
)
|
||||||
assert p.description() == "Girl holding pumpkin"
|
assert p.description == "Girl holding pumpkin"
|
||||||
assert p.name() == "I found one!"
|
assert p.title == "I found one!"
|
||||||
assert p.albums() == ["Pumpkin Farm"]
|
assert p.albums == ["Pumpkin Farm"]
|
||||||
assert p.persons() == ["Katie"]
|
assert p.persons == ["Katie"]
|
||||||
assert p.path().endswith(
|
assert p.path.endswith(
|
||||||
"/tests/Test-10.14.5.photoslibrary/Masters/2019/07/27/20190727-131650/Pumkins2.jpg"
|
"/tests/Test-10.14.5.photoslibrary/Masters/2019/07/27/20190727-131650/Pumkins2.jpg"
|
||||||
)
|
)
|
||||||
assert p.ismissing() == False
|
assert p.ismissing == False
|
||||||
|
|
||||||
|
|
||||||
def test_missing():
|
def test_missing():
|
||||||
@@ -138,8 +138,8 @@ def test_missing():
|
|||||||
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.path() == None
|
assert p.path == None
|
||||||
assert p.ismissing() == True
|
assert p.ismissing == True
|
||||||
|
|
||||||
|
|
||||||
def test_count():
|
def test_count():
|
||||||
@@ -168,4 +168,4 @@ def test_keyword_not_in_album():
|
|||||||
photos2 = photosdb.photos(keywords=["Kids"])
|
photos2 = photosdb.photos(keywords=["Kids"])
|
||||||
photos3 = [p for p in photos2 if p not in photos1]
|
photos3 = [p for p in photos2 if p not in photos1]
|
||||||
assert len(photos3) == 1
|
assert len(photos3) == 1
|
||||||
assert photos3[0].uuid() == "od0fmC7NQx+ayVr+%i06XA"
|
assert photos3[0].uuid == "od0fmC7NQx+ayVr+%i06XA"
|
||||||
|
|||||||
@@ -118,20 +118,20 @@ def test_attributes():
|
|||||||
photos = photosdb.photos(uuid=["15uNd7%8RguTEgNPKHfTWw"])
|
photos = photosdb.photos(uuid=["15uNd7%8RguTEgNPKHfTWw"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.keywords() == ["Kids"]
|
assert p.keywords == ["Kids"]
|
||||||
assert p.original_filename() == "Pumkins2.jpg"
|
assert p.original_filename == "Pumkins2.jpg"
|
||||||
assert p.filename() == "Pumkins2.jpg"
|
assert p.filename == "Pumkins2.jpg"
|
||||||
assert p.date() == datetime.datetime(
|
assert p.date == datetime.datetime(
|
||||||
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
2018, 9, 28, 16, 7, 7, 0, datetime.timezone(datetime.timedelta(seconds=-14400))
|
||||||
)
|
)
|
||||||
assert p.description() == "Girl holding pumpkin"
|
assert p.description == "Girl holding pumpkin"
|
||||||
assert p.name() == "I found one!"
|
assert p.title == "I found one!"
|
||||||
assert p.albums() == ["Pumpkin Farm", "Test Album (1)"]
|
assert p.albums == ["Pumpkin Farm", "Test Album (1)"]
|
||||||
assert p.persons() == ["Katie"]
|
assert p.persons == ["Katie"]
|
||||||
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 p.ismissing == False
|
||||||
|
|
||||||
|
|
||||||
def test_missing():
|
def test_missing():
|
||||||
@@ -141,8 +141,8 @@ def test_missing():
|
|||||||
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.path() == None
|
assert p.path == None
|
||||||
assert p.ismissing() == True
|
assert p.ismissing == True
|
||||||
|
|
||||||
|
|
||||||
def test_favorite():
|
def test_favorite():
|
||||||
@@ -152,7 +152,7 @@ def test_favorite():
|
|||||||
photos = photosdb.photos(uuid=["6bxcNnzRQKGnK4uPrCJ9UQ"])
|
photos = photosdb.photos(uuid=["6bxcNnzRQKGnK4uPrCJ9UQ"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.favorite() == True
|
assert p.favorite == True
|
||||||
|
|
||||||
|
|
||||||
def test_not_favorite():
|
def test_not_favorite():
|
||||||
@@ -162,7 +162,7 @@ def test_not_favorite():
|
|||||||
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 p.favorite == False
|
||||||
|
|
||||||
|
|
||||||
def test_hidden():
|
def test_hidden():
|
||||||
@@ -172,7 +172,7 @@ def test_hidden():
|
|||||||
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.hidden() == True
|
assert p.hidden == True
|
||||||
|
|
||||||
|
|
||||||
def test_not_hidden():
|
def test_not_hidden():
|
||||||
@@ -182,7 +182,7 @@ def test_not_hidden():
|
|||||||
photos = photosdb.photos(uuid=["6bxcNnzRQKGnK4uPrCJ9UQ"])
|
photos = photosdb.photos(uuid=["6bxcNnzRQKGnK4uPrCJ9UQ"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.hidden() == False
|
assert p.hidden == False
|
||||||
|
|
||||||
|
|
||||||
def test_location_1():
|
def test_location_1():
|
||||||
@@ -193,7 +193,7 @@ def test_location_1():
|
|||||||
photos = photosdb.photos(uuid=["3Jn73XpSQQCluzRBMWRsMA"])
|
photos = photosdb.photos(uuid=["3Jn73XpSQQCluzRBMWRsMA"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
lat, lon = p.location()
|
lat, lon = p.location
|
||||||
assert lat == pytest.approx(51.50357167)
|
assert lat == pytest.approx(51.50357167)
|
||||||
assert lon == pytest.approx(-0.1318055)
|
assert lon == pytest.approx(-0.1318055)
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ def test_location_2():
|
|||||||
photos = photosdb.photos(uuid=["YZFCPY24TUySvpu7owiqxA"])
|
photos = photosdb.photos(uuid=["YZFCPY24TUySvpu7owiqxA"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
lat, lon = p.location()
|
lat, lon = p.location
|
||||||
assert lat is None
|
assert lat is None
|
||||||
assert lon is None
|
assert lon is None
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ def test_hasadjustments1():
|
|||||||
photos = photosdb.photos(uuid=["6bxcNnzRQKGnK4uPrCJ9UQ"])
|
photos = photosdb.photos(uuid=["6bxcNnzRQKGnK4uPrCJ9UQ"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.hasadjustments() == True
|
assert p.hasadjustments == True
|
||||||
|
|
||||||
|
|
||||||
def test_hasadjustments2():
|
def test_hasadjustments2():
|
||||||
@@ -230,7 +230,7 @@ def test_hasadjustments2():
|
|||||||
photos = photosdb.photos(uuid=["15uNd7%8RguTEgNPKHfTWw"])
|
photos = photosdb.photos(uuid=["15uNd7%8RguTEgNPKHfTWw"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
assert p.hasadjustments() == False
|
assert p.hasadjustments == False
|
||||||
|
|
||||||
|
|
||||||
def test_external_edit1():
|
def test_external_edit1():
|
||||||
@@ -242,7 +242,7 @@ def test_external_edit1():
|
|||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
|
|
||||||
assert p.external_edit() == True
|
assert p.external_edit == True
|
||||||
|
|
||||||
|
|
||||||
def test_external_edit2():
|
def test_external_edit2():
|
||||||
@@ -254,7 +254,7 @@ def test_external_edit2():
|
|||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
|
|
||||||
assert p.external_edit() == False
|
assert p.external_edit == False
|
||||||
|
|
||||||
|
|
||||||
def test_path_edited1():
|
def test_path_edited1():
|
||||||
@@ -265,7 +265,7 @@ def test_path_edited1():
|
|||||||
photos = photosdb.photos(uuid=["6bxcNnzRQKGnK4uPrCJ9UQ"])
|
photos = photosdb.photos(uuid=["6bxcNnzRQKGnK4uPrCJ9UQ"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
path = p.path_edited()
|
path = p.path_edited
|
||||||
assert path.endswith("resources/media/version/00/00/fullsizeoutput_9.jpeg")
|
assert path.endswith("resources/media/version/00/00/fullsizeoutput_9.jpeg")
|
||||||
|
|
||||||
|
|
||||||
@@ -277,7 +277,7 @@ def test_path_edited2():
|
|||||||
photos = photosdb.photos(uuid=["15uNd7%8RguTEgNPKHfTWw"])
|
photos = photosdb.photos(uuid=["15uNd7%8RguTEgNPKHfTWw"])
|
||||||
assert len(photos) == 1
|
assert len(photos) == 1
|
||||||
p = photos[0]
|
p = photos[0]
|
||||||
path = p.path_edited()
|
path = p.path_edited
|
||||||
assert path is None
|
assert path is None
|
||||||
|
|
||||||
|
|
||||||
@@ -307,7 +307,7 @@ def test_keyword_not_in_album():
|
|||||||
photos2 = photosdb.photos(keywords=["Kids"])
|
photos2 = photosdb.photos(keywords=["Kids"])
|
||||||
photos3 = [p for p in photos2 if p not in photos1]
|
photos3 = [p for p in photos2 if p not in photos1]
|
||||||
assert len(photos3) == 1
|
assert len(photos3) == 1
|
||||||
assert photos3[0].uuid() == "od0fmC7NQx+ayVr+%i06XA"
|
assert photos3[0].uuid == "od0fmC7NQx+ayVr+%i06XA"
|
||||||
|
|
||||||
|
|
||||||
def test_get_db_path():
|
def test_get_db_path():
|
||||||
|
|||||||
Reference in New Issue
Block a user