mirror of
https://github.com/jellyfin/jellyfin-plugin-artwork.git
synced 2024-11-27 00:00:25 +00:00
Update plugin to latest artwork spec
This commit is contained in:
parent
002231e388
commit
3b381750e4
23
.github/dependabot.yml
vendored
Normal file
23
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Fetch and update latest `nuget` pkgs
|
||||
- package-ecosystem: nuget
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
time: '00:00'
|
||||
open-pull-requests-limit: 10
|
||||
commit-message:
|
||||
prefix: chore
|
||||
include: scope
|
||||
|
||||
# Fetch and update latest `github-actions` pkgs
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: weekly
|
||||
time: '00:00'
|
||||
open-pull-requests-limit: 10
|
||||
commit-message:
|
||||
prefix: chore
|
||||
include: scope
|
9
.github/release-drafter.yml
vendored
Normal file
9
.github/release-drafter.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
_extends: jellyfin-meta-plugins
|
||||
|
||||
template: |
|
||||
<!-- Optional: add a release summary here -->
|
||||
[Plugin build can be downloaded here](https://repo.jellyfin.org/releases/plugin/artwork/artwork_$NEXT_MAJOR_VERSION.0.0.0.zip).
|
||||
|
||||
## :sparkles: What's New
|
||||
|
||||
$CHANGES
|
31
.github/workflows/build-dotnet.yml
vendored
Normal file
31
.github/workflows/build-dotnet.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
name: Test Build Plugin
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.x
|
||||
|
||||
- name: Install dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build
|
||||
run: dotnet build --configuration Release --no-restore
|
||||
|
||||
- name: Test
|
||||
run: dotnet test --no-restore --verbosity normal
|
44
.github/workflows/codeql-analysis.yml
vendored
Normal file
44
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
name: Run CodeQL
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
paths-ignore:
|
||||
- '**/*.md'
|
||||
schedule:
|
||||
- cron: '24 2 * * 4'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'csharp' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.x
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
19
.github/workflows/create-github-release.yml
vendored
Normal file
19
.github/workflows/create-github-release.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: Publish Drafted GitHub Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: [ 'v*' ]
|
||||
|
||||
jobs:
|
||||
publish_release_draft:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get version from GITHUB_REF
|
||||
id: get-version
|
||||
run: echo "::set-output name=version::${GITHUB_REF/refs\/tags\//}"
|
||||
|
||||
- name: Publish release on GitHub
|
||||
uses: test-room-7/action-publish-release-drafts@v0
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag-name: ${{ steps.get-version.outputs.version }}
|
16
.github/workflows/update-release-draft.yml
vendored
Normal file
16
.github/workflows/update-release-draft.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# Automates creation of Release Drafts using Release Drafter
|
||||
name: Update Release Draft
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
update_release_draft:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Drafts your next Release notes as Pull Requests are merged into "master"
|
||||
- uses: release-drafter/release-drafter@v5.14.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
@ -47,7 +47,13 @@ namespace Jellyfin.Plugin.Artwork
|
||||
yield return new PluginPageInfo
|
||||
{
|
||||
Name = Name,
|
||||
EmbeddedResourcePath = prefix + ".Configuration.config.html"
|
||||
EmbeddedResourcePath = prefix + ".Configuration.Web.config.html",
|
||||
};
|
||||
|
||||
yield return new PluginPageInfo
|
||||
{
|
||||
Name = $"{Name}.js",
|
||||
EmbeddedResourcePath = prefix + ".Configuration.Web.config.js"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Jellyfin.Plugin.Artwork.Models;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
|
||||
@ -12,6 +13,7 @@ namespace Jellyfin.Plugin.Artwork.Configuration
|
||||
/// <summary>
|
||||
/// Gets or sets the list of artwork repos.
|
||||
/// </summary>
|
||||
[SuppressMessage(category: "Performance", checkId: "CA1819", Target = "ArtworkRepos", Justification = "Xml Serializer doesn't support IReadOnlyList")]
|
||||
public ArtworkRepo[] ArtworkRepos { get; set; } = Array.Empty<ArtworkRepo>();
|
||||
}
|
||||
}
|
39
Jellyfin.Plugin.Artwork/Configuration/Web/config.html
Normal file
39
Jellyfin.Plugin.Artwork/Configuration/Web/config.html
Normal file
@ -0,0 +1,39 @@
|
||||
<div data-role="page" id="artworkConfigurationPage" class="page type-interior pluginConfigurationPage fullWidthContent"
|
||||
data-controller="__plugin/Artwork.js">
|
||||
<div class="content-primary">
|
||||
<div class="verticalSection">
|
||||
<div class="sectionTitleContainer">
|
||||
<h2 class="sectionTitle">Artwork</h2>
|
||||
<a is="emby-linkbutton" class="raised raised-mini" style="margin-left: 2em;" target="_blank"
|
||||
href="https://github.com/jellyfin/jellyfin-plugin-artwork">
|
||||
<i class="md-icon button-icon button-icon-left secondaryText"></i>
|
||||
<span>Help</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="artworkConfigurationForm">
|
||||
<div id="configurationWrapper"></div>
|
||||
<button id="btnAddRepo" is="emby-button" type="button" class="raised button block">
|
||||
<span>Add new Repository</span>
|
||||
</button>
|
||||
<br/>
|
||||
<button id="saveConfig" is="emby-button" type="submit" class="raised button-submit block">
|
||||
<span>Save</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<template id="template-repository">
|
||||
<div data-id="repo-config">
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" data-id="txtRepositoryName" required="required" label="Repository Name:"/>
|
||||
<span>The artwork repository name.</span>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="text" data-id="txtRepositoryUrl" required="required" label="Repository Url:"/>
|
||||
<span>The artwork repository url.</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
69
Jellyfin.Plugin.Artwork/Configuration/Web/config.js
Normal file
69
Jellyfin.Plugin.Artwork/Configuration/Web/config.js
Normal file
@ -0,0 +1,69 @@
|
||||
export default function (view) {
|
||||
const Artwork = {
|
||||
pluginId: "7871D3B1-F1B9-4318-9C27-F35998FFBBCC",
|
||||
configurationWrapper: document.querySelector("#configurationWrapper"),
|
||||
|
||||
template: document.querySelector("#template-repository"),
|
||||
btnAddRepo: document.querySelector("#btnAddRepo"),
|
||||
btnSave: document.querySelector("#saveConfig"),
|
||||
addRepo: function (config) {
|
||||
const template = Artwork.template.cloneNode(true).content;
|
||||
|
||||
template.querySelector("[data-id=txtRepositoryName]").value = config.Name || "";
|
||||
template.querySelector("[data-id=txtRepositoryUrl]").value = config.Url || "";
|
||||
|
||||
Artwork.configurationWrapper.appendChild(template);
|
||||
},
|
||||
saveConfig: function (e) {
|
||||
e.preventDefault();
|
||||
Dashboard.showLoadingMsg();
|
||||
|
||||
const config = {
|
||||
ArtworkRepos: []
|
||||
};
|
||||
|
||||
const configs = document.querySelectorAll("[data-id=repo-config]");
|
||||
for (let i = 0; i < configs.length; i++) {
|
||||
const repo = {
|
||||
Name: configs[i].querySelector("[data-id=txtRepositoryName]").value,
|
||||
Url: configs[i].querySelector("[data-id=txtRepositoryUrl]").value
|
||||
};
|
||||
|
||||
config.ArtworkRepos.push(repo);
|
||||
}
|
||||
|
||||
window.ApiClient.updatePluginConfiguration(Artwork.pluginId, config)
|
||||
.then(Dashboard.processPluginConfigurationUpdateResult)
|
||||
.catch(function (error) {
|
||||
console.error(error);
|
||||
})
|
||||
.finally(function () {
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
},
|
||||
loadConfig: function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
window.ApiClient.getPluginConfiguration(Artwork.pluginId)
|
||||
.then(function (config) {
|
||||
for (let i = 0; i < config.ArtworkRepos.length; i++) {
|
||||
Artwork.addRepo(config.ArtworkRepos[i]);
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error(error);
|
||||
})
|
||||
.finally(function () {
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
},
|
||||
init: function () {
|
||||
Artwork.btnAddRepo.addEventListener("click", Artwork.addRepo);
|
||||
Artwork.btnSave.addEventListener("click", Artwork.saveConfig);
|
||||
Artwork.loadConfig();
|
||||
}
|
||||
}
|
||||
|
||||
view.addEventListener("viewshow", function (e) {
|
||||
Artwork.init();
|
||||
});
|
||||
}
|
@ -14,9 +14,10 @@ namespace Jellyfin.Plugin.Artwork
|
||||
/// <summary>
|
||||
/// Get the remote image info for item.
|
||||
/// </summary>
|
||||
/// <param name="imageTypeKey">The item repo key.</param>
|
||||
/// <param name="itemType">The item type.</param>
|
||||
/// <param name="providerIds">The provider ids.</param>
|
||||
/// <returns>The list of remote image info.</returns>
|
||||
Task<IEnumerable<RemoteImageInfo>> GetImageInfos(Type itemType, IHasProviderIds providerIds);
|
||||
Task<IEnumerable<RemoteImageInfo>> GetImageInfos(string imageTypeKey, Type itemType, IHasProviderIds providerIds);
|
||||
}
|
||||
}
|
@ -7,6 +7,8 @@
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<AnalysisMode>AllEnabledByDefault</AnalysisMode>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -14,23 +16,15 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.*" PrivateAssets="All" />
|
||||
<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\Web\config.html" />
|
||||
<None Remove="Configuration\Web\config.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Configuration\config.html" />
|
||||
<EmbeddedResource Include="Configuration\Web\config.html" />
|
||||
<EmbeddedResource Include="Configuration\Web\config.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
@ -10,17 +10,25 @@ namespace Jellyfin.Plugin.Artwork.Models
|
||||
/// <summary>
|
||||
/// Gets or sets the artwork name.
|
||||
/// </summary>
|
||||
[JsonPropertyName("name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the machine name.
|
||||
/// </summary>
|
||||
[JsonPropertyName("machine-name")]
|
||||
public string MachineName { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the artwork.
|
||||
/// </summary>
|
||||
[JsonPropertyName("artwork")]
|
||||
public ArtworkImages? ArtworkImages { get; set; }
|
||||
public ArtworkImageDto? ArtworkImages { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the providers.
|
||||
/// </summary>
|
||||
public Providers? Providers { get; set; }
|
||||
[JsonPropertyName("providers")]
|
||||
public ArtworkProviderDto? Providers { get; set; }
|
||||
}
|
||||
}
|
36
Jellyfin.Plugin.Artwork/Models/ArtworkImageDto.cs
Normal file
36
Jellyfin.Plugin.Artwork/Models/ArtworkImageDto.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Jellyfin.Plugin.Artwork.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The artwork image dto.
|
||||
/// </summary>
|
||||
public class ArtworkImageDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the backdrop image url.
|
||||
/// </summary>
|
||||
[JsonPropertyName("backdrop")]
|
||||
public IReadOnlyList<string> Backdrop { get; set; } = Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the primary image url.
|
||||
/// </summary>
|
||||
[JsonPropertyName("primary")]
|
||||
public IReadOnlyList<string> Primary { get; set; } = Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the thumb image url.
|
||||
/// </summary>
|
||||
[JsonPropertyName("thumb")]
|
||||
public IReadOnlyList<string> Thumb { get; set; } = Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logo image url.
|
||||
/// </summary>
|
||||
[JsonPropertyName("logo")]
|
||||
public IReadOnlyList<string> Logo { get; set; } = Array.Empty<string>();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
namespace Jellyfin.Plugin.Artwork.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The artwork images.
|
||||
/// </summary>
|
||||
public class ArtworkImages
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the backdrop image url.
|
||||
/// </summary>
|
||||
public string? Backdrop { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the primary image url.
|
||||
/// </summary>
|
||||
public string? Primary { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the thumb image url.
|
||||
/// </summary>
|
||||
public string? Thumb { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logo image url.
|
||||
/// </summary>
|
||||
public string? Logo { get; set; }
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
namespace Jellyfin.Plugin.Artwork.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The providers.
|
||||
/// The artwork provider dto.
|
||||
/// </summary>
|
||||
public class Providers
|
||||
public class ArtworkProviderDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the anilist identifier.
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Jellyfin.Plugin.Artwork.Models
|
||||
{
|
||||
@ -10,16 +10,13 @@ namespace Jellyfin.Plugin.Artwork.Models
|
||||
/// <summary>
|
||||
/// Gets or sets the repo name.
|
||||
/// </summary>
|
||||
public string? Name { get; set; }
|
||||
[Required]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the repo url.
|
||||
/// </summary>
|
||||
public string? Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item types.
|
||||
/// </summary>
|
||||
public string[] ItemType { get; set; } = Array.Empty<string>();
|
||||
[Required]
|
||||
public string Url { get; set; } = null!;
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
namespace Jellyfin.Plugin.Artwork.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// The artwork type.
|
||||
/// </summary>
|
||||
public enum ArtworkType
|
||||
{
|
||||
/// <summary>
|
||||
/// Studio artwork.
|
||||
/// </summary>
|
||||
Studio = 1
|
||||
}
|
||||
}
|
@ -17,10 +17,9 @@ namespace Jellyfin.Plugin.Artwork.Providers
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Get supported image types.
|
||||
/// Gets the supported image types.
|
||||
/// </summary>
|
||||
/// <returns>The supported image types.</returns>
|
||||
public static IEnumerable<ImageType> GetSupportedImages()
|
||||
=> SupportedImages;
|
||||
public static IEnumerable<ImageType> GetSupportedImages => SupportedImages;
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -41,16 +42,16 @@ namespace Jellyfin.Plugin.Artwork.Providers
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
|
||||
=> ArtworkProviderHelper.GetSupportedImages();
|
||||
=> ArtworkProviderHelper.GetSupportedImages;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
|
||||
=> _repositoryCache.GetImageInfos(item.GetType(), item);
|
||||
=> _repositoryCache.GetImageInfos("studios", typeof(Studio), item);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
=> _httpClientFactory
|
||||
.CreateClient(NamedClient.Default)
|
||||
.GetAsync(url, cancellationToken);
|
||||
.GetAsync(new Uri(url), cancellationToken);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
@ -41,32 +42,21 @@ namespace Jellyfin.Plugin.Artwork
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetImageInfos(Type itemType, IHasProviderIds providerIds)
|
||||
public async Task<IEnumerable<RemoteImageInfo>> GetImageInfos(string imageTypeKey, Type itemType, IHasProviderIds providerIds)
|
||||
{
|
||||
var artworkRepo = ArtworkPlugin.Instance!.Configuration.ArtworkRepos;
|
||||
var remoteImageInfos = new List<RemoteImageInfo>();
|
||||
|
||||
var itemTypeString = itemType.ToString();
|
||||
foreach (var repo in artworkRepo)
|
||||
{
|
||||
var arrayIndex = Array.FindIndex(repo.ItemType, t => string.Equals(t, itemTypeString, StringComparison.OrdinalIgnoreCase));
|
||||
if (arrayIndex == -1)
|
||||
{
|
||||
// Repo not configured for item type.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(repo.Url))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var artworkDtos = await GetFromRepo(repo.Url);
|
||||
var fullUrl = repo.Url.TrimEnd('/') + $"/{imageTypeKey}.json";
|
||||
var artworkDtos = await GetFromRepo(fullUrl).ConfigureAwait(false);
|
||||
var artworkDto = GetMatch(itemType, providerIds, artworkDtos);
|
||||
if (artworkDto?.ArtworkImages != null)
|
||||
{
|
||||
AddImageInfos(ref remoteImageInfos, artworkDto.ArtworkImages);
|
||||
}
|
||||
AddImageInfos(
|
||||
repo,
|
||||
imageTypeKey,
|
||||
ref remoteImageInfos,
|
||||
artworkDto);
|
||||
}
|
||||
|
||||
return remoteImageInfos;
|
||||
@ -83,79 +73,61 @@ namespace Jellyfin.Plugin.Artwork
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(
|
||||
providerIds.ProviderIds["AniList"],
|
||||
artworkDto.Providers.Anilist,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
if (providerIds.TryGetProviderId("AniList", out var providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Anilist, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
|
||||
if (string.Equals(
|
||||
providerIds.ProviderIds[MetadataProvider.Imdb.ToString()],
|
||||
artworkDto.Providers.Imdb,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
if (providerIds.TryGetProviderId(MetadataProvider.Imdb, out providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Imdb, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
|
||||
if (string.Equals(
|
||||
providerIds.ProviderIds[MetadataProvider.Tmdb.ToString()],
|
||||
artworkDto.Providers.Tmdb,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
if (providerIds.TryGetProviderId(MetadataProvider.Tmdb, out providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Tmdb, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
|
||||
if (string.Equals(
|
||||
providerIds.ProviderIds[MetadataProvider.Tvdb.ToString()],
|
||||
artworkDto.Providers.Tvdb,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
if (providerIds.TryGetProviderId(MetadataProvider.Tvdb, out providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Tvdb, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
|
||||
if ((itemType == typeof(Audio) || itemType == typeof(MusicAlbum))
|
||||
&& string.Equals(
|
||||
providerIds.ProviderIds[MetadataProvider.MusicBrainzReleaseGroup.ToString()],
|
||||
artworkDto.Providers.Musicbrainz,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
&& providerIds.TryGetProviderId(MetadataProvider.MusicBrainzReleaseGroup, out providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Musicbrainz, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
|
||||
if (itemType == typeof(Audio)
|
||||
&& string.Equals(
|
||||
providerIds.ProviderIds[MetadataProvider.MusicBrainzAlbumArtist.ToString()],
|
||||
artworkDto.Providers.Musicbrainz,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
&& providerIds.TryGetProviderId(MetadataProvider.MusicBrainzAlbumArtist, out providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Musicbrainz, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
|
||||
if ((itemType == typeof(MusicAlbum) || itemType == typeof(Audio))
|
||||
&& string.Equals(
|
||||
providerIds.ProviderIds[MetadataProvider.MusicBrainzAlbum.ToString()],
|
||||
artworkDto.Providers.Musicbrainz,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
&& providerIds.TryGetProviderId(MetadataProvider.MusicBrainzAlbum, out providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Musicbrainz, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
|
||||
if (itemType == typeof(MusicArtist)
|
||||
&& string.Equals(
|
||||
providerIds.ProviderIds[MetadataProvider.MusicBrainzArtist.ToString()],
|
||||
artworkDto.Providers.Musicbrainz,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
&& providerIds.TryGetProviderId(MetadataProvider.MusicBrainzArtist, out providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Musicbrainz, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
|
||||
if (itemType == typeof(Audio)
|
||||
&& string.Equals(
|
||||
providerIds.ProviderIds[MetadataProvider.MusicBrainzTrack.ToString()],
|
||||
artworkDto.Providers.Musicbrainz,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
&& providerIds.TryGetProviderId(MetadataProvider.MusicBrainzTrack, out providerId)
|
||||
&& string.Equals(providerId, artworkDto.Providers.Musicbrainz, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return artworkDto;
|
||||
}
|
||||
@ -164,41 +136,58 @@ namespace Jellyfin.Plugin.Artwork
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void AddImageInfos(ref List<RemoteImageInfo> imageInfos, ArtworkImages artworkImages)
|
||||
private static void AddImageInfos(
|
||||
ArtworkRepo repo,
|
||||
string itemKey,
|
||||
ref List<RemoteImageInfo> imageInfos,
|
||||
ArtworkDto? artworkDto)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(artworkImages.Backdrop))
|
||||
if (artworkDto?.ArtworkImages == null)
|
||||
{
|
||||
// Repo or images not found.
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* 0: machine name
|
||||
* 1: image type
|
||||
* 2: image extension
|
||||
*/
|
||||
var imageTemplate = repo.Url.TrimEnd('/') + $"/{itemKey}/{0}/{1}.{2}";
|
||||
|
||||
foreach (var image in artworkDto.ArtworkImages.Backdrop)
|
||||
{
|
||||
imageInfos.Add(new RemoteImageInfo
|
||||
{
|
||||
Type = ImageType.Backdrop,
|
||||
Url = artworkImages.Backdrop
|
||||
Url = string.Format(CultureInfo.InvariantCulture, imageTemplate, artworkDto.MachineName, "backdrop", image)
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(artworkImages.Primary))
|
||||
foreach (var image in artworkDto.ArtworkImages.Primary)
|
||||
{
|
||||
imageInfos.Add(new RemoteImageInfo
|
||||
{
|
||||
Type = ImageType.Primary,
|
||||
Url = artworkImages.Primary
|
||||
Url = string.Format(CultureInfo.InvariantCulture, imageTemplate, artworkDto.MachineName, "primary", image)
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(artworkImages.Thumb))
|
||||
foreach (var image in artworkDto.ArtworkImages.Thumb)
|
||||
{
|
||||
imageInfos.Add(new RemoteImageInfo
|
||||
{
|
||||
Type = ImageType.Thumb,
|
||||
Url = artworkImages.Thumb
|
||||
Url = string.Format(CultureInfo.InvariantCulture, imageTemplate, artworkDto.MachineName, "thumb", image)
|
||||
});
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(artworkImages.Logo))
|
||||
foreach (var image in artworkDto.ArtworkImages.Logo)
|
||||
{
|
||||
imageInfos.Add(new RemoteImageInfo
|
||||
{
|
||||
Type = ImageType.Logo,
|
||||
Url = artworkImages.Logo
|
||||
Url = string.Format(CultureInfo.InvariantCulture, imageTemplate, artworkDto.MachineName, "logo", image)
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -214,7 +203,8 @@ namespace Jellyfin.Plugin.Artwork
|
||||
{
|
||||
var artworkDto = await _httpClientFactory
|
||||
.CreateClient(NamedClient.Default)
|
||||
.GetFromJsonAsync<IReadOnlyList<ArtworkDto>>(repositoryUrl);
|
||||
.GetFromJsonAsync<IReadOnlyList<ArtworkDto>>(repositoryUrl)
|
||||
.ConfigureAwait(false);
|
||||
if (artworkDto != null)
|
||||
{
|
||||
_memoryCache.Set(repositoryUrl, artworkDto, _cacheExpire);
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RuleSet Name="Rules for Jellyfin.Server" Description="Code analysis rules for Jellyfin.Server.csproj" ToolsVersion="14.0">
|
||||
<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" />
|
||||
@ -10,6 +10,8 @@
|
||||
|
||||
<!-- 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 -->
|
||||
@ -30,11 +32,17 @@
|
||||
<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.FxCopAnalyzers" RuleNamespace="Microsoft.Design">
|
||||
<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 -->
|
||||
@ -45,6 +53,8 @@
|
||||
<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 -->
|
||||
@ -53,7 +63,11 @@
|
||||
<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 -->
|
||||
|
Loading…
Reference in New Issue
Block a user