If wasn’t simple , but I found a Python library called osxphotos for working with the Photos Library. Python is my language of choice, so this was a good find.
It does take several seconds to run, so if I dumped a large number of images into my downloads folder, it could take a while to process them. But, I had my photo import rule turned off for months because of this issue. So I think it’s a good tradeoff.
In Hazel, I used the “Passes shell script” condition to run my script that returns 0 if the file is in the library, 1 if it is not.
Hazel Rules
Rule #1 If image file is older than 1 day and in photo library, move to Trash folder.
Rule #2 If image file is older than 1 day, import into Photos and move to backup images library folder on NAS.
Shell Script
#!/bin/bash
DIR=“$( cd “$( dirname “${BASH_SOURCE[0]}” )” >/dev/null 2>&1 && pwd )”
PROJECTDIR=$(dirname $DIR)
LOGFILE=“${PROJECTDIR}/output.log”
FILENAME=$(basename ${1})
echo “Running script $0 with arguments ${@}” # >> “${LOGFILE}” 2>&1
source $PROJECTDIR/venv/bin/activate
python $PROJECTDIR/photos_utils/image_exists.py --image_name ${FILENAME} # >> “${LOGFILE}” 2>&1
RC=$?
echo “Return code is ${RC}” # >> “${LOGFILE}” # 2>&1
echo " " #>> “${LOGFILE}” 2>&1
echo " " #>> “${LOGFILE}” 2>&1
deactivate
exit $RC
Python Script
import re
import sys
import time
import osxphotos
import argparse
from datetime import datetime
def create_arguments():
parser = argparse.ArgumentParser(description='Returns 0 if image file exists in Photos Library. Else returns 1.')
parser.add_argument('--image_name', action='store', dest='image_name',required=True, help='Name of image file')
return parser.parse_args()
def main():
args = create_arguments()
photosdb = osxphotos.PhotosDB()
results = [ photo for photo in photosdb.photos( movies=False, images=True ) if photo.original_filename == args.image_name ]
if results:
print("File exists in library")
return 0
else:
print("File does not exist in library")
return 1
# print(results)
return
if __name__ == "__main__":
start_time = datetime.now()
results = main()
print(f"Script completed in {(datetime.now() - start_time).seconds} seconds.")
sys.exit(results)
Note that Python is running in a virtual environment(venv act/deact lines ) atm. I’ll eventually change that.