[home]

Monitoring Photo Uploads with inotifywait

photo organization

I wanted a way to easily and automatically organize my photos upon upload to my server. I have been using an exiftool command to organize based on dateTime data into folders like:

YYYY/
    MM/
      DD/
        year_month_day_hr-min-s-CameraModel.ext

I realize this is a lot, but this way I can know all about when the photo was taken if the metadata gets changed and without having to open the photo. Well, provided that the metadata is properly read and preserved for the first organization.

This is the command I use on a directory or a single file. It's a bit of an eyesore.

  exiftool -ext+ AVI -v0 -P -m -r \
    '-Directory<'"$DEST"'${dateTimeOriginal#;DateFmt("%Y/%m/%d")}' \
    '-Filename<${dateTimeOriginal#;DateFmt("%Y_%m_%d_%H-%M-%S")}_${Model}%-c.${FileTypeExtension}' \
    "$source_dir"

what I want to change

Running this command to move files from an Import Dir to my NAS storage works totally fine and is a great option, so naturally I had to mess with it. I wanted the script to automatically run when I moved files into an Import Dir. I could have used cron to just schedule the task for every-so-often but for some reason that just didn't feel right in my head. So instead I ended up messing with inotifywait to create a solution that I was happy with, and one that felt like an upgrade from cron.

the monitoring script

cron really is the simpler option to just have the script run every so often and move and files from Here to There. But I wanted to experiment with inotifywait and watch the directory for file events. I ended up with this implementation:

while true; do
    # file create triggers wakeup/removes blocking
    inotifywait -e create "$SRC"

    # wait again to see when file creation and modification stops
    inotifywait -e create -e modify -t 60 -m "$SRC"

    process_dir "$SRC" "$DEST"

    immich_scan_library

done
  1. inotifywait for a CREATE event in the Import Dir. Once it receives an event it moves on.
  2. inotifywait again for any CREATE or MODIFY events (i.e. events that occur during file transfer) but this time, only move on after no events are received for 60 seconds. Use -m to continuously monitor for events, and -t to set the timeout length. In a sense we use this inotifywait call as a keepalive so we can make sure the process has ended. I originally tried just using one inotifywait call and process individual files as they came in but 1: that was a bit slower to process files and 2: using something like rsync, which transfers in chunks and renames files, causes issues with processing on a file. It was better to just find a way to wait to ensure that the transfer was done and then process the whole directory. 60 seconds was chosen arbitrarily but I think it's a good middle ground of wait time. I'm leaning toward making it shorter because MODIFY events help ensure the timeout countdown restarts.
  3. process the directory with the exiftool command
  4. POST to the Immich API to initiate a library scan

Full source available here.

Overall this was a very fun exercise in using inotifywait to fit my very specific preference, and I am happy with the result. I made this into a systemd service, and it seems to be working how I want! Now I can upload from any of my devices and it will process my files once they land in the Import Directory.