The file KNOWN.BUGS removed
[abcde.git] / cddb-tool
1 #!/bin/bash
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 received a copy of the GNU General Public License
10 # along with this program; if not, write to the Free Software
11 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 -e timestamping=off -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 new_checkexec ()
117 {
118         if [ ! "$@" = "" ]; then
119                 # Cut off any command-line option we added in
120                 X=$(echo $@ | cut -d' ' -f2)
121                 if [ "$(which $X)" = "" ]; then
122                         return 1
123                 elif [ ! -x $(which $X) ]; then
124                         return 2
125                 fi
126         fi
127         return 0
128 }
129
130 COMMAND=$1
131 shift
132 case $COMMAND in
133 parse)  # takes 1 argument, a filename, and dumps out a sh parseable version
134         CDDBFILE="$1"
135
136         set -e
137         # names chosen to match usage in abcde code
138         DISCID=$(grep ^DISCID= "$CDDBFILE" | cut -f2 -d= | tr -d \[:cntrl:\])
139         DARTISTALBUM="$(grep ^DTITLE= "$CDDBFILE" | cut -f2- -d= | tr -d \\n | sed 's- / -~-g' | tr -d \[:cntrl:\])"
140         DARTIST="$(echo "$DARTISTALBUM" | cut -f1 -d~ | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\])"
141         DALBUM="$(echo "$DARTISTALBUM" | cut -f2 -d~ | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\])"
142         CDDBGENRE="$(grep '^#CATEGORY=' "$CDDBFILE" | cut -f2- -d= | tr -d \[:cntrl:\])"
143         if grep "^DYEAR" "$CDDBFILE" 2>&1 > /dev/null ; then
144                 CDYEAR=$(grep "^DYEAR" "$CDDBFILE" | cut -f2- -d= | tr -d \[:cntrl:\])
145         elif grep YEAR "$CDDBFILE" 2>&1 > /dev/null ; then
146                 CDYEAR=$(grep "YEAR" "$CDDBFILE" | grep -v "DYEAR" | awk 'BEGIN{FS="YEAR:"}{print $2}' | awk '{print $1}')
147         else
148                 CDYEAR=""
149         fi
150         CDGENRE=$(grep '^DGENRE=' "$CDDBFILE" | cut -f2- -d= | tr -d \[:cntrl:\])
151
152         set +e
153         echo DISCID="\"$DISCID\""
154         echo DALBUM="\"$DALBUM\""
155         echo DARTIST="\"$DARTIST\""
156         echo CDDBGENRE="\"$CDDBGENRE\""
157         echo CDYEAR="\"$CDYEAR\""
158         echo CDGENRE="\"$CDGENRE\""
159         NUMTRACKS=$(grep -E '^TTITLE[0-9]+=' "$CDDBFILE" | wc -l)
160         CURRTRACK=0
161         while [ "$CURRTRACK" -lt $NUMTRACKS ]; do
162                 CURRTRACKM1=$CURRTRACK # Track minus 1 (cddb numbers from 0)
163                 CURRTRACK=$(expr $CURRTRACK + 1)
164                 echo -n "TRACK${CURRTRACK}=\""
165                 grep ^TTITLE${CURRTRACKM1}= "$CDDBFILE" | cut -f2 -d= | sed 's,\\,\\\\,g;s,\([\"\$\`]\),\\\1,g' | tr -d \[:cntrl:\]
166                 echo \"
167         done
168         ;;
169
170 template)
171         DISCID="$@"
172         DISCNUM=$1
173         echo '# xmcd CD database file'
174         echo '#'
175         echo '# Track frame offsets:'
176         NUMTRACKS=$2
177         for x in $(f_seq 3 $(expr $NUMTRACKS + 2))
178         do
179                 printf "#\t$(echo "$DISCID" | cut -f$x -d' ')\n"
180         done
181         x=$(expr $x + 1)
182         LENGTH=$(echo "$DISCID" | cut -f$x -d' ')
183         echo "#"
184         echo "# Disc length: $LENGTH seconds"
185         echo "#"
186         echo "# Submitted via: $NAME $VERSION"
187         echo "#"
188         echo "#blues,classical,country,data,folk,jazz,newage,reggae,rock,soundtrack,misc"
189         echo "#CATEGORY=misc"
190         echo DISCID="$DISCNUM"
191         echo "DTITLE=Unknown Artist / Unknown Album"
192         echo "DYEAR="
193         echo "DGENRE="
194         # TTITLE0 -- TTITLEn
195         for x in $(f_seq 1 $NUMTRACKS)
196         do
197                 echo "TTITLE$(expr $x - 1)=Track $x"
198         done
199         echo "EXTD="
200         # EXTT0 -- EXTTn
201         for x in $(f_seq 1 $NUMTRACKS)
202         do
203                 echo "EXTT$(expr $x - 1)="
204         done
205         echo "PLAYORDER="
206         ;;
207
208 send) # cddb-tool send filename email@address
209         FILE="$1"
210         ADDRESS="$2"
211         DISCID=$(grep ^DISCID= "$FILE" | cut -f2 -d= | tr -d \[:cntrl:\])
212         CDDBGENRE=$(grep '^#CATEGORY=' "$FILE" | cut -f2- -d= | tr -d \[:cntrl:\])
213         # Use bsd-mailx by preference if we can, as it allows addition
214         # of extra headers. Otherwise, try to force UTF-8 via environment
215         if new_checkexec bsd-mailx; then
216                 grep -v "^#CATEGORY=" "$FILE" | iconv -t utf-8 | bsd-mailx -a "Content-Type: text/plain; charset=utf-8" -s "cddb $CDDBGENRE $DISCID" "$ADDRESS"
217         else
218                 # Find the first UTF-8 locale on the system, if any
219                 UTF_LOCALE=$(locale -a | awk '/UTF-8/ { print $1; exit}')
220                 if [ "$UTF_LOCALE"x != ""x ] ; then
221                         export LC_ALL=$UTF_LOCALE
222                 fi
223                 grep -v "^#CATEGORY=" "$FILE" | iconv -t utf-8 | mail -s "cddb $CDDBGENRE $DISCID" "$ADDRESS"
224         fi
225         ;;
226
227 query) # cddb-tool query serverurl proto user host discid...
228         SERVER="$1"
229         PROTO="$2"
230         USER="$3"
231         HOST="$4"
232         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
233         shift 4
234         TRACKINFO="$@"
235         TRACKINFOPLUS=$(echo $TRACKINFO | tr ' ' '+')
236         RESULTS=$($HTTPGET "$SERVER?cmd=cddb+query+$TRACKINFOPLUS&hello=$HELLOINFO&proto=$PROTO") || exit $LOOKUP_ERR
237         echo "$RESULTS" | tr '\r' '\n' | tr -s '\n' | sed 's/^ //g'
238         ;;
239
240 read) # cddb-tool read serverurl proto user host genre discnumber
241         SERVER="$1"
242         PROTO="$2"
243         USER="$3"
244         HOST="$4"
245         CATEGORY="$5"
246         DISCID="$6"
247         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
248         $HTTPGET $CDDBDATA "$SERVER?cmd=cddb+read+$CATEGORY+$DISCID&hello=$HELLOINFO&proto=$PROTO" 2>/dev/null
249         ;;
250
251 stat) # cddb-tool stat serverurl user host proto
252         SERVER="$1"
253         USER="$2"
254         HOST="$3"
255         PROTO="$4"
256         HELLOINFO="$USER+$HOST+$NAME+$VERSION"
257         $HTTPGET $CDDBDATA "$SERVER?cmd=stat&hello=$HELLOINFO&proto=$PROTO" 2>/dev/null
258         ;;
259
260 help) # help
261         help
262         ;;
263
264 *) # usage
265         usage
266         ;;
267 esac