diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-10-27 15:03:23 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2016-10-27 15:03:23 -0400 |
| commit | e12f27d8ed9a9ecb36d19ac4dbceab9fa215315c (patch) | |
| tree | f81057ceea7c7f1b6554ec365117c2f9a49dbfd4 /MediaBrowser.Providers/Music | |
| parent | 7130d8a78f5d995ff53049477a2864a2a2dd2aff (diff) | |
make provider project portabl
Diffstat (limited to 'MediaBrowser.Providers/Music')
| -rw-r--r-- | MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs | 245 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs | 152 |
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) |
