#!/bin/sh # # copy-camera-media - copy images and videos off Bien's Olympus and HTC # # $Id$ # written to be called automatically when a camera or phone is plugged in, # but it can also copy files from directories supplied as arguments PATH=/usr/local/bin:/usr/bin:/bin export PATH Die() { echo $0: fatal error: $@ 1>&2 exit 1 } DieIfMissing() { for x in "$@" do type "$x" >/dev/null || Die missing executable $x done } DieIfMissing exiftool rsync # parse the command line: command [-options] [sourcedir] [destdir] rsyncopts= while : do case "$1" in -*|--*) rsyncopts="$rsyncopts $1" shift ;; *) break ;; esac done # default source directory [ $# -eq 0 ] && set /media [ -d "$1" ] || Die cannot find source directory $1 # default destination directory if [ $# -eq 1 ] then HOME=`getent passwd "$me" | awk -F: '{print $6}'` [ -d "$HOME" ] || Die cannot find home directory $HOME set "$1" $HOME/Pictures fi [ -d "$2" ] || Die cannot find destination directory $2 # we may be started automatically as root # in which case we want to execute the real work # as the user who actually owns the pictures # convention: if $OWNER is set, it is the user in question; # if not, we scan all picture owners and reexecute as them me=`id -nu` case "$OWNER" in "$me") ;; '') find "$@" -type f \ -exec exiftool -if '!defined ${Error}' -p '${Directory}/${FileName}' '{}' + 2>/dev/null | perl -lne '$seen{$_}++ or print' | # why is this necessary? perl -lne ' my $o = (stat($_))[4] // next; my @u = getpwuid($o) or next; my $o = $u[0] or next; # never run as unknown user or root $seen{$o}++ or print $o # deduplicate ' | while read ownerid do owner=`getent passwd $ownerid | awk -F: '{print $1}'` case "$owner" in "$me") exec env OWNER=$owner PATH=$PATH "$0" $rsyncopts "$@";; *) exec sudo -u $owner env OWNER=$owner PATH=$PATH "$0" $rsyncopts "$@";; esac done exit $? ;; *) if getent passwd "$OWNER" >/dev/null then sudo -u $OWNER env OWNER=$OWNER PATH=$PATH "$0" $rsyncopts "$@" exit $? else Die cannot execute as $OWNER fi ;; esac #echo executing as $me find "$1" -type f -user "$me" \ -exec exiftool -if '!defined ${Error}' -p '${Directory}/${FileName}' '{}' + 2>/dev/null | while IFS= read -r f do exiftool -q -d '%Y %m' -p '${filemodifydate} XXX ${model} XXX ${software}' "$f" 2>/dev/null | perl -wlpe ' my ($date, $model, $software) = split(/ XXX /); warn "date: $date, camera model: $model, software: $software\n"; $date =~ s# 0[1-6]#-helft1# or $date =~ s# [01]\d#-helft2#; if ($model eq "HTC Desire") # matches Bien"s HTC { $model = "HTC" # for backward compatibility only } elsif ($model eq "C765UZ") # matches Bien"s Olympus { $model = "Olympus" # for backward compatibility only } elsif ($model =~ /^VG\w+/) # matches the *.JPG on Reinier"s Olympus VG-150 { $model = "Olympus $&" } elsif ($model =~ /^Unknown/ && $software =~ /^OLYMPUS (\w+)/) # matches the *.AVI on Reinier"s Olympus VG-150 (seriously!) { $model = "Olympus $1" } elsif (!$model && $software =~ /MediaTek/) # matches Reinier"s Acer X220 # this heuristic should be smarter { $model = "Acer Z220" } elsif (!$model) { #warn "unspecified, unguessed camera model\n"; $model = "unknown" } $model =~ s#\s+##g; $_ = sprintf("%s-%s", $date, $model); warn "semester: $date, adjusted camera model: $model, software: $software\n"; #warn "dir: $_\n"; ' | while read reltgtdir do M=${T}/$reltgtdir [ -d "$M" ] || mkdir "$M" || continue echo rsync -a $rsyncopts "$f" "$M/" rsync -a $rsyncopts "$f" "$M/" done done