mirror of
https://github.com/jellyfin/jellyfin-plugin-coverartarchive.git
synced 2024-11-23 05:49:55 +00:00
Add analyzers and remove all warnings
This commit is contained in:
parent
0d73da0f71
commit
c6045d0096
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
bin/
|
||||
obj/
|
||||
.vs/
|
||||
.idea
|
@ -2,27 +2,10 @@ using MediaBrowser.Model.Plugins;
|
||||
|
||||
namespace Jellyfin.Plugin.CoverArtArchive.Configuration
|
||||
{
|
||||
public enum SomeOptions
|
||||
{
|
||||
OneOption,
|
||||
AnotherOption
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The (empty) plugin configuration.
|
||||
/// </summary>
|
||||
public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
// store configurable settings your plugin might need
|
||||
public bool TrueFalseSetting { get; set; }
|
||||
public int AnInteger { get; set; }
|
||||
public string AString { get; set; }
|
||||
public SomeOptions Options { get; set; }
|
||||
|
||||
public PluginConfiguration()
|
||||
{
|
||||
// set default options here
|
||||
Options = SomeOptions.AnotherOption;
|
||||
TrueFalseSetting = true;
|
||||
AnInteger = 2;
|
||||
AString = "string";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,18 @@
|
||||
namespace Jellyfin.Plugin.CoverArtArchive
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants.
|
||||
/// </summary>
|
||||
public static class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the user agent.
|
||||
/// </summary>
|
||||
public const string UserAgent = "jellyfin-plugin-coverartarchive";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the api base url.
|
||||
/// </summary>
|
||||
public const string ApiBaseUrl = "https://coverartarchive.org";
|
||||
}
|
||||
}
|
||||
|
51
Jellyfin.Plugin.CoverArtArchive/CoverArtArchivePlugin.cs
Normal file
51
Jellyfin.Plugin.CoverArtArchive/CoverArtArchivePlugin.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Plugin.CoverArtArchive.Configuration;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.CoverArtArchive
|
||||
{
|
||||
/// <summary>
|
||||
/// The cover art plugin.
|
||||
/// </summary>
|
||||
public class CoverArtArchivePlugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CoverArtArchivePlugin"/> class.
|
||||
/// </summary>
|
||||
/// <param name="applicationPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
|
||||
/// <param name="xmlSerializer">Instance of the <see cref="IXmlSerializer"/> interface.</param>
|
||||
public CoverArtArchivePlugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
|
||||
: base(applicationPaths, xmlSerializer)
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string Name => "Cover Art Archive";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Guid Id => Guid.Parse("8119f3c6-cfc2-4d9c-a0ba-028f1d93e526");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin instance.
|
||||
/// </summary>
|
||||
public static CoverArtArchivePlugin? Instance { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<PluginPageInfo> GetPages()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new PluginPageInfo
|
||||
{
|
||||
Name = Name,
|
||||
EmbeddedResourcePath = $"{GetType().Namespace}.Configuration.configPage.html"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,11 @@
|
||||
<RootNamespace>Jellyfin.Plugin.CoverArtArchive</RootNamespace>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
<FileVersion>2.0.0.0</FileVersion>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -13,6 +18,13 @@
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
|
||||
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
|
||||
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Configuration\configPage.html" />
|
||||
<EmbeddedResource Include="Configuration\configPage.html" />
|
||||
|
@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Plugin.CoverArtArchive.Configuration;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.CoverArtArchive
|
||||
{
|
||||
public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
{
|
||||
public override string Name => "Cover Art Archive";
|
||||
|
||||
public override Guid Id => Guid.Parse("8119f3c6-cfc2-4d9c-a0ba-028f1d93e526");
|
||||
|
||||
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) : base(applicationPaths, xmlSerializer)
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public static Plugin Instance { get; private set; }
|
||||
|
||||
public IEnumerable<PluginPageInfo> GetPages()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new PluginPageInfo
|
||||
{
|
||||
Name = this.Name,
|
||||
EmbeddedResourcePath = string.Format("{0}.Configuration.configPage.html", GetType().Namespace)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
46
Jellyfin.Plugin.CoverArtArchive/Providers/ApiImageDto.cs
Normal file
46
Jellyfin.Plugin.CoverArtArchive/Providers/ApiImageDto.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Jellyfin.Plugin.CoverArtArchive.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// The api image dto.
|
||||
/// </summary>
|
||||
public class ApiImageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the list of types.
|
||||
/// </summary>
|
||||
public IReadOnlyList<ApiImageType> Types { get; set; } = Array.Empty<ApiImageType>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this is a front image.
|
||||
/// </summary>
|
||||
public bool Front { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this is a back image.
|
||||
/// </summary>
|
||||
public bool Back { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image.
|
||||
/// </summary>
|
||||
public string? Image { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the thumbnails.
|
||||
/// </summary>
|
||||
public ApiThumbnailsDto? Thumbnails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image comment.
|
||||
/// </summary>
|
||||
public string? Comment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this image has been approved.
|
||||
/// </summary>
|
||||
public bool Approved { get; set; }
|
||||
}
|
||||
}
|
91
Jellyfin.Plugin.CoverArtArchive/Providers/ApiImageType.cs
Normal file
91
Jellyfin.Plugin.CoverArtArchive/Providers/ApiImageType.cs
Normal file
@ -0,0 +1,91 @@
|
||||
namespace Jellyfin.Plugin.CoverArtArchive.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// The api image type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// https://musicbrainz.org/doc/Cover_Art/Types.
|
||||
/// </remarks>
|
||||
public enum ApiImageType
|
||||
{
|
||||
/// <summary>
|
||||
/// Front image.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ImageType.Box
|
||||
/// </remarks>
|
||||
Front,
|
||||
|
||||
/// <summary>
|
||||
/// Back image.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ImageType.BoxRear
|
||||
/// </remarks>
|
||||
Back, // ImageType.BoxRear
|
||||
|
||||
/// <summary>
|
||||
/// Booklet image.
|
||||
/// </summary>
|
||||
Booklet,
|
||||
|
||||
/// <summary>
|
||||
/// Medium image
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ImageType.Disc
|
||||
/// </remarks>
|
||||
Medium, // ImageType.Disc
|
||||
|
||||
/// <summary>
|
||||
/// Tray image.
|
||||
/// </summary>
|
||||
Tray,
|
||||
|
||||
/// <summary>
|
||||
/// Obi image.
|
||||
/// </summary>
|
||||
Obi,
|
||||
|
||||
/// <summary>
|
||||
/// Spine image.
|
||||
/// </summary>
|
||||
Spine,
|
||||
|
||||
/// <summary>
|
||||
/// Track image.
|
||||
/// </summary>
|
||||
Track,
|
||||
|
||||
/// <summary>
|
||||
/// Liner image.
|
||||
/// </summary>
|
||||
Liner,
|
||||
|
||||
/// <summary>
|
||||
/// Sticker image.
|
||||
/// </summary>
|
||||
Sticker,
|
||||
|
||||
/// <summary>
|
||||
/// Poster image
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ImageType.Art
|
||||
/// </remarks>
|
||||
Poster, // ImageType.Art
|
||||
|
||||
/// <summary>
|
||||
/// Watermark image.
|
||||
/// </summary>
|
||||
Watermark,
|
||||
|
||||
/// <summary>
|
||||
/// Other image
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Raw or Unedited
|
||||
/// </remarks>
|
||||
Other,
|
||||
}
|
||||
}
|
21
Jellyfin.Plugin.CoverArtArchive/Providers/ApiReleaseDto.cs
Normal file
21
Jellyfin.Plugin.CoverArtArchive/Providers/ApiReleaseDto.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Jellyfin.Plugin.CoverArtArchive.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// The api release dto.
|
||||
/// </summary>
|
||||
public class ApiReleaseDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the release.
|
||||
/// </summary>
|
||||
public string? Release { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the list of images.
|
||||
/// </summary>
|
||||
public IReadOnlyList<ApiImageDto> Images { get; set; } = Array.Empty<ApiImageDto>();
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
namespace Jellyfin.Plugin.CoverArtArchive.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// Api thumbnails dto.
|
||||
/// </summary>
|
||||
public class ApiThumbnailsDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the small thumbnail.
|
||||
/// </summary>
|
||||
public string? Small { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the large thumbnail.
|
||||
/// </summary>
|
||||
public string? Large { get; set; }
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
@ -16,156 +16,173 @@ using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Plugin.CoverArtArchive.Providers {
|
||||
|
||||
/* https://musicbrainz.org/doc/Cover_Art/Types */
|
||||
public enum ApiImageTypeEnum {
|
||||
Front, // ImageType.Box
|
||||
Back, // ImageType.BoxRear
|
||||
Booklet,
|
||||
Medium, // ImageType.Disc
|
||||
Tray,
|
||||
Obi,
|
||||
Spine,
|
||||
Track,
|
||||
Liner,
|
||||
Sticker,
|
||||
Poster, // ImageType.Art
|
||||
Watermark,
|
||||
// Raw/Unedited,
|
||||
Other,
|
||||
}
|
||||
|
||||
public class ApiRelease {
|
||||
public string Release { get; set; }
|
||||
public List<ApiImage> Images { get; set; }
|
||||
}
|
||||
|
||||
public class ApiImage {
|
||||
public List<ApiImageTypeEnum> Types { get; set; }
|
||||
public bool Front { get; set; }
|
||||
public bool Back { get; set; }
|
||||
public string Image { get; set; }
|
||||
public ApiThumbnails Thumbnails { get; set; }
|
||||
public string Comment { get; set; }
|
||||
public bool Approved { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class ApiThumbnails {
|
||||
public string Small { get; set; }
|
||||
public string Large { get; set; }
|
||||
}
|
||||
|
||||
public class CoverArtArchiveImageProvider : IRemoteImageProvider {
|
||||
namespace Jellyfin.Plugin.CoverArtArchive.Providers
|
||||
{
|
||||
/// <summary>
|
||||
/// The cover art archive image provider.
|
||||
/// </summary>
|
||||
public class CoverArtArchiveImageProvider : IRemoteImageProvider
|
||||
{
|
||||
private readonly ILogger<CoverArtArchiveImageProvider> _logger;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly JsonSerializerOptions _serializerOptions;
|
||||
public CoverArtArchiveImageProvider(IHttpClientFactory httpClientFactory, ILogger<CoverArtArchiveImageProvider> logger) {
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CoverArtArchiveImageProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/> interface.</param>
|
||||
/// <param name="logger">Instance of the <see cref="ILogger{CoverArtArchiveImageProvider}"/> interface.</param>
|
||||
public CoverArtArchiveImageProvider(
|
||||
IHttpClientFactory httpClientFactory,
|
||||
ILogger<CoverArtArchiveImageProvider> logger)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_logger = logger;
|
||||
|
||||
_serializerOptions = new JsonSerializerOptions {
|
||||
_serializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
};
|
||||
_serializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase));
|
||||
}
|
||||
|
||||
public string Name => "Cover Art Archive";
|
||||
|
||||
public bool Supports(BaseItem item) => item is MusicAlbum;
|
||||
|
||||
public IEnumerable<ImageType> GetSupportedImages(BaseItem item) {
|
||||
return new[] { ImageType.Primary, ImageType.Box, ImageType.BoxRear, ImageType.Disc };
|
||||
}
|
||||
|
||||
public async Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken) {
|
||||
_logger.LogDebug("GetImageResponse({url})", url);
|
||||
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
|
||||
return await httpClient.GetAsync(url).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<RemoteImageInfo>> _getImages(string url, CancellationToken cancellationToken) {
|
||||
_logger.LogDebug("_getImages({url})", url);
|
||||
List<RemoteImageInfo> list = new List<RemoteImageInfo>();
|
||||
|
||||
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
|
||||
var response = await httpClient.GetAsync(url).ConfigureAwait(false);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK) {
|
||||
await using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
ApiRelease release = await JsonSerializer.DeserializeAsync<ApiRelease>(stream, _serializerOptions);
|
||||
|
||||
foreach (ApiImage image in release.Images) {
|
||||
_logger.LogDebug(image.Types.ToString());
|
||||
if (image.Types.Contains(ApiImageTypeEnum.Front)) {
|
||||
list.Add(
|
||||
new RemoteImageInfo {
|
||||
ProviderName = Name,
|
||||
Url = image.Image,
|
||||
Type = ImageType.Box,
|
||||
ThumbnailUrl = image.Thumbnails.Small ?? image.Thumbnails.Large,
|
||||
CommunityRating = image.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
}
|
||||
);
|
||||
list.Add(
|
||||
new RemoteImageInfo {
|
||||
ProviderName = Name,
|
||||
Url = image.Image,
|
||||
Type = ImageType.Primary,
|
||||
ThumbnailUrl = image.Thumbnails.Small ?? image.Thumbnails.Large,
|
||||
CommunityRating = image.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
}
|
||||
);
|
||||
}
|
||||
if (image.Types.Contains(ApiImageTypeEnum.Back)) {
|
||||
list.Add(
|
||||
new RemoteImageInfo {
|
||||
ProviderName = Name,
|
||||
Url = image.Image,
|
||||
Type = ImageType.BoxRear,
|
||||
ThumbnailUrl = image.Thumbnails.Small ?? image.Thumbnails.Large,
|
||||
CommunityRating = image.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
}
|
||||
);
|
||||
}
|
||||
if (image.Types.Contains(ApiImageTypeEnum.Medium)) {
|
||||
list.Add(
|
||||
new RemoteImageInfo {
|
||||
ProviderName = Name,
|
||||
Url = image.Image,
|
||||
Type = ImageType.Disc,
|
||||
ThumbnailUrl = image.Thumbnails.Small ?? image.Thumbnails.Large,
|
||||
CommunityRating = image.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
}
|
||||
);
|
||||
}
|
||||
Converters =
|
||||
{
|
||||
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
|
||||
}
|
||||
} else {
|
||||
_logger.LogWarning("Got HTTP {} - {}", response.StatusCode, response.Headers.Location);
|
||||
}
|
||||
return list;
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken) {
|
||||
/// <inheritdoc />
|
||||
public string Name
|
||||
=> "Cover Art Archive";
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Supports(BaseItem item)
|
||||
=> item is MusicAlbum;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
ImageType.Primary,
|
||||
ImageType.Box,
|
||||
ImageType.BoxRear,
|
||||
ImageType.Disc
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogDebug("GetImageResponse({Url})", url);
|
||||
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
|
||||
return await httpClient.GetAsync(new Uri(url), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
|
||||
{
|
||||
var list = new List<RemoteImageInfo>();
|
||||
var musicBrainzId = item.GetProviderId(MetadataProvider.MusicBrainzAlbum);
|
||||
|
||||
if (!string.IsNullOrEmpty(musicBrainzId)) {
|
||||
list.AddRange(await _getImages($"{Constants.ApiBaseUrl}/release/{musicBrainzId}/", cancellationToken));
|
||||
if (!string.IsNullOrEmpty(musicBrainzId))
|
||||
{
|
||||
list.AddRange(await GetImagesInternal($"{Constants.ApiBaseUrl}/release/{musicBrainzId}/", cancellationToken)
|
||||
.ConfigureAwait(false));
|
||||
}
|
||||
if (list.Count == 0) {
|
||||
|
||||
if (list.Count == 0)
|
||||
{
|
||||
var musicBrainzGroupId = item.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup);
|
||||
if (!string.IsNullOrEmpty(musicBrainzGroupId)) {
|
||||
list.AddRange(await _getImages($"{Constants.ApiBaseUrl}/release-group/{musicBrainzGroupId}/", cancellationToken));
|
||||
if (!string.IsNullOrEmpty(musicBrainzGroupId))
|
||||
{
|
||||
list.AddRange(await GetImagesInternal($"{Constants.ApiBaseUrl}/release-group/{musicBrainzGroupId}/", cancellationToken)
|
||||
.ConfigureAwait(false));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<RemoteImageInfo>> GetImagesInternal(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogDebug("GetImagesInternal({Url})", url);
|
||||
List<RemoteImageInfo> list = new List<RemoteImageInfo>();
|
||||
|
||||
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
|
||||
var response = await httpClient.GetAsync(new Uri(url), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
|
||||
var releaseDto = await JsonSerializer.DeserializeAsync<ApiReleaseDto>(stream, _serializerOptions, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (releaseDto == null)
|
||||
{
|
||||
return Array.Empty<RemoteImageInfo>();
|
||||
}
|
||||
|
||||
foreach (ApiImageDto image in releaseDto.Images)
|
||||
{
|
||||
_logger.LogDebug("ImageType: {ImageType}", image.Types);
|
||||
if (image.Types.Contains(ApiImageType.Front))
|
||||
{
|
||||
list.Add(
|
||||
new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = image.Image,
|
||||
Type = ImageType.Box,
|
||||
ThumbnailUrl = image.Thumbnails?.Small ?? image.Thumbnails?.Large,
|
||||
CommunityRating = image.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
});
|
||||
list.Add(
|
||||
new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = image.Image,
|
||||
Type = ImageType.Primary,
|
||||
ThumbnailUrl = image.Thumbnails?.Small ?? image.Thumbnails?.Large,
|
||||
CommunityRating = image.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
});
|
||||
}
|
||||
|
||||
if (image.Types.Contains(ApiImageType.Back))
|
||||
{
|
||||
list.Add(
|
||||
new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = image.Image,
|
||||
Type = ImageType.BoxRear,
|
||||
ThumbnailUrl = image.Thumbnails?.Small ?? image.Thumbnails?.Large,
|
||||
CommunityRating = image.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
});
|
||||
}
|
||||
|
||||
if (image.Types.Contains(ApiImageType.Medium))
|
||||
{
|
||||
list.Add(
|
||||
new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = image.Image,
|
||||
Type = ImageType.Disc,
|
||||
ThumbnailUrl = image.Thumbnails?.Small ?? image.Thumbnails?.Large,
|
||||
CommunityRating = image.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Got HTTP {StatusCode} - {Location}", response.StatusCode, response.Headers.Location);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
82
jellyfin.ruleset
Normal file
82
jellyfin.ruleset
Normal file
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RuleSet Name="Rules for Jellyfin" Description="Code analysis rules for Jellyfin" ToolsVersion="14.0">
|
||||
<Rules AnalyzerId="StyleCop.Analyzers" RuleNamespace="StyleCop.Analyzers">
|
||||
<!-- disable warning SA1202: 'public' members must come before 'private' members -->
|
||||
<Rule Id="SA1202" Action="Info" />
|
||||
<!-- disable warning SA1204: Static members must appear before non-static members -->
|
||||
<Rule Id="SA1204" Action="Info" />
|
||||
<!-- disable warning SA1404: Code analysis suppression should have justification -->
|
||||
<Rule Id="SA1404" Action="Info" />
|
||||
|
||||
<!-- disable warning SA1009: Closing parenthesis should be followed by a space. -->
|
||||
<Rule Id="SA1009" Action="None" />
|
||||
<!-- disable warning SA1011: Closing square bracket should be followed by a space. -->
|
||||
<Rule Id="SA1011" Action="None" />
|
||||
<!-- disable warning SA1101: Prefix local calls with 'this.' -->
|
||||
<Rule Id="SA1101" Action="None" />
|
||||
<!-- disable warning SA1108: Block statements should not contain embedded comments -->
|
||||
<Rule Id="SA1108" Action="None" />
|
||||
<!-- disable warning SA1128:: Put constructor initializers on their own line -->
|
||||
<Rule Id="SA1128" Action="None" />
|
||||
<!-- disable warning SA1130: Use lambda syntax -->
|
||||
<Rule Id="SA1130" Action="None" />
|
||||
<!-- disable warning SA1200: 'using' directive must appear within a namespace declaration -->
|
||||
<Rule Id="SA1200" Action="None" />
|
||||
<!-- disable warning SA1309: Fields must not begin with an underscore -->
|
||||
<Rule Id="SA1309" Action="None" />
|
||||
<!-- disable warning SA1413: Use trailing comma in multi-line initializers -->
|
||||
<Rule Id="SA1413" Action="None" />
|
||||
<!-- disable warning SA1512: Single-line comments must not be followed by blank line -->
|
||||
<Rule Id="SA1512" Action="None" />
|
||||
<!-- disable warning SA1515: Single-line comment should be preceded by blank line -->
|
||||
<Rule Id="SA1515" Action="None" />
|
||||
<!-- disable warning SA1600: Elements should be documented -->
|
||||
<Rule Id="SA1600" Action="None" />
|
||||
<!-- disable warning SA1602: Enumeration items should be documented -->
|
||||
<Rule Id="SA1602" Action="None" />
|
||||
<!-- disable warning SA1633: The file header is missing or not located at the top of the file -->
|
||||
<Rule Id="SA1633" Action="None" />
|
||||
</Rules>
|
||||
|
||||
<Rules AnalyzerId="Microsoft.CodeAnalysis.NetAnalyzers" RuleNamespace="Microsoft.Design">
|
||||
<!-- error on CA2016: Forward the CancellationToken parameter to methods that take one
|
||||
or pass in 'CancellationToken.None' explicitly to indicate intentionally not propagating the token -->
|
||||
<Rule Id="CA2016" Action="Error" />
|
||||
|
||||
<!-- disable warning CA1031: Do not catch general exception types -->
|
||||
<Rule Id="CA1031" Action="Info" />
|
||||
<!-- disable warning CA1032: Implement standard exception constructors -->
|
||||
<Rule Id="CA1032" Action="Info" />
|
||||
<!-- disable warning CA1062: Validate arguments of public methods -->
|
||||
<Rule Id="CA1062" Action="Info" />
|
||||
<!-- disable warning CA1716: Identifiers should not match keywords -->
|
||||
<Rule Id="CA1716" Action="Info" />
|
||||
<!-- disable warning CA1720: Identifiers should not contain type names -->
|
||||
<Rule Id="CA1720" Action="Info" />
|
||||
<!-- disable warning CA1805: Do not initialize unnecessarily -->
|
||||
<Rule Id="CA1805" Action="Info" />
|
||||
<!-- disable warning CA1812: internal class that is apparently never instantiated.
|
||||
If so, remove the code from the assembly.
|
||||
If this class is intended to contain only static members, make it static -->
|
||||
<Rule Id="CA1812" Action="Info" />
|
||||
<!-- disable warning CA1822: Member does not access instance data and can be marked as static -->
|
||||
<Rule Id="CA1822" Action="Info" />
|
||||
<!-- disable warning CA2000: Dispose objects before losing scope -->
|
||||
<Rule Id="CA2000" Action="Info" />
|
||||
<!-- disable warning CA5394: Do not use insecure randomness -->
|
||||
<Rule Id="CA5394" Action="Info" />
|
||||
|
||||
<!-- disable warning CA1014: Mark assemblies with CLSCompliantAttribute -->
|
||||
<Rule Id="CA1014" Action="Info" />
|
||||
<!-- disable warning CA1054: Change the type of parameter url from string to System.Uri -->
|
||||
<Rule Id="CA1054" Action="None" />
|
||||
<!-- disable warning CA1055: URI return values should not be strings -->
|
||||
<Rule Id="CA1055" Action="None" />
|
||||
<!-- disable warning CA1056: URI properties should not be strings -->
|
||||
<Rule Id="CA1056" Action="None" />
|
||||
<!-- disable warning CA1303: Do not pass literals as localized parameters -->
|
||||
<Rule Id="CA1303" Action="None" />
|
||||
<!-- disable warning CA1308: Normalize strings to uppercase -->
|
||||
<Rule Id="CA1308" Action="None" />
|
||||
</Rules>
|
||||
</RuleSet>
|
Loading…
Reference in New Issue
Block a user