diff --git a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs index f5982cce91..e2b3bd0d25 100644 --- a/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs +++ b/MediaBrowser.Controller/Providers/Movies/MovieDbProvider.cs @@ -1044,8 +1044,8 @@ namespace MediaBrowser.Controller.Providers.Movies boxset.OfficialRating = firstChild != null ? firstChild.OfficialRating : null; } - if (movie.RunTimeTicks == null && movieData.runtime > 0) - movie.RunTimeTicks = TimeSpan.FromMinutes(movieData.runtime).Ticks; + //if (movie.RunTimeTicks == null && movieData.runtime > 0) + // movie.RunTimeTicks = TimeSpan.FromMinutes(movieData.runtime).Ticks; //studios if (movieData.production_companies != null) diff --git a/MediaBrowser.Controller/Providers/Music/LastfmArtistProvider.cs b/MediaBrowser.Controller/Providers/Music/LastfmArtistProvider.cs index a9183259ff..578c99b1d7 100644 --- a/MediaBrowser.Controller/Providers/Music/LastfmArtistProvider.cs +++ b/MediaBrowser.Controller/Providers/Music/LastfmArtistProvider.cs @@ -1,4 +1,8 @@ -using MediaBrowser.Common.Net; +using System; +using System.Globalization; +using System.Net; +using System.Text; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; @@ -27,19 +31,37 @@ namespace MediaBrowser.Controller.Providers.Music protected override async Task FindId(BaseItem item, CancellationToken cancellationToken) { // Try to find the id using last fm - var id = await FindIdFromLastFm(item, cancellationToken).ConfigureAwait(false); + var result = await FindIdFromLastFm(item, cancellationToken).ConfigureAwait(false); - if (!string.IsNullOrEmpty(id)) + if (!string.IsNullOrEmpty(result.Item1)) { - return id; + return result.Item1; } - // If we don't get anything, go directly to music brainz + // If there were no artists returned at all, then don't bother with musicbrainz + if (!result.Item2) + { + return null; + } + + try + { + // If we don't get anything, go directly to music brainz + return await FindIdFromMusicBrainz(item, cancellationToken).ConfigureAwait(false); + } + catch (HttpException e) + { + if (e.StatusCode.HasValue && e.StatusCode.Value == HttpStatusCode.BadRequest) + { + // They didn't like a character in the name. Handle the exception so that the provider doesn't keep retrying over and over + return null; + } - return await FindIdFromMusicBrainz(item, cancellationToken).ConfigureAwait(false); + throw; + } } - private async Task FindIdFromLastFm(BaseItem item, CancellationToken cancellationToken) + private async Task> FindIdFromLastFm(BaseItem item, CancellationToken cancellationToken) { //Execute the Artist search against our name and assume first one is the one we want var url = RootUrl + string.Format("method=artist.search&artist={0}&api_key={1}&format=json", UrlEncode(item.Name), ApiKey); @@ -58,17 +80,23 @@ namespace MediaBrowser.Controller.Providers.Music return null; } - if (searchResult != null && searchResult.results != null && searchResult.results.artistmatches != null && searchResult.results.artistmatches.artist.Any()) + if (searchResult != null && searchResult.results != null && searchResult.results.artistmatches != null && searchResult.results.artistmatches.artist.Count > 0) { - return searchResult.results.artistmatches.artist.First().mbid; + var artist = searchResult.results.artistmatches.artist.FirstOrDefault(i => i.name != null && string.Compare(i.name, item.Name, CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace) == 0) ?? + searchResult.results.artistmatches.artist.First(); + + return new Tuple(artist.mbid, true); } - return null; + return new Tuple(null, false); } private async Task FindIdFromMusicBrainz(BaseItem item, CancellationToken cancellationToken) { - var url = string.Format("http://www.musicbrainz.org/ws/2/artist/?query=artist:{0}", UrlEncode(item.Name)); + // They seem to throw bad request failures on any term with a slash + var nameToSearch = item.Name.Replace('/', ' '); + + var url = string.Format("http://www.musicbrainz.org/ws/2/artist/?query=artist:{0}", UrlEncode(nameToSearch)); var doc = await FanArtAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false); @@ -81,22 +109,39 @@ namespace MediaBrowser.Controller.Providers.Music return node.Value; } - // Try again using the search with accent characters url - url = string.Format("http://www.musicbrainz.org/ws/2/artist/?query=artistaccent:{0}", UrlEncode(item.Name)); + if (HasDiacritics(item.Name)) + { + // Try again using the search with accent characters url + url = string.Format("http://www.musicbrainz.org/ws/2/artist/?query=artistaccent:{0}", UrlEncode(nameToSearch)); - doc = await FanArtAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false); + doc = await FanArtAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false); - ns = new XmlNamespaceManager(doc.NameTable); - ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#"); - node = doc.SelectSingleNode("//mb:artist-list/mb:artist[@type='Group']/@id", ns); + ns = new XmlNamespaceManager(doc.NameTable); + ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#"); + node = doc.SelectSingleNode("//mb:artist-list/mb:artist[@type='Group']/@id", ns); - if (node != null && node.Value != null) - { - return node.Value; + if (node != null && node.Value != null) + { + return node.Value; + } } return null; } + + private bool HasDiacritics(string text) + { + return !string.Equals(text, RemoveDiacritics(text), StringComparison.Ordinal); + } + + private string RemoveDiacritics(string text) + { + return string.Concat( + text.Normalize(NormalizationForm.FormD) + .Where(ch => CharUnicodeInfo.GetUnicodeCategory(ch) != + UnicodeCategory.NonSpacingMark) + ).Normalize(NormalizationForm.FormC); + } protected override async Task FetchLastfmData(BaseItem item, string id, CancellationToken cancellationToken) {