From 09dfa071dc27820f1820bd56126dfa5cd5e01027 Mon Sep 17 00:00:00 2001 From: dkanada Date: Fri, 31 May 2019 01:48:20 -0700 Subject: [PATCH] move fanart image provider to plugin --- MediaBrowser.Api/Library/LibraryService.cs | 12 - .../Configuration/FanartOptions.cs | 11 - .../Configuration/ServerConfiguration.cs | 7 +- .../Movies/FanartMovieImageProvider.cs | 334 ---------------- .../Music/FanArtAlbumProvider.cs | 201 ---------- .../Music/FanArtArtistProvider.cs | 335 ---------------- .../TV/FanArt/FanArtSeasonProvider.cs | 205 ---------- .../TV/FanArt/FanartSeriesProvider.cs | 378 ------------------ 8 files changed, 3 insertions(+), 1480 deletions(-) delete mode 100644 MediaBrowser.Model/Configuration/FanartOptions.cs delete mode 100644 MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs delete mode 100644 MediaBrowser.Providers/Music/FanArtAlbumProvider.cs delete mode 100644 MediaBrowser.Providers/Music/FanArtArtistProvider.cs delete mode 100644 MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs delete mode 100644 MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 9f8da9c168..ddf45f9f3c 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -490,18 +490,6 @@ namespace MediaBrowser.Api.Library { return false; } - else if (string.Equals(name, "FanArt", StringComparison.OrdinalIgnoreCase)) - { - if (string.Equals(type, "Season", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - if (string.Equals(type, "MusicVideo", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - return true; - } else if (string.Equals(name, "TheAudioDB", StringComparison.OrdinalIgnoreCase)) { return true; diff --git a/MediaBrowser.Model/Configuration/FanartOptions.cs b/MediaBrowser.Model/Configuration/FanartOptions.cs deleted file mode 100644 index 9c8be39be7..0000000000 --- a/MediaBrowser.Model/Configuration/FanartOptions.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace MediaBrowser.Model.Configuration -{ - public class FanartOptions - { - /// - /// Gets or sets the user API key. - /// - /// The user API key. - public string UserApiKey { get; set; } - } -} diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 0ba36b4b9d..2673597caa 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -49,9 +49,9 @@ namespace MediaBrowser.Model.Configuration public bool EnableNormalizedItemByNameIds { get; set; } /// - /// Gets or sets the value pointing to the file system where the ssl certiifcate is located.. + /// Gets or sets the value pointing to the file system where the ssl certificate is located.. /// - /// The value pointing to the file system where the ssl certiifcate is located.. + /// The value pointing to the file system where the ssl certificate is located.. public string CertificatePath { get; set; } public string CertificatePassword { get; set; } @@ -259,7 +259,7 @@ namespace MediaBrowser.Model.Configuration { ItemType = "MusicVideo", DisabledMetadataFetchers = new [] { "The Open Movie Database" }, - DisabledImageFetchers = new [] { "The Open Movie Database", "FanArt" } + DisabledImageFetchers = new [] { "The Open Movie Database" } }, new MetadataOptions { @@ -285,7 +285,6 @@ namespace MediaBrowser.Model.Configuration { ItemType = "Season", DisabledMetadataFetchers = new [] { "TheMovieDb" }, - DisabledImageFetchers = new [] { "FanArt" } }, new MetadataOptions { diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs deleted file mode 100644 index 70d187bf55..0000000000 --- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs +++ /dev/null @@ -1,334 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Providers; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Providers.Music; -using MediaBrowser.Providers.TV; -using MediaBrowser.Providers.TV.FanArt; - -namespace MediaBrowser.Providers.Movies -{ - public class FanartMovieImageProvider : IRemoteImageProvider, IHasOrder - { - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IServerConfigurationManager _config; - private readonly IHttpClient _httpClient; - private readonly IFileSystem _fileSystem; - private readonly IJsonSerializer _json; - - private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/movies/{1}?api_key={0}"; - - internal static FanartMovieImageProvider Current; - - public FanartMovieImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json) - { - _config = config; - _httpClient = httpClient; - _fileSystem = fileSystem; - _json = json; - - Current = this; - } - - public string Name => ProviderName; - - public static string ProviderName => "FanArt"; - - public bool Supports(BaseItem item) - { - return item is Movie || item is BoxSet || item is MusicVideo; - } - - public IEnumerable GetSupportedImages(BaseItem item) - { - return new List - { - ImageType.Primary, - ImageType.Thumb, - ImageType.Art, - ImageType.Logo, - ImageType.Disc, - ImageType.Banner, - ImageType.Backdrop - }; - } - - public async Task> GetImages(BaseItem item, CancellationToken cancellationToken) - { - var baseItem = item; - var list = new List(); - - var movieId = baseItem.GetProviderId(MetadataProviders.Tmdb); - - if (!string.IsNullOrEmpty(movieId)) - { - // Bad id entered - try - { - await EnsureMovieJson(movieId, cancellationToken).ConfigureAwait(false); - } - catch (HttpException ex) - { - if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound) - { - throw; - } - } - - var path = GetFanartJsonPath(movieId); - - try - { - AddImages(list, path, cancellationToken); - } - catch (FileNotFoundException) - { - // No biggie. Don't blow up - } - catch (IOException) - { - // No biggie. Don't blow up - } - } - - var language = item.GetPreferredMetadataLanguage(); - - var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase); - - // Sort first by width to prioritize HD versions - return list.OrderByDescending(i => i.Width ?? 0) - .ThenByDescending(i => - { - if (string.Equals(language, i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 3; - } - if (!isLanguageEn) - { - if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 2; - } - } - if (string.IsNullOrEmpty(i.Language)) - { - return isLanguageEn ? 3 : 2; - } - return 0; - }) - .ThenByDescending(i => i.CommunityRating ?? 0); - } - - private void AddImages(List list, string path, CancellationToken cancellationToken) - { - var root = _json.DeserializeFromFile(path); - - AddImages(list, root, cancellationToken); - } - - private void AddImages(List list, RootObject obj, CancellationToken cancellationToken) - { - PopulateImages(list, obj.hdmovieclearart, ImageType.Art, 1000, 562); - PopulateImages(list, obj.hdmovielogo, ImageType.Logo, 800, 310); - PopulateImages(list, obj.moviedisc, ImageType.Disc, 1000, 1000); - PopulateImages(list, obj.movieposter, ImageType.Primary, 1000, 1426); - PopulateImages(list, obj.movielogo, ImageType.Logo, 400, 155); - PopulateImages(list, obj.movieart, ImageType.Art, 500, 281); - PopulateImages(list, obj.moviethumb, ImageType.Thumb, 1000, 562); - PopulateImages(list, obj.moviebanner, ImageType.Banner, 1000, 185); - PopulateImages(list, obj.moviebackground, ImageType.Backdrop, 1920, 1080); - } - - private void PopulateImages(List list, List images, ImageType type, int width, int height) - { - if (images == null) - { - return; - } - - list.AddRange(images.Select(i => - { - var url = i.url; - - if (!string.IsNullOrEmpty(url)) - { - var likesString = i.likes; - - var info = new RemoteImageInfo - { - RatingType = RatingType.Likes, - Type = type, - Width = width, - Height = height, - ProviderName = Name, - Url = url, - Language = i.lang - }; - - if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes)) - { - info.CommunityRating = likes; - } - - return info; - } - - return null; - }).Where(i => i != null)); - } - - public int Order => 1; - - public Task GetImageResponse(string url, CancellationToken cancellationToken) - { - return _httpClient.GetResponse(new HttpRequestOptions - { - CancellationToken = cancellationToken, - Url = url - }); - } - - /// - /// Gets the movie data path. - /// - /// The application paths. - /// The identifier. - /// System.String. - internal static string GetMovieDataPath(IApplicationPaths appPaths, string id) - { - var dataPath = Path.Combine(GetMoviesDataPath(appPaths), id); - - return dataPath; - } - - /// - /// Gets the movie data path. - /// - /// The app paths. - /// System.String. - internal static string GetMoviesDataPath(IApplicationPaths appPaths) - { - var dataPath = Path.Combine(appPaths.CachePath, "fanart-movies"); - - return dataPath; - } - - public string GetFanartJsonPath(string id) - { - var movieDataPath = GetMovieDataPath(_config.ApplicationPaths, id); - return Path.Combine(movieDataPath, "fanart.json"); - } - - /// - /// Downloads the movie json. - /// - /// The identifier. - /// The cancellation token. - /// Task. - internal async Task DownloadMovieJson(string id, CancellationToken cancellationToken) - { - cancellationToken.ThrowIfCancellationRequested(); - - var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, id); - - var clientKey = FanartSeriesProvider.Current.GetFanartOptions().UserApiKey; - if (!string.IsNullOrWhiteSpace(clientKey)) - { - url += "&client_key=" + clientKey; - } - - var path = GetFanartJsonPath(id); - - Directory.CreateDirectory(Path.GetDirectoryName(path)); - - try - { - using (var httpResponse = await _httpClient.SendAsync(new HttpRequestOptions - { - Url = url, - CancellationToken = cancellationToken, - BufferContent = true - - }, "GET").ConfigureAwait(false)) - { - using (var response = httpResponse.Content) - { - using (var fileStream = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true)) - { - await response.CopyToAsync(fileStream).ConfigureAwait(false); - } - } - } - } - catch (HttpException exception) - { - if (exception.StatusCode.HasValue && exception.StatusCode.Value == HttpStatusCode.NotFound) - { - // If the user has automatic updates enabled, save a dummy object to prevent repeated download attempts - _json.SerializeToFile(new RootObject(), path); - - return; - } - - throw; - } - } - - internal Task EnsureMovieJson(string id, CancellationToken cancellationToken) - { - var path = GetFanartJsonPath(id); - - var fileInfo = _fileSystem.GetFileSystemInfo(path); - - if (fileInfo.Exists) - { - if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2) - { - return Task.CompletedTask; - } - } - - return DownloadMovieJson(id, cancellationToken); - } - - public class Image - { - public string id { get; set; } - public string url { get; set; } - public string lang { get; set; } - public string likes { get; set; } - } - - public class RootObject - { - public string name { get; set; } - public string tmdb_id { get; set; } - public string imdb_id { get; set; } - public List hdmovielogo { get; set; } - public List moviedisc { get; set; } - public List movielogo { get; set; } - public List movieposter { get; set; } - public List hdmovieclearart { get; set; } - public List movieart { get; set; } - public List moviebackground { get; set; } - public List moviebanner { get; set; } - public List moviethumb { get; set; } - } - } -} diff --git a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs b/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs deleted file mode 100644 index ebb740ffe4..0000000000 --- a/MediaBrowser.Providers/Music/FanArtAlbumProvider.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Providers; -using MediaBrowser.Model.Serialization; - -namespace MediaBrowser.Providers.Music -{ - public class FanartAlbumProvider : IRemoteImageProvider, IHasOrder - { - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IServerConfigurationManager _config; - private readonly IHttpClient _httpClient; - private readonly IFileSystem _fileSystem; - private readonly IJsonSerializer _jsonSerializer; - - public FanartAlbumProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer jsonSerializer) - { - _config = config; - _httpClient = httpClient; - _fileSystem = fileSystem; - _jsonSerializer = jsonSerializer; - } - - public string Name => ProviderName; - - public static string ProviderName => "FanArt"; - - public bool Supports(BaseItem item) - { - return item is MusicAlbum; - } - - public IEnumerable GetSupportedImages(BaseItem item) - { - return new List - { - ImageType.Primary, - ImageType.Disc - }; - } - - public async Task> GetImages(BaseItem item, CancellationToken cancellationToken) - { - var album = (MusicAlbum)item; - - var list = new List(); - - var musicArtist = album.MusicArtist; - - if (musicArtist == null) - { - return list; - } - - var artistMusicBrainzId = musicArtist.GetProviderId(MetadataProviders.MusicBrainzArtist); - - if (!string.IsNullOrEmpty(artistMusicBrainzId)) - { - await FanartArtistProvider.Current.EnsureArtistJson(artistMusicBrainzId, cancellationToken).ConfigureAwait(false); - - var artistJsonPath = FanartArtistProvider.GetArtistJsonPath(_config.CommonApplicationPaths, artistMusicBrainzId); - - var musicBrainzReleaseGroupId = album.GetProviderId(MetadataProviders.MusicBrainzReleaseGroup); - - var musicBrainzId = album.GetProviderId(MetadataProviders.MusicBrainzAlbum); - - try - { - AddImages(list, artistJsonPath, musicBrainzId, musicBrainzReleaseGroupId, cancellationToken); - } - catch (FileNotFoundException) - { - - } - catch (IOException) - { - - } - } - - var language = item.GetPreferredMetadataLanguage(); - - var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase); - - // Sort first by width to prioritize HD versions - return list.OrderByDescending(i => i.Width ?? 0) - .ThenByDescending(i => - { - if (string.Equals(language, i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 3; - } - if (!isLanguageEn) - { - if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 2; - } - } - if (string.IsNullOrEmpty(i.Language)) - { - return isLanguageEn ? 3 : 2; - } - return 0; - }) - .ThenByDescending(i => i.CommunityRating ?? 0) - .ThenByDescending(i => i.VoteCount ?? 0); - } - - /// - /// Adds the images. - /// - /// The list. - /// The path. - /// The release identifier. - /// The release group identifier. - /// The cancellation token. - private void AddImages(List list, string path, string releaseId, string releaseGroupId, CancellationToken cancellationToken) - { - var obj = _jsonSerializer.DeserializeFromFile(path); - - if (obj.albums != null) - { - var album = obj.albums.FirstOrDefault(i => string.Equals(i.release_group_id, releaseGroupId, StringComparison.OrdinalIgnoreCase)); - - if (album != null) - { - PopulateImages(list, album.albumcover, ImageType.Primary, 1000, 1000); - PopulateImages(list, album.cdart, ImageType.Disc, 1000, 1000); - } - } - } - - private void PopulateImages(List list, - List images, - ImageType type, - int width, - int height) - { - if (images == null) - { - return; - } - - list.AddRange(images.Select(i => - { - var url = i.url; - - if (!string.IsNullOrEmpty(url)) - { - var likesString = i.likes; - - var info = new RemoteImageInfo - { - RatingType = RatingType.Likes, - Type = type, - Width = width, - Height = height, - ProviderName = Name, - Url = url.Replace("http://", "https://", StringComparison.OrdinalIgnoreCase), - Language = i.lang - }; - - if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes)) - { - info.CommunityRating = likes; - } - - return info; - } - - return null; - }).Where(i => i != null)); - } - // After embedded provider - public int Order => 1; - - public Task GetImageResponse(string url, CancellationToken cancellationToken) - { - return _httpClient.GetResponse(new HttpRequestOptions - { - CancellationToken = cancellationToken, - Url = url - }); - } - } -} diff --git a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs b/MediaBrowser.Providers/Music/FanArtArtistProvider.cs deleted file mode 100644 index 75b4213c52..0000000000 --- a/MediaBrowser.Providers/Music/FanArtArtistProvider.cs +++ /dev/null @@ -1,335 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Providers; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Providers.TV; -using MediaBrowser.Providers.TV.FanArt; - -namespace MediaBrowser.Providers.Music -{ - public class FanartArtistProvider : IRemoteImageProvider, IHasOrder - { - internal const string ApiKey = "184e1a2b1fe3b94935365411f919f638"; - private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3.1/music/{1}?api_key={0}"; - - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IServerConfigurationManager _config; - private readonly IHttpClient _httpClient; - private readonly IFileSystem _fileSystem; - private readonly IJsonSerializer _jsonSerializer; - - internal static FanartArtistProvider Current; - - public FanartArtistProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer jsonSerializer) - { - _config = config; - _httpClient = httpClient; - _fileSystem = fileSystem; - _jsonSerializer = jsonSerializer; - - Current = this; - } - - public string Name => ProviderName; - - public static string ProviderName => "FanArt"; - - public bool Supports(BaseItem item) - { - return item is MusicArtist; - } - - public IEnumerable GetSupportedImages(BaseItem item) - { - return new List - { - ImageType.Primary, - ImageType.Logo, - ImageType.Art, - ImageType.Banner, - ImageType.Backdrop - }; - } - - public async Task> GetImages(BaseItem item, CancellationToken cancellationToken) - { - var artist = (MusicArtist)item; - - var list = new List(); - - var artistMusicBrainzId = artist.GetProviderId(MetadataProviders.MusicBrainzArtist); - - if (!string.IsNullOrEmpty(artistMusicBrainzId)) - { - await EnsureArtistJson(artistMusicBrainzId, cancellationToken).ConfigureAwait(false); - - var artistJsonPath = GetArtistJsonPath(_config.CommonApplicationPaths, artistMusicBrainzId); - - try - { - AddImages(list, artistJsonPath, cancellationToken); - } - catch (FileNotFoundException) - { - - } - catch (IOException) - { - - } - } - - var language = item.GetPreferredMetadataLanguage(); - - var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase); - - // Sort first by width to prioritize HD versions - return list.OrderByDescending(i => i.Width ?? 0) - .ThenByDescending(i => - { - if (string.Equals(language, i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 3; - } - if (!isLanguageEn) - { - if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 2; - } - } - if (string.IsNullOrEmpty(i.Language)) - { - return isLanguageEn ? 3 : 2; - } - return 0; - }) - .ThenByDescending(i => i.CommunityRating ?? 0) - .ThenByDescending(i => i.VoteCount ?? 0); - } - - /// - /// Adds the images. - /// - /// The list. - /// The path. - /// The cancellation token. - private void AddImages(List list, string path, CancellationToken cancellationToken) - { - var obj = _jsonSerializer.DeserializeFromFile(path); - - PopulateImages(list, obj.artistbackground, ImageType.Backdrop, 1920, 1080); - PopulateImages(list, obj.artistthumb, ImageType.Primary, 500, 281); - PopulateImages(list, obj.hdmusiclogo, ImageType.Logo, 800, 310); - PopulateImages(list, obj.musicbanner, ImageType.Banner, 1000, 185); - PopulateImages(list, obj.musiclogo, ImageType.Logo, 400, 155); - PopulateImages(list, obj.hdmusicarts, ImageType.Art, 1000, 562); - PopulateImages(list, obj.musicarts, ImageType.Art, 500, 281); - } - - private void PopulateImages(List list, - List images, - ImageType type, - int width, - int height) - { - if (images == null) - { - return; - } - - list.AddRange(images.Select(i => - { - var url = i.url; - - if (!string.IsNullOrEmpty(url)) - { - var likesString = i.likes; - - var info = new RemoteImageInfo - { - RatingType = RatingType.Likes, - Type = type, - Width = width, - Height = height, - ProviderName = Name, - Url = url.Replace("http://", "https://", StringComparison.OrdinalIgnoreCase), - Language = i.lang - }; - - if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes)) - { - info.CommunityRating = likes; - } - - return info; - } - - return null; - }).Where(i => i != null)); - } - - public int Order => 0; - - public Task GetImageResponse(string url, CancellationToken cancellationToken) - { - return _httpClient.GetResponse(new HttpRequestOptions - { - CancellationToken = cancellationToken, - Url = url - }); - } - - internal Task EnsureArtistJson(string musicBrainzId, CancellationToken cancellationToken) - { - var jsonPath = GetArtistJsonPath(_config.ApplicationPaths, musicBrainzId); - - var fileInfo = _fileSystem.GetFileSystemInfo(jsonPath); - - if (fileInfo.Exists) - { - if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2) - { - return Task.CompletedTask; - } - } - - return DownloadArtistJson(musicBrainzId, cancellationToken); - } - - /// - /// Downloads the artist data. - /// - /// The music brainz id. - /// The cancellation token. - /// Task{System.Boolean}. - internal async Task DownloadArtistJson(string musicBrainzId, CancellationToken cancellationToken) - { - cancellationToken.ThrowIfCancellationRequested(); - - var url = string.Format(FanArtBaseUrl, ApiKey, musicBrainzId); - - var clientKey = FanartSeriesProvider.Current.GetFanartOptions().UserApiKey; - if (!string.IsNullOrWhiteSpace(clientKey)) - { - url += "&client_key=" + clientKey; - } - - var jsonPath = GetArtistJsonPath(_config.ApplicationPaths, musicBrainzId); - - Directory.CreateDirectory(Path.GetDirectoryName(jsonPath)); - - try - { - using (var httpResponse = await _httpClient.SendAsync(new HttpRequestOptions - { - Url = url, - CancellationToken = cancellationToken, - BufferContent = true - - }, "GET").ConfigureAwait(false)) - { - using (var response = httpResponse.Content) - { - using (var saveFileStream = _fileSystem.GetFileStream(jsonPath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true)) - { - await response.CopyToAsync(saveFileStream).ConfigureAwait(false); - } - } - } - } - catch (HttpException ex) - { - if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) - { - _jsonSerializer.SerializeToFile(new FanartArtistResponse(), jsonPath); - } - else - { - throw; - } - } - } - - /// - /// Gets the artist data path. - /// - /// The application paths. - /// The music brainz artist identifier. - /// System.String. - private static string GetArtistDataPath(IApplicationPaths appPaths, string musicBrainzArtistId) - { - var dataPath = Path.Combine(GetArtistDataPath(appPaths), musicBrainzArtistId); - - return dataPath; - } - - /// - /// Gets the artist data path. - /// - /// The application paths. - /// System.String. - internal static string GetArtistDataPath(IApplicationPaths appPaths) - { - var dataPath = Path.Combine(appPaths.CachePath, "fanart-music"); - - return dataPath; - } - - internal static string GetArtistJsonPath(IApplicationPaths appPaths, string musicBrainzArtistId) - { - var dataPath = GetArtistDataPath(appPaths, musicBrainzArtistId); - - return Path.Combine(dataPath, "fanart.json"); - } - - - public class FanartArtistImage - { - public string id { get; set; } - public string url { get; set; } - public string likes { get; set; } - public string disc { get; set; } - public string size { get; set; } - public string lang { get; set; } - } - - public class Album - { - public string release_group_id { get; set; } - public List cdart { get; set; } - public List albumcover { get; set; } - } - - public class FanartArtistResponse - { - public string name { get; set; } - public string mbid_id { get; set; } - public List artistthumb { get; set; } - public List artistbackground { get; set; } - public List hdmusiclogo { get; set; } - public List musicbanner { get; set; } - public List musiclogo { get; set; } - public List musicarts { get; set; } - public List hdmusicarts { get; set; } - public List albums { get; set; } - } - } -} diff --git a/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs deleted file mode 100644 index 58356910f6..0000000000 --- a/MediaBrowser.Providers/TV/FanArt/FanArtSeasonProvider.cs +++ /dev/null @@ -1,205 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Providers; -using MediaBrowser.Model.Serialization; - -namespace MediaBrowser.Providers.TV.FanArt -{ - public class FanArtSeasonProvider : IRemoteImageProvider, IHasOrder - { - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IServerConfigurationManager _config; - private readonly IHttpClient _httpClient; - private readonly IFileSystem _fileSystem; - private readonly IJsonSerializer _json; - - public FanArtSeasonProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json) - { - _config = config; - _httpClient = httpClient; - _fileSystem = fileSystem; - _json = json; - } - - public string Name => ProviderName; - - public static string ProviderName => "FanArt"; - - public bool Supports(BaseItem item) - { - return item is Season; - } - - public IEnumerable GetSupportedImages(BaseItem item) - { - return new List - { - ImageType.Backdrop, - ImageType.Thumb, - ImageType.Banner, - ImageType.Primary - }; - } - - public async Task> GetImages(BaseItem item, CancellationToken cancellationToken) - { - var list = new List(); - - var season = (Season)item; - var series = season.Series; - - if (series != null) - { - var id = series.GetProviderId(MetadataProviders.Tvdb); - - if (!string.IsNullOrEmpty(id) && season.IndexNumber.HasValue) - { - // Bad id entered - try - { - await FanartSeriesProvider.Current.EnsureSeriesJson(id, cancellationToken).ConfigureAwait(false); - } - catch (HttpException ex) - { - if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound) - { - throw; - } - } - - var path = FanartSeriesProvider.Current.GetFanartJsonPath(id); - - try - { - AddImages(list, season.IndexNumber.Value, path, cancellationToken); - } - catch (FileNotFoundException) - { - // No biggie. Don't blow up - } - catch (IOException) - { - // No biggie. Don't blow up - } - } - } - - var language = item.GetPreferredMetadataLanguage(); - - var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase); - - // Sort first by width to prioritize HD versions - return list.OrderByDescending(i => i.Width ?? 0) - .ThenByDescending(i => - { - if (string.Equals(language, i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 3; - } - if (!isLanguageEn) - { - if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 2; - } - } - if (string.IsNullOrEmpty(i.Language)) - { - return isLanguageEn ? 3 : 2; - } - return 0; - }) - .ThenByDescending(i => i.CommunityRating ?? 0) - .ThenByDescending(i => i.VoteCount ?? 0); - } - - private void AddImages(List list, int seasonNumber, string path, CancellationToken cancellationToken) - { - var root = _json.DeserializeFromFile(path); - - AddImages(list, root, seasonNumber, cancellationToken); - } - - private void AddImages(List list, FanartSeriesProvider.RootObject obj, int seasonNumber, CancellationToken cancellationToken) - { - PopulateImages(list, obj.seasonposter, ImageType.Primary, 1000, 1426, seasonNumber); - PopulateImages(list, obj.seasonbanner, ImageType.Banner, 1000, 185, seasonNumber); - PopulateImages(list, obj.seasonthumb, ImageType.Thumb, 500, 281, seasonNumber); - PopulateImages(list, obj.showbackground, ImageType.Backdrop, 1920, 1080, seasonNumber); - } - - private void PopulateImages(List list, - List images, - ImageType type, - int width, - int height, - int seasonNumber) - { - if (images == null) - { - return; - } - - list.AddRange(images.Select(i => - { - var url = i.url; - var season = i.season; - - if (!string.IsNullOrEmpty(url) && - !string.IsNullOrEmpty(season) && - int.TryParse(season, NumberStyles.Integer, _usCulture, out var imageSeasonNumber) && - seasonNumber == imageSeasonNumber) - { - var likesString = i.likes; - - var info = new RemoteImageInfo - { - RatingType = RatingType.Likes, - Type = type, - Width = width, - Height = height, - ProviderName = Name, - Url = url.Replace("http://", "https://", StringComparison.OrdinalIgnoreCase), - Language = i.lang - }; - - if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes)) - { - info.CommunityRating = likes; - } - - return info; - } - - return null; - }).Where(i => i != null)); - } - - public int Order => 1; - - public Task GetImageResponse(string url, CancellationToken cancellationToken) - { - return _httpClient.GetResponse(new HttpRequestOptions - { - CancellationToken = cancellationToken, - Url = url - }); - } - } -} diff --git a/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs b/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs deleted file mode 100644 index 49cd9596e4..0000000000 --- a/MediaBrowser.Providers/TV/FanArt/FanartSeriesProvider.cs +++ /dev/null @@ -1,378 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Extensions; -using MediaBrowser.Model.IO; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Providers; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Providers.Music; - -namespace MediaBrowser.Providers.TV.FanArt -{ - public class FanartSeriesProvider : IRemoteImageProvider, IHasOrder - { - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IServerConfigurationManager _config; - private readonly IHttpClient _httpClient; - private readonly IFileSystem _fileSystem; - private readonly IJsonSerializer _json; - - private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/tv/{1}?api_key={0}"; - - internal static FanartSeriesProvider Current { get; private set; } - - public FanartSeriesProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json) - { - _config = config; - _httpClient = httpClient; - _fileSystem = fileSystem; - _json = json; - - Current = this; - } - - public string Name => ProviderName; - - public static string ProviderName => "FanArt"; - - public bool Supports(BaseItem item) - { - return item is Series; - } - - public IEnumerable GetSupportedImages(BaseItem item) - { - return new List - { - ImageType.Primary, - ImageType.Thumb, - ImageType.Art, - ImageType.Logo, - ImageType.Backdrop, - ImageType.Banner - }; - } - - public async Task> GetImages(BaseItem item, CancellationToken cancellationToken) - { - var list = new List(); - - var series = (Series)item; - - var id = series.GetProviderId(MetadataProviders.Tvdb); - - if (!string.IsNullOrEmpty(id)) - { - // Bad id entered - try - { - await EnsureSeriesJson(id, cancellationToken).ConfigureAwait(false); - } - catch (HttpException ex) - { - if (!ex.StatusCode.HasValue || ex.StatusCode.Value != HttpStatusCode.NotFound) - { - throw; - } - } - - var path = GetFanartJsonPath(id); - - try - { - AddImages(list, path, cancellationToken); - } - catch (FileNotFoundException) - { - // No biggie. Don't blow up - } - catch (IOException) - { - // No biggie. Don't blow up - } - } - - var language = item.GetPreferredMetadataLanguage(); - - var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase); - - // Sort first by width to prioritize HD versions - return list.OrderByDescending(i => i.Width ?? 0) - .ThenByDescending(i => - { - if (string.Equals(language, i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 3; - } - if (!isLanguageEn) - { - if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase)) - { - return 2; - } - } - if (string.IsNullOrEmpty(i.Language)) - { - return isLanguageEn ? 3 : 2; - } - return 0; - }) - .ThenByDescending(i => i.CommunityRating ?? 0) - .ThenByDescending(i => i.VoteCount ?? 0); - } - - private void AddImages(List list, string path, CancellationToken cancellationToken) - { - var root = _json.DeserializeFromFile(path); - - AddImages(list, root, cancellationToken); - } - - private void AddImages(List list, RootObject obj, CancellationToken cancellationToken) - { - PopulateImages(list, obj.hdtvlogo, ImageType.Logo, 800, 310); - PopulateImages(list, obj.hdclearart, ImageType.Art, 1000, 562); - PopulateImages(list, obj.clearlogo, ImageType.Logo, 400, 155); - PopulateImages(list, obj.clearart, ImageType.Art, 500, 281); - PopulateImages(list, obj.showbackground, ImageType.Backdrop, 1920, 1080, true); - PopulateImages(list, obj.seasonthumb, ImageType.Thumb, 500, 281); - PopulateImages(list, obj.tvthumb, ImageType.Thumb, 500, 281); - PopulateImages(list, obj.tvbanner, ImageType.Banner, 1000, 185); - PopulateImages(list, obj.tvposter, ImageType.Primary, 1000, 1426); - } - - private void PopulateImages(List list, - List images, - ImageType type, - int width, - int height, - bool allowSeasonAll = false) - { - if (images == null) - { - return; - } - - list.AddRange(images.Select(i => - { - var url = i.url; - var season = i.season; - - var isSeasonValid = string.IsNullOrEmpty(season) || - (allowSeasonAll && string.Equals(season, "all", StringComparison.OrdinalIgnoreCase)); - - if (!string.IsNullOrEmpty(url) && isSeasonValid) - { - var likesString = i.likes; - - var info = new RemoteImageInfo - { - RatingType = RatingType.Likes, - Type = type, - Width = width, - Height = height, - ProviderName = Name, - Url = url.Replace("http://", "https://", StringComparison.OrdinalIgnoreCase), - Language = i.lang - }; - - if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes)) - { - info.CommunityRating = likes; - } - - return info; - } - - return null; - }).Where(i => i != null)); - } - - public int Order => 1; - - public Task GetImageResponse(string url, CancellationToken cancellationToken) - { - return _httpClient.GetResponse(new HttpRequestOptions - { - CancellationToken = cancellationToken, - Url = url - }); - } - - /// - /// Gets the series data path. - /// - /// The app paths. - /// The series id. - /// System.String. - internal static string GetSeriesDataPath(IApplicationPaths appPaths, string seriesId) - { - var seriesDataPath = Path.Combine(GetSeriesDataPath(appPaths), seriesId); - - return seriesDataPath; - } - - /// - /// Gets the series data path. - /// - /// The app paths. - /// System.String. - internal static string GetSeriesDataPath(IApplicationPaths appPaths) - { - var dataPath = Path.Combine(appPaths.CachePath, "fanart-tv"); - - return dataPath; - } - - public string GetFanartJsonPath(string tvdbId) - { - var dataPath = GetSeriesDataPath(_config.ApplicationPaths, tvdbId); - return Path.Combine(dataPath, "fanart.json"); - } - - private readonly SemaphoreSlim _ensureSemaphore = new SemaphoreSlim(1, 1); - internal async Task EnsureSeriesJson(string tvdbId, CancellationToken cancellationToken) - { - var path = GetFanartJsonPath(tvdbId); - - // Only allow one thread in here at a time since every season will be calling this method, possibly concurrently - await _ensureSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - var fileInfo = _fileSystem.GetFileSystemInfo(path); - - if (fileInfo.Exists) - { - if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2) - { - return; - } - } - - await DownloadSeriesJson(tvdbId, cancellationToken).ConfigureAwait(false); - } - finally - { - _ensureSemaphore.Release(); - } - } - - public FanartOptions GetFanartOptions() - { - return _config.GetConfiguration("fanart"); - } - - /// - /// Downloads the series json. - /// - /// The TVDB identifier. - /// The cancellation token. - /// Task. - internal async Task DownloadSeriesJson(string tvdbId, CancellationToken cancellationToken) - { - cancellationToken.ThrowIfCancellationRequested(); - - var url = string.Format(FanArtBaseUrl, FanartArtistProvider.ApiKey, tvdbId); - - var clientKey = GetFanartOptions().UserApiKey; - if (!string.IsNullOrWhiteSpace(clientKey)) - { - url += "&client_key=" + clientKey; - } - - var path = GetFanartJsonPath(tvdbId); - - Directory.CreateDirectory(Path.GetDirectoryName(path)); - - try - { - using (var httpResponse = await _httpClient.SendAsync(new HttpRequestOptions - { - Url = url, - CancellationToken = cancellationToken, - BufferContent = true - - }, "GET").ConfigureAwait(false)) - { - using (var response = httpResponse.Content) - { - using (var fileStream = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true)) - { - await response.CopyToAsync(fileStream).ConfigureAwait(false); - } - } - } - } - catch (HttpException exception) - { - if (exception.StatusCode.HasValue && exception.StatusCode.Value == HttpStatusCode.NotFound) - { - // If the user has automatic updates enabled, save a dummy object to prevent repeated download attempts - _json.SerializeToFile(new RootObject(), path); - - return; - } - - throw; - } - } - - public class Image - { - public string id { get; set; } - public string url { get; set; } - public string lang { get; set; } - public string likes { get; set; } - public string season { get; set; } - } - - public class RootObject - { - public string name { get; set; } - public string thetvdb_id { get; set; } - public List clearlogo { get; set; } - public List hdtvlogo { get; set; } - public List clearart { get; set; } - public List showbackground { get; set; } - public List tvthumb { get; set; } - public List seasonposter { get; set; } - public List seasonthumb { get; set; } - public List hdclearart { get; set; } - public List tvbanner { get; set; } - public List characterart { get; set; } - public List tvposter { get; set; } - public List seasonbanner { get; set; } - } - } - - public class FanartConfigStore : IConfigurationFactory - { - public IEnumerable GetConfigurations() - { - return new ConfigurationStore[] - { - new ConfigurationStore - { - Key = "fanart", - ConfigurationType = typeof(FanartOptions) - } - }; - } - } -}