update music brainz album responses

pull/702/head
Luke Pulverenti 8 years ago
parent 023b12a798
commit cc2ac9e387

@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Music
private readonly IApplicationHost _appHost; private readonly IApplicationHost _appHost;
private readonly ILogger _logger; 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) public MusicBrainzAlbumProvider(IHttpClient httpClient, IApplicationHost appHost, ILogger logger)
{ {
@ -44,7 +44,7 @@ namespace MediaBrowser.Providers.Music
if (!string.IsNullOrEmpty(releaseId)) 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 else
{ {
@ -52,7 +52,7 @@ namespace MediaBrowser.Providers.Music
if (!string.IsNullOrWhiteSpace(artistMusicBrainzId)) 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), WebUtility.UrlEncode(searchInfo.Name),
artistMusicBrainzId); artistMusicBrainzId);
} }
@ -60,7 +60,7 @@ namespace MediaBrowser.Providers.Music
{ {
isNameSearch = true; 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.Name),
WebUtility.UrlEncode(searchInfo.GetAlbumArtist())); WebUtility.UrlEncode(searchInfo.GetAlbumArtist()));
} }
@ -199,57 +199,86 @@ namespace MediaBrowser.Providers.Music
private async Task<ReleaseResult> GetReleaseResult(string albumName, string artistId, CancellationToken cancellationToken) 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), WebUtility.UrlEncode(albumName),
artistId); artistId);
var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false); 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) 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(albumName),
WebUtility.UrlEncode(artistName)); WebUtility.UrlEncode(artistName));
var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false); 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); public string ReleaseId;
ns.AddNamespace("mb", MusicBrainzBaseUrl + "/ns/mmd-2.0#"); public string ReleaseGroupId;
var result = new ReleaseResult public static ReleaseResult Parse(XmlDocument doc)
{ {
var docElem = doc.DocumentElement;
}; if (docElem == null)
{
var releaseIdNode = doc.SelectSingleNode("//mb:release-list/mb:release/@id", ns); return new ReleaseResult();
}
if (releaseIdNode != null) var releaseList = docElem.FirstChild;
if (releaseList == null)
{ {
result.ReleaseId = releaseIdNode.Value; return new ReleaseResult();
} }
var releaseGroupIdNode = doc.SelectSingleNode("//mb:release-list/mb:release/mb:release-group/@id", ns); var nodes = releaseList.ChildNodes;
string releaseId = null;
string releaseGroupId = null;
if (releaseGroupIdNode != null) if (nodes != null)
{
foreach (var node in nodes.Cast<XmlNode>())
{ {
result.ReleaseGroupId = releaseGroupIdNode.Value; if (string.Equals(node.Name, "release", StringComparison.OrdinalIgnoreCase))
{
releaseId = node.Attributes["id"].Value;
releaseGroupId = GetReleaseGroupIdFromReleaseNode(node);
break;
}
}
} }
return result; return new ReleaseResult
{
ReleaseId = releaseId,
ReleaseGroupId = releaseGroupId
};
} }
private class ReleaseResult private static string GetReleaseGroupIdFromReleaseNode(XmlNode node)
{ {
public string ReleaseId; var subNodes = node.ChildNodes;
public string ReleaseGroupId; if (subNodes != null)
{
foreach (var subNode in subNodes.Cast<XmlNode>())
{
if (string.Equals(subNode.Name, "release-group", StringComparison.OrdinalIgnoreCase))
{
return subNode.Attributes["id"].Value;
}
}
}
return null;
}
} }
/// <summary> /// <summary>
@ -260,7 +289,7 @@ namespace MediaBrowser.Providers.Music
/// <returns>Task{System.String}.</returns> /// <returns>Task{System.String}.</returns>
private async Task<string> GetReleaseGroupId(string releaseEntryId, CancellationToken cancellationToken) 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); var doc = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false);
@ -276,6 +305,49 @@ namespace MediaBrowser.Providers.Music
/// </summary> /// </summary>
private readonly SemaphoreSlim _musicBrainzResourcePool = new SemaphoreSlim(1, 1); 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> /// <summary>
/// Gets the music brainz response. /// Gets the music brainz response.
/// </summary> /// </summary>
@ -284,10 +356,16 @@ namespace MediaBrowser.Providers.Music
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{XmlDocument}.</returns> /// <returns>Task{XmlDocument}.</returns>
internal async Task<XmlDocument> GetMusicBrainzResponse(string url, bool isSearch, CancellationToken cancellationToken) internal async Task<XmlDocument> GetMusicBrainzResponse(string url, bool isSearch, CancellationToken cancellationToken)
{
var urlInfo = await GetMbzUrl().ConfigureAwait(false);
if (urlInfo.throttleMs > 0)
{ {
// MusicBrainz is extremely adamant about limiting to one request per second // 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(); var doc = new XmlDocument();
@ -319,5 +397,11 @@ namespace MediaBrowser.Providers.Music
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
internal class MbzUrl
{
public string url { get; set; }
public int throttleMs { get; set; }
}
} }
} }

@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Music
if (!string.IsNullOrWhiteSpace(musicBrainzId)) 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) var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -35,7 +35,7 @@ namespace MediaBrowser.Providers.Music
// They seem to throw bad request failures on any term with a slash // They seem to throw bad request failures on any term with a slash
var nameToSearch = searchInfo.Name.Replace('/', ' '); 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); var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.Music
if (HasDiacritics(searchInfo.Name)) if (HasDiacritics(searchInfo.Name))
{ {
// Try again using the search with accent characters url // 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); doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
@ -62,9 +62,6 @@ namespace MediaBrowser.Providers.Music
private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc) 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 list = new List<RemoteSearchResult>();
var docElem = doc.DocumentElement; var docElem = doc.DocumentElement;

Loading…
Cancel
Save