[banshee] [Banshee.Metadata] Improve MusicBrainz coverart search



commit 79aa7b6b0589101cd05ca21d4fdbb1c7424ccf8e
Author: Aurélien Mino <aurelien mino gmail com>
Date:   Fri Nov 5 09:56:59 2010 -0500

    [Banshee.Metadata] Improve MusicBrainz coverart search
    
    Use MusicBrainz# for the API queries, use the track's MB IDs if
    available, and fetch from Jamendo and CDBaby if MB points to coverart
    there.  Fixes bgo#621254
    
    Signed-off-by: Gabriel Burt <gabriel burt gmail com>

 build/build.environment.mk                         |    2 +-
 .../MusicBrainzQueryJob.cs                         |  153 +++++++++++++-------
 2 files changed, 99 insertions(+), 56 deletions(-)
---
diff --git a/build/build.environment.mk b/build/build.environment.mk
index 641db4d..11a83ad 100644
--- a/build/build.environment.mk
+++ b/build/build.environment.mk
@@ -89,7 +89,7 @@ REF_BANSHEE_CORE = $(LINK_HYENA_DEPS) $(LINK_MONO_POSIX) $(LINK_GLIB) \
 LINK_BANSHEE_CORE = -r:$(DIR_BIN)/Banshee.Core.dll
 LINK_BANSHEE_CORE_DEPS = $(REF_BANSHEE_CORE) $(LINK_BANSHEE_CORE)
 
-REF_BANSHEE_SERVICES = $(LINK_SQLITE) $(LINK_BANSHEE_CORE_DEPS) $(LINK_MONO_MEDIA_DEPS) $(LINK_LASTFM_DEPS)
+REF_BANSHEE_SERVICES = $(LINK_SQLITE) $(LINK_BANSHEE_CORE_DEPS) $(LINK_MONO_MEDIA_DEPS) $(LINK_LASTFM_DEPS) $(LINK_MUSICBRAINZ_DEPS)
 LINK_BANSHEE_SERVICES = -r:$(DIR_BIN)/Banshee.Services.dll
 LINK_BANSHEE_SERVICES_DEPS = $(REF_BANSHEE_SERVICES) $(LINK_BANSHEE_SERVICES)
 
diff --git a/src/Core/Banshee.Services/Banshee.Metadata.MusicBrainz/MusicBrainzQueryJob.cs b/src/Core/Banshee.Services/Banshee.Metadata.MusicBrainz/MusicBrainzQueryJob.cs
index cab9f1b..7dc9248 100644
--- a/src/Core/Banshee.Services/Banshee.Metadata.MusicBrainz/MusicBrainzQueryJob.cs
+++ b/src/Core/Banshee.Services/Banshee.Metadata.MusicBrainz/MusicBrainzQueryJob.cs
@@ -3,8 +3,10 @@
 //
 // Author:
 //   Aaron Bockover <abockover novell com>
+//   Aurélien Mino <aurelien mino gmail com>
 //
 // Copyright (C) 2006-2008 Novell, Inc.
+// Copyright (C) 2010 Aurélien Mino
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -27,12 +29,17 @@
 //
 
 using System;
+using System.Collections;
 using System.IO;
 using System.Net;
 using System.Xml;
 using System.Text;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Web;
+using System.Text.RegularExpressions;
+
+using MusicBrainz;
 
 using Hyena;
 using Banshee.Base;
@@ -41,6 +48,7 @@ using Banshee.Kernel;
 using Banshee.Collection;
 using Banshee.Streaming;
 using Banshee.Networking;
+using Banshee.Collection.Database;
 
 namespace Banshee.Metadata.MusicBrainz
 {
@@ -48,16 +56,33 @@ namespace Banshee.Metadata.MusicBrainz
     {
         private static string AmazonUriFormat = "http://images.amazon.com/images/P/{0}.01._SCLZZZZZZZ_.jpg";;
 
-        private string asin;
-
-        public MusicBrainzQueryJob (IBasicTrackInfo track)
+        class CoverArtSite
         {
-            Track = track;
+             public Regex Regex;
+             public string ImgURI;
+
+             public CoverArtSite (Regex regex, string img_URI) {
+                this.Regex = regex;
+                this.ImgURI = img_URI;
+             }
         }
 
-        public MusicBrainzQueryJob (IBasicTrackInfo track, string asin) : this (track)
+        private static CoverArtSite [] CoverArtSites = new CoverArtSite [] {
+            // CDBaby
+            new CoverArtSite (
+                new Regex (@"http://(?:www\.)?cdbaby.com/cd/(\w)(\w)(\w*)"),
+                "http://cdbaby.name/{0}/{1}/{0}{1}{2}.jpg";
+            ),
+            // Jamendo
+            new CoverArtSite (
+                new Regex (@"http:\/\/(?:www\.)?jamendo.com\/(?:[a-z]+\/)?album\/([0-9]+)"),
+                "http://www.jamendo.com/get/album/id/album/artworkurl/redirect/{0}/?artwork_size=0";
+            )
+        };
+
+        public MusicBrainzQueryJob (IBasicTrackInfo track)
         {
-            this.asin = asin;
+            Track = track;
         }
 
         public override void Run ()
@@ -67,6 +92,7 @@ namespace Banshee.Metadata.MusicBrainz
 
         public bool Lookup ()
         {
+
             if (Track == null || (Track.MediaAttributes & TrackMediaAttributes.Podcast) != 0) {
                 return false;
             }
@@ -81,68 +107,85 @@ namespace Banshee.Metadata.MusicBrainz
                 return false;
             }
 
-            if (asin == null) {
-                asin = FindAsin ();
-                if (asin == null) {
-                    return false;
+            DatabaseTrackInfo dbtrack;
+            dbtrack = Track as DatabaseTrackInfo;
+
+            Release release;
+
+            // If we have the MBID of the album, we can do a direct MusicBrainz lookup
+            if (dbtrack != null && dbtrack.AlbumMusicBrainzId != null) {
+
+                release = Release.Get (dbtrack.AlbumMusicBrainzId);
+                if (!String.IsNullOrEmpty (release.GetAsin ()) && SaveCover (String.Format (AmazonUriFormat, release.GetAsin ()))) {
+                    return true;
                 }
-            }
 
-            if (SaveHttpStreamCover (new Uri (String.Format (AmazonUriFormat, asin)), artwork_id,
-                new string [] { "image/gif" })) {
-                Log.Debug ("Downloaded cover art from Amazon", artwork_id);
-                StreamTag tag = new StreamTag ();
-                tag.Name = CommonTags.AlbumCoverId;
-                tag.Value = artwork_id;
+            // Otherwise we do a MusicBrainz search
+            } else {
+                ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
+                parameters.Title = Track.AlbumTitle;
+                parameters.Artist = Track.AlbumArtist;
+                if (dbtrack != null) {
+                    parameters.TrackCount = dbtrack.TrackCount;
+                }
 
-                AddTag (tag);
+                Query<Release> query = Release.Query (parameters);
+                release = query.PerfectMatch ();
 
-                return true;
+                foreach (Release r in query.Best ()) {
+                    if (!String.IsNullOrEmpty (r.GetAsin ()) && SaveCover (String.Format (AmazonUriFormat, r.GetAsin ()))) {
+                        return true;
+                    }
+                }
             }
 
-            return false;
-        }
+            if (release == null) {
+                return false;
+            }
 
-        // MusicBrainz has this new XML API, so I'm using that here
-        // instead of using the stuff in the MusicBrainz namespace
-        // which sucks and doesn't even appear to work anymore.
+            // No success with ASIN, let's try with other linked URLs
+            ReadOnlyCollection<UrlRelation> relations = release.GetUrlRelations ();
+            foreach (UrlRelation relation in relations) {
 
-        private string FindAsin ()
-        {
-            string album_artist = HttpUtility.UrlEncode (Track.AlbumArtist);
-            string album_title = HttpUtility.UrlEncode (Track.AlbumTitle);
-            Uri uri = new Uri (String.Format ("http://musicbrainz.org/ws/1/release/?type=xml&artist={0}&title={1}";,
-                album_artist, album_title));
-
-            HttpWebResponse response = GetHttpStream (uri);
-            if (response == null) {
-                return null;
-            }
+                foreach (CoverArtSite site in CoverArtSites) {
 
-            using (Stream stream = response.GetResponseStream ()) {
-                XmlTextReader reader = new XmlTextReader (stream);
-
-                bool haveMatch = false;
-
-                while (reader.Read ()) {
-                    if (reader.NodeType == XmlNodeType.Element) {
-                        switch (reader.LocalName) {
-                            case "release":
-                                haveMatch = reader["ext:score"] == "100";
-                                break;
-                            case "asin":
-                                if (haveMatch) {
-                                    return reader.ReadString ();
-                                }
-                            break;
-                        default:
-                            break;
+                   Match m = site.Regex.Match (relation.Target.AbsoluteUri);
+                   if (m.Success) {
+                        string [] parameters = new string [m.Groups.Count];
+                        for (int i = 1; i < m.Groups.Count; i++) {
+                            parameters[i-1] = m.Groups[i].Value;
                         }
-                    }
+
+                        String uri = String.Format (site.ImgURI, parameters);
+                        if (SaveCover (uri)) {
+                             return true;
+                        }
+                   }
+                }
+
+                if (relation.Type == "CoverArtLink" && SaveCover (relation.Target.AbsoluteUri)) {
+                   return true;
                 }
             }
 
-            return null;
+            return false;
         }
+
+        private bool SaveCover (string uri) {
+
+            string artwork_id = Track.ArtworkId;
+
+            if (SaveHttpStreamCover (new Uri (uri), artwork_id, null)) {
+                Log.Debug ("Downloaded cover art", artwork_id);
+                StreamTag tag = new StreamTag ();
+                tag.Name = CommonTags.AlbumCoverId;
+                tag.Value = artwork_id;
+
+                AddTag (tag);
+                return true;
+            }
+            return false;
+         }
+
     }
 }



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