Moved AppleScript to photoscript

This commit is contained in:
Rhet Turnbull 2020-11-14 13:34:50 -08:00
parent 52c054f81f
commit 3c85f26f90
6 changed files with 74 additions and 104 deletions

View File

@ -21,9 +21,10 @@ import re
import tempfile
from collections import namedtuple # pylint: disable=syntax-error
import photoscript
from mako.template import Template
from .._applescript import AppleScript
# from .._applescript import AppleScript
from .._constants import (
_MAX_IPTC_KEYWORD_LEN,
_OSXPHOTOS_NONE_SENTINEL,
@ -31,8 +32,8 @@ from .._constants import (
_UNKNOWN_PERSON,
_XMP_TEMPLATE_NAME,
)
from ..export_db import ExportDBNoOp
from ..exiftool import ExifTool
from ..export_db import ExportDBNoOp
from ..fileutil import FileUtil
from ..utils import dd_to_dms_str, findfiles
@ -78,33 +79,33 @@ def _export_photo_uuid_applescript(
"""
# setup the applescript to do the export
export_scpt = AppleScript(
"""
on export_by_uuid(theUUID, thePath, original, edited, theTimeOut)
tell application "Photos"
set thePath to thePath
set theItem to media item id theUUID
set theFilename to filename of theItem
set itemList to {theItem}
# export_scpt = AppleScript(
# """
# on export_by_uuid(theUUID, thePath, original, edited, theTimeOut)
# tell application "Photos"
# set thePath to thePath
# set theItem to media item id theUUID
# set theFilename to filename of theItem
# set itemList to {theItem}
if original then
with timeout of theTimeOut seconds
export itemList to POSIX file thePath with using originals
end timeout
end if
# if original then
# with timeout of theTimeOut seconds
# export itemList to POSIX file thePath with using originals
# end timeout
# end if
if edited then
with timeout of theTimeOut seconds
export itemList to POSIX file thePath
end timeout
end if
# if edited then
# with timeout of theTimeOut seconds
# export itemList to POSIX file thePath
# end timeout
# end if
return theFilename
end tell
# return theFilename
# end tell
end export_by_uuid
"""
)
# end export_by_uuid
# """
# )
dest = pathlib.Path(dest)
if not dest.is_dir():
@ -115,30 +116,32 @@ def _export_photo_uuid_applescript(
tmpdir = tempfile.TemporaryDirectory(prefix="osxphotos_")
# export original
exported_files = []
filename = None
try:
filename = export_scpt.call(
"export_by_uuid", uuid, tmpdir.name, original, edited, timeout
)
photo = photoscript.Photo(uuid)
filename = photo.filename
exported_files = photo.export(tmpdir.name, original=original, timeout=timeout)
# filename = export_scpt.call(
# "export_by_uuid", uuid, tmpdir.name, original, edited, timeout
# )
except Exception as e:
logging.warning(f"Error exporting uuid {uuid}: {e}")
return None
if filename is not None:
if exported_files and filename:
# need to find actual filename as sometimes Photos renames JPG to jpeg on export
# may be more than one file exported (e.g. if Live Photo, Photos exports both .jpeg and .mov)
# TemporaryDirectory will cleanup on return
filename_stem = pathlib.Path(filename).stem
files = glob.glob(os.path.join(tmpdir.name, "*"))
exported_paths = []
for fname in files:
path = pathlib.Path(fname)
if len(files) > 1 and not live_photo and path.suffix.lower() == ".mov":
for fname in exported_files:
path = pathlib.Path(tmpdir.name) / fname
if len(exported_files) > 1 and not live_photo and path.suffix.lower() == ".mov":
# it's the .mov part of live photo but not requested, so don't export
logging.debug(f"Skipping live photo file {path}")
continue
if len(files) > 1 and burst and path.stem != filename_stem:
if len(exported_files) > 1 and burst and path.stem != filename_stem:
# skip any burst photo that's not the one we asked for
logging.debug(f"Skipping burst photo file {path}")
continue

View File

@ -103,7 +103,7 @@ class PhotosDB:
# tempfile.TemporaryDirectory gets cleaned up when the object does
self._tempdir = tempfile.TemporaryDirectory(prefix="osxphotos_")
self._tempdir_name = self._tempdir.name
# set up the data structures used to store all the Photo database info
# TODO: I don't think these keywords flags are actually used
@ -266,11 +266,8 @@ class PhotosDB:
# photoanalysisd sometimes maintains this lock even after Photos is closed
# In those cases, make a temp copy of the file for sqlite3 to read
if _db_is_locked(self._dbfile):
try:
self._tmp_db = self._link_db_file(self._dbfile)
except:
verbose(f"Database locked, creating temporary copy.")
self._tmp_db = self._copy_db_file(self._dbfile)
verbose(f"Database locked, creating temporary copy.")
self._tmp_db = self._copy_db_file(self._dbfile)
self._db_version = get_db_version(self._tmp_db)
@ -285,11 +282,8 @@ class PhotosDB:
verbose(f"Processing database {self._dbfile_actual}")
# if database is exclusively locked, make a copy of it and use the copy
if _db_is_locked(self._dbfile_actual):
try:
self._tmp_db = self._link_db_file(self._dbfile_actual)
except:
verbose(f"Database locked, creating temporary copy.")
self._tmp_db = self._copy_db_file(self._dbfile_actual)
verbose(f"Database locked, creating temporary copy.")
self._tmp_db = self._copy_db_file(self._dbfile_actual)
if _debug():
logging.debug(
@ -553,31 +547,32 @@ class PhotosDB:
return dest_path
def _link_db_file(self, fname):
""" links the sqlite database file to a temp file """
""" returns the name of the temp file """
""" If sqlite shared memory and write-ahead log files exist, those are copied too """
# required because python's sqlite3 implementation can't read a locked file
# _, suffix = os.path.splitext(fname)
dest_name = dest_path = ""
try:
dest_name = pathlib.Path(fname).name
dest_path = os.path.join(self._tempdir_name, dest_name)
FileUtil.hardlink(fname, dest_path)
# link write-ahead log and shared memory files (-wal and -shm) files if they exist
if os.path.exists(f"{fname}-wal"):
FileUtil.hardlink(f"{fname}-wal", f"{dest_path}-wal")
if os.path.exists(f"{fname}-shm"):
FileUtil.hardlink(f"{fname}-shm", f"{dest_path}-shm")
except:
print("Error linking " + fname + " to " + dest_path, file=sys.stderr)
raise Exception
# NOTE: This method seems to cause problems with applescript
# Bummer...would'be been nice to avoid copying the DB
# def _link_db_file(self, fname):
# """ links the sqlite database file to a temp file """
# """ returns the name of the temp file """
# """ If sqlite shared memory and write-ahead log files exist, those are copied too """
# # required because python's sqlite3 implementation can't read a locked file
# # _, suffix = os.path.splitext(fname)
# dest_name = dest_path = ""
# try:
# dest_name = pathlib.Path(fname).name
# dest_path = os.path.join(self._tempdir_name, dest_name)
# FileUtil.hardlink(fname, dest_path)
# # link write-ahead log and shared memory files (-wal and -shm) files if they exist
# if os.path.exists(f"{fname}-wal"):
# FileUtil.hardlink(f"{fname}-wal", f"{dest_path}-wal")
# if os.path.exists(f"{fname}-shm"):
# FileUtil.hardlink(f"{fname}-shm", f"{dest_path}-shm")
# except:
# print("Error linking " + fname + " to " + dest_path, file=sys.stderr)
# raise Exception
if _debug():
logging.debug(dest_path)
return dest_path
# if _debug():
# logging.debug(dest_path)
# return dest_path
def _process_database4(self):
""" process the Photos database to extract info

View File

@ -79,6 +79,7 @@ setup(
"pathvalidate==2.2.1",
"dataclasses==0.7;python_version<'3.7'",
"wurlitzer>=2.0.1",
"photoscript>=0.1.0",
],
entry_points={"console_scripts": ["osxphotos=osxphotos.__main__:cli"]},
include_package_data=True,

View File

@ -11,9 +11,9 @@ pytestmark = pytest.mark.skipif(
PHOTOS_DB = "/Users/rhet/Pictures/Photos Library.photoslibrary"
UUID_DICT = {
"has_adjustments": "A8111956-E900-4DEC-9191-A04A87C07BC5",
"no_adjustments": "EA7BB55F-92F1-4818-94E3-E8DEDC6B2E31",
"live": "9032C168-9319-40C0-8210-5ADC42F4C603",
"has_adjustments": "2B2D5434-6D31-49E2-BF47-B973D34A317B",
"no_adjustments": "A8D646C3-89A9-4D74-8001-4EB46BA55B94",
"live": "BFF29EBD-22DF-4FCF-9817-317E7104EA50",
}

View File

@ -20,10 +20,10 @@ NAMES_DICT = {
"heic": "7783E8E6-9CAC-40F3-BE22-81FB7051C266.jpeg",
}
UUID_LIVE_HEIC = "1337F3F6-5C9F-4FC7-80CC-BD9A5B928F72"
UUID_LIVE_HEIC = "612CE30B-3D8F-417A-9B14-EC42CBA10ACC"
NAMES_LIVE_HEIC = [
"1337F3F6-5C9F-4FC7-80CC-BD9A5B928F72.jpeg",
"1337F3F6-5C9F-4FC7-80CC-BD9A5B928F72.mov",
"612CE30B-3D8F-417A-9B14-EC42CBA10ACC.jpeg",
"612CE30B-3D8F-417A-9B14-EC42CBA10ACC.mov",
]

View File

@ -1,29 +0,0 @@
""" Test PhotosDB._link_db_file """
import pytest
from tempdiskimage import TempDiskImage
PHOTOS_DB = "tests/Test-Movie-5_0.photoslibrary"
def test_link_db(capsys):
""" Test that database doesn't get copied when opened """
import osxphotos
photosdb = osxphotos.PhotosDB(dbfile=PHOTOS_DB, verbose=print)
captured = capsys.readouterr()
assert "creating temporary copy" not in captured.out
def test_copy_db(capsys):
""" Test that database does get copied if on different filesystem """
import pathlib
import tempfile
import osxphotos
from osxphotos.fileutil import FileUtil
with TempDiskImage(prefix="osxphotos") as tmpimg:
newdb = pathlib.Path(tmpimg.name) / pathlib.Path(PHOTOS_DB).name
FileUtil.copy(PHOTOS_DB,newdb)
photosdb = osxphotos.PhotosDB(dbfile=newdb, verbose=print)
captured = capsys.readouterr()
assert "creating temporary copy" in captured.out