aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Providers/Music
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-27 15:03:23 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-27 15:03:23 -0400
commite12f27d8ed9a9ecb36d19ac4dbceab9fa215315c (patch)
treef81057ceea7c7f1b6554ec365117c2f9a49dbfd4 /MediaBrowser.Providers/Music
parent7130d8a78f5d995ff53049477a2864a2a2dd2aff (diff)
make provider project portabl
Diffstat (limited to 'MediaBrowser.Providers/Music')
-rw-r--r--MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs245
-rw-r--r--MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs152
2 files changed, 241 insertions, 156 deletions
diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
index 9ed8f0a00..b1c38345e 100644
--- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
+++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
@@ -15,6 +15,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Xml;
namespace MediaBrowser.Providers.Music
{
@@ -26,15 +27,17 @@ namespace MediaBrowser.Providers.Music
private readonly IApplicationHost _appHost;
private readonly ILogger _logger;
private readonly IJsonSerializer _json;
+ private readonly IXmlReaderSettingsFactory _xmlSettings;
public static string MusicBrainzBaseUrl = "https://www.musicbrainz.org";
- public MusicBrainzAlbumProvider(IHttpClient httpClient, IApplicationHost appHost, ILogger logger, IJsonSerializer json)
+ public MusicBrainzAlbumProvider(IHttpClient httpClient, IApplicationHost appHost, ILogger logger, IJsonSerializer json, IXmlReaderSettingsFactory xmlSettings)
{
_httpClient = httpClient;
_appHost = appHost;
_logger = logger;
_json = json;
+ _xmlSettings = xmlSettings;
Current = this;
}
@@ -71,17 +74,18 @@ namespace MediaBrowser.Providers.Music
if (!string.IsNullOrWhiteSpace(url))
{
- var doc = await GetMusicBrainzResponse(url, isNameSearch, cancellationToken).ConfigureAwait(false);
-
- return GetResultsFromResponse(doc);
+ using (var reader = await GetMusicBrainzResponse(url, isNameSearch, cancellationToken).ConfigureAwait(false))
+ {
+ return GetResultsFromResponse(reader);
+ }
}
return new List<RemoteSearchResult>();
}
- private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
+ private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlReader reader)
{
- return ReleaseResult.Parse(doc).Select(i =>
+ return ReleaseResult.Parse(reader).Select(i =>
{
var result = new RemoteSearchResult
{
@@ -191,9 +195,10 @@ namespace MediaBrowser.Providers.Music
WebUtility.UrlEncode(albumName),
artistId);
- var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
-
- return ReleaseResult.Parse(doc, 1).FirstOrDefault();
+ using (var reader = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
+ {
+ return ReleaseResult.Parse(reader, 1).FirstOrDefault();
+ }
}
private async Task<ReleaseResult> GetReleaseResultByArtistName(string albumName, string artistName, CancellationToken cancellationToken)
@@ -202,9 +207,10 @@ namespace MediaBrowser.Providers.Music
WebUtility.UrlEncode(albumName),
WebUtility.UrlEncode(artistName));
- var doc = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
-
- return ReleaseResult.Parse(doc, 1).FirstOrDefault();
+ using (var reader = await GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
+ {
+ return ReleaseResult.Parse(reader, 1).FirstOrDefault();
+ }
}
private class ReleaseResult
@@ -215,108 +221,114 @@ namespace MediaBrowser.Providers.Music
public string Overview;
public int? Year;
- public static List<ReleaseResult> Parse(XmlDocument doc, int? limit = null)
+ public static List<ReleaseResult> Parse(XmlReader reader, int? limit = null)
{
- var docElem = doc.DocumentElement;
- var list = new List<ReleaseResult>();
+ reader.MoveToContent();
- if (docElem == null)
+ // Loop through each element
+ while (reader.Read())
{
- return list;
- }
-
- var releaseList = docElem.FirstChild;
- if (releaseList == null)
- {
- return list;
- }
-
- var nodes = releaseList.ChildNodes;
-
- if (nodes != null)
- {
- foreach (var node in nodes.Cast<XmlNode>())
+ switch (reader.Name)
{
- if (string.Equals(node.Name, "release", StringComparison.OrdinalIgnoreCase))
- {
- var releaseId = node.Attributes["id"].Value;
- var releaseGroupId = GetReleaseGroupIdFromReleaseNode(node);
-
- list.Add(new ReleaseResult
+ case "release-list":
{
- ReleaseId = releaseId,
- ReleaseGroupId = releaseGroupId,
- Title = GetValueFromReleaseNode(node, "title"),
- Overview = GetValueFromReleaseNode(node, "annotation"),
- Year = GetYearFromReleaseNode(node, "date")
- });
-
- if (limit.HasValue && list.Count >= limit.Value)
+ using (var subReader = reader.ReadSubtree())
+ {
+ return ParseReleaseList(subReader);
+ }
+ }
+ default:
{
+ reader.Skip();
break;
}
- }
}
}
- return list;
+ return new List<ReleaseResult>();
}
- private static int? GetYearFromReleaseNode(XmlNode node, string name)
+ private static List<ReleaseResult> ParseReleaseList(XmlReader reader)
{
- var subNodes = node.ChildNodes;
- if (subNodes != null)
+ var list = new List<ReleaseResult>();
+
+ reader.MoveToContent();
+
+ // Loop through each element
+ while (reader.Read())
{
- foreach (var subNode in subNodes.Cast<XmlNode>())
+ switch (reader.Name)
{
- if (string.Equals(subNode.Name, name, StringComparison.OrdinalIgnoreCase))
- {
- DateTime date;
- if (DateTime.TryParse(subNode.InnerText, out date))
+ case "release":
{
- return date.Year;
- }
+ var releaseId = reader.GetAttribute("id");
- return null;
- }
+ using (var subReader = reader.ReadSubtree())
+ {
+ var artist = ParseRelease(subReader, releaseId);
+ list.Add(artist);
+ }
+ break;
+ }
+ default:
+ {
+ reader.Skip();
+ break;
+ }
}
}
- return null;
+ return list;
}
- private static string GetValueFromReleaseNode(XmlNode node, string name)
+ private static ReleaseResult ParseRelease(XmlReader reader, string releaseId)
{
- var subNodes = node.ChildNodes;
- if (subNodes != null)
+ var result = new ReleaseResult
{
- foreach (var subNode in subNodes.Cast<XmlNode>())
- {
- if (string.Equals(subNode.Name, name, StringComparison.OrdinalIgnoreCase))
- {
- return subNode.InnerText;
- }
- }
- }
+ ReleaseId = releaseId
+ };
- return null;
- }
+ reader.MoveToContent();
- private static string GetReleaseGroupIdFromReleaseNode(XmlNode node)
- {
- var subNodes = node.ChildNodes;
- if (subNodes != null)
+ // Loop through each element
+ while (reader.Read())
{
- foreach (var subNode in subNodes.Cast<XmlNode>())
+ switch (reader.Name)
{
- if (string.Equals(subNode.Name, "release-group", StringComparison.OrdinalIgnoreCase))
- {
- return subNode.Attributes["id"].Value;
- }
+ case "title":
+ {
+ result.Title = reader.ReadElementContentAsString();
+ break;
+ }
+ case "date":
+ {
+ var val = reader.ReadElementContentAsString();
+ DateTime date;
+ if (DateTime.TryParse(val, out date))
+ {
+ result.Year = date.Year;
+ }
+ break;
+ }
+ case "annotation":
+ {
+ result.Overview = reader.ReadElementContentAsString();
+ break;
+ }
+ case "release-group":
+ {
+ result.ReleaseGroupId = reader.GetAttribute("id");
+ break;
+ }
+ default:
+ {
+ reader.Skip();
+ break;
+ }
}
}
- return null;
+ return result;
}
}
@@ -330,33 +342,54 @@ namespace MediaBrowser.Providers.Music
{
var url = string.Format("/ws/2/release-group/?query=reid:{0}", releaseEntryId);
- var doc = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false);
-
- var docElem = doc.DocumentElement;
-
- if (docElem == null)
+ using (var reader = await GetMusicBrainzResponse(url, false, cancellationToken).ConfigureAwait(false))
{
- return null;
- }
+ reader.MoveToContent();
- var releaseList = docElem.FirstChild;
- if (releaseList == null)
- {
+ // Loop through each element
+ while (reader.Read())
+ {
+ switch (reader.Name)
+ {
+ case "release-group-list":
+ {
+ using (var subReader = reader.ReadSubtree())
+ {
+ return GetFirstReleaseGroupId(subReader);
+ }
+ }
+ default:
+ {
+ reader.Skip();
+ break;
+ }
+ }
+ }
return null;
}
+ }
- var nodes = releaseList.ChildNodes;
+ private string GetFirstReleaseGroupId(XmlReader reader)
+ {
+ reader.MoveToContent();
- if (nodes != null)
+ // Loop through each element
+ while (reader.Read())
{
- foreach (var node in nodes.Cast<XmlNode>())
+ switch (reader.Name)
{
- if (string.Equals(node.Name, "release-group", StringComparison.OrdinalIgnoreCase))
- {
- return node.Attributes["id"].Value;
- }
+ case "release-group":
+ {
+ return reader.GetAttribute("id");
+ }
+ default:
+ {
+ reader.Skip();
+ break;
+ }
}
}
+
return null;
}
@@ -432,7 +465,7 @@ namespace MediaBrowser.Providers.Music
/// <param name="isSearch">if set to <c>true</c> [is search].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{XmlDocument}.</returns>
- internal async Task<XmlDocument> GetMusicBrainzResponse(string url, bool isSearch, CancellationToken cancellationToken)
+ internal async Task<XmlReader> GetMusicBrainzResponse(string url, bool isSearch, CancellationToken cancellationToken)
{
var urlInfo = await GetMbzUrl().ConfigureAwait(false);
@@ -444,8 +477,6 @@ namespace MediaBrowser.Providers.Music
url = urlInfo.url.TrimEnd('/') + url;
- var doc = new XmlDocument();
-
var options = new HttpRequestOptions
{
Url = url,
@@ -458,11 +489,15 @@ namespace MediaBrowser.Providers.Music
{
using (var oReader = new StreamReader(xml, Encoding.UTF8))
{
- doc.Load(oReader);
+ var settings = _xmlSettings.Create(false);
+
+ settings.CheckCharacters = false;
+ settings.IgnoreProcessingInstructions = true;
+ settings.IgnoreComments = true;
+
+ return XmlReader.Create(oReader, settings);
}
}
-
- return doc;
}
public int Order
diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
index adb771e7c..e0e839ef9 100644
--- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
@@ -26,10 +26,11 @@ namespace MediaBrowser.Providers.Music
{
var url = string.Format("/ws/2/artist/?query=arid:{0}", musicBrainzId);
- var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
- .ConfigureAwait(false);
-
- return GetResultsFromResponse(doc);
+ using (var reader = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, false, cancellationToken)
+ .ConfigureAwait(false))
+ {
+ return GetResultsFromResponse(reader);
+ }
}
else
{
@@ -38,13 +39,14 @@ namespace MediaBrowser.Providers.Music
var url = String.Format("/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
- var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
-
- var results = GetResultsFromResponse(doc).ToList();
-
- if (results.Count > 0)
+ using (var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
{
- return results;
+ var results = GetResultsFromResponse(doc).ToList();
+
+ if (results.Count > 0)
+ {
+ return results;
+ }
}
if (HasDiacritics(searchInfo.Name))
@@ -52,73 +54,121 @@ namespace MediaBrowser.Providers.Music
// Try again using the search with accent characters url
url = String.Format("/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
- doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false);
-
- return GetResultsFromResponse(doc);
+ using (var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, true, cancellationToken).ConfigureAwait(false))
+ {
+ return GetResultsFromResponse(doc);
+ }
}
}
return new List<RemoteSearchResult>();
}
- private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
+ private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlReader reader)
{
- var list = new List<RemoteSearchResult>();
+ reader.MoveToContent();
- var docElem = doc.DocumentElement;
-
- if (docElem == null)
+ // Loop through each element
+ while (reader.Read())
{
- return list;
+ switch (reader.Name)
+ {
+ case "artist-list":
+ {
+ using (var subReader = reader.ReadSubtree())
+ {
+ return ParseArtistList(subReader);
+ }
+ }
+ default:
+ {
+ reader.Skip();
+ break;
+ }
+ }
}
- var artistList = docElem.FirstChild;
- if (artistList == null)
- {
- return list;
- }
+ return new List<RemoteSearchResult>();
+ }
- var nodes = artistList.ChildNodes;
+ private IEnumerable<RemoteSearchResult> ParseArtistList(XmlReader reader)
+ {
+ var list = new List<RemoteSearchResult>();
+
+ reader.MoveToContent();
- if (nodes != null)
+ // Loop through each element
+ while (reader.Read())
{
- foreach (var node in nodes.Cast<XmlNode>())
+ switch (reader.Name)
{
- if (node.Attributes != null)
- {
- string name = null;
- string overview = null;
- string mbzId = node.Attributes["id"].Value;
-
- foreach (var child in node.ChildNodes.Cast<XmlNode>())
+ case "artist":
{
- if (string.Equals(child.Name, "name", StringComparison.OrdinalIgnoreCase))
- {
- name = child.InnerText;
- }
- if (string.Equals(child.Name, "annotation", StringComparison.OrdinalIgnoreCase))
+ var mbzId = reader.GetAttribute("id");
+
+ using (var subReader = reader.ReadSubtree())
{
- overview = child.InnerText;
+ var artist = ParseArtist(subReader, mbzId);
+ list.Add(artist);
}
+ break;
}
-
- if (!string.IsNullOrWhiteSpace(mbzId) && !string.IsNullOrWhiteSpace(name))
+ default:
{
- var result = new RemoteSearchResult
- {
- Name = name,
- Overview = overview
- };
+ reader.Skip();
+ break;
+ }
+ }
+ }
+
+ return list;
+ }
+
+ private RemoteSearchResult ParseArtist(XmlReader reader, string artistId)
+ {
+ var result = new RemoteSearchResult();
- result.SetProviderId(MetadataProviders.MusicBrainzArtist, mbzId);
+ reader.MoveToContent();
- list.Add(result);
+ // Loop through each element
+ while (reader.Read())
+ {
+ switch (reader.Name)
+ {
+ case "name":
+ {
+ result.Name = reader.ReadElementContentAsString();
+ break;
+ }
+ //case "sort-name":
+ // {
+ // break;
+ // }
+ //case "tag-list":
+ // {
+ // break;
+ // }
+ case "annotation":
+ {
+ result.Overview = reader.ReadElementContentAsString();
+ break;
+ }
+ default:
+ {
+ reader.Skip();
+ break;
}
- }
}
}
- return list;
+ result.SetProviderId(MetadataProviders.MusicBrainzArtist, artistId);
+
+ if (string.IsNullOrWhiteSpace(artistId) || string.IsNullOrWhiteSpace(result.Name))
+ {
+ return null;
+ }
+
+ return result;
}
public async Task<MetadataResult<MusicArtist>> GetMetadata(ArtistInfo id, CancellationToken cancellationToken)