Fix getopts setup for "P"
[abcde.git] / abcde-musicbrainz-tool
index 3e83ad0..27efcef 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
-# Copyright (c) 2012 Steve McIntyre <93sam@debian.org>
+# Copyright (c) 2012-2018 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.
 #
@@ -16,16 +16,13 @@ use utf8;
 use POSIX qw(ceil);
 use Digest::SHA;
 use MusicBrainz::DiscID;
-use WebService::MusicBrainz::Release;
-use WebService::MusicBrainz::Artist;
-use WebService::MusicBrainz::Response::Track;
-use WebService::MusicBrainz::Response::TrackList;
+use WebService::MusicBrainz 1.0.4;
 use Getopt::Long;
 use Pod::Usage;
 
 my $FRAMES_PER_S = 75;
 
-my ($device, $command, $discid, @discinfo, $workdir, $help, $man);
+my ($device, $command, $discid, @discinfo, $workdir, $help, $man, $start);
 Getopt::Long::Configure ('no_ignore_case');
 Getopt::Long::Configure ('no_auto_abbrev');
 GetOptions ("device=s"       => \$device,
@@ -33,6 +30,7 @@ GetOptions ("device=s"       => \$device,
             "discid=s"       => \$discid,
             "discinfo=i{5,}" => \@discinfo,
             "workdir=s"      => \$workdir,
+            "start=s"        => \$start,
             "help|h"         => \$help,
             "man"            => \$man) or pod2usage(-verbose => 0, -exitcode => 2);
 if (@ARGV) {
@@ -52,6 +50,9 @@ if (!defined($command)) {
 if (!defined($workdir)) {
     $workdir = "/tmp";
 }
+if (!defined($start)) {
+    $start = "0";
+}
 
 sub calc_sha1($) {
     my $filename = shift;
@@ -83,20 +84,31 @@ if ($command =~ m/^id/) {
        print STDERR "Discid undefined.\n";
        exit(1);
     }
-    my $ws = WebService::MusicBrainz::Release->new();
-    my $response = $ws->search({ DISCID => $discid });
-    my @releases = $response->release_list();
-    my $releasenum = 0;
+    my $ws = WebService::MusicBrainz->new();
+    my $response = $ws->search(discid => {
+       discid => $discid,
+       inc => ['artists', 'artist-credits', 'recordings']
+        });
+    my @releases = @{ $response->{'releases'} };
+    my $releasenum = $start;
     my @sums;
 
     foreach my $release (@releases) {
-        my $a_artist = $release->artist()->name();
+        my $a_artist = "";
+        if (@{ $release->{'artist-credit'} } > 0) {
+            $a_artist = @{ $release->{'artist-credit'} }[0]->{'name'};
+        }
         my $va = 0;
+        my $rel_year = "";
         if ($a_artist =~ /Various Artists/) {
             $va = 1;
         }
-       my @events = @{$release->release_event_list()->events()};
-       my $rel_year =  substr($events[0]->date(),0,4);
+
+        my @release_events = @{ $release->{'release-events'} };
+
+        if (@release_events > 0) {
+            $rel_year =  substr(@release_events[0]->{'date'},0,4);
+        }
 
         $releasenum++;
         open (OUT, "> $workdir/cddbread.$releasenum");
@@ -104,13 +116,36 @@ if ($command =~ m/^id/) {
         print OUT "# xmcd style database file\n";
         print OUT "#\n";
         print OUT "# Track frame offsets:\n";
-        # Assume standard pregap
-        my $total_len = 2000;
-        my @tracks = @{$release->track_list()->tracks()};
+
+        my @offsets = @{ $response->{'offsets'}};
+        foreach my $offset (@offsets) {
+            printf OUT "#       %d\n", $offset;
+        }
+
+        # Locate the media that contains a disc with the discid we requested
+        # initially. The API may return multiple media associated with the
+        # release, including media with different discids
+        my @mediums = grep {
+            my @disks = @{ $_->{'discs'} };
+            grep { $_->{'id'} eq $discid } @disks;
+        } @{ $release->{'media'} };
+
+        if (not @mediums) {
+            # This release doesn't have a media with our requested dicsid
+            # Shouldn't happen (?), skip it
+            next;
+        }
+
+        # Only consider the first medium
+        my $medium = @mediums[0];
+        my @tracks = @{ $medium->{'tracks'} };
+
+        my $total_len = 0;
         for (my $i = 0; $i < scalar(@tracks); $i++) {
-            printf OUT "#       %d\n", ceil($total_len * $FRAMES_PER_S / 1000.0);
-            $total_len += $tracks[$i]->duration();
+            my $track = $tracks[$i];
+            $total_len += $track->{'length'};
         }
+
         print OUT "#\n";
         printf OUT "# Disc length: %d seconds\n", $total_len / 1000.0;
         print OUT "#\n";
@@ -119,16 +154,15 @@ if ($command =~ m/^id/) {
         print OUT "#blues,classical,country,data,folk,jazz,newage,reggae,rock,soundtrack,misc\n";
         print OUT "#CATEGORY=none\n";
         print OUT "DISCID=" . $discid . "\n";
-        print OUT "DTITLE=" . $a_artist. " / " . $release->title() . "\n";
+        print OUT "DTITLE=" . $a_artist. " / " . $release->{'title'} . "\n";
         print OUT "DYEAR=" . $rel_year . "\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;
+            my $t_name = $track->{'title'};
+            if ($va and @{ $track->{'artist-credit'} } > 0) {
+                my $t_artist = $track->{'artist-credit'}->[0]->{'name'};
                 printf OUT "TTITLE%d=%s / %s\n", $i, $t_artist, $t_name;
             } else {
                 printf OUT "TTITLE%d=%s\n", $i, $t_name;
@@ -145,12 +179,12 @@ if ($command =~ m/^id/) {
 
         # save release mbid
         open (OUT, "> $workdir/mbid.$releasenum");
-        print OUT $release->id;
+        print OUT $release->{'id'};
         close OUT;
 
         # save release asin
         open (OUT, "> $workdir/asin.$releasenum");
-        print OUT $release->asin;
+        print OUT $release->{'asin'};
         close OUT;
 
         # Check to see that this entry is unique; generate a checksum
@@ -166,9 +200,8 @@ if ($command =~ m/^id/) {
         push (@sums, $checksum);
     }
 } elsif ($command =~ m/calcid/) {
-# Calculate MusicBrainz ID from disc offsets; see
-# http://musicbrainz.org/doc/DiscIDCalculation
-
+    # Calculate MusicBrainz ID from disc offsets; see
+    # https://musicbrainz.org/doc/DiscIDCalculation
 
     if ($#discinfo < 5) {
        print STDERR "Insufficient or missing discinfo data.\n";
@@ -205,7 +238,7 @@ if ($command =~ m/^id/) {
     print $id;
     if (-t STDOUT) { print "\n"; }
 } else {
-    print STDERR "Unknown commmand given.\n";
+    print STDERR "Unknown command given.\n";
     pod2usage(1);
     exit(1);
 }