-
Notifications
You must be signed in to change notification settings - Fork 1
/
photo-ingest.sh
executable file
·244 lines (216 loc) · 7.19 KB
/
photo-ingest.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#!/bin/bash
usage()
{
printf "Usage: $0 [-h]\n"
printf "\t-a <artist>\tname to use in copyright notices.\n"
printf "\t-c <comment>\toptional - suffix for destdir.\n"
printf "\t-d <destdir>\toptional - specify a destination directory. Defaults to PhotosTODO-YYYYmmdd.\n"
printf "\t-g grouping\toptional - 'm' or 'md'. Defaults to 'md'.\n"
printf "\t-h\t\tprint this help screen.\n"
printf "\t-s <srcdir>\tspecify source directory with images/videos.\n"
printf "\t-t <h>\t\toffset picture dates by <h> hours (int or float). +h to jump forward and -h to fall back.\n"
exit 1;
}
logD()
{
printf '%s%s%s\n' "$(tput setaf 4)" "${1:-}" "$(tput sgr0)" >&2
}
logE()
{
printf '%s%s%s\n' "$(tput setaf 1)" "${1:-}" "$(tput sgr0)" >&2
}
logI()
{
printf '%s%s%s\n' "$(tput setaf 2)" "${1:-}" "$(tput sgr0)" >&2
}
checkos()
{
if [[ "$OSTYPE" == "linux-gnu" ]]; then
return
elif [[ "$OSTYPE" == "darwin"* ]]; then
# Mac OSX
{ logE "OS $OSTYPE not supported. Aborting."; exit 1; }
elif [[ "$OSTYPE" == "cygwin" ]]; then
# POSIX compatibility layer and Linux environment emulation for Windows
{ logE "OS $OSTYPE not supported. Aborting."; exit 1; }
elif [[ "$OSTYPE" == "msys" ]]; then
# Lightweight shell and GNU utilities compiled for Windows (part of MinGW)
{ logE "OS $OSTYPE not supported. Aborting."; exit 1; }
elif [[ "$OSTYPE" == "win32" ]]; then
# I'm not sure this can happen.
{ logE "OS $OSTYPE not supported. Aborting."; exit 1; }
elif [[ "$OSTYPE" == "freebsd"* ]]; then
# ...
{ logE "OS $OSTYPE not supported. Aborting."; exit 1; }
else
# Unknown.
{ logE "Unhandled OS $OSTYPE not supported. Aborting."; exit 1; }
fi
}
prereqs()
{
checkos
REQUIREMENTS="exiftool jhead jpegtran"
for r in $REQUIREMENTS
do
# Ref: https://stackoverflow.com/questions/592620
hash $r 2>/dev/null || { logE "$r is not installed. Aborting."; exit 1; }
done
# Check mandatory arguments
[[ ! -z $srcdir ]] || { logE "srcdir not specified. Aborting."; usage; }
[[ ! -z $artist ]] || { logE "Copyright name not specified. Aborting."; usage; }
# Check source directory
[[ -d $srcdir ]] || { logE "$srcdir doesn't exist. Aborting."; exit 1; }
}
genCustomTags()
{
# The heredoc uses tabs for indents
# http://tldp.org/LDP/abs/html/here-docs.html
# https://stackoverflow.com/questions/9104706
cat > $customtags <<EOM
%Image::ExifTool::UserDefined::Options = (
# QuickTime Date/Times are in UTC
# http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=7992.0
'QuickTimeUTC' => 1,
# Needed for some MOV files
# https://sno.phy.queensu.ca/~phil/exiftool/ExifTool.html#ExtractEmbedded
'ExtractEmbedded' => 1,
);
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
CamName => {
Require => 'Model',
ValueConv => '\$val[0]',
# replace model with nickname
PrintConv => {
EOM
# https://stackoverflow.com/questions/4990575
while IFS="=" read -r key value; do
case "$key" in
'#'*);; # Skip comments
*)
printf "\t\t\t\t\t%s\n" "$key => $value," >> $customtags
esac
done < photo-ingest-deviceData.props
cat >> $customtags <<EOM
},
},
},
);
1; #end
EOM
# Remove first tab introduced as a result of indentation in heredocs above
sed -i 's/\t//1' $customtags
}
genCopyrightConfig()
{
# The heredoc *must* use tabs for all indents including the delimiter
# http://tldp.org/LDP/abs/html/here-docs.html
# https://stackoverflow.com/questions/9104706
cat > $copyrightcfg <<-EOM
-r
-P
-overwrite_original
-progress
-d
%Y
-Copyright<Copyright \$createdate, $artist. All rights reserved.
-CopyrightNotice<Copyright \$createdate, $artist. All rights reserved.
-Rights<Copyright \$createdate, $artist. All rights reserved.
-Artist=$artist
EOM
}
adjustTime()
{
if [[ -z $timeoffset ]]; then
return
fi
case "$timeoffset" in
'+'*)
# Jump forward by $timeoffset
logI "Moving forward by ${timeoffset#*+} hours in $srcdir\n"
exiftool -m -stay_open 1 -f -progress -overwrite_original -ext jpg -ext cr2 -r -P "-AllDates+=${timeoffset#*+}" $srcdir
;;
'-'*)
# Fall back by $timeoffset
logI "Falling back by ${timeoffset#*-} hours in $srcdir\n"
exiftool -m -stay_open 1 -f -progress -overwrite_original -ext jpg -ext cr2 -r -P "-AllDates-=${timeoffset#*-}" $srcdir
;;
*)
{ logE "Unsupported time offset $timeoffset. Aborting."; exit 1; }
esac
}
renameFiles()
{
logI "Renaming and copying photos from $srcdir to $destdir\n"
case "$groupby" in
m|M)
# Group by month: Example - 2019/10 - October/xxx
destGroup="$destdir/%Y/\"%m - %B\"/%Y%m%d-%H%M%S-%%f-%%.3nc-"
logD "Grouping by month: Y/m -B/Ymd-HMS-f-i\n"
;;
*)
destGroup="$destdir/%Y/%m%d/%Y%m%d-%H%M%S-%%f-%%.3nc-"
# Default to grouping by month-day: Example - 2019/1030/xxx
logD "Grouping by month-day: Y/md/Ymd-HMS-f-i\n"
;;
esac
# If a date/time tag specified by -filename doesn't exist, then the option is ignored,
# and the last one of these with a valid date/time tag will override earlier ones.
# http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=7992.0
exiftool -config $customtags -stay_open 1 -f -progress -r -P \
-ext jpg -ext cr2 -ext mov -ext mp4 \
-o $destdir/%e-files/%f/ -d $destGroup "-filename<\${FileModifyDate}\${CamName}.%le" \
"-filename<\${GPSDateTime}\${CamName}.%le" "-filename<\${MediaCreateDate}\${CamName}.%le" \
"-filename<\${DateTimeOriginal}\${CamName}.%le" "-filename<\${CreateDate}\${CamName}.%le" \
$srcdir
rm -f $customtags
}
addCopyright()
{
logI "Updating copyright information in $destdir\n"
exiftool -m -@ $copyrightcfg $destdir
rm -f $copyrightcfg
}
autoRotate()
{
logI "Rotating files in $destdir using EXIF orientation info\n"
shopt -s globstar
jhead -ft -autorot $destdir/**/*.jpg
}
main()
{
SECONDS=0
prereqs
today=$(date +%Y%m%d)
now=$(date +%Y%m%d-%H%M%S)
desktop="/home/${USER}/Desktop"
[[ -z $destdir ]] && destdir="${desktop}/PhotosTODO-${today}"
[[ ! -z $comment ]] && destdir="${destdir}-${comment}"
copyrightcfg="${destdir}/exiftool-copyright-$now.txt"
customtags="${destdir}/exiftool-customtags-$now.txt"
mkdir -p $destdir
genCopyrightConfig
genCustomTags
adjustTime
renameFiles
addCopyright
autoRotate
# https://unix.stackexchange.com/questions/27013/displaying-seconds-as-days-hours-mins-seconds
eval "echo $(date -ud "@$SECONDS" +'Time elapsed: $((%s/3600/24)) days %H hours %M mins %S secs')"
}
while getopts "a:c:d:g:hs:t:" options; do
case $options in
a) artist=$OPTARG;;
c) comment=$OPTARG;;
d) destdir=$OPTARG;;
g) groupby=$OPTARG;;
h) usage;;
s) srcdir=$OPTARG;;
t) timeoffset=$OPTARG;;
\?) usage;;
*) usage;;
esac
done
shift $((OPTIND-1))
main