22a6fddafce9c63f317f4ff258ee4e26a616c49d
[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, 2004 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.5
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"Darwin" ] ; then
40                 HTTPGET=curl
41                 HTTPGETOPTS=${HTTPGETOPTS:="-f -s"}
42         else
43                 HTTPGET=wget
44                 HTTPGETOPTS=${HTTPGETOPTS:="-q -O -"}
45         fi
46 fi
47
48 HTTPGET="$HTTPGET $HTTPGETOPTS"
49
50 usage() {
51           cat << EOF
52 $NAME version $VERSION
53 usage: one of:
54   $0 parse file
55   $0 template disc-id tracks
56   $0 send file address
57   $0 read server proto user host disc-id genre
58   $0 query server proto user host disc-id tracks
59   $0 stat serverurl user host proto
60   $0 help
61 EOF
62 }
63
64 help() {
65         cat << EOF
66 $NAME version $VERSION
67 A toolbox for doing cddb related stuff
68
69 Usage: $0 command [command_options]
70
71 Commands:
72   parse file
73         Get data out of a cddb file - dumps to stdout in a form
74         source'able by the shell
75
76   send file address
77         Mails a CDDB file to a specified address, using correct format.
78         Category should be one of blues, classical, country, data, folk,
79         jazz, newage, reggae, rock, soundtrack, or misc.
80   template disc-id tracks
81         Generates a template (empty) cddb file to stdout.  The command
82         line should be essentially the output of cd-discid.
83   query server proto user host disc-id tracks
84         Looks up disc on server (should be of form "http://host/~cddb/cddb.cgi")
85         remainder of command line is in the same form as that returned
86         by the cd-discid program.  
87   read server proto user host disc-id genre
88         CDDB file is dumped to stdout. File will contain an extra
89         #CATEGORY= line, which leaves it a valid CDDB file but which will
90         be recognized by parse and send commands. Uses wget, so if you
91         need to use a proxy then just configure wget to do so. user and
92         host will be used for identifying ourselves to the CDDB server.
93   stat serverurl user host proto
94         Check server status with given protocol. This can be used to check
95         if the server supports given protocol. Most common values for proto
96         should be 5 and 3. With 3 you will not get DYEAR and DGENRE fields
97         in response.
98   help  
99         Display this.
100 EOF
101 }
102
103 f_seq ()
104 {
105         i=$1
106         while [ $i -ne `expr $2 + 1` ]
107         do
108                 echo $i
109                 i=`expr $i + 1`
110         done
111 }
112
113 COMMAND=$1
114 shift
115 case $COMMAND in
116 parse)  # takes 1 argument, a filename, and dumps out a sh parseable version
117         CDDBFILE="$1"
118         
119         set -e
120         # names chosen to match usage in abcde code
121         DISCID=$(grep ^DISCID= "$CDDBFILE" | cut -f2 -d= | tr -d \[:cntrl:\])
122         DARTISTALBUM=$(grep ^DTITLE= "$CDDBFILE" | cut -f2- -d= | tr -d \\n | sed 's- / -~-g' | tr -d \[:cntrl:\])
123         DARTIST=$(echo "$DARTISTALBUM" | cut -f1 -d~ | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\])
124         DALBUM=$(echo "$DARTISTALBUM" | cut -f2 -d~ | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\])
125         CDDBGENRE=$(grep '^#CATEGORY=' "$CDDBFILE" | cut -f2- -d=)
126         if grep "^DYEAR" "$CDDBFILE" 2>&1 > /dev/null ; then
127                 CDYEAR=$(grep "^DYEAR" "$CDDBFILE" | cut -f2- -d= | tr -d \[:cntrl:\])
128         elif grep YEAR "$CDDBFILE" 2>&1 > /dev/null ; then
129                 CDYEAR=$(grep "YEAR" "$CDDBFILE" | grep -v "DYEAR" | awk 'BEGIN{FS="YEAR:"}{print $2}' | awk '{print $1}')
130         else
131                 CDYEAR=""
132         fi
133         CDGENRE=$(grep '^DGENRE=' "$CDDBFILE" | cut -f2- -d= | tr -d \[:cntrl:\])
134
135         set +e
136         echo DISCID="\"$DISCID\""
137         echo DALBUM="\"$DALBUM\""
138         echo DARTIST="\"$DARTIST\""
139         echo CDDBGENRE="\"$CDDBGENRE\""
140         echo CDYEAR="\"$CDYEAR\""
141         echo CDGENRE="\"$CDGENRE\""
142         NUMTRACKS=$(grep -E '^TTITLE[0-9]+=' "$CDDBFILE" | wc -l)
143         CURRTRACK=0
144         while [ "$CURRTRACK" -lt $NUMTRACKS ]; do
145                 CURRTRACKM1=$CURRTRACK # Track minus 1 (cddb numbers from 0)
146                 CURRTRACK=$(expr $CURRTRACK + 1)
147                 echo -n "TRACK${CURRTRACK}=\""
148                 grep ^TTITLE${CURRTRACKM1}= "$CDDBFILE" | cut -f2 -d= | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\]
149                 echo \"
150         done
151         ;;
152
153 template)
154         DISCID="$@"
155         DISCNUM=$1
156         echo '# xmcd CD database file'
157         echo '#'
158         echo '# Track frame offsets:'
159         NUMTRACKS=$2
160         for x in $(f_seq 3 $(expr $NUMTRACKS + 2))
161         do
162                 printf "#\t$(echo "$DISCID" | cut -f$x -d' ')\n"
163         done
164         x=$(expr $x + 1)
165         LENGTH=$(echo "$DISCID" | cut -f$x -d' ')
166         echo "#"
167         echo "# Disc length: $LENGTH seconds"
168         echo "#"
169         echo "# Submitted via: $NAME $VERSION"
170         echo "#"
171         echo "#blues,classical,country,data,folk,jazz,newage,reggae,rock,soundtrack,misc"
172         echo "#CATEGORY=misc"
173         echo DISCID="$DISCNUM"
174         echo "DTITLE=Unknown Artist / Unknown Album"
175         echo "DYEAR="
176         echo "DGENRE="
177         # TTITLE0 -- TTITLEn
178         for x in $(f_seq 1 $NUMTRACKS)
179         do
180                 echo "TTITLE$(expr $x - 1)=Track $x"
181         done
182         echo "EXTD="
183         # EXTT0 -- EXTTn
184         for x in $(f_seq 1 $NUMTRACKS)
185         do
186                 echo "EXTT$(expr $x - 1)="
187         done
188         echo "PLAYORDER="
189         ;;
190
191 send) # cddb-tool send filename email@address
192         FILE="$1"
193         ADDRESS="$2"
194         DISCID=$(grep ^DISCID= "$FILE" | cut -f2 -d= | tr -d \[:cntrl:\])
195         CDDBGENRE=$(grep '^#CATEGORY=' "$FILE" | cut -f2- -d=)
196         grep -v "^#CATEGORY=" "$FILE" | mail -s "cddb $CDDBGENRE $DISCID" "$ADDRESS"
197         ;;
198
199 query) # cddb-tool query serverurl proto user host discid...
200         SERVER="$1"
201         PROTO="$2"
202         USER="$3"
203         HOST="$4"
204         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
205         shift 4
206         TRACKINFO="$@"
207         TRACKINFOPLUS=$(echo $TRACKINFO | tr ' ' '+')
208         RESULTS=$($HTTPGET "$SERVER?cmd=cddb+query+$TRACKINFOPLUS\&hello=$HELLOINFO\&proto=$PROTO") || exit $LOOKUP_ERR
209         echo $RESULTS | tr '\r' '\n' | tr -s '\n' | sed 's/^ //g'
210         ;;
211
212 read) # cddb-tool read serverurl proto user host genre discnumber
213         SERVER="$1"
214         PROTO="$2"
215         USER="$3"
216         HOST="$4"
217         CATEGORY="$5"
218         DISCID="$6"
219         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
220         $HTTPGET $CDDBDATA "$SERVER?cmd=cddb+read+$CATEGORY+$DISCID\&hello=$HELLOINFO\&proto=$PROTO" 2>/dev/null
221         ;;
222
223 stat) # cddb-tool stat serverurl user host proto
224         SERVER="$1"
225         USER="$2"
226         HOST="$3"
227         PROTO="$4"
228         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
229         $HTTPGET $CDDBDATA "$SERVER?cmd=stat&hello=$HELLOINFO\&proto=$PROTO" 2>/dev/null
230         ;;
231
232 help) # help
233         help
234         ;;
235
236 *) # usage
237         usage
238         ;;
239 esac