Merge pull request #2 from jellyfin/style

Fix style issues
This commit is contained in:
Anthony Lavado 2019-10-13 00:46:12 -04:00 committed by GitHub
commit 362fd96399
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 241 additions and 169 deletions

View File

@ -1,23 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Jellyfin.Plugin.Fanart</RootNamespace>
<AssemblyVersion>1.0.0</AssemblyVersion>
<FileVersion>1.0.0</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Jellyfin.Controller" Version="10.*" />
<PackageReference Include="Jellyfin.Model" Version="10.*" />
</ItemGroup>
<ItemGroup>
<None Remove="Configuration\configPage.html" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Configuration\configPage.html" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>Jellyfin.Plugin.Fanart</RootNamespace>
<AssemblyVersion>1.1.0</AssemblyVersion>
<FileVersion>1.1.0</FileVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Jellyfin.Controller" Version="10.*" />
<PackageReference Include="Jellyfin.Model" Version="10.*" />
</ItemGroup>
<ItemGroup>
<None Remove="Configuration\configPage.html" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Configuration\configPage.html" />
</ItemGroup>
</Project>

View File

@ -10,18 +10,24 @@ namespace Jellyfin.Plugin.Fanart
{
public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
{
public override string Name => "Fanart";
public override Guid Id => Guid.Parse("170a157f-ac6c-437a-abdd-ca9c25cebd39");
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) : base(applicationPaths, xmlSerializer)
public const string ApiKey = "184e1a2b1fe3b94935365411f919f638";
public const string BaseUrl = "https://webservice.fanart.tv/v3/{2}/{1}?api_key={0}";
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
: base(applicationPaths, xmlSerializer)
{
Instance = this;
}
/// <inheritdoc />
public override string Name => "Fanart";
/// <inheritdoc />
public override Guid Id { get; } = new Guid("170a157f-ac6c-437a-abdd-ca9c25cebd39");
public static Plugin Instance { get; private set; }
public static string ApiKey = "184e1a2b1fe3b94935365411f919f638";
public static string BaseUrl = "https://webservice.fanart.tv/v3/{2}/{1}?api_key={0}";
/// <inheritdoc />
public IEnumerable<PluginPageInfo> GetPages()
{
return new[]

View File

@ -13,7 +13,6 @@ 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;
@ -21,29 +20,28 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
public class AlbumProvider : 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 AlbumProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer jsonSerializer)
public AlbumProvider(IServerConfigurationManager config, IHttpClient httpClient, IJsonSerializer jsonSerializer)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
_jsonSerializer = jsonSerializer;
}
public string Name => ProviderName;
/// <inheritdoc />
public string Name => "Fanart";
public static string ProviderName => "Fanart";
/// <inheritdoc />
public int Order => 1; // After embedded provider
/// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is MusicAlbum;
}
=> item is MusicAlbum;
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new List<ImageType>
@ -53,6 +51,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
};
}
/// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var album = (MusicAlbum)item;
@ -104,6 +103,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
return 3;
}
if (!isLanguageEn)
{
if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
@ -111,10 +111,12 @@ namespace Jellyfin.Plugin.Fanart.Providers
return 2;
}
}
if (string.IsNullOrEmpty(i.Language))
{
return isLanguageEn ? 3 : 2;
}
return 0;
})
.ThenByDescending(i => i.CommunityRating ?? 0)
@ -145,7 +147,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
}
}
private void PopulateImages(List<RemoteImageInfo> list,
private void PopulateImages(
List<RemoteImageInfo> list,
List<ArtistProvider.ArtistImage> images,
ImageType type,
int width,
@ -175,7 +178,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
Language = i.lang
};
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes))
if (!string.IsNullOrEmpty(likesString)
&& int.TryParse(likesString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var likes))
{
info.CommunityRating = likes;
}
@ -186,9 +190,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
return null;
}).Where(i => i != null));
}
// After embedded provider
public int Order => 1;
/// <inheritdoc />
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClient.GetResponse(new HttpRequestOptions

View File

@ -24,14 +24,11 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
public class ArtistProvider : 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;
internal static ArtistProvider Current;
public ArtistProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer jsonSerializer)
{
_config = config;
@ -42,15 +39,19 @@ namespace Jellyfin.Plugin.Fanart.Providers
Current = this;
}
public string Name => ProviderName;
internal static ArtistProvider Current { get; private set; }
public static string ProviderName => "Fanart";
/// <inheritdoc />
public string Name => "Fanart";
/// <inheritdoc />
public int Order => 0;
/// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is MusicArtist;
}
=> item is MusicArtist;
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new List<ImageType>
@ -63,6 +64,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
};
}
/// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var artist = (MusicArtist)item;
@ -103,6 +105,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
return 3;
}
if (!isLanguageEn)
{
if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
@ -110,10 +113,12 @@ namespace Jellyfin.Plugin.Fanart.Providers
return 2;
}
}
if (string.IsNullOrEmpty(i.Language))
{
return isLanguageEn ? 3 : 2;
}
return 0;
})
.ThenByDescending(i => i.CommunityRating ?? 0)
@ -139,7 +144,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
PopulateImages(list, obj.musicarts, ImageType.Art, 500, 281);
}
private void PopulateImages(List<RemoteImageInfo> list,
private void PopulateImages(
List<RemoteImageInfo> list,
List<ArtistImage> images,
ImageType type,
int width,
@ -169,7 +175,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
Language = i.lang
};
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes))
if (!string.IsNullOrEmpty(likesString)
&& int.TryParse(likesString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var likes))
{
info.CommunityRating = likes;
}
@ -181,8 +188,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
}).Where(i => i != null));
}
public int Order => 0;
/// <inheritdoc />
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClient.GetResponse(new HttpRequestOptions
@ -198,12 +204,10 @@ namespace Jellyfin.Plugin.Fanart.Providers
var fileInfo = _fileSystem.GetFileSystemInfo(jsonPath);
if (fileInfo.Exists)
if (fileInfo.Exists
&& (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
{
if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
{
return Task.CompletedTask;
}
return Task.CompletedTask;
}
return DownloadArtistJson(musicBrainzId, cancellationToken);
@ -219,7 +223,12 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
cancellationToken.ThrowIfCancellationRequested();
var url = string.Format(Plugin.BaseUrl, Plugin.ApiKey, musicBrainzId, "music");
var url = string.Format(
CultureInfo.InvariantCulture,
Plugin.BaseUrl,
Plugin.ApiKey,
musicBrainzId,
"music");
var clientKey = Plugin.Instance.Configuration.PersonalApiKey;
if (!string.IsNullOrWhiteSpace(clientKey))
@ -233,21 +242,19 @@ namespace Jellyfin.Plugin.Fanart.Providers
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 httpResponse = await _httpClient.SendAsync(
new HttpRequestOptions
{
using (var saveFileStream = _fileSystem.GetFileStream(jsonPath, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
{
await response.CopyToAsync(saveFileStream).ConfigureAwait(false);
}
}
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)
@ -295,35 +302,50 @@ namespace Jellyfin.Plugin.Fanart.Providers
return Path.Combine(dataPath, "fanart.json");
}
public class ArtistImage
{
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<ArtistImage> cdart { get; set; }
public List<ArtistImage> albumcover { get; set; }
}
public class ArtistResponse
{
public string name { get; set; }
public string mbid_id { get; set; }
public List<ArtistImage> artistthumb { get; set; }
public List<ArtistImage> artistbackground { get; set; }
public List<ArtistImage> hdmusiclogo { get; set; }
public List<ArtistImage> musicbanner { get; set; }
public List<ArtistImage> musiclogo { get; set; }
public List<ArtistImage> musicarts { get; set; }
public List<ArtistImage> hdmusicarts { get; set; }
public List<Album> albums { get; set; }
}
}

View File

@ -23,33 +23,30 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
public class MovieProvider : 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;
internal static MovieProvider Current;
public MovieProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
_json = json;
Current = this;
}
public string Name => ProviderName;
/// <inheritdoc />
public string Name => "Fanart";
public static string ProviderName => "Fanart";
/// <inheritdoc />
public int Order => 1;
/// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is Movie || item is BoxSet || item is MusicVideo;
}
=> item is Movie || item is BoxSet || item is MusicVideo;
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new List<ImageType>
@ -64,6 +61,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
};
}
/// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var baseItem = item;
@ -90,7 +88,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
try
{
AddImages(list, path, cancellationToken);
AddImages(list, path);
}
catch (FileNotFoundException)
{
@ -114,6 +112,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
return 3;
}
if (!isLanguageEn)
{
if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
@ -121,23 +120,25 @@ namespace Jellyfin.Plugin.Fanart.Providers
return 2;
}
}
if (string.IsNullOrEmpty(i.Language))
{
return isLanguageEn ? 3 : 2;
}
return 0;
})
.ThenByDescending(i => i.CommunityRating ?? 0);
}
private void AddImages(List<RemoteImageInfo> list, string path, CancellationToken cancellationToken)
private void AddImages(List<RemoteImageInfo> list, string path)
{
var root = _json.DeserializeFromFile<RootObject>(path);
AddImages(list, root, cancellationToken);
AddImages(list, root);
}
private void AddImages(List<RemoteImageInfo> list, RootObject obj, CancellationToken cancellationToken)
private void AddImages(List<RemoteImageInfo> list, RootObject obj)
{
PopulateImages(list, obj.hdmovieclearart, ImageType.Art, 1000, 562);
PopulateImages(list, obj.hdmovielogo, ImageType.Logo, 800, 310);
@ -176,7 +177,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
Language = i.lang
};
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes))
if (!string.IsNullOrEmpty(likesString)
&& int.TryParse(likesString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var likes))
{
info.CommunityRating = likes;
}
@ -188,8 +190,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
}).Where(i => i != null));
}
public int Order => 1;
/// <inheritdoc />
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClient.GetResponse(new HttpRequestOptions
@ -224,7 +225,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
return dataPath;
}
public string GetJsonPath(string id)
private string GetJsonPath(string id)
{
var movieDataPath = GetMovieDataPath(_config.ApplicationPaths, id);
return Path.Combine(movieDataPath, "fanart.json");
@ -240,7 +241,12 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
cancellationToken.ThrowIfCancellationRequested();
var url = string.Format(Plugin.BaseUrl, Plugin.ApiKey, id, "movies");
var url = string.Format(
CultureInfo.InvariantCulture,
Plugin.BaseUrl,
Plugin.ApiKey,
id,
"movies");
var clientKey = Plugin.Instance.Configuration.PersonalApiKey;
if (!string.IsNullOrWhiteSpace(clientKey))
@ -254,21 +260,19 @@ namespace Jellyfin.Plugin.Fanart.Providers
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 httpResponse = await _httpClient.SendAsync(
new HttpRequestOptions
{
using (var fileStream = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
{
await response.CopyToAsync(fileStream).ConfigureAwait(false);
}
}
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)
@ -291,12 +295,10 @@ namespace Jellyfin.Plugin.Fanart.Providers
var fileInfo = _fileSystem.GetFileSystemInfo(path);
if (fileInfo.Exists)
if (fileInfo.Exists
&& (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
{
if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
{
return Task.CompletedTask;
}
return Task.CompletedTask;
}
return DownloadMovieJson(id, cancellationToken);
@ -305,24 +307,38 @@ namespace Jellyfin.Plugin.Fanart.Providers
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<Image> hdmovielogo { get; set; }
public List<Image> moviedisc { get; set; }
public List<Image> movielogo { get; set; }
public List<Image> movieposter { get; set; }
public List<Image> hdmovieclearart { get; set; }
public List<Image> movieart { get; set; }
public List<Image> moviebackground { get; set; }
public List<Image> moviebanner { get; set; }
public List<Image> moviethumb { get; set; }
}
}

View File

@ -7,14 +7,12 @@ 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;
@ -23,29 +21,26 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
public class SeasonProvider : 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 SeasonProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json)
public SeasonProvider(IHttpClient httpClient, IJsonSerializer json)
{
_config = config;
_httpClient = httpClient;
_fileSystem = fileSystem;
_json = json;
}
public string Name => ProviderName;
/// <inheritdoc />
public string Name => "Fanart";
public static string ProviderName => "Fanart";
/// <inheritdoc />
public int Order => 1;
/// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is Season;
}
=> item is Season;
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new List<ImageType>
@ -57,6 +52,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
};
}
/// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
@ -112,6 +108,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
return 3;
}
if (!isLanguageEn)
{
if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
@ -119,10 +116,12 @@ namespace Jellyfin.Plugin.Fanart.Providers
return 2;
}
}
if (string.IsNullOrEmpty(i.Language))
{
return isLanguageEn ? 3 : 2;
}
return 0;
})
.ThenByDescending(i => i.CommunityRating ?? 0)
@ -144,7 +143,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
PopulateImages(list, obj.showbackground, ImageType.Backdrop, 1920, 1080, seasonNumber);
}
private void PopulateImages(List<RemoteImageInfo> list,
private void PopulateImages(
List<RemoteImageInfo> list,
List<SeriesProvider.Image> images,
ImageType type,
int width,
@ -161,10 +161,10 @@ namespace Jellyfin.Plugin.Fanart.Providers
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)
if (!string.IsNullOrEmpty(url)
&& !string.IsNullOrEmpty(season)
&& int.TryParse(season, NumberStyles.Integer, CultureInfo.InvariantCulture, out var imageSeasonNumber)
&& seasonNumber == imageSeasonNumber)
{
var likesString = i.likes;
@ -179,7 +179,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
Language = i.lang
};
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes))
if (!string.IsNullOrEmpty(likesString)
&& int.TryParse(likesString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var likes))
{
info.CommunityRating = likes;
}
@ -191,8 +192,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
}).Where(i => i != null));
}
public int Order => 1;
/// <inheritdoc />
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClient.GetResponse(new HttpRequestOptions

View File

@ -6,14 +6,12 @@ using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Plugin.Fanart.Configuration;
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;
@ -26,13 +24,12 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
public class SeriesProvider : 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;
internal static SeriesProvider Current { get; private set; }
private readonly SemaphoreSlim _ensureSemaphore = new SemaphoreSlim(1, 1);
public SeriesProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem, IJsonSerializer json)
{
@ -44,15 +41,19 @@ namespace Jellyfin.Plugin.Fanart.Providers
Current = this;
}
public string Name => ProviderName;
internal static SeriesProvider Current { get; private set; }
public static string ProviderName => "Fanart";
/// <inheritdoc />
public string Name => "Fanart";
/// <inheritdoc />
public int Order => 1;
/// <inheritdoc />
public bool Supports(BaseItem item)
{
return item is Series;
}
=> item is Series;
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new List<ImageType>
@ -66,6 +67,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
};
}
/// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
@ -93,7 +95,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
try
{
AddImages(list, path, cancellationToken);
AddImages(list, path);
}
catch (FileNotFoundException)
{
@ -117,6 +119,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
return 3;
}
if (!isLanguageEn)
{
if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
@ -124,24 +127,26 @@ namespace Jellyfin.Plugin.Fanart.Providers
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<RemoteImageInfo> list, string path, CancellationToken cancellationToken)
private void AddImages(List<RemoteImageInfo> list, string path)
{
var root = _json.DeserializeFromFile<RootObject>(path);
AddImages(list, root, cancellationToken);
AddImages(list, root);
}
private void AddImages(List<RemoteImageInfo> list, RootObject obj, CancellationToken cancellationToken)
private void AddImages(List<RemoteImageInfo> list, RootObject obj)
{
PopulateImages(list, obj.hdtvlogo, ImageType.Logo, 800, 310);
PopulateImages(list, obj.hdclearart, ImageType.Art, 1000, 562);
@ -154,7 +159,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
PopulateImages(list, obj.tvposter, ImageType.Primary, 1000, 1426);
}
private void PopulateImages(List<RemoteImageInfo> list,
private void PopulateImages(
List<RemoteImageInfo> list,
List<Image> images,
ImageType type,
int width,
@ -189,7 +195,8 @@ namespace Jellyfin.Plugin.Fanart.Providers
Language = i.lang
};
if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Integer, _usCulture, out var likes))
if (!string.IsNullOrEmpty(likesString)
&& int.TryParse(likesString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var likes))
{
info.CommunityRating = likes;
}
@ -201,8 +208,7 @@ namespace Jellyfin.Plugin.Fanart.Providers
}).Where(i => i != null));
}
public int Order => 1;
/// <inheritdoc />
public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
return _httpClient.GetResponse(new HttpRequestOptions
@ -243,7 +249,6 @@ namespace Jellyfin.Plugin.Fanart.Providers
return Path.Combine(dataPath, "fanart.json");
}
private readonly SemaphoreSlim _ensureSemaphore = new SemaphoreSlim(1, 1);
internal async Task EnsureSeriesJson(string tvdbId, CancellationToken cancellationToken)
{
var path = GetJsonPath(tvdbId);
@ -281,7 +286,12 @@ namespace Jellyfin.Plugin.Fanart.Providers
{
cancellationToken.ThrowIfCancellationRequested();
var url = string.Format(Plugin.BaseUrl, Plugin.ApiKey, tvdbId, "tv");
var url = string.Format(
CultureInfo.InvariantCulture,
Plugin.BaseUrl,
Plugin.ApiKey,
tvdbId,
"tv");
var clientKey = Plugin.Instance.Configuration.PersonalApiKey;
if (!string.IsNullOrWhiteSpace(clientKey))
@ -295,21 +305,19 @@ namespace Jellyfin.Plugin.Fanart.Providers
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 httpResponse = await _httpClient.SendAsync(
new HttpRequestOptions
{
using (var fileStream = _fileSystem.GetFileStream(path, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read, true))
{
await response.CopyToAsync(fileStream).ConfigureAwait(false);
}
}
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)
@ -329,27 +337,44 @@ namespace Jellyfin.Plugin.Fanart.Providers
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<Image> clearlogo { get; set; }
public List<Image> hdtvlogo { get; set; }
public List<Image> clearart { get; set; }
public List<Image> showbackground { get; set; }
public List<Image> tvthumb { get; set; }
public List<Image> seasonposter { get; set; }
public List<Image> seasonthumb { get; set; }
public List<Image> hdclearart { get; set; }
public List<Image> tvbanner { get; set; }
public List<Image> characterart { get; set; }
public List<Image> tvposter { get; set; }
public List<Image> seasonbanner { get; set; }
}
}

View File

@ -1,7 +1,7 @@
---
name: "jellyfin-plugin-fanart"
guid: "170a157f-ac6c-437a-abdd-ca9c25cebd39"
version: "1.0.0"
version: "1.1.0"
nicename: "Fanart"
description: "Scrape poster images from fanart.tv"
overview: "Scrape poster images for movies, shows, and artists in your library."