Răsfoiți Sursa

update music brainz album responses

Luke Pulverenti 9 ani în urmă
părinte
comite
cc2ac9e387

+ 115 - 31
MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs

@@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Music
         private readonly IApplicationHost _appHost;
         private readonly ILogger _logger;
 
-        public static string MusicBrainzBaseUrl = "http://musicbrainz.fercasas.com:5000";
+        public static string MusicBrainzBaseUrl = "https://www.musicbrainz.org";
 
         public MusicBrainzAlbumProvider(IHttpClient httpClient, IApplicationHost appHost, ILogger logger)
         {
@@ -44,7 +44,7 @@ namespace MediaBrowser.Providers.Music
 
             if (!string.IsNullOrEmpty(releaseId))
             {
-                url = string.Format(MusicBrainzBaseUrl + "/ws/2/release/?query=reid:{0}", releaseId);
+                url = string.Format("/ws/2/release/?query=reid:{0}", releaseId);
             }
             else
             {
@@ -52,7 +52,7 @@ namespace MediaBrowser.Providers.Music
 
                 if (!string.IsNullOrWhiteSpace(artistMusicBrainzId))
                 {
-                    url = string.Format(MusicBrainzBaseUrl + "/ws/2/release/?query=\"{0}\" AND arid:{1}",
+                    url = string.Format("/ws/2/release/?query=\"{0}\" AND arid:{1}",
                         WebUtility.UrlEncode(searchInfo.Name),
                         artistMusicBrainzId);
                 }
@@ -60,7 +60,7 @@ namespace MediaBrowser.Providers.Music
                 {
                     isNameSearch = true;
 
-                    url = string.Format(MusicBrainzBaseUrl + "/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
+                    url = string.Format("/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
                        WebUtility.UrlEncode(searchInfo.Name),
                        WebUtility.UrlEncode(searchInfo.GetAlbumArtist()));
                 }
@@ -199,57 +199,86 @@ namespace MediaBrowser.Providers.Music
 
         private async Task<ReleaseResult> GetReleaseResult(string albumName, string artistId, CancellationToken cancellationToken)
         {
-            var url = string.Format(MusicBrainzBaseUrl + "/ws/2/release/?query=\"{0}\" AND arid:{1}",
+            var url = string.Format("/ws/2/release/?query=\"{0}\" AND arid:{1}",
                 WebUtility.UrlEncode(albumName),
                 artistId);
 
             var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
 
-            return GetReleaseResult(doc);
+            return ReleaseResult.Parse(doc);
         }
 
         private async Task<ReleaseResult> GetReleaseResultByArtistName(string albumName, string artistName, CancellationToken cancellationToken)
         {
-            var url = string.Format(MusicBrainzBaseUrl + "/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
+            var url = string.Format("/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
                 WebUtility.UrlEncode(albumName),
                 WebUtility.UrlEncode(artistName));
 
             var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
 
-            return GetReleaseResult(doc);
+            return ReleaseResult.Parse(doc);
         }
 
-        private ReleaseResult GetReleaseResult(XmlDocument doc)
+        private class ReleaseResult
         {
-            var ns = new XmlNamespaceManager(doc.NameTable);
-            ns.AddNamespace("mb", MusicBrainzBaseUrl + "/ns/mmd-2.0#");
+            public string ReleaseId;
+            public string ReleaseGroupId;
 
-            var result = new ReleaseResult
+            public static ReleaseResult Parse(XmlDocument doc)
             {
+                var docElem = doc.DocumentElement;
 
-            };
+                if (docElem == null)
+                {
+                    return new ReleaseResult();
+                }
 
-            var releaseIdNode = doc.SelectSingleNode("//mb:release-list/mb:release/@id", ns);
+                var releaseList = docElem.FirstChild;
+                if (releaseList == null)
+                {
+                    return new ReleaseResult();
+                }
 
-            if (releaseIdNode != null)
-            {
-                result.ReleaseId = releaseIdNode.Value;
-            }
+                var nodes = releaseList.ChildNodes;
+                string releaseId = null;
+                string releaseGroupId = null;
 
-            var releaseGroupIdNode = doc.SelectSingleNode("//mb:release-list/mb:release/mb:release-group/@id", ns);
+                if (nodes != null)
+                {
+                    foreach (var node in nodes.Cast<XmlNode>())
+                    {
+                        if (string.Equals(node.Name, "release", StringComparison.OrdinalIgnoreCase))
+                        {
+                            releaseId = node.Attributes["id"].Value;
+                            releaseGroupId = GetReleaseGroupIdFromReleaseNode(node);
+                            break;
+                        }
+                    }
+                }
 
-            if (releaseGroupIdNode != null)
-            {
-                result.ReleaseGroupId = releaseGroupIdNode.Value;
+                return new ReleaseResult
+                {
+                    ReleaseId = releaseId,
+                    ReleaseGroupId = releaseGroupId
+                };
             }
 
-            return result;
-        }
+            private static string GetReleaseGroupIdFromReleaseNode(XmlNode node)
+            {
+                var subNodes = node.ChildNodes;
+                if (subNodes != null)
+                {
+                    foreach (var subNode in subNodes.Cast<XmlNode>())
+                    {
+                        if (string.Equals(subNode.Name, "release-group", StringComparison.OrdinalIgnoreCase))
+                        {
+                            return subNode.Attributes["id"].Value;
+                        }
+                    }
+                }
 
-        private class ReleaseResult
-        {
-            public string ReleaseId;
-            public string ReleaseGroupId;
+                return null;
+            }
         }
 
         /// <summary>
@@ -260,7 +289,7 @@ namespace MediaBrowser.Providers.Music
         /// <returns>Task{System.String}.</returns>
         private async Task<string> GetReleaseGroupId(string releaseEntryId, CancellationToken cancellationToken)
         {
-            var url = string.Format(MusicBrainzBaseUrl + "/ws/2/release-group/?query=reid:{0}", releaseEntryId);
+            var url = string.Format("/ws/2/release-group/?query=reid:{0}", releaseEntryId);
 
             var doc = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false);
 
@@ -276,6 +305,49 @@ namespace MediaBrowser.Providers.Music
         /// </summary>
         private readonly SemaphoreSlim _musicBrainzResourcePool = new SemaphoreSlim(1, 1);
 
+        private long _lastMbzUrlQueryTicks = 0;
+        private List<MbzUrl> _mbzUrls = null;
+        private MbzUrl _chosenUrl;
+
+        private async Task<MbzUrl> GetMbzUrl()
+        {
+            if (_mbzUrls == null || (DateTime.UtcNow.Ticks - _lastMbzUrlQueryTicks) > TimeSpan.FromHours(12).Ticks)
+            {
+                await RefreshMzbUrls().ConfigureAwait(false);
+
+                var urls = _mbzUrls.ToList();
+                _chosenUrl = urls[new Random().Next(0, urls.Count - 1)];
+            }
+
+            return _chosenUrl;
+        }
+
+        private async Task RefreshMzbUrls()
+        {
+            try
+            {
+                _mbzUrls = new List<MbzUrl>
+                {
+                    new MbzUrl
+                    {
+                        url = MusicBrainzBaseUrl,
+                        throttleMs = 1000
+                    }
+                };
+            }
+            catch
+            {
+                _mbzUrls = new List<MbzUrl>
+                {
+                    new MbzUrl
+                    {
+                        url = MusicBrainzBaseUrl,
+                        throttleMs = 1000
+                    }
+                };
+            }
+        }
+
         /// <summary>
         /// Gets the music brainz response.
         /// </summary>
@@ -285,9 +357,15 @@ namespace MediaBrowser.Providers.Music
         /// <returns>Task{XmlDocument}.</returns>
         internal async Task<XmlDocument> GetMusicBrainzResponse(string url, bool isSearch, CancellationToken cancellationToken)
         {
-            // MusicBrainz is extremely adamant about limiting to one request per second
+            var urlInfo = await GetMbzUrl().ConfigureAwait(false);
+
+            if (urlInfo.throttleMs > 0)
+            {
+                // MusicBrainz is extremely adamant about limiting to one request per second
+                await Task.Delay(urlInfo.throttleMs, cancellationToken).ConfigureAwait(false);
+            }
 
-            await Task.Delay(1000, cancellationToken).ConfigureAwait(false);
+            url = urlInfo.url.TrimEnd('/') + url;
 
             var doc = new XmlDocument();
 
@@ -319,5 +397,11 @@ namespace MediaBrowser.Providers.Music
         {
             throw new NotImplementedException();
         }
+
+        internal class MbzUrl
+        {
+            public string url { get; set; }
+            public int throttleMs { get; set; }
+        }
     }
 }

+ 3 - 6
MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs

@@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Music
 
             if (!string.IsNullOrWhiteSpace(musicBrainzId))
             {
-                var url = string.Format(MusicBrainzAlbumProvider.MusicBrainzBaseUrl + "/ws/2/artist/?query=arid:{0}", musicBrainzId);
+                var url = string.Format("/ws/2/artist/?query=arid:{0}", musicBrainzId);
 
                 var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
                             .ConfigureAwait(false);
@@ -35,7 +35,7 @@ namespace MediaBrowser.Providers.Music
                 // They seem to throw bad request failures on any term with a slash
                 var nameToSearch = searchInfo.Name.Replace('/', ' ');
 
-                var url = String.Format(MusicBrainzAlbumProvider.MusicBrainzBaseUrl + "/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
+                var url = String.Format("/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
 
                 var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
 
@@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.Music
                 if (HasDiacritics(searchInfo.Name))
                 {
                     // Try again using the search with accent characters url
-                    url = String.Format(MusicBrainzAlbumProvider.MusicBrainzBaseUrl + "/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
+                    url = String.Format("/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
 
                     doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
 
@@ -62,9 +62,6 @@ namespace MediaBrowser.Providers.Music
 
         private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
         {
-            //var ns = new XmlNamespaceManager(doc.NameTable);
-            //ns.AddNamespace("mb", "https://musicbrainz.org/ns/mmd-2.0#");
-
             var list = new List<RemoteSearchResult>();
 
             var docElem = doc.DocumentElement;