Added YEAR and GENRE to replaygain()
[abcde.git] / cddb-tool
1 #!/bin/sh
2
3 # Copyright (C) 1999 Nathaniel Smith <njs@uclink4.berkeley.edu>
4 # Copyright (C) 1999, 2000, 2001 Robert Woodcock <rcw@debian.org>
5 # Copyright (C) 2003, 2005 Jesus Climent <jesus.climent@hispalinux.es>
6 # This code is hereby licensed for public consumption under either the
7 # GNU GPL v2 or greater, or Larry Wall's Artistic License - your choice.
8 #
9 # You should have recieved a copy of the GNU General Public License
10 # along with this program; if not, write to the Free Software
11 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
12
13 # Copyright for this work is to expire January 1, 2010, after which it
14 # shall be public domain.
15
16 # TODO:
17 #  - Add more error checking
18
19 # KNOWN BUGS:
20 #  - Not much error checking, esp. of arguments
21 #  - Submitted via: line is created by template, when it really should be in send.
22 #    Oh well.
23
24 VERSION=0.4.7
25 NAME=cddb-tool
26
27 #return codes
28 BAD_SYNTAX_ERR=10  # invalid CDDB file
29 NO_TMP_ERR=11      # can't create a temp file
30 NO_MATCH_ERR=12    # try submitting one
31 LOOKUP_ERR=13      # problem connecting to cddb server
32 EMPTY_QUERY_RESPONSE=14 # query response = "", (probably no net connection)
33
34 # assume a reasonable default if $HTTPGET is undefined
35 if [ "$HTTPGET" = "" ]; then
36         if [ X"$(uname)" = X"FreeBSD" ] ; then
37                 HTTPGET=fetch
38                 HTTPGETOPTS=${HTTPGETOPTS:="-q -o -"}
39         elif [ X"$(uname)" = X"NetBSD" ] ; then
40                 HTTPGET=ftp
41                 HTTPGETOPTS=${HTTPGETOPTS:="-a -V -o - "}
42         elif [ X"$(uname)" = X"Darwin" ] ; then
43                 HTTPGET=curl
44                 HTTPGETOPTS=${HTTPGETOPTS:="-f -s"}
45         else
46                 HTTPGET=wget
47                 HTTPGETOPTS=${HTTPGETOPTS:="-q -nv -O -"}
48         fi
49 fi
50
51 HTTPGET="$HTTPGET $HTTPGETOPTS"
52
53 usage() {
54           cat << EOF
55 $NAME version $VERSION
56 usage: one of:
57   $0 parse file
58   $0 template disc-id tracks
59   $0 send file address
60   $0 read server proto user host disc-id genre
61   $0 query server proto user host disc-id tracks
62   $0 stat serverurl user host proto
63   $0 help
64 EOF
65 }
66
67 help() {
68         cat << EOF
69 $NAME version $VERSION
70 A toolbox for doing cddb related stuff
71
72 Usage: $0 command [command_options]
73
74 Commands:
75   parse file
76         Get data out of a cddb file - dumps to stdout in a form
77         source'able by the shell
78
79   send file address
80         Mails a CDDB file to a specified address, using correct format.
81         Category should be one of blues, classical, country, data, folk,
82         jazz, newage, reggae, rock, soundtrack, or misc.
83   template disc-id tracks
84         Generates a template (empty) cddb file to stdout.  The command
85         line should be essentially the output of cd-discid.
86   query server proto user host disc-id tracks
87         Looks up disc on server (should be of form "http://host/~cddb/cddb.cgi")
88         remainder of command line is in the same form as that returned
89         by the cd-discid program.  
90   read server proto user host disc-id genre
91         CDDB file is dumped to stdout. File will contain an extra
92         #CATEGORY= line, which leaves it a valid CDDB file but which will
93         be recognized by parse and send commands. Uses wget, so if you
94         need to use a proxy then just configure wget to do so. user and
95         host will be used for identifying ourselves to the CDDB server.
96   stat serverurl user host proto
97         Check server status with given protocol. This can be used to check
98         if the server supports given protocol. Most common values for proto
99         should be 5 and 3. With 3 you will not get DYEAR and DGENRE fields
100         in response.
101   help  
102         Display this.
103 EOF
104 }
105
106 f_seq ()
107 {
108         i=$1
109         while [ $i -ne `expr $2 + 1` ]
110         do
111                 echo $i
112                 i=`expr $i + 1`
113         done
114 }
115
116 COMMAND=$1
117 shift
118 case $COMMAND in
119 parse)  # takes 1 argument, a filename, and dumps out a sh parseable version
120         CDDBFILE="$1"
121         
122         set -e
123         # names chosen to match usage in abcde code
124         DISCID=$(grep ^DISCID= "$CDDBFILE" | cut -f2 -d= | tr -d \[:cntrl:\])
125         DARTISTALBUM="$(grep ^DTITLE= "$CDDBFILE" | cut -f2- -d= | tr -d \\n | sed 's- / -~-g' | tr -d \[:cntrl:\])"
126         DARTIST="$(echo "$DARTISTALBUM" | cut -f1 -d~ | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\])"
127         DALBUM="$(echo "$DARTISTALBUM" | cut -f2 -d~ | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\])"
128         CDDBGENRE="$(grep '^#CATEGORY=' "$CDDBFILE" | cut -f2- -d= | tr -d \[:cntrl:\])"
129         if grep "^DYEAR" "$CDDBFILE" 2>&1 > /dev/null ; then
130                 CDYEAR=$(grep "^DYEAR" "$CDDBFILE" | cut -f2- -d= | tr -d \[:cntrl:\])
131         elif grep YEAR "$CDDBFILE" 2>&1 > /dev/null ; then
132                 CDYEAR=$(grep "YEAR" "$CDDBFILE" | grep -v "DYEAR" | awk 'BEGIN{FS="YEAR:"}{print $2}' | awk '{print $1}')
133         else
134                 CDYEAR=""
135         fi
136         CDGENRE=$(grep '^DGENRE=' "$CDDBFILE" | cut -f2- -d= | tr -d \[:cntrl:\])
137
138         set +e
139         echo DISCID="\"$DISCID\""
140         echo DALBUM="\"$DALBUM\""
141         echo DARTIST="\"$DARTIST\""
142         echo CDDBGENRE="\"$CDDBGENRE\""
143         echo CDYEAR="\"$CDYEAR\""
144         echo CDGENRE="\"$CDGENRE\""
145         NUMTRACKS=$(grep -E '^TTITLE[0-9]+=' "$CDDBFILE" | wc -l)
146         CURRTRACK=0
147         while [ "$CURRTRACK" -lt $NUMTRACKS ]; do
148                 CURRTRACKM1=$CURRTRACK # Track minus 1 (cddb numbers from 0)
149                 CURRTRACK=$(expr $CURRTRACK + 1)
150                 echo -n "TRACK${CURRTRACK}=\""
151                 grep ^TTITLE${CURRTRACKM1}= "$CDDBFILE" | cut -f2 -d= | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\]
152                 echo \"
153         done
154         ;;
155
156 template)
157         DISCID="$@"
158         DISCNUM=$1
159         echo '# xmcd CD database file'
160         echo '#'
161         echo '# Track frame offsets:'
162         NUMTRACKS=$2
163         for x in $(f_seq 3 $(expr $NUMTRACKS + 2))
164         do
165                 printf "#\t$(echo "$DISCID" | cut -f$x -d' ')\n"
166         done
167         x=$(expr $x + 1)
168         LENGTH=$(echo "$DISCID" | cut -f$x -d' ')
169         echo "#"
170         echo "# Disc length: $LENGTH seconds"
171         echo "#"
172         echo "# Submitted via: $NAME $VERSION"
173         echo "#"
174         echo "#blues,classical,country,data,folk,jazz,newage,reggae,rock,soundtrack,misc"
175         echo "#CATEGORY=misc"
176         echo DISCID="$DISCNUM"
177         echo "DTITLE=Unknown Artist / Unknown Album"
178         echo "DYEAR="
179         echo "DGENRE="
180         # TTITLE0 -- TTITLEn
181         for x in $(f_seq 1 $NUMTRACKS)
182         do
183                 echo "TTITLE$(expr $x - 1)=Track $x"
184         done
185         echo "EXTD="
186         # EXTT0 -- EXTTn
187         for x in $(f_seq 1 $NUMTRACKS)
188         do
189                 echo "EXTT$(expr $x - 1)="
190         done
191         echo "PLAYORDER="
192         ;;
193
194 send) # cddb-tool send filename email@address
195         FILE="$1"
196         ADDRESS="$2"
197         DISCID=$(grep ^DISCID= "$FILE" | cut -f2 -d= | tr -d \[:cntrl:\])
198         CDDBGENRE=$(grep '^#CATEGORY=' "$FILE" | cut -f2- -d= | tr -d \[:cntrl:\])
199         grep -v "^#CATEGORY=" "$FILE" | iconv -t utf-8 | mail -a "Content-Type: text/plain; charset=utf-8" -s "cddb $CDDBGENRE $DISCID" "$ADDRESS"
200         ;;
201
202 query) # cddb-tool query serverurl proto user host discid...
203         SERVER="$1"
204         PROTO="$2"
205         USER="$3"
206         HOST="$4"
207         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
208         shift 4
209         TRACKINFO="$@"
210         TRACKINFOPLUS=$(echo $TRACKINFO | tr ' ' '+')
211         RESULTS=$($HTTPGET "$SERVER?cmd=cddb+query+$TRACKINFOPLUS\&hello=$HELLOINFO\&proto=$PROTO") || exit $LOOKUP_ERR
212         echo "$RESULTS" | tr '\r' '\n' | tr -s '\n' | sed 's/^ //g'
213         ;;
214
215 read) # cddb-tool read serverurl proto user host genre discnumber
216         SERVER="$1"
217         PROTO="$2"
218         USER="$3"
219         HOST="$4"
220         CATEGORY="$5"
221         DISCID="$6"
222         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
223         $HTTPGET $CDDBDATA "$SERVER?cmd=cddb+read+$CATEGORY+$DISCID\&hello=$HELLOINFO\&proto=$PROTO" 2>/dev/null
224         ;;
225
226 stat) # cddb-tool stat serverurl user host proto
227         SERVER="$1"
228         USER="$2"
229         HOST="$3"
230         PROTO="$4"
231         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
232         $HTTPGET $CDDBDATA "$SERVER?cmd=stat&hello=$HELLOINFO\&proto=$PROTO" 2>/dev/null
233         ;;
234
235 help) # help
236         help
237         ;;
238
239 *) # usage
240         usage
241         ;;
242 esac