aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-06-15 15:52:38 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-06-15 15:52:38 -0400
commitcc2ac9e3879619920b84aba2132c2f1323fdeb71 (patch)
treea542001ce5d1f5d6eba03ef7284a1f090c67c544
parent023b12a798d6bf475a3b20488c1921e7fdb68dc5 (diff)
update music brainz album responses
-rw-r--r--MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs146
-rw-r--r--MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs9
2 files changed, 118 insertions, 37 deletions
diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
index d76c89dfb..09a0edcf0 100644
--- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
+++ b/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; }
+ }
}
}
diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
index 86563b2b9..f36062ebe 100644
--- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
+++ b/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;