This commit is contained in:
Rhet Turnbull 2021-05-28 08:48:21 -07:00
parent b026147c9a
commit 2d68594b78
5 changed files with 38 additions and 26 deletions

View File

@ -1,3 +1,3 @@
""" version info """
__version__ = "0.42.25"
__version__ = "0.42.26"

View File

@ -23,12 +23,14 @@ EXIFTOOL_STAYOPEN_EOF_LEN = len(EXIFTOOL_STAYOPEN_EOF)
# list of exiftool processes to cleanup when exiting or when terminate is called
EXIFTOOL_PROCESSES = []
@atexit.register
def terminate_exiftool():
"""Terminate any running ExifTool subprocesses; call this to cleanup when done using ExifTool """
for proc in EXIFTOOL_PROCESSES:
proc._stop_proc()
@lru_cache(maxsize=1)
def get_exiftool_path():
""" return path of exiftool, cache result """
@ -70,15 +72,14 @@ class _ExifToolProc:
self._exiftool = exiftool or get_exiftool_path()
self._start_proc()
EXIFTOOL_PROCESSES.append(self)
@property
def process(self):
""" return the exiftool subprocess """
if self._process_running:
return self._process
else:
raise ValueError("exiftool process is not running")
self._start_proc()
return self._process
@property
def pid(self):
@ -116,15 +117,21 @@ class _ExifToolProc:
)
self._process_running = True
EXIFTOOL_PROCESSES.append(self)
def _stop_proc(self):
""" stop the exiftool process if it's running, otherwise, do nothing """
if not self._process_running:
return
self._process.stdin.write(b"-stay_open\n")
self._process.stdin.write(b"False\n")
self._process.stdin.flush()
try:
self._process.stdin.write(b"-stay_open\n")
self._process.stdin.write(b"False\n")
self._process.stdin.flush()
except Exception as e:
pass
try:
self._process.communicate(timeout=5)
except subprocess.TimeoutExpired:
@ -134,9 +141,6 @@ class _ExifToolProc:
del self._process
self._process_running = False
def __del__(self):
self._stop_proc()
class ExifTool:
""" Basic exiftool interface for reading and writing EXIF tags """
@ -162,9 +166,12 @@ class ExifTool:
# if running as a context manager, self._context_mgr will be True
self._context_mgr = False
self._exiftoolproc = _ExifToolProc(exiftool=exiftool)
self._process = self._exiftoolproc.process
self._read_exif()
@property
def _process(self):
return self._exiftoolproc.process
def setvalue(self, tag, value):
"""Set tag to value(s); if value is None, will delete tag

View File

@ -3,9 +3,10 @@ import os
import pathlib
import pytest
from applescript import AppleScript
from photoscript.utils import ditto
import osxphotos
from applescript import AppleScript
from osxphotos.exiftool import _ExifToolProc
@ -63,7 +64,9 @@ def pytest_collection_modifyitems(config, items):
# --addalbum given in cli: do not skip addalbum tests (these require interactive test)
return
skip_addalbum = pytest.mark.skip(reason="need --addalbum option and MacOS Catalina to run")
skip_addalbum = pytest.mark.skip(
reason="need --addalbum option and MacOS Catalina to run"
)
for item in items:
if "addalbum" in item.keywords:
item.add_marker(skip_addalbum)

View File

@ -34,9 +34,9 @@ UUID_BURST_ALBUM = {
"TestBurst2/IMG_9814.JPG",
],
"38F8F30C-FF6D-49DA-8092-18497F1D6628": [
"TestBurst/IMG_9812.JPG",
"TestBurst/IMG_9812.JPG",
"TestBurst/IMG_9813.JPG",
"TestBurst/IMG_9814.JPG", # in my personal library, "38F8F30C-FF6D-49DA-8092-18497F1D6628"
"TestBurst/IMG_9814.JPG", # in my personal library, "38F8F30C-FF6D-49DA-8092-18497F1D6628"
"TestBurst/IMG_9815.JPG",
"TestBurst/IMG_9816.JPG",
"TestBurst2/IMG_9814.JPG",
@ -1229,16 +1229,12 @@ def test_export_exiftool_path():
import shutil
import tempfile
from osxphotos.cli import export
from osxphotos.exiftool import ExifTool, get_exiftool_path
from osxphotos.exiftool import ExifTool
runner = CliRunner()
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
tempdir = tempfile.TemporaryDirectory()
exiftool_source = get_exiftool_path()
exiftool_path = os.path.join(tempdir.name, "myexiftool")
shutil.copy2(exiftool_source, exiftool_path)
for uuid in CLI_EXIFTOOL:
result = runner.invoke(
export,
@ -1250,11 +1246,11 @@ def test_export_exiftool_path():
"--uuid",
f"{uuid}",
"--exiftool-path",
exiftool_path,
exiftool,
],
)
assert result.exit_code == 0
assert f"exiftool path: {exiftool_path}" in result.output
assert f"exiftool path: {exiftool}" in result.output
files = glob.glob("*")
assert sorted(files) == sorted([CLI_EXIFTOOL[uuid]["File:FileName"]])
@ -1290,9 +1286,6 @@ def test_export_exiftool_path_render_template():
cwd = os.getcwd()
# pylint: disable=not-context-manager
with runner.isolated_filesystem():
tempdir = tempfile.TemporaryDirectory()
exiftool_path = os.path.join(tempdir.name, "myexiftool")
shutil.copy2(exiftool_source, exiftool_path)
for uuid in CLI_EXIFTOOL:
result = runner.invoke(
export,
@ -1305,7 +1298,7 @@ def test_export_exiftool_path_render_template():
"--uuid",
f"{uuid}",
"--exiftool-path",
exiftool_path,
exiftool,
],
)
assert result.exit_code == 0

View File

@ -425,8 +425,17 @@ def test_exiftool_terminate():
import subprocess
exif1 = osxphotos.exiftool.ExifTool(TEST_FILE_ONE_KEYWORD)
ps = subprocess.run(["ps"], capture_output=True)
stdout = ps.stdout.decode("utf-8")
assert "exiftool -stay_open" in stdout
osxphotos.exiftool.terminate_exiftool()
ps = subprocess.run(["ps"], capture_output=True)
stdout = ps.stdout.decode("utf-8")
assert "exiftool -stay_open" not in stdout
# verify we can create a new instance after termination
exif2 = osxphotos.exiftool.ExifTool(TEST_FILE_ONE_KEYWORD)
assert exif2.asdict()["IPTC:Keywords"] == "wedding"