Add support for Musicbrainz using a perl helper script.
authorEinvalSledge@gmail.com <EinvalSledge@gmail.com@a0fa61bc-5347-0410-a1a9-7f54aa4e1825>
Fri, 13 Apr 2012 20:56:01 +0000 (20:56 +0000)
committerEinvalSledge@gmail.com <EinvalSledge@gmail.com@a0fa61bc-5347-0410-a1a9-7f54aa4e1825>
Fri, 13 Apr 2012 20:56:01 +0000 (20:56 +0000)
git-svn-id: http://abcde.googlecode.com/svn/trunk@295 a0fa61bc-5347-0410-a1a9-7f54aa4e1825

FAQ
Makefile
abcde
abcde-musicbrainz-tool [new file with mode: 0644]
abcde.1
abcde.conf
changelog

diff --git a/FAQ b/FAQ
index 419139b..8e136ae 100644 (file)
--- a/FAQ
+++ b/FAQ
@@ -3,8 +3,10 @@
 
 Q. Who created abcde? Who develops it nowadays?
 A. It was originally created by Robert Woodcook. He decided to give up 
 
 Q. Who created abcde? Who develops it nowadays?
 A. It was originally created by Robert Woodcook. He decided to give up 
-   maintaining it at some point in 2002 and Jesus Climent took over.  Contact
-   jesus.climent@hispalinux.es if you have a problem or a suggestion.
+   maintaining it at some point in 2002 and Jesus Climent took over. In 2012,
+   Colin Tuckley and Steve McIntyre joined in to help. Contact
+   jesus.climent@hispalinux.es, colint@debian.org or 93sam@debian.org if you
+   have a problem or a suggestion.
 
 
 1. INSTALLATION
 
 
 1. INSTALLATION
@@ -156,8 +158,8 @@ A. Yes. Use "abcde -1 -o flac -a default,cue" and it will create a single-track
    Ogg/Vorbis format. Of course you can select whatever format you want.
    
 
    Ogg/Vorbis format. Of course you can select whatever format you want.
    
 
-3. CDDB
-   ====
+3. CDDB and Musicbrainz
+   ====================
 
 Q. I need to go through an HTTP proxy for CDDB access. 
 A. No problem, just export your http_proxy variable first so wget/fetch/curl 
 
 Q. I need to go through an HTTP proxy for CDDB access. 
 A. No problem, just export your http_proxy variable first so wget/fetch/curl 
@@ -182,6 +184,8 @@ Q. After requesting CDDB data, I received several answers which seem to be
 A. Yes. When asked which one you want to select, use "X,Y" where X and Y are
    the numbers of the selections you want to find the difference between.
 
 A. Yes. When asked which one you want to select, use "X,Y" where X and Y are
    the numbers of the selections you want to find the difference between.
 
+Q. I don't like CDDB/FreeDB. How can I use Musicbrainz instead?
+A. Set CDDBMETHOD=musicbrainz and try it!
 
 3. FORMATS
    =======
 
 3. FORMATS
    =======
index 0a2c6ad..002ddea 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,7 @@ install:
        $(INSTALL) -d -m 755 $(bindir)
        $(INSTALL) -m 755 -o 0 abcde $(bindir)
        $(INSTALL) -m 755 -o 0 cddb-tool $(bindir)
        $(INSTALL) -d -m 755 $(bindir)
        $(INSTALL) -m 755 -o 0 abcde $(bindir)
        $(INSTALL) -m 755 -o 0 cddb-tool $(bindir)
+       $(INSTALL) -m 755 -o 0 abcde-musicbrainz-tool $(bindir)
        $(INSTALL) -d -m 755 $(mandir)
        $(INSTALL) -m 644 -o 0 abcde.1 $(mandir)
        $(INSTALL) -m 644 -o 0 cddb-tool.1 $(mandir)
        $(INSTALL) -d -m 755 $(mandir)
        $(INSTALL) -m 644 -o 0 abcde.1 $(mandir)
        $(INSTALL) -m 644 -o 0 cddb-tool.1 $(mandir)
diff --git a/abcde b/abcde
index 4f36556..d585c16 100755 (executable)
--- a/abcde
+++ b/abcde
@@ -1785,8 +1785,7 @@ do_discid ()
                        *)
                                case "$CDDBMETHOD" in
                                        cddb) TRACKINFO=$($CDDISCID "$CDROM") ;;
                        *)
                                case "$CDDBMETHOD" in
                                        cddb) TRACKINFO=$($CDDISCID "$CDROM") ;;
-                                       # FIXME # musicbrainz needs a cleanup
-                                       musicbrainz) TRACKINFO=$($MUSICBRAINZ -c "$CDROM" ) ;;
+                                       musicbrainz) TRACKINFO=$($MUSICBRAINZ --command id --device "$CDROM") ;;
                                esac
                                ;;
                esac
                                esac
                                ;;
                esac
@@ -2218,15 +2217,76 @@ do_localcddb ()
        fi
 }
 
        fi
 }
 
-do_musicbrainzstat ()
-{
-       :
-}
+# do_musicbrainz
+# Work with the musicbrainz WS API, then transform the results here so
+# they look (very) like the results from CDDB. Maybe not the best way
+# to go, but it Works For Me (TM)
 
 do_musicbrainz ()
 {
 
 do_musicbrainz ()
 {
-# Use MBE_TOCGetCDIndexId on a perl query
-       :
+       if checkstatus musicbrainz-readcomplete; then :; else
+               vecho "Obtaining Musicbrainz results..."
+               # If MB is to be used, interpret the query results and read all
+               # the available entries.
+               rm -f "$ABCDETEMPDIR/cddbchoices"
+               CDDBCHOICES=1 # Overridden by multiple matches
+               ${MUSICBRAINZ} --command data --device "$CDROM" --workdir $ABCDETEMPDIR
+
+               # The helper script will write disc matches out to
+               # cddbread.*. Count how many we have
+               NUM_RESPONSES=$(echo ${ABCDETEMPDIR}/cddbread.* | wc -w)
+               if [ "$NUM_RESPONSES" -eq 1 ] ; then
+                       # One exact match
+                       echo -n "Retrieved 1 Musicbrainz match..." >> "$ABCDETEMPDIR/cddbchoices"
+                       echo "done." >> "$ABCDETEMPDIR/cddbchoices"
+                       echo cddb-read-1-complete >> "$ABCDETEMPDIR/status"
+                       echo cddb-choice=1 >> "$ABCDETEMPDIR/status"
+                       ATITLE=$(grep -e '^DTITLE=' ${ABCDETEMPDIR}/cddbread.1 | cut -c8- )
+                       echo "200 none ${ATITLE}" >> "$ABCDETEMPDIR/cddbquery"
+                       # List out disc title/author and contents
+                       echo ---- ${ATITLE} ---- >> "$ABCDETEMPDIR/cddbchoices"
+                       for TRACK in $(f_seq_row 1 $TRACKS)
+                       do
+                               echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.1" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
+                       done
+                       echo >> "$ABCDETEMPDIR/cddbchoices"
+               elif [ "$NUM_RESPONSES" -eq 0 ] ; then
+                       # No matches. Use the normal cddb template for the user to
+                       # fill in
+                       echo "No Musicbrainz match." >> "$ABCDETEMPDIR/cddbchoices"
+                       $CDDBTOOL template $(cat "$ABCDETEMPDIR/discid") > "$ABCDETEMPDIR/cddbread.0"
+                       # List out disc title/author and contents of template
+                       echo ---- Unknown Artist / Unknown Album ---- >> "$ABCDETEMPDIR/cddbchoices"
+                       UNKNOWNDISK=y
+                       for TRACK in $(f_seq_row 1 $TRACKS)
+                       do
+                               echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.0" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
+                       done
+                       echo >> "$ABCDETEMPDIR/cddbchoices"
+                       echo cddb-read-0-complete >> "$ABCDETEMPDIR/status"
+                       echo cddb-choice=0 >> "$ABCDETEMPDIR/status"
+                       echo 503 > "$ABCDETEMPDIR/cddbquery"
+               else
+                       echo "210 Found exact matches, list follows (until terminating .)" > "$ABCDETEMPDIR/cddbquery"
+                       echo "Multiple Musicbrainz matches:" >> "$ABCDETEMPDIR/cddbchoices"
+                       for file in $ABCDETEMPDIR/cddbread.*
+                       do
+                               X=$(echo $file | sed 's/^.*cddbread\.//g')
+                               echo cddb-read-$X-complete >> "$ABCDETEMPDIR/status"
+                               ATITLE=$(grep -e '^DTITLE=' ${ABCDETEMPDIR}/cddbread.$X | cut -c8- )
+                               echo "none ${ATITLE}" >> "$ABCDETEMPDIR/cddbquery"
+                               # List out disc title/author and contents
+                               echo "#$X: ---- ${ATITLE} ----" >> "$ABCDETEMPDIR/cddbchoices"
+                               for TRACK in $(f_seq_row 1 $TRACKS)
+                               do
+                                       echo $TRACK: "$(grep ^TTITLE$(expr $TRACK - 1)= "$ABCDETEMPDIR/cddbread.$X" | cut -f2- -d= | tr -d \\r\\n)" >> "$ABCDETEMPDIR/cddbchoices"
+                               done
+                               echo >> "$ABCDETEMPDIR/cddbchoices"
+                       done
+                       echo "." >> "$ABCDETEMPDIR/cddbquery"
+               fi
+               echo "musicbrainz-readcomplete" >> "$ABCDETEMPDIR/status"
+       fi
 }
 
 # do_cddbstat
 }
 
 # do_cddbstat
@@ -2972,7 +3032,7 @@ post_encode ()
 # Builtin defaults
 
 # CDDB
 # Builtin defaults
 
 # CDDB
-# Defaults to FreeDB, but a python musicbrainz can be used
+# Defaults to FreeDB, but musicbrainz can be used too, via the abcde-musicbrainz-tool script
 CDDBMETHOD=cddb
 CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
 CDDBSUBMIT=freedb-submit@freedb.org
 CDDBMETHOD=cddb
 CDDBURL="http://freedb.freedb.org/~cddb/cddb.cgi"
 CDDBSUBMIT=freedb-submit@freedb.org
@@ -3065,7 +3125,7 @@ DAGRAB=dagrab
 CDDAFS=cp
 CDDISCID=cd-discid
 CDDBTOOL=cddb-tool
 CDDAFS=cp
 CDDISCID=cd-discid
 CDDBTOOL=cddb-tool
-MUSICBRAINZ=musicbrainz-get-tracks
+MUSICBRAINZ=abcde-musicbrainz-tool
 EJECT=eject
 MD5SUM=md5sum
 DISTMP3=distmp3
 EJECT=eject
 MD5SUM=md5sum
 DISTMP3=distmp3
@@ -3897,14 +3957,8 @@ if [ "$DOREAD" = "y" ]; then
        vecho "done."
 fi
 
        vecho "done."
 fi
 
-case "$CDDBMETHOD" in
-       cddb)
-               do_discid # Get ABCDETEMPDIR created and status file initialized
-               ;;
-       musicbrainz)
-               do_musicbrainz id
-               ;;
-esac
+# Get ABCDETEMPDIR created and status file initialized
+do_discid
 
 if [ "$DOCDDB" = "y" ]; then
        # start with a sane default:
 
 if [ "$DOCDDB" = "y" ]; then
        # start with a sane default:
diff --git a/abcde-musicbrainz-tool b/abcde-musicbrainz-tool
new file mode 100644 (file)
index 0000000..7a0f567
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/perl
+# Copyright (c) 2012 Steve McIntyre <93sam@debian.org>
+# This code is hereby licensed for public consumption under either the
+# GNU GPL v2 or greater, or Larry Wall's Artistic license - your choice.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+# abcde-musicbrainz-tool
+# 
+# Helper script for abcde to work with the MusicBrainz WS API (v2)
+
+use strict;
+use encoding "utf8";
+use MusicBrainz::DiscID;
+use WebService::MusicBrainz::Release;
+use WebService::MusicBrainz::Artist;
+use WebService::MusicBrainz::Response::Track;
+use WebService::MusicBrainz::Response::TrackList;
+use Getopt::Long;
+
+my $FRAMES_PER_SEC = 75;
+
+my ($device, $command, $workdir);
+Getopt::Long::Configure ('no_ignore_case');
+Getopt::Long::Configure ('no_auto_abbrev');
+GetOptions ("device=s"   => \$device,
+            "command=s"  => \$command,
+            "workdir=s" => \$workdir);
+
+if (!defined($device)) {
+    $device = "/dev/cdrom";
+}
+if (!defined($command)) {
+    $command = "id";
+}
+if (!defined($workdir)) {
+    $workdir = "/tmp";
+}
+
+my $disc = new MusicBrainz::DiscID($device);
+
+# read the disc in the default disc drive */
+if ( $disc->read() == 0 ) {
+    printf STDERR "Error: %s\n", $disc->error_msg();
+    exit(1);
+}
+
+if ($command =~ m/id/) {
+
+    printf("%s ", $disc->id());
+    printf("%d ", $disc->last_track_num() + 1 - $disc->first_track_num());
+    
+    for ( my $i = $disc->first_track_num;
+          $i <= $disc->last_track_num; $i++ ) {
+        printf("%d ", $disc->track_offset($i));
+    }
+    printf("%d\n", $disc->sectors() / $FRAMES_PER_SEC);
+
+} elsif ($command =~ m/data/) {
+    my $ws = WebService::MusicBrainz::Release->new();
+    my $response = $ws->search({ DISCID => $disc->id()});
+    my @releases = $response->release_list();
+    my $releasenum = 0;
+
+    foreach my $release (@releases) {
+        my $a_artist = $release->artist()->name();
+        my $va = 0;
+        if ($a_artist =~ /Various Artists/) {
+            $va = 1;
+        }
+        $releasenum++;
+        open (OUT, "> $workdir/cddbread.$releasenum");
+        binmode OUT, ":utf8";
+        print OUT "# xmcd style database file\n";
+        print OUT "#\n";
+        print OUT "# Track frame offsets:\n";
+        for ( my $i = $disc->first_track_num;
+              $i <= $disc->last_track_num; $i++ ) {
+            print OUT "#       " . $disc->track_offset($i) . "\n";
+        }
+        print OUT "#\n";
+        printf OUT "# Disc length: %d seconds\n", $disc->sectors() / $FRAMES_PER_SEC;
+        print OUT "#\n";
+        print OUT "# Submitted via: XXXXXX\n";
+        print OUT "#\n";
+        print OUT "#blues,classical,country,data,folk,jazz,newage,reggae,rock,soundtrack,misc\n";
+        print OUT "#CATEGORY=none\n";
+        print OUT "DISCID=" . $disc->id() . "\n";
+        print OUT "DTITLE=" . $a_artist. " / " . $release->title() . "\n";
+        print OUT "DYEAR=\n";
+        print OUT "DGENRE=\n";
+           
+        my @tracks = @{$release->track_list()->tracks()};
+        for (my $i = 0; $i < scalar(@tracks); $i++) {
+            my $track = $tracks[$i];
+            my $t_name = $track->title;
+            if ($va) {
+                my $t_artist = $track->artist->name;
+                printf OUT "TTITLE%d=%s / %s\n", $i, $t_artist, $t_name;
+            } else {
+                printf OUT "TTITLE%d=%s\n", $i, $t_name;
+            }
+        }
+
+        print OUT "EXTD=\n";
+        for (my $i = 0; $i < scalar(@tracks); $i++) {
+            printf OUT "EXTT%d=\n", $i;
+        }
+        print OUT "PLAYORDER=\n";
+        print OUT ".\n";
+        close OUT;
+    }
+}
+
+undef $disc;
diff --git a/abcde.1 b/abcde.1
index dd2c35d..706d601 100644 (file)
--- a/abcde.1
+++ b/abcde.1
@@ -245,7 +245,8 @@ Here is a list of options abcde recognizes:
 Specifies the method we want to use to retrieve the track information. Two
 values are recognized: "cddb" and "musicbrainz". The "cddb" value needs the
 CDDBURL and HELLOINFO variables described below. The "musicbrainz" value uses
 Specifies the method we want to use to retrieve the track information. Two
 values are recognized: "cddb" and "musicbrainz". The "cddb" value needs the
 CDDBURL and HELLOINFO variables described below. The "musicbrainz" value uses
-Python to establish a conversation with the server for information retrieval.
+the Perl helper script abcde-musicbrainz-tool to establish a
+conversation with the Musicbrainz server for information retrieval.
 .TP
 .B CDDBURL
 Specifies a server to use for CDDB lookups.
 .TP
 .B CDDBURL
 Specifies a server to use for CDDB lookups.
index 362b374..94ab5c6 100644 (file)
@@ -5,6 +5,8 @@
 # .abcde.conf file in your home directory.
 
 # CDDB options
 # .abcde.conf file in your home directory.
 
 # CDDB options
+# Choose whether you want to use CDDB or Musicbrainz. Default is CDDB
+#CDDBMETHOD=cddb
 
 # If you wish to use a different CDDB server, edit this line.
 # If you just wanted to use a proxy server, just set your http_proxy
 
 # If you wish to use a different CDDB server, edit this line.
 # If you just wanted to use a proxy server, just set your http_proxy
index a65fdee..800535f 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,3 +1,11 @@
+abcde 2.5.0, unreleased
+
+  * Bumped to 2.5.0
+  * Add support for Musicbrainz using a perl helper script.
+    Closes: #655970
+
+ -- Steve McIntyre <93sam@debian.org>  Fri, 13 Apr 2011 21:25:43 +0100
+
 abcde 2.4.2
 
   * Bumped to 2.4.2
 abcde 2.4.2
 
   * Bumped to 2.4.2