[sound-juicer/gnome-3-18] Use MCN to resolve multiple album matches



commit 35f865031ab3d8966f3b9767ad1db70079bf5aea
Author: Andreas Hehn <andreasgnmhehn noiseload de>
Date:   Tue Nov 3 22:54:48 2015 +0100

    Use MCN to resolve multiple album matches
    
    Retrieve barcode from MusicBrainz and read-out the MCN (Media catalog
    number) from the CD using libdiscid. If the MCN matches the barcode
    from MusicBrainz then return only the matching release which avoids
    showing the multiple album dialog.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=757247

 libjuicer/sj-metadata-musicbrainz5.c |   38 ++++++++++++++++++++++++++++++++-
 libjuicer/sj-structures.c            |    2 +
 libjuicer/sj-structures.h            |    2 +
 3 files changed, 40 insertions(+), 2 deletions(-)
---
diff --git a/libjuicer/sj-metadata-musicbrainz5.c b/libjuicer/sj-metadata-musicbrainz5.c
index eeeb246..edb1cda 100644
--- a/libjuicer/sj-metadata-musicbrainz5.c
+++ b/libjuicer/sj-metadata-musicbrainz5.c
@@ -348,6 +348,7 @@ get_release_labels (Mb5Release *release)
     label_data = g_new0 (LabelDetails, 1);
     label_data->name = g_strdup (buffer);
     GET (label_data->sortname, mb5_label_get_sortname, label);
+    GET (label_data->catalog_number, mb5_labelinfo_get_catalognumber, info);
     label_list = g_list_prepend (label_list, label_data);
   skip:
     ;
@@ -901,6 +902,8 @@ make_album_from_release (SjMetadataMusicbrainz5  *self,
   }
 
   album->disc_number = mb5_medium_get_position (medium);
+
+  GET(album->barcode, mb5_release_get_barcode, release);
   fill_tracks_from_medium (self, medium, album, cancellable, error);
   if (*error != NULL)
     return NULL;
@@ -914,6 +917,30 @@ make_album_from_release (SjMetadataMusicbrainz5  *self,
   return album;
 }
 
+static gboolean
+album_barcode_matches_discid_mcn (const char *barcode,
+                                  DiscId     *disc)
+{
+  const char *mcn;
+
+  if (barcode == NULL || !discid_has_feature(DISCID_FEATURE_MCN))
+    return FALSE;
+
+  mcn = discid_get_mcn (disc);
+  if (mcn == NULL)
+    return FALSE;
+  /* The MCN should match an EAN barcode (13 digits)
+   * or an UPC barcode (12 digits) with a leading '0'.
+   */
+  gsize len = strlen (barcode);
+  if (len == 12) /* UPC barcode - skip leading '0' */
+    return *mcn == '0' && strcmp (mcn + 1, barcode) == 0;
+  else if (len == 13) /* EAN barcode */
+    return strcmp (mcn, barcode) == 0;
+  else /* Unknown/invalid barcode */
+    return FALSE;
+}
+
 /*
  * Virtual methods
  */
@@ -933,6 +960,7 @@ mb5_list_albums (SjMetadata    *metadata,
   char buffer[1024];
   int i;
   DiscId disc = NULL;
+  gboolean mcn_matches = FALSE;
 
   g_return_val_if_fail (SJ_IS_METADATA_MUSICBRAINZ5 (metadata), NULL);
 
@@ -946,7 +974,7 @@ mb5_list_albums (SjMetadata    *metadata,
   disc = discid_new ();
   if (disc == NULL)
     return NULL;
-  if (discid_read_sparse (disc, priv->cdrom, 0) == 0)
+  if (discid_read_sparse (disc, priv->cdrom, DISCID_FEATURE_MCN) == 0)
     goto free_discid;
 
   if (url != NULL)
@@ -972,7 +1000,7 @@ mb5_list_albums (SjMetadata    *metadata,
   if (mb5_release_list_size (releases) == 0)
     return NULL;
 
-  for (i = 0; i < mb5_release_list_size (releases); i++) {
+  for (i = 0; i < mb5_release_list_size (releases) && !mcn_matches; i++) {
     AlbumDetails *album;
 
     release = mb5_release_list_item (releases, i);
@@ -1037,6 +1065,12 @@ artist-rels";
             }
 
             album->metadata_source = SOURCE_MUSICBRAINZ;
+            mcn_matches = album_barcode_matches_discid_mcn (album->barcode, disc);
+            if (mcn_matches) {
+              g_list_free_full (albums, (GDestroyNotify) album_details_free);
+              albums = g_list_append (NULL, album);
+              break;
+            }
             albums = g_list_append (albums, album);
           }
         }
diff --git a/libjuicer/sj-structures.c b/libjuicer/sj-structures.c
index ebd7181..579b9c8 100644
--- a/libjuicer/sj-structures.c
+++ b/libjuicer/sj-structures.c
@@ -59,6 +59,7 @@ void album_details_free(AlbumDetails *album)
   g_free (album->wikipedia);
   g_free (album->lyrics_url);
   g_free (album->country);
+  g_free (album->barcode);
   g_free (album->type);
   g_list_free_full (album->labels, (GDestroyNotify)label_details_free);
   g_free (album);
@@ -112,5 +113,6 @@ void label_details_free (LabelDetails *label)
 {
   g_free (label->name);
   g_free (label->sortname);
+  g_free (label->catalog_number);
   g_free (label);
 }
diff --git a/libjuicer/sj-structures.h b/libjuicer/sj-structures.h
index 5cb0b50..28e4aa6 100644
--- a/libjuicer/sj-structures.h
+++ b/libjuicer/sj-structures.h
@@ -81,6 +81,7 @@ struct _AlbumDetails {
   char *type;
   char *lyrics_url;
   char *country;
+  char *barcode;
 };
 
 struct _ArtistDetails {
@@ -101,6 +102,7 @@ struct _ArtistCredit
 struct _LabelDetails {
   char *name;
   char *sortname;
+  char *catalog_number;
 };
 
 void album_details_free(AlbumDetails *album);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]