-
-
Save ljm42/02b54ce9cc36f992515b to your computer and use it in GitHub Desktop.
#!/bin/bash | |
PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin | |
## Usage (after configuration): | |
## 1. Insert camera's memory card into a USB port on your unRAID system | |
## 2. The system will automatically move (or copy) any images/videos from the memory card to the array | |
## If jhead was installed, it will automatically rotate images according to the exif data | |
## 3. Wait for the imperial theme to play, then remove the memory card | |
## Preparation: | |
## 1. Install jhead (to automatically rotate photos) using the Nerd Pack plugin | |
## 2. Install the "Unassigned Devices" plugin | |
## 3. Use that plugin to set this script to run *in the background* when a memory card is inserted | |
## 4. Configure variables in this script as described below | |
## Warning: | |
## The newperms script has a bug in unRAID 6.1.3 - 6.1.7 | |
## see https://lime-technology.com/forum/index.php?topic=43388.0 | |
## --- BEGIN CONFIGURATION --- | |
## SET THIS FOR YOUR CAMERAS: | |
## array of directories under /DCIM/ that contain files you want to move (or copy) | |
## can contain regex | |
VALIDDIRS=("/DCIM/[0-9][0-9][0-9]___[0-9][0-9]" "/DCIM/[0-9][0-9][0-9]CANON" "/DCIM/[0-9][0-9][0-9]_FUJI" "/DCIM/[0-9][0-9][0-9]NIKON" \ | |
"/DCIM/[0-9][0-9][0-9]MSDCF" "/DCIM/[0-9][0-9][0-9]OLYMP" "/DCIM/[0-9][0-9][0-9]MEDIA" "/DCIM/[0-9][0-9][0-9]GOPRO" "/DCIM/[0-9][0-9][0-9]_PANA") | |
## SET THIS FOR YOUR SYSTEM: | |
## location to move files to. use date command to ensure unique dir | |
DESTINATION="/mnt/user/Photos/To Be Filed/incoming/$(date +"%Y-%m-%d-%H-%M-%S-%N")/" | |
## SET THIS FOR YOUR SYSTEM: | |
## change to "move" when you are confident everything is working | |
MOVE_OR_COPY="copy" | |
## set this to 1 and check the syslog for additional debugging info | |
DEBUG="" | |
## Available variables: | |
# AVAIL : available space | |
# USED : used space | |
# SIZE : partition size | |
# SERIAL : disk serial number | |
# ACTION : if mounting, ADD; if unmounting, REMOVE | |
# MOUNTPOINT : where the partition is mounted | |
# FSTYPE : partition filesystem | |
# LABEL : partition label | |
# DEVICE : partition device, e.g /dev/sda1 | |
# OWNER : "udev" if executed by UDEV, otherwise "user" | |
# PROG_NAME : program name of this script | |
# LOGFILE : log file for this script | |
log_all() { | |
log_local "$1" | |
logger "$PROG_NAME-$1" | |
} | |
log_local() { | |
echo "`date` $PROG_NAME-$1" | |
echo "`date` $PROG_NAME-$1" >> $LOGFILE | |
} | |
log_debug() { | |
if [ ${DEBUG} ] | |
then | |
log_local "$1" | |
fi | |
} | |
beep_imperial() { | |
for i in $(seq 1 ${1}); do | |
beep -f 392 -l 450 -r 3 -D 150 -n -f 311.13 -l 400 -D 50 \ | |
-n -f 466.16 -l 100 -D 50 -n -f 392 -l 500 -D 100 \ | |
-n -f 311.13 -l 400 -D 50 -n -f 466.16 -l 100 -D 50 \ | |
-n -f 392 -l 600 -D 600 -n -f 587.33 -l 450 -r 3 -D 150 \ | |
-n -f 622.25 -l 400 -D 50 -n -f 466.16 -l 100 -D 50 \ | |
-n -f 369.99 -l 500 -D 100 -n -f 311.13 -l 400 -D 50 \ | |
-n -f 466.16 -l 100 -D 50 -n -f 392 -l 500 -D 100 | |
sleep 2 | |
done | |
} | |
case $ACTION in | |
'ADD' ) | |
# | |
# Beep that the device is plugged in. | |
# | |
beep -l 200 -f 600 -n -l 200 -f 800 | |
sleep 2 | |
if [ -d ${MOUNTPOINT} ] | |
then | |
# only process an automount. manual mount is messy, users may or may not expect it to unmount afterwards | |
if [ "$OWNER" = "udev" ]; then | |
log_all "Started" | |
log_debug "Logging to $LOGFILE" | |
RSYNCFLAG="" | |
MOVEMSG="copying" | |
if [ ${MOVE_OR_COPY} == "move" ]; then | |
RSYNCFLAG=" --remove-source-files " | |
MOVEMSG="moving" | |
fi | |
# only operate on USB disks that contain a /DCIM directory, everything else will simply be mounted | |
if [ -d "${MOUNTPOINT}/DCIM" ]; then | |
log_debug "DCIM exists ${MOUNTPOINT}/DCIM" | |
# loop through all the subdirs in /DCIM looking for dirs defined in VALIDDIRS | |
for DIR in ${MOUNTPOINT}/DCIM/*; do | |
if [ -d "${DIR}" ]; then | |
log_debug "checking ${DIR}" | |
for element in "${VALIDDIRS[@]}"; do | |
if [[ ${DIR} =~ ${element} ]]; then | |
# process this dir | |
log_local "${MOVEMSG} ${DIR}/ to ${DESTINATION}" | |
rsync -a ${RSYNCFLAG} "${DIR}/" "${DESTINATION}" | |
# remove empty directory from memory card | |
if [ ${MOVE_OR_COPY} == "move" ]; then | |
rmdir ${DIR} | |
fi | |
fi | |
done | |
fi | |
done | |
# files were moved (or copied). rotate images, fix permissions | |
if [ -d "${DESTINATION}" ]; then | |
if [ -e "/usr/bin/jhead" -a -e "/usr/bin/jpegtran" ]; then | |
log_debug "running jhead on ${DESTINATION}" | |
jhead -autorot -ft "${DESTINATION}"*.[jJ][pP][gG] | |
fi | |
log_debug "fixing permissions on ${DESTINATION}" | |
newperms "${DESTINATION}" | |
fi | |
# sync and unmount USB drive | |
sync -f ${DESTINATION} | |
sync -f ${MOUNTPOINT} | |
sleep 1 | |
/usr/local/sbin/rc.unassigned umount $DEVICE | |
# send notification | |
beep_imperial 1 | |
/usr/local/emhttp/webGui/scripts/notify -e "unRAID Server Notice" -s "Photo Import" -d "Photo Import completed" -i "normal" | |
fi # end check for DCIM directory | |
else | |
log_all "Photo Import drive not processed, owner is $OWNER" | |
fi # end check for valid owner | |
else | |
log_all "Mountpoint doesn't exist ${MOUNTPOINT}" | |
fi # end check for valid mountpoint | |
;; | |
'REMOVE' ) | |
# | |
# Beep that the device is unmounted. | |
# | |
beep -l 200 -f 800 -n -l 200 -f 600 | |
log_all "Photo Import drive unmounted, can safely be removed" | |
;; | |
esac |
Thanks for the feedback! Wasn't sure if anyone else was using it, although it makes my life a lot easier.
I'm not sure about the directory that starts with '/MP_ROOT/', it seems like the code would skip it since it is hard coded to assume everything will start with /DCIM/. Which camera uses /MP_ROOT/, and do the files actually get copied?
Hi @ljm42, is it possible to add the Camera Make/Model as a folder in the destination? I don't know much about scripting etc. I try to get by but I would be worried about not correctly error checking it and damaging my files :)
Thank you in advance
Hmm, I don't seem to get notified when someone comments here.
This script only has access to filenames, so it wouldn't have the camera details. As written, it creates a new folder based on the current date/time so you don't have to worry much about it stomping on your existing files.
Oh maybe you mean you don't want to modify the list of VALIDDIRS. Well, the good news is that MOVE_OR_COPY is set to "copy" by default. You can try it out, and only switch it to "move" when you are confident the files are going to the right place.
@ljm42
Love your script been using it a while now. Just wanted to clarify a couple of things.
Should I be letting the script mount the SD card or should I have unassigned devices mounting the drive? Currently, I have it set to automount and the only issue I get then is that the user is "user" instead of "udev"
2. evenwebb was saying would it be possible to have folders for different cameras. A parent dir for canon, GoPro, etc. Personally, I haven't been able to come up with a way of doing that without messing things up. But I'm not the best with script work anyway.
3. Anyone that sees this comment and uses Panasonic cameras I got it to work with "/DCIM/[0-9][0-9][0-9]_PANA"
Thank you for the script! Importing pictures from my camera have never been this easy even with the weird permission issue that happens ever now and again.
You can ignore #2 you already addressed that it seems. Thanks!
mkdir -p "${DESTINATION}"
needs to be added before the rsync
line, otherwise the directory will not be created and nothing will be copied
mkdir -p "${DESTINATION}"
needs to be added before thersync
line, otherwise the directory will not be created and nothing will be copied
Ah, I could see how that would be needed if your DESTINATION directory was something was something like /incoming/year/month/ instead of /incoming/date/. rsync will create a single new directory but probably not two.
Thanks for the feedback! Wasn't sure if anyone else was using it, although it makes my life a lot easier.
I'm not sure about the directory that starts with '/MP_ROOT/', it seems like the code would skip it since it is hard coded to assume everything will start with /DCIM/. Which camera uses /MP_ROOT/, and do the files actually get copied?