summaryrefslogtreecommitdiff
path: root/bin/menuscripts/treetag.sh
blob: 3ded6371c751a19d72026a35dff0787989f83660 (plain)
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
#!/bin/sh

VERSION="0.3"

batch=0
rename=0

help ()
{
	cat <<-EOF >&2
	Usage: treetag.sh [options]
	Options:
	-b              Enable batch mode
	-d <directory>  Specify the music directory
	-h              Show this help message and exit
	-r              also rename file
	-v              Print version information and exit
	EOF
}

log () { >&2 printf '%s\n' "$@"; }
die () { log "$@"; exit 1; }
require () { command -v "$1" > /dev/null || die "E: This script needs '$1' to be installed."; }
ls_dirs() { find . -mindepth 1 -maxdepth 1 -type d -printf "%f\n"; }

### Tag files in the current directory
# $1: artist name
# $2: album name
treetag ()
{
	[ -z "$1" ] || [ -z "$2" ] && return 1
	artist="$1"
	album="$2"

	>&2 printf "artist: %s\n" "$artist"
	>&2 printf "album: %s\n" "$album"
	find . -maxdepth 1 -type f -printf '%f\n' | sort -g |
		while read -r file
		do
			>&2 printf "file: %s\n" "$file"
			! soxi "$file" > /dev/null 2>&1 && continue

			# Remove number prefix and extension
			name="$(printf '%s' "${file%.*}" | sed 's/^[0-9]*\s*[. -]\s*//')"
			i=$((i+1))

			log "I: [$artist] ($album) #$i $name"

			id3v2 \
				-a "$artist" \
				-A "$album" \
				-t "$name" \
				-T "$i" \
				-- "$file"
			printf '%s\n' "$i" > .count

			[ $rename -eq 1 ] && mv -- "$file" "$i. $name.${file##*.}"

		done
		if [ -f .count ]
		then
			log "I: $(cat .count) file(s) tagged."
			rm .count
		else
			log "I: No files tagged."
		fi
}

batch_tag ()
{
	artist="${PWD##*/}" # basename of current dir
	ls_dirs |
		while read -r album
		do (cd "$album" && treetag "$artist" "$album")
		done
}

# Tag interactively with fzf
interactive ()
{
	require "fzf"

	artist="$(ls_dirs | fzf)"
	[ "$artist" ] && cd "$artist" || exit 1

	choice="$artist"
	while true
	do
		choice="$(ls_dirs | fzf --prompt "$choice:")"
		if [ "$choice" ]
		then 
			album="$choice"
			cd "$album" || exit 1

			printf 'stop? '
			head -n 1 | grep -q "[yY]" && break
		else 
			break
		fi
	done

	treetag "$artist" "$album"
}

while getopts ":d:bhrv" opt
do
	case $opt in
		b) batch=1 ;;
		d) musdir="$OPTARG" ;;
		h) help; exit ;;
		r) rename=1 ;;
		v) log "treetag.sh $VERSION"; exit ;;
		:) die "E: Option -$OPTARG requires an argument" ;;
		?) die "E: Invalid option: -$OPTARG" ;;
	esac
done

require "id3v2"
require "sox"

cd "${musdir:=.}" || exit 1

if [ $batch -eq 1 ] 
then
	batch_tag
else
	interactive
fi