forked from flying-sausages/tunedbren
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rename.sh
executable file
·182 lines (161 loc) · 6.23 KB
/
rename.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
#!/bin/bash
name=$(basename $0)
filetypes="mp3 flac"
sanitize() {
# Sanitizes file name components.
# This will probably need to be extended to deal with exotic fuckery
echo -n "$1" | sed -e 's| / |, |g' -e 's|/|,|g' | tr -d '<>:"|?*\\'
}
flactag() {
# flactag TAG FILE returns the content of that tag in a FLAC file
metaflac "--show-tag=${1}" "$2" | cut -d '=' -f 2- | awk 'BEGIN {OUT=""} {if(NR==1){OUT=$0;} else {OUT=OUT" & "$0;}} END {print OUT;}'
}
check_dependencies() {
# Little sanity check for executables that we need...
DEPENDENCIES="id3convert mp3info metaflac egrep cut awk sed"
for dep in $DEPENDENCIES
do
[ -z $(which $dep) ] && {
echo "${name}: Missing dependency: ${dep}" 1>&2
exit -99
}
done
}
check_dependencies
usage() {
echo "$name [-option1 -option2 ... ] /path/to/files/"
here=$(dirname "${BASH_SOURCE[0]}")
cat "${here}/README.md"
}
# If there are no args...show usage
[[ $# -lt 1 ]] && { usage; exit -1; }
IN_DIR=''
DIR_TEMPLATE='%a - %l [%c] [%y] [%src] [%b]'
DIR_ARTIST=''
FILE_TEMPLATE='%n. %a - %s'
FILE_ARTIST=''
ALBUM=''
CATALOG=''
YEAR=''
BITRATE=''
SOURCE=''
OUT_DIR=''
# Gather command line arguments by shifting them off one by one
while [ $# -gt 0 ]
do
case "$1" in
-t) shift; FILE_TEMPLATE="$1";
;;
-d) shift; DIR_TEMPLATE="$1";
;;
-a) shift; DIR_ARTIST="$1";
;;
-ta) shift; FILE_ARTIST="$1";
;;
-l) shift; ALBUM="$1";
;;
-c) shift; CATALOG="$1";
;;
-y) shift; YEAR="$1";
;;
-b) shift; BITRATE="$1";
;;
-src) shift; SOURCE=$(echo ${1} | awk '{print toupper($0);}');
;;
*) IN_DIR="$1";
;;
esac
shift;
done
# A few sanity checks...
[ -z "$IN_DIR" ] && { echo "${name}: No input directory."; usage; exit -2; }
[ -d "$IN_DIR" ] || { echo "${name}: '$IN_DIR' is not a directory."; exit -3; }
[ -z "$FILE_TEMPLATE" ] && { echo "${name}: No file template."; exit -3; }
[ -z "$DIR_TEMPLATE" ] && { echo "${name}: No directory template."; exit -3; }
# Convert ID3 tags if there are any MP3 files
[ $(ls "$IN_DIR" | grep -q '\.mp3$') ] && {
id3convert "$IN_DIR"/*.mp3 || {
echo "${name}: Failed to convert ID3 tags, continuing anyway."
}
}
FILE_ARTIST_PARAM="$FILE_ARTIST" # Saving this one because we'll have to restore it for Various Artists releases
for filetype in $filetypes
do
ls "$IN_DIR"/*."$filetype" 2>/dev/null | while read IN_FILE
do
[ -n "$OUT_DIR" ] && {
# If we have already moved the directory, adjust the input file name accordingly
IN_FILE_BASE=$(basename "$IN_FILE")
IN_FILE="${OUT_DIR}/${IN_FILE_BASE}"
FILE_ARTIST="$FILE_ARTIST_PARAM"
}
# Grab info from meta tags
case $filetype in
mp3)
TITLE=$(mp3info -p "%t" "$IN_FILE")
TRACKNUMBER=$(mp3info -p "%n" "$IN_FILE")
[ -z "$FILE_ARTIST" ] && { FILE_ARTIST=$(mp3info -p "%a" "$IN_FILE"); }
[ -z "$DIR_ARTIST" ] && { DIR_ARTIST="$FILE_ARTIST"; }
[ -z "$ALBUM" ] && { ALBUM=$(mp3info -p "%l" "$IN_FILE"); }
[ -z "$YEAR" ] && { YEAR=$(mp3info -p "%y" "$IN_FILE"); }
[ -z "$BITRATE" ] && { BITRATE=$(mp3info -p "%r" "$IN_FILE"); }
;;
flac)
TITLE=$(flactag TITLE "$IN_FILE")
TRACKNUMBER=$(flactag TRACKNUMBER "$IN_FILE")
[ -z "$FILE_ARTIST" ] && { FILE_ARTIST=$(flactag ARTIST "$IN_FILE"); }
[ -z "$DIR_ARTIST" ] && { DIR_ARTIST=$(flactag ALBUMARTIST "$IN_FILE"); }
[ -z "$ALBUM" ] && { ALBUM=$(flactag ALBUM "$IN_FILE"); }
[ -z "$YEAR" ] && { YEAR=$(flactag DATE "$IN_FILE"); }
[ -z "$CATALOG" ] && { CATALOG=$(flactag CATALOGNUMBER "$IN_FILE"); }
[ -z "$BITRATE" ] && { BITRATE="FLAC"; }
;;
*) echo "${name}: Unimplemented filetype $filetype"
;;
esac
# Generate an output directory name, if there is none yet
[ -z "$OUT_DIR" ] && {
echo "Generating output directory name"
[ -z "$DIR_ARTIST" ] && { echo "${name}: Empty directory artist. Please set it using the -a parameter."; exit -4; }
[ -z "$ALBUM" ] && { echo "${name}: Empty Album field. Please set it using the -l parameter."; exit -4; }
[ -z "$CATALOG" ] && { echo "${name}: Empty Catalogue Number field. Please set it using the -c parameter."; exit -4; }
[ -z "$YEAR" ] && { echo "${name}: Empty Year field. Please set it using the -y parameter."; exit -4; }
[ -z "$BITRATE" ] && { echo "${name}: Empty Bitrate field. Please set it using the -b parameter."; exit -4; }
[ -z "$SOURCE" ] && { echo "${name}: Empty Source field. Please set it using the -src parameter."; exit -4; }
# Eval directory template
DIR_ARTIST=$(sanitize "$DIR_ARTIST")
ALBUM=$(sanitize "$ALBUM")
CATALOG=$(sanitize "$CATALOG")
YEAR=$(sanitize "$YEAR")
BITRATE=$(sanitize "$BITRATE")
SOURCE=$(sanitize "$SOURCE")
OUT_DIR=$(echo -n "$DIR_TEMPLATE" | sed -e "s/%a/${DIR_ARTIST}/g" -e "s/%l/${ALBUM}/g" -e "s/%c/${CATALOG}/g" -e "s/%y/${YEAR}/g" -e "s/%b/${BITRATE}/g" -e "s/%src/${SOURCE}/g" -e 's|%.|\&|g')
OUT_DIR_PARENT=$(dirname "$IN_DIR")
OUT_DIR="${OUT_DIR_PARENT}/${OUT_DIR}"
[ "$IN_DIR" != "$OUT_DIR" ] && mv -v "$IN_DIR" "$OUT_DIR"
# Also, see if there's an image to be renamed
[ -f "${OUT_DIR}/cover.jpg" -o -f "${OUT_DIR}/cover.png" ] || {
find "$OUT_DIR" -maxdepth 1 -iname '*.jpg' | head -1 | while read newcover; do mv "$newcover" "${OUT_DIR}/cover.jpg"; done
find "$OUT_DIR" -maxdepth 1 -iname '*.png' | head -1 | while read newcover; do mv "$newcover" "${OUT_DIR}/cover.png"; done
}
}
[ -z "$TITLE" -o -z "$TRACKNUMBER" -o -z "$FILE_ARTIST" ] && {
echo "${name}: Input file ${IN_FILE} does not contain required meta tags (artist, number and title)."
exit -5
}
# Eval file template
FILE_ARTIST=$(sanitize "$FILE_ARTIST")
ALBUM=$(sanitize "$ALBUM")
CATALOG=$(sanitize "$CATALOG")
YEAR=$(sanitize "$YEAR")
BITRATE=$(sanitize "$BITRATE")
SOURCE=$(sanitize "$SOURCE")
TITLE=$(sanitize "$TITLE")
TRACKNUMBER=$(printf "%02d" "$TRACKNUMBER")
TRACKNUMBER=$(sanitize "$TRACKNUMBER")
OUT_FILE=$(echo -n "$FILE_TEMPLATE" | sed -e "s/%a/${FILE_ARTIST}/g" -e "s/%l/${ALBUM}/g" -e "s/%c/${CATALOG}/g" -e "s/%y/${YEAR}/g" -e "s/%b/${BITRATE}/g " -e "s/%s/${TITLE}/g" -e "s/%src/${SOURCE}/g" -e "s/%n/${TRACKNUMBER}/g" -e 's|%.|\&|g')
OUT_FILE="${OUT_FILE}.${filetype}"
IN_FILE_BASE=$(basename "$IN_FILE")
[ "${OUT_DIR}/${IN_FILE_BASE}" != "${OUT_DIR}/${OUT_FILE}" ] && mv -v "${OUT_DIR}/${IN_FILE_BASE}" "${OUT_DIR}/${OUT_FILE}"
done
done