Exposed --use-photos-export and --use-photokit
This commit is contained in:
10
README.md
10
README.md
@@ -356,6 +356,16 @@ Options:
|
||||
to a filesystem that doesn't support Mac OS
|
||||
extended attributes. Only use this if you
|
||||
get an error while exporting.
|
||||
--use-photos-export Force the use of AppleScript or PhotoKit to
|
||||
export even if not missing (see also '--
|
||||
download-missing' and '--use-photokit').
|
||||
--use-photokit Use with '--download-missing' or '--use-
|
||||
photos-export' to use direct Photos
|
||||
interface instead of AppleScript to export.
|
||||
Highly experimental alpha feature; does not
|
||||
work with iTerm2 (use with Terminal.app).
|
||||
This is faster and more reliable than the
|
||||
default AppleScript interface.
|
||||
-h, --help Show this message and exit.
|
||||
|
||||
** Export **
|
||||
|
||||
@@ -28,6 +28,7 @@ from .export_db import ExportDB, ExportDBInMemory
|
||||
from .fileutil import FileUtil, FileUtilNoOp
|
||||
from .path_utils import is_valid_filepath, sanitize_filename, sanitize_filepath
|
||||
from .photoinfo import ExportResults
|
||||
from .photokit import check_photokit_authorization, request_photokit_authorization
|
||||
from .phototemplate import TEMPLATE_SUBSTITUTIONS, TEMPLATE_SUBSTITUTIONS_MULTI_VALUED
|
||||
|
||||
# global variable to control verbose output
|
||||
@@ -1394,15 +1395,15 @@ def query(
|
||||
"--use-photos-export",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
hidden=True,
|
||||
help="Force the use of AppleScript to export even if not missing (see also --download-missing).",
|
||||
help="Force the use of AppleScript or PhotoKit to export even if not missing (see also '--download-missing' and '--use-photokit').",
|
||||
)
|
||||
@click.option(
|
||||
"--use-photokit",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
hidden=True,
|
||||
help="Use PhotoKit interface instead of AppleScript to export. Highly experimental alpha feature.",
|
||||
help="Use with '--download-missing' or '--use-photos-export' to use direct Photos interface instead of AppleScript to export. "
|
||||
"Highly experimental alpha feature; does not work with iTerm2 (use with Terminal.app). "
|
||||
"This is faster and more reliable than the default AppleScript interface.",
|
||||
)
|
||||
@DB_ARGUMENT
|
||||
@click.argument("dest", nargs=1, type=click.Path(exists=True))
|
||||
@@ -1545,6 +1546,18 @@ def export(
|
||||
click.echo(cli.commands["export"].get_help(ctx), err=True)
|
||||
return
|
||||
|
||||
if use_photokit and not check_photokit_authorization():
|
||||
click.echo(
|
||||
"Requesting access to use your Photos library. Click 'OK' on the dialog box to grant access."
|
||||
)
|
||||
request_photokit_authorization()
|
||||
click.confirm("Have you granted access?")
|
||||
if not check_photokit_authorization():
|
||||
click.echo(
|
||||
"Failed to get access to the Photos library which is needed with `--use-photokit`."
|
||||
)
|
||||
return
|
||||
|
||||
# initialize export flags
|
||||
# by default, will export all versions of photos unless skip flag is set
|
||||
(export_edited, export_bursts, export_live, export_raw) = [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
""" version info """
|
||||
|
||||
__version__ = "0.36.20"
|
||||
__version__ = "0.36.21"
|
||||
|
||||
|
||||
@@ -80,6 +80,58 @@ def path_to_NSURL(path):
|
||||
return url
|
||||
|
||||
|
||||
def check_photokit_authorization():
|
||||
""" Check authorization to use user's Photos Library
|
||||
|
||||
Returns:
|
||||
True if user has authorized access to the Photos library, otherwise False
|
||||
"""
|
||||
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
return auth_status == Photos.PHAuthorizationStatusAuthorized
|
||||
|
||||
|
||||
def request_photokit_authorization():
|
||||
""" Request authorization to user's Photos Library
|
||||
|
||||
Returns:
|
||||
authorization status
|
||||
|
||||
Note: In actual practice, the terminal process running the python code
|
||||
will do the actual request.
|
||||
"""
|
||||
|
||||
(_, major, _) = _get_os_version()
|
||||
|
||||
def handler(status):
|
||||
pass
|
||||
|
||||
auth_status = 0
|
||||
if int(major) < 16:
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
if auth_status != Photos.PHAuthorizationStatusAuthorized:
|
||||
# it seems the first try fails after Terminal prompts user for access so try again
|
||||
for _ in range(2):
|
||||
Photos.PHPhotoLibrary.requestAuthorization_(handler)
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
if auth_status == Photos.PHAuthorizationStatusAuthorized:
|
||||
break
|
||||
else:
|
||||
# requestAuthorization deprecated in 10.16/11.0
|
||||
# but requestAuthorizationForAccessLevel not yet implemented in pyobjc (will be in ver 7.0)
|
||||
# https://developer.apple.com/documentation/photokit/phphotolibrary/3616053-requestauthorizationforaccesslev?language=objc
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
if auth_status != Photos.PHAuthorizationStatusAuthorized:
|
||||
# it seems the first try fails after Terminal prompts user for access so try again
|
||||
for _ in range(2):
|
||||
Photos.PHPhotoLibrary.requestAuthorization_(handler)
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
if auth_status == Photos.PHAuthorizationStatusAuthorized:
|
||||
break
|
||||
|
||||
return auth_status
|
||||
|
||||
|
||||
### exceptions
|
||||
class PhotoKitError(Exception):
|
||||
"""Base class for exceptions in this module. """
|
||||
@@ -1051,12 +1103,6 @@ class PhotoLibrary:
|
||||
# get image manager and request options
|
||||
self._phimagemanager = Photos.PHCachingImageManager.defaultManager()
|
||||
|
||||
def _auth_status(self, status):
|
||||
""" Handler for requestAuthorization_ """
|
||||
# This doesn't actually get called but requestAuthorization needs a callable handler
|
||||
# The Terminal will handle the actual authorization when called
|
||||
pass
|
||||
|
||||
def request_authorization(self):
|
||||
""" Request authorization to user's Photos Library
|
||||
|
||||
@@ -1064,33 +1110,8 @@ class PhotoLibrary:
|
||||
authorization status
|
||||
"""
|
||||
|
||||
(_, major, _) = _get_os_version()
|
||||
|
||||
auth_status = 0
|
||||
if int(major) < 16:
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
if auth_status != Photos.PHAuthorizationStatusAuthorized:
|
||||
# it seems the first try fails after Terminal prompts user for access so try again
|
||||
for _ in range(2):
|
||||
Photos.PHPhotoLibrary.requestAuthorization_(self._auth_status)
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
if auth_status == Photos.PHAuthorizationStatusAuthorized:
|
||||
break
|
||||
else:
|
||||
# requestAuthorization deprecated in 10.16/11.0
|
||||
# but requestAuthorizationForAccessLevel not yet implemented in pyobjc (will be in ver 7.0)
|
||||
# https://developer.apple.com/documentation/photokit/phphotolibrary/3616053-requestauthorizationforaccesslev?language=objc
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
if auth_status != Photos.PHAuthorizationStatusAuthorized:
|
||||
# it seems the first try fails after Terminal prompts user for access so try again
|
||||
for _ in range(2):
|
||||
Photos.PHPhotoLibrary.requestAuthorization_(self._auth_status)
|
||||
auth_status = Photos.PHPhotoLibrary.authorizationStatus()
|
||||
if auth_status == Photos.PHAuthorizationStatusAuthorized:
|
||||
break
|
||||
|
||||
self.auth_status = auth_status
|
||||
return auth_status
|
||||
self.auth_status = request_photokit_authorization()
|
||||
return self.auth_status
|
||||
|
||||
def fetch_uuid_list(self, uuid_list):
|
||||
""" fetch PHAssets with uuids in uuid_list
|
||||
|
||||
Reference in New Issue
Block a user