-
Notifications
You must be signed in to change notification settings - Fork 0
/
cvccommit
executable file
·304 lines (257 loc) · 10.8 KB
/
cvccommit
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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#!/bin/bash
################################################################################
# Loading configuration
################################################################################
CVCINTERNAL_SCRIPTROOT=$(dirname "$0")
source "${CVCINTERNAL_SCRIPTROOT}/config"
################################################################################
# Documentation
################################################################################
# Return code reference
# 1 Syntax error in invocation
# 2 Missing argument
# 3 Target CVC file does not exist
# 4 Related audio file does not exist
# 5 Error during CVC expansion: cvcexpand returned an error
# 6 metaflac couldn't remove current tags from the audio file
# 7 metaflac couldn't import new tags to the audio file
# 8 metaflac couldn't remove embedded pictures from the audio file
# 9 metaflac couldn't embed a picture into an audio file
# 16 Internal error
# Show usage
function usage {
echo "This command updates Vorbis Comments within FLAC files. It expands a CVC file"
echo "to Vorbis Comments using cvcexpand, stores the resulting tags to a companion"
echo "file with the .tags extension, then updates the actual audio file using"
echo "metaflac. On-disk updates are only performed when needed."
echo ""
echo "Usage: cvccommit [-f] [-h] [-l <lang>] [-v] <file>"
echo ""
echo "Options:"
echo "-f Force the script to perform on-disk updates, even if it seems"
echo " not necessary".
echo "-h Show this message."
echo "-l <lang> Specify a language filter (cvcexpand -l option)."
echo "-v Verbose mode."
echo ""
echo "Arguments:"
echo "<file> A text file with CVC content."
}
################################################################################
# Option and argument parsing
################################################################################
# Default values
cvcexpandExtraArgs=""
# Calling option parser
while getopts ":fhl:v" option; do
case "${option}" in
# -f: Force mode
f)
OPT_Force=1
;;
# -h: Help
h)
usage
exit
;;
# -l: Language filter
l)
cvcexpandExtraArgs+="-l ${OPTARG}"
;;
# -v: Verbose mode
v)
OPT_Verbose=1
;;
# Syntax error
\?)
>&2 echo "ERROR: Invalid option: -${OPTARG}"
usage
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 1 || exit 1
;;
# Syntax error
:)
>&2 echo "ERROR: Option -${OPTARG} requires an argument."
usage
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 1 || exit 1
;;
# Any other value is an internal error
*)
>&2 echo "ERROR: Internal getopts error."
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 16 || exit 16
;;
esac
done
shift $((OPTIND-1))
# Checking whether a CVC file was supplied as an argument.
if [ -z "$1" ]
then
>&2 echo "ERROR: No CVC file was specified."
usage
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 2 || exit 2
fi
################################################################################
# Additional checks
################################################################################
# Abstracting supplied arguments
targetCVCFile="$1"
# Checking whether the supplied CVC file does exist
if [ ! -f "${targetCVCFile}" ]
then
>&2 echo "ERROR: The CVC file ${targetCVCFile} does not exist!"
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 3 || exit 3
fi
# Generating related filenames
targetFileBasename=$(basename "$1" .${CFG_FileExtensions_CVC})
targetFileBasedir=$(dirname "${targetCVCFile}")
targetAudioFile="${targetFileBasedir}/${targetFileBasename}.${CFG_FileExtensions_Audio}"
targetTagsFile="${targetFileBasedir}/${targetFileBasename}.${CFG_FileExtensions_Tags}"
# If the supplied CVC filename is in the ignore list, we escape here.
for ignoredFilename in "${CFG_CVCCommit_IgnoredFilenames[@]}"; do
if [ "${targetFileBasename}" == "${ignoredFilename}" ]
then
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 0 || exit 0
fi
done
# Checking whether the related audio file does exist
if [ ! -f "${targetAudioFile}" ]
then
>&2 echo "ERROR: The related audio file ${targetAudioFile} does not exist!"
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 4 || exit 4
fi
################################################################################
# Performing CVC expansion
################################################################################
[ "${OPT_Verbose}" ] && echo "Performing CVC expansion on file ${targetCVCFile}..."
expansionOutput=$("${CFG_CVCTools_CVCExpand}" ${cvcexpandExtraArgs} "${targetCVCFile}")
if [ ! "$?" -eq 0 ]
then
>&2 echo "ERROR: Error in CVC expansion. Operation halted."
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 5 || exit 5
fi
################################################################################
# Data comparison and tags file update
################################################################################
# We only compare Vorbis Comments if a .tags file already exists.
if [ -f "${targetTagsFile}" ]
then
echo "${expansionOutput}" | diff -q "${targetTagsFile}" - > /dev/null
if [ "$?" -gt 0 ] || [ "${OPT_Force}" ]
then
[ "${OPT_Verbose}" ] && echo "Updating tag file ${targetTagsFile}..."
echo "${expansionOutput}" > "${targetTagsFile}"
else
[ "${OPT_Verbose}" ] && echo "Tag file is already up to date."
fi
# If not tags file exists, we write a new one now
else
[ "${OPT_Verbose}" ] && echo "Creating tag file '${targetTagsFile}'..."
echo "${expansionOutput}" > "${targetTagsFile}"
fi
################################################################################
# Updating tags
################################################################################
if [[ "${targetTagsFile}" -nt "${targetAudioFile}" ]] || [ "${OPT_Force}" ]
then
[ "${OPT_Verbose}" ] && echo "Updating metadata in audio file ${targetAudioFile}..."
# Deleting current FLAC tags
"${CFG_ExtTools_Metaflac}" --remove-all-tags "${targetAudioFile}" > /dev/null
if [ ! "$?" -eq 0 ]
then
>&2 echo "ERROR: Unable to erase current FLAC tags. Operation halted."
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 6 || exit 6
fi
# Adding the new tags
"${CFG_CVCTools_CVCExpand}" "${targetCVCFile}" | \
"${CFG_ExtTools_Metaflac}" --import-tags-from=- "${targetAudioFile}"
if [ ! "$?" -eq 0 ]
then
>&2 echo "ERROR: Unable to add the new FLAC tags. Operation halted."
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 7 || exit 7
fi
else
[ "${OPT_Verbose}" ] && echo "Audio file metadata are already up to date."
fi
################################################################################
# Updating embedded pictures
################################################################################
# Initializing variables
updateEmbeddedPictures=0
declare -a frontPictures
declare -a backPictures
# Searching for picture files
for pictureBasename in "${CFG_CVCCommit_AlbumArt_Front[@]}" "${CFG_CVCCommit_AlbumArt_Back[@]}"
do
# Enumerating valid picture file extensions
for pictureExtension in "${CFG_CVCCommit_PictureExtensions[@]}"
do
# Expected picture filename
pictureFile="${targetFileBasedir}/${pictureBasename}.${pictureExtension}"
# If a picture file with the expected file name is found, it must be
# embedded into the audio file.
if [ -f "${pictureFile}" ]
then
# Front picture
if [[ " ${CFG_CVCCommit_AlbumArt_Front[*]} " == *" ${pictureBasename} "* ]]
then
# We add the picture file to the list of found picture files.
[ "${OPT_Verbose}" ] && echo "Album picture found (front): ${pictureBasename}.${pictureExtension}"
frontPictures+=("${pictureFile}")
# Back picture
elif [[ " ${CFG_CVCCommit_AlbumArt_Back[*]} " == *" ${pictureBasename} "* ]]
then
# We add the picture file to the list of found picture files.
[ "${OPT_Verbose}" ] && echo "Album picture found (back): ${pictureBasename}.${pictureExtension}"
backPictures+=("${pictureFile}")
else
>&2 echo "ERROR: Unable to deduce the type of an album picture."
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 16 || exit 16
fi
# If at least one picture file is newer than the last modification
# time of the audio file, the audio file needs to be updated. Since
# that update requires removing all embedded pictures from the file
# first, all available pictures will have to be reembedded. A single
# newer picture file is thus enough to trigger the update process.
if [[ "${pictureFile}" -nt "${targetAudioFile}" ]] || [ "${OPT_Force}" ]
then
updateEmbeddedPictures=1
fi
fi
done
done
# If the audio file needs to be updated, we do it here
if [ "${updateEmbeddedPictures}" -eq 1 ]
then
# Deleting previous embedded pictures
[ "${OPT_Verbose}" ] && echo "Removing all embedded pictures from the audio file ${targetAudioFile}..."
"${CFG_ExtTools_Metaflac}" --remove --block-type=PICTURE "${targetAudioFile}" > /dev/null
# Checking removal result
if [ ! "$?" -eq 0 ]
then
>&2 echo "ERROR: Unable to remove embedded pictures from a FLAC file."
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 8 || exit 8
fi
# Embedding front pictures
for pictureFile in "${frontPictures[@]}"
do
[ "${OPT_Verbose}" ] && echo "Embedding front picture ${pictureFile} into file ${targetAudioFile}..."
"${CFG_ExtTools_Metaflac}" --import-picture-from="3||||${pictureFile}" "${targetAudioFile}" > /dev/null
if [ ! "$?" -eq 0 ]
then
>&2 echo "ERROR: Unable to embed a picture into a FLAC file. Operation halted."
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 9 || exit 9
fi
done
# Embedding back pictures
for pictureFile in "${backPictures[@]}"
do
[ "${OPT_Verbose}" ] && echo "Embedding back picture ${pictureFile} into file ${targetAudioFile}..."
"${CFG_ExtTools_Metaflac}" --import-picture-from="4||||${pictureFile}" "${targetAudioFile}" > /dev/null
if [ ! "$?" -eq 0 ]
then
>&2 echo "ERROR: Unable to embed a picture into a FLAC file. Operation halted."
[[ "${BASH_SOURCE[0]}" != "${0}" ]] && return 9 || exit 9
fi
done
else
[ "${OPT_Verbose}" ] && echo "Embedded pictures are up to date."
fi