-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds --skip-dups to osxphotos import, #1264:
- Loading branch information
Showing
4 changed files
with
194 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
"""Query Photos database for photos matching fingerprint """ | ||
|
||
from __future__ import annotations | ||
|
||
import pathlib | ||
import sqlite3 | ||
|
||
from ._constants import _DB_TABLE_NAMES | ||
from .photosdb.photosdb_utils import get_photos_version_from_model | ||
|
||
|
||
class FingerprintQuery: | ||
"""Class to query Photos database for photos matching fingerprint""" | ||
|
||
def __init__(self, photos_library: str | pathlib.Path): | ||
"""Create a new FingerprintQuery object | ||
Args: | ||
photos_library: path to Photos library | ||
""" | ||
self.photos_library = ( | ||
pathlib.Path(photos_library) | ||
if not isinstance(photos_library, pathlib.Path) | ||
else photos_library | ||
) | ||
if self.photos_library.is_dir(): | ||
# assume path to root of Photos library | ||
# if not, assume it's the path to the Photos.sqlite file | ||
self.photos_library = self.photos_library / "database" / "Photos.sqlite" | ||
self.conn = sqlite3.connect(str(self.photos_library)) | ||
self.photos_version = get_photos_version_from_model(str(self.photos_library)) | ||
|
||
def photos_by_fingerprint(self, fingerprint: str) -> list[tuple[str, str]]: | ||
"""Return a list of tuples of (uuid, fingerprint) for all photos matching fingerprint""" | ||
|
||
asset_table = _DB_TABLE_NAMES[self.photos_version]["ASSET"] | ||
sql = f""" | ||
SELECT {asset_table}.ZUUID, | ||
ZADDITIONALASSETATTRIBUTES.ZORIGINALFILENAME | ||
FROM {asset_table} | ||
JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = {asset_table}.Z_PK | ||
WHERE ZADDITIONALASSETATTRIBUTES.ZMASTERFINGERPRINT = ? | ||
""" | ||
return self.conn.execute(sql, (fingerprint,)).fetchall() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
"""Sqlite3 datetime adapters; import this module to register adapters for datetime objects; | ||
these were built in before Python 3.12 but are deprecated in 3.12 """ | ||
|
||
import datetime | ||
import sqlite3 | ||
|
||
# Reference: https://docs.python.org/3/library/sqlite3.html?highlight=sqlite3#sqlite3-adapter-converter-recipes | ||
|
||
|
||
def adapt_date_iso(val): | ||
"""Adapt datetime.date to ISO 8601 date.""" | ||
return val.isoformat() | ||
|
||
|
||
def adapt_datetime_iso(val): | ||
"""Adapt datetime.datetime to timezone-naive ISO 8601 date.""" | ||
return val.isoformat() | ||
|
||
|
||
def adapt_datetime_epoch(val): | ||
"""Adapt datetime.datetime to Unix timestamp.""" | ||
return int(val.timestamp()) | ||
|
||
|
||
def convert_date(val): | ||
"""Convert ISO 8601 date to datetime.date object.""" | ||
return datetime.date.fromisoformat(val.decode()) | ||
|
||
|
||
def convert_datetime(val): | ||
"""Convert ISO 8601 datetime to datetime.datetime object.""" | ||
return datetime.datetime.fromisoformat(val.decode()) | ||
|
||
|
||
def convert_timestamp(val): | ||
"""Convert Unix epoch timestamp to datetime.datetime object.""" | ||
return datetime.datetime.fromtimestamp(int(val)) | ||
|
||
|
||
def register_adapters(): | ||
"""Register adapters for datetime objects.""" | ||
sqlite3.register_adapter(datetime.date, adapt_date_iso) | ||
sqlite3.register_adapter(datetime.datetime, adapt_datetime_iso) | ||
sqlite3.register_adapter(datetime.datetime, adapt_datetime_epoch) | ||
|
||
|
||
def register_converters(): | ||
"""Register converters for datetime objects.""" | ||
sqlite3.register_converter("date", convert_date) | ||
sqlite3.register_converter("datetime", convert_datetime) | ||
sqlite3.register_converter("timestamp", convert_timestamp) | ||
|
||
|
||
def register(): | ||
"""Register adapters and converters for datetime objects.""" | ||
register_adapters() | ||
register_converters() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters