Completed implementation of --jpeg-ext, fixed --dry-run, closes #330, #346

This commit is contained in:
Rhet Turnbull
2021-01-11 06:45:35 -08:00
parent 55c088eea2
commit 4d924d0826
4 changed files with 108 additions and 20 deletions

View File

@@ -1,3 +1,3 @@
""" version info """
__version__ = "0.39.14"
__version__ = "0.39.15"

View File

@@ -60,6 +60,11 @@ class FileUtilABC(ABC):
def convert_to_jpeg(cls, src_file, dest_file, compression_quality=1.0):
pass
@classmethod
@abstractmethod
def rename(cls, src, dest):
pass
class FileUtilMacOS(FileUtilABC):
""" Various file utilities """
@@ -201,6 +206,21 @@ class FileUtilMacOS(FileUtilABC):
src_file, dest_file, compression_quality=compression_quality
)
@classmethod
def rename(cls, src, dest):
""" Copy src to dest
Args:
src: path to source file
dest: path to destination file
Returns:
Name of renamed file (dest)
"""
os.rename(str(src), str(dest))
return dest
@staticmethod
def _sig(st):
""" return tuple of (mode, size, mtime) of file based on os.stat
@@ -266,3 +286,7 @@ class FileUtilNoOp(FileUtil):
@classmethod
def convert_to_jpeg(cls, src_file, dest_file, compression_quality=1.0):
cls.verbose(f"convert_to_jpeg: {src_file}, {dest_file}, {compression_quality}")
@classmethod
def rename(cls, src, dest):
cls.verbose(f"rename: {src}, {dest}")

View File

@@ -49,7 +49,7 @@ from ..photokit import (
PhotoKitFetchFailed,
PhotoLibrary,
)
from ..utils import dd_to_dms_str, findfiles, noop
from ..utils import dd_to_dms_str, findfiles, noop, get_preferred_uti_extension
class ExportError(Exception):
@@ -311,6 +311,34 @@ def _check_export_suffix(src, dest, edited):
)
# not a class method, don't import into PhotoInfo
def rename_jpeg_files(files, jpeg_ext, fileutil):
""" rename any jpeg files in files so that extension matches jpeg_ext
Args:
files: list of file paths
jpeg_ext: extension to use for jpeg files found in files, e.g. "jpg"
fileutil: a FileUtil object
Returns:
list of files with updated names
Note: If non-jpeg files found, they will be ignore and returned in the return list
"""
jpeg_ext = "." + jpeg_ext
jpegs = [".jpeg", ".jpg"]
new_files = []
for file in files:
path = pathlib.Path(file)
if path.suffix.lower() in jpegs and path.suffix != jpeg_ext:
new_file = path.parent / (path.stem + jpeg_ext)
fileutil.rename(file, new_file)
new_files.append(new_file)
else:
new_files.append(file)
return new_files
def export(
self,
dest,
@@ -749,6 +777,8 @@ def export2(
)
all_results += results
else:
# TODO: move this big if/else block to separate functions
# e.g. _export_with_photos_export or such
# use_photo_export
# export live_photo .mov file?
live_photo = True if live_photo and self.live_photo else False
@@ -763,7 +793,10 @@ def export2(
else:
# didn't get passed a filename, add _edited
filestem = f"{dest.stem}{edited_identifier}"
dest = dest.parent / f"{filestem}.jpeg"
uti = self.uti_edited if edited and self.uti_edited else self.uti
ext = get_preferred_uti_extension(uti)
dest = dest.parent / f"{filestem}{ext}"
if use_photokit:
photolib = PhotoLibrary()
photo = None
@@ -786,13 +819,17 @@ def export2(
)
)
if photo:
try:
exported = photo.export(
dest.parent, dest.name, version=PHOTOS_VERSION_CURRENT
)
all_results.exported.extend(exported)
except Exception as e:
all_results.error.append((str(dest), e))
if not dry_run:
try:
exported = photo.export(
dest.parent, dest.name, version=PHOTOS_VERSION_CURRENT
)
all_results.exported.extend(exported)
except Exception as e:
all_results.error.append((str(dest), e))
else:
# dry_run, don't actually export
all_results.exported.append(str(dest))
else:
try:
exported = _export_photo_uuid_applescript(
@@ -827,13 +864,17 @@ def export2(
photo = [p for p in bursts if p.uuid.startswith(self.uuid)]
photo = photo[0] if photo else None
if photo:
try:
exported = photo.export(
dest.parent, dest.name, version=PHOTOS_VERSION_ORIGINAL
)
all_results.exported.extend(exported)
except Exception as e:
all_results.error.append((str(dest), e))
if not dry_run:
try:
exported = photo.export(
dest.parent, dest.name, version=PHOTOS_VERSION_ORIGINAL
)
all_results.exported.extend(exported)
except Exception as e:
all_results.error.append((str(dest), e))
else:
# dry_run, don't actually export
all_results.exported.append(str(dest))
else:
try:
exported = _export_photo_uuid_applescript(
@@ -851,6 +892,13 @@ def export2(
except ExportError as e:
all_results.error.append((str(dest), e))
if all_results.exported:
if jpeg_ext:
# use_photos_export (both PhotoKit and AppleScript) don't use the
# file extension provided (instead they use extension for UTI)
# so if jpeg_ext is set, rename any non-conforming jpegs
all_results.exported = rename_jpeg_files(
all_results.exported, jpeg_ext, fileutil
)
if touch_file:
for exported_file in all_results.exported:
all_results.touched.append(exported_file)
@@ -859,9 +907,6 @@ def export2(
if update:
all_results.new.extend(all_results.exported)
# else:
# all_results.error.append((str(dest), f"Error exporting photo {self.uuid} to {dest} with use_photos_export"))
# export metadata
sidecars = []
sidecar_json_files_skipped = []
@@ -1769,3 +1814,4 @@ def _write_sidecar(self, filename, sidecar_str):
f = open(filename, "w")
f.write(sidecar_str)
f.close()

View File

@@ -107,3 +107,21 @@ def test_convert_to_jpeg_quality():
assert FileUtil.convert_to_jpeg(imgfile, outfile, compression_quality=0.1)
assert outfile.is_file()
assert outfile.stat().st_size < 1000000
def test_rename_file():
# rename file with valid src, dest
import pathlib
import tempfile
from osxphotos.fileutil import FileUtil
temp_dir = tempfile.TemporaryDirectory(prefix="osxphotos_")
src = "tests/test-images/wedding.jpg"
dest = f"{temp_dir.name}/foo.jpg"
dest2 = f"{temp_dir.name}/bar.jpg"
FileUtil.copy(src, dest)
result = FileUtil.rename(dest, dest2)
assert result
assert pathlib.Path(dest2).exists()
assert not pathlib.Path(dest).exists()