# add-metadata-to-best-of-bootie-halloween-2023 -rw-r--r-- 4.9 KiB View raw
                                                                                
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
#!/usr/bin/env bash

# Ben Zanin, 2023-10-25

# If you have downloaded the Best of Bootie - Halloween 10 (2023) mashup
# from https://bootiemashup.com/mix-tapes/halloween-booootie-10-2023/
# only to discover that the MP3 files in the zip archive contain no tags
# at all, run this script to populate some meaningful values in there.
#
# You'll need a host system that has bash 4.x or greater.  Linux and WSL
# or WSL2 under Windows should do; macOS has the unfortunate problem of
# offering only bash 3.x, you'll need to install something less moribund
# via 'brew install bash' or whatever mechanism you prefer.
#
# You'll also need the id3v2 utility installed, either via 'brew install
# id3v2' under macOS or 'apt-get install id3v2' under Debian/Ubuntu or
# however else you install software on your machine.
#
# This program looks for and honours two environment variables: 'DEBUG',
# which makes the output much more chatty on standard error, and
# USE_ID3V2_SLASH_SEPARATED_ARTISTS, which transforms the many artists
# in each metadata tag to be separated by slashes instead of their more
# human-friendly format listed on the Best of Bootie album page.

if ! command -v id3v2 > /dev/null 2>&1; then
	>&2 printf 'could not find prerequisite tool: id3v2\n'
	exit 1
fi

if [[ ! ${BASH_VERSINFO-UNSET} =~ ^[45] ]]; then
	>&2 printf 'we need bash >= 4.2 to run but found %s\n' \
	  "${BASH_VERSINFO-no \$BASH_VERSINFO variable set}"
	>&2 printf '(this program uses bash array features, see %s )\n' \
	  'https://mywiki.wooledge.org/BashFAQ/061'
	exit 1
fi

declare -a fn_artists missing opts_id3v2
declare -i i tracktotal tracknum
declare    fn artists title artist artist_tag_value

fn_artists=( \
  '01 fnogg - Shake It Down In My Dragula.mp3'  'Rob Zombie vs. Taylor Swift vs. Disturbed'
  '02 CastleR - There Will Be Life.mp3'         'Kim Petras vs. Backstreet Boys'
  '03 Titus Jones - Gimme Sweet Halloween.mp3'  'Korn vs. ABBA vs. Beyoncé vs. Muse'
  '04 reconthuse - Seven Nation Nightmare.mp3'  'Alice Cooper vs. White Stripes'
  '05 IamJstncrdble - Haunted Thriller.mp3'     'Taylor Swift vs. Michael Jackson'
  '06 iWillBattle - Vampire Hammer.mp3'         'Olivia Rodrigo vs. Ghost'
  '07 iWillBattle - Mucky Mary [GaGa Muck].mp3' 'The Cramps vs. Lady Gaga'
  "08 DSP - Somebody's Watching Girl.mp3"       'The Cure vs. Rockwell'
  '09 MasDaMind - I’m Your Black Wolf.mp3'      'KC & the Sunshine Band vs. Zombie Hyperdrive'
  '10 Lewis Wake - Scary Edge.mp3'              'Britney Spears vs. REZZ'
  '11 Aggro1 - Zombie Rootkit.mp3'              'The Cranberries vs. Emurse'
  '12 Voicedude - Werewolves On The Storm.mp3'  'Warren Zevon vs. The Doors + American Werewolf In London'
  '13 Kill_mR_DJ - Spell Box.mp3'               'Screaming Jay Hawkins vs. Portishead vs. Creedence Clearwater Revival'
)

tracktotal=$((${#fn_artists[@]}/2))

for ((i=0; i<${#fn_artists[@]}; i+=2)); do
	fn=${fn_artists[i]}
	if [[ ! -f "$fn" ]]; then
		missing+=($((1+(i/2))) "$fn")
	fi
done
if ((${#missing[@]} > 0)); then
	>&2 printf 'missing track %02d, filename: %s\n' "${missing[@]}"
	exit 2
fi

for ((i=0; i<${#fn_artists[@]}; i+=2)); do
	fn=${fn_artists[i+0]}
	artists=${fn_artists[i+1]}
	title=${fn#* - }
	title=${title%.mp3}
	artist=${fn%% - *}
	artist=${artist:3}
	tracknum=$((1+(i/2)))
	if [[ $title == *Your\ Black\ Wolf* ]]; then
		title=${title//’/\'}
	fi
	artist_tag_value="$artist: $artists"
	if [[ ${USE_ID3V2_SLASH_SEPARATED_ARTISTS+SET} == 'SET' ]]; then
	  # not personally something I care about, but set and export this
	  # variable if you have strong opinions about separating multiple
	  # artists with slashes in the ID3v2 metadata
		artist_tag_value=${artist_tag_value/: /\/}
		artist_tag_value=${artist_tag_value// vs. /\/}
	fi
	opts_id3v2=( \
	  '--id3v2-only'
	  '--artist' "$artist_tag_value"
	  '--album'  'Best of Bootie - Halloween Bootie 10 (2023)'
	  '--song'   "$title"
	  '--genre'  'bootie mashup'
	  '--year'   '2023'
	  '--track'  "$tracknum/$tracktotal"
	  '--comment' 'See album info at https //bootiemashup.com/mix-tapes/halloween-booootie-10-2023/'
	    # infuriatingly there seems to be no reasonable way to populate
	    # a comment tag with the id3v2 tag if that value contains a ":"
	    # character, so we use a stupid space instead.  Harrumph.
	    #
	    # cf. https://www.jetmore.org/john/blog/2012/07/patch-allow-id3v21-to-include-colons-in-comment-fields/
	    # and http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=681847
	)
	if [[ ${DEBUG+SET} == 'SET' ]]; then
		declare -p fn title artists artist tracknum tracktotal
		printf 'id3v2:\n'
		printf '  %-10s %s\n' \
		  "${opts_id3v2[0]}" '' "${opts_id3v2[@]:1}" "$fn" ''
	fi
	if ! id3v2 -R "$fn" | grep -q -E ': No ID3 tag$'; then
	  # don't mess around with files that already have metadata in them,
	  # no sense in complicating things.  To start over just extract the
	  # MP3 files from the zip archive again.
		>&2 printf 'file already has id3v2 metadata, skipping: %s\n' \
		  "$fn"
		continue
	fi
	id3v2 "${opts_id3v2[@]}" "$fn"
done