From 326f2aa44d9f1ef6b48c16d0c408a4fb16081d4b Mon Sep 17 00:00:00 2001 From: CroneKorkN Date: Sat, 7 Mar 2026 11:37:49 +0100 Subject: [PATCH] parallel picsort --- .../nextcloud-picsort/files/nextcloud-picsort | 120 +++++++++++------- 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/bundles/nextcloud-picsort/files/nextcloud-picsort b/bundles/nextcloud-picsort/files/nextcloud-picsort index a204553..c55b9df 100644 --- a/bundles/nextcloud-picsort/files/nextcloud-picsort +++ b/bundles/nextcloud-picsort/files/nextcloud-picsort @@ -1,70 +1,101 @@ #!/bin/bash +set -euo pipefail -USER="$1" +if [[ $# -ne 4 ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi -REL_SOURCE_PATH="/$1/files/$2" -ABS_SOURCE_PATH="/var/lib/nextcloud/$1/files/$2" +NC_USER="$1" +SOURCE_SUBDIR="$2" +DEST_SUBDIR="$3" +UNSORTABLE_SUBDIR="$4" -REL_DEST_PATH="/$1/files/$3" -ABS_DEST_PATH="/var/lib/nextcloud/$1/files/$3" +REL_SOURCE_PATH="/$NC_USER/files/$SOURCE_SUBDIR" +ABS_SOURCE_PATH="/var/lib/nextcloud/$NC_USER/files/$SOURCE_SUBDIR" -REL_UNSORTABLE_PATH="/$1/files/$4" -ABS_UNSORTABLE_PATH="/var/lib/nextcloud/$1/files/$4" +REL_DEST_PATH="/$NC_USER/files/$DEST_SUBDIR" +ABS_DEST_PATH="/var/lib/nextcloud/$NC_USER/files/$DEST_SUBDIR" + +REL_UNSORTABLE_PATH="/$NC_USER/files/$UNSORTABLE_SUBDIR" +ABS_UNSORTABLE_PATH="/var/lib/nextcloud/$NC_USER/files/$UNSORTABLE_SUBDIR" echo "STARTING..." chown -R www-data:www-data "$ABS_SOURCE_PATH" chmod -R 770 "$ABS_SOURCE_PATH" -SCAN="FALSE" -IFS=$'\n' -for f in `find "$ABS_SOURCE_PATH" -iname *.PNG -o -iname *.JPG -o -iname *.JPEG -o -iname *.HEIC -o -iname *.CR2 -o -iname *.CR3 -o -iname *.MP4 -o -iname *.MOV`; do - SCAN="TRUE" +process_file() { + local f="$1" + local DATETIME DATE TIME YEAR MONTH DAY HOUR MINUTE SECOND HASH EXT RAW FILE RELPATH DIRNAME + echo "PROCESSING: $f" - EXIF=`exiftool "$f"` - if grep -q '^Create Date' <<< $EXIF - then - DATETIME=`grep -m 1 "^Create Date" <<< $EXIF | cut -d: -f2- | xargs` - elif grep -q '^File Modification Date' <<< $EXIF - then - DATETIME=`grep -m 1 '^File Modification Date' <<< $EXIF | cut -d: -f2- | xargs` - else - RELPATH=$(realpath --relative-to="$ABS_SOURCE_PATH" "$f") - DIRNAME=$(dirname "$ABS_UNSORTABLE_PATH/$RELPATH") - echo "UNSORTABLE: $f" - mkdir -p "$DIRNAME" - mv "$f" "$DIRNAME" - continue + DATETIME="$( + exiftool -s -s -s -CreateDate "$f" 2>/dev/null | head -n1 + )" + + if [[ -z "$DATETIME" ]]; then + DATETIME="$( + exiftool -s -s -s -FileModifyDate "$f" 2>/dev/null | head -n1 | cut -d'+' -f1 | cut -d'-' -f1 + )" fi - DATE=`cut -d' ' -f1 <<< $DATETIME` - TIME=`cut -d' ' -f2 <<< $DATETIME | cut -d'+' -f1` + if [[ -z "$DATETIME" ]]; then + RELPATH="$(realpath --relative-to="$ABS_SOURCE_PATH" "$f")" + DIRNAME="$(dirname "$ABS_UNSORTABLE_PATH/$RELPATH")" + echo "UNSORTABLE: $f" + mkdir -p "$DIRNAME" + mv -n -- "$f" "$DIRNAME/" + return 0 + fi - YEAR=`cut -d':' -f1 <<< $DATE` - MONTH=`cut -d':' -f2 <<< $DATE` - DAY=`cut -d':' -f3 <<< $DATE` - HOUR=`cut -d':' -f1 <<< $TIME` - MINUTE=`cut -d':' -f2 <<< $TIME` - SECOND=`cut -d':' -f3 <<< $TIME` + DATE="$(cut -d' ' -f1 <<< "$DATETIME")" + TIME="$(cut -d' ' -f2 <<< "$DATETIME" | cut -d'+' -f1)" - HASH=`sha256sum "$f" | xxd -r -p | base64 | head -c 3 | tr '/+' '_-'` - EXT=`echo "${f##*.}" | tr '[:upper:]' '[:lower:]'` - if [[ "$EXT" = "cr2" ]] || [[ "$EXT" = "cr3" ]] - then + YEAR="$(cut -d':' -f1 <<< "$DATE")" + MONTH="$(cut -d':' -f2 <<< "$DATE")" + DAY="$(cut -d':' -f3 <<< "$DATE")" + HOUR="$(cut -d':' -f1 <<< "$TIME")" + MINUTE="$(cut -d':' -f2 <<< "$TIME")" + SECOND="$(cut -d':' -f3 <<< "$TIME")" + + HASH="$(sha256sum "$f" | awk '{print $1}' | xxd -r -p | base64 | head -c 6 | tr '/+' '_-')" + EXT="$(tr '[:upper:]' '[:lower:]' <<< "${f##*.}")" + + if [[ "$EXT" == "cr2" || "$EXT" == "cr3" ]]; then RAW="raw/" else RAW="" fi - FILE="$ABS_DEST_PATH/$YEAR-$MONTH/$RAW$YEAR$MONTH$DAY"-"$HOUR$MINUTE$SECOND"_"$HASH"."$EXT" + + FILE="$ABS_DEST_PATH/$YEAR-$MONTH/${RAW}${YEAR}${MONTH}${DAY}-${HOUR}${MINUTE}${SECOND}_${HASH}.${EXT}" echo "DESTINATION: $FILE" mkdir -p "$(dirname "$FILE")" - mv -v "$f" "$FILE" -done + mv -- "$f" "$FILE" +} + +mapfile -d '' -t FILES < <( + find "$ABS_SOURCE_PATH" -type f \( \ + -iname '*.PNG' -o \ + -iname '*.JPG' -o \ + -iname '*.JPEG' -o \ + -iname '*.HEIC' -o \ + -iname '*.CR2' -o \ + -iname '*.CR3' -o \ + -iname '*.MP4' -o \ + -iname '*.MOV' \ + \) -print0 +) + +if ((${#FILES[@]})); then + export -f process_file + export ABS_SOURCE_PATH ABS_DEST_PATH ABS_UNSORTABLE_PATH + + printf '%s\0' "${FILES[@]}" | + xargs -0 -n1 -P"$(nproc)" bash -c 'process_file "$1"' _ -if [ "$SCAN" == "TRUE" ]; then echo "SCANNING..." - # find "$ABS_SOURCE_PATH/"* -type d -empty -delete >> /var/echo/nc-picsort.echo # nextcloud app bug when deleting folders chown -R www-data:www-data "$ABS_DEST_PATH" chown -R www-data:www-data "$ABS_UNSORTABLE_PATH" chmod -R 770 "$ABS_DEST_PATH" @@ -72,7 +103,8 @@ if [ "$SCAN" == "TRUE" ]; then sudo -u www-data php /opt/nextcloud/occ files:scan --path "$REL_SOURCE_PATH" sudo -u www-data php /opt/nextcloud/occ files:scan --path "$REL_UNSORTABLE_PATH" sudo -u www-data php /opt/nextcloud/occ files:scan --path "$REL_DEST_PATH" - #sudo -u www-data php /opt/nextcloud/occ preview:pre-generate +else + echo "NO MATCHING FILES FOUND." fi -echo "FINISH." +echo "FINISH." \ No newline at end of file