mirror of
https://github.com/jellyfin/jellyfin-plugin-coverartarchive.git
synced 2024-11-23 05:49:55 +00:00
Remove configuration page and migrate to MetaBrainz.MusicBrainz.CoverArt
This commit is contained in:
parent
f0c8951f1f
commit
543bca15ca
@ -1,75 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Cover Art Archive</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="CoverArtArchiveConfigPage" data-role="page" class="page type-interior pluginConfigurationPage" data-require="emby-input,emby-button,emby-select,emby-checkbox">
|
||||
<div data-role="content">
|
||||
<div class="content-primary">
|
||||
<form id="CoverArtArchiveConfigForm">
|
||||
<div class="selectContainer">
|
||||
<label class="selectLabel" for="Options">Several Options</label>
|
||||
<select is="emby-select" id="Options" name="Options" class="emby-select-withcolor emby-select">
|
||||
<option id="optOneOption" value="OneOption">One Option</option>
|
||||
<option id="optAnotherOption" value="AnotherOption">Another Option</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputeLabel inputLabelUnfocused" for="AnInteger">An Integer</label>
|
||||
<input id="AnInteger" name="AnInteger" type="number" is="emby-input" min="0" />
|
||||
<div class="fieldDescription">A Description</div>
|
||||
</div>
|
||||
<div class="checkboxContainer checkboxContainer-withDescripton">
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="TrueFalseSetting" name="TrueFalseCheckBox" type="checkbox" is="emby-checkbox" />
|
||||
<span>A Checkbox</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputeLabel inputLabelUnfocused" for="AString">A String</label>
|
||||
<input id="AString" name="AString" type="text" is="emby-input" />
|
||||
<div class="fieldDescription">Another Description</div>
|
||||
</div>
|
||||
<div>
|
||||
<button is="emby-button" type="submit" class="raised button-submit block emby-button">
|
||||
<span>Save</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var CoverArtArchiveConfig = {
|
||||
pluginUniqueId: '8119f3c6-cfc2-4d9c-a0ba-028f1d93e526'
|
||||
};
|
||||
|
||||
$('#CoverArtArchiveConfigPage').on('pageshow', function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
ApiClient.getPluginConfiguration(CoverArtArchiveConfig.pluginUniqueId).then(function (config) {
|
||||
$('#Options').val(config.Options).change();
|
||||
$('#AnInteger').val(config.AnInteger).change();
|
||||
document.getElementById('TrueFalseSetting').checked = config.TrueFalseSetting;
|
||||
$('#AString').val(config.AString).change();
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
});
|
||||
|
||||
$('#CoverArtArchiveConfigForm').on('submit', function () {
|
||||
Dashboard.showLoadingMsg();
|
||||
ApiClient.getPluginConfiguration(CoverArtArchiveConfig.pluginUniqueId).then(function (config) {
|
||||
config.Options = $('#Options').val();
|
||||
config.AnInteger = $('#AnInteger').val();
|
||||
config.TrueFalseSetting = document.getElementById('TrueFalseSetting').checked;
|
||||
config.AString = $('#AString').val();
|
||||
ApiClient.updatePluginConfiguration(CoverArtArchiveConfig.pluginUniqueId, config).then(function (result) {
|
||||
Dashboard.processPluginConfigurationUpdateResult(result);
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,18 +0,0 @@
|
||||
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";
|
||||
}
|
||||
}
|
153
Jellyfin.Plugin.CoverArtArchive/CoverArtArchiveImageProvider.cs
Normal file
153
Jellyfin.Plugin.CoverArtArchive/CoverArtArchiveImageProvider.cs
Normal file
@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using MetaBrainz.MusicBrainz.CoverArt;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Jellyfin.Plugin.CoverArtArchive
|
||||
{
|
||||
/// <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;
|
||||
|
||||
private readonly CoverArt _coverArtClient;
|
||||
|
||||
/// <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
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
Converters =
|
||||
{
|
||||
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
|
||||
}
|
||||
};
|
||||
|
||||
_coverArtClient = new CoverArt("Jellyfin Cover Art Archive Plugin", Assembly.GetExecutingAssembly().GetName().Version!.ToString(), "apps@jellyfin.org");
|
||||
}
|
||||
|
||||
/// <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
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
|
||||
{
|
||||
// TODO: Should probably also use the MusicBrainz library for this.
|
||||
_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))
|
||||
{
|
||||
try
|
||||
{
|
||||
var release = await _coverArtClient.FetchReleaseAsync(Guid.Parse(musicBrainzId)).ConfigureAwait(false);
|
||||
|
||||
var frontImage = release.Images.SingleOrDefault(image => image.Types == CoverArtType.Front);
|
||||
|
||||
if (frontImage is not null)
|
||||
{
|
||||
list.Add(new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = frontImage.Location!.ToString(),
|
||||
Type = ImageType.Primary,
|
||||
ThumbnailUrl = ((frontImage.Thumbnails.Large ?? frontImage.Thumbnails.Small)!).ToString(),
|
||||
CommunityRating = frontImage.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
HttpWebResponse response = (HttpWebResponse)e.Response!;
|
||||
_logger.LogWarning("Got HTTP {StatusCode} when getting image for MusicBrainz release {ReleaseId}", response.StatusCode, musicBrainzId);
|
||||
}
|
||||
}
|
||||
|
||||
if (list.Count == 0)
|
||||
{
|
||||
var musicBrainzGroupId = item.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup);
|
||||
if (!string.IsNullOrEmpty(musicBrainzGroupId))
|
||||
{
|
||||
try
|
||||
{
|
||||
var release = await _coverArtClient.FetchGroupReleaseAsync(Guid.Parse(musicBrainzGroupId)).ConfigureAwait(false);
|
||||
|
||||
var frontImage = release.Images.SingleOrDefault(image => image.Types == CoverArtType.Front);
|
||||
|
||||
if (frontImage is not null)
|
||||
{
|
||||
list.Add(new RemoteImageInfo
|
||||
{
|
||||
ProviderName = Name,
|
||||
Url = frontImage.Location!.ToString(),
|
||||
Type = ImageType.Primary,
|
||||
ThumbnailUrl = ((frontImage.Thumbnails.Large ?? frontImage.Thumbnails.Small)!).ToString(),
|
||||
CommunityRating = frontImage.Approved ? 1 : 0,
|
||||
RatingType = RatingType.Score,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
HttpWebResponse response = (HttpWebResponse)e.Response!;
|
||||
_logger.LogWarning("Got HTTP {StatusCode} when getting image for MusicBrainz release group {ReleaseId}", response.StatusCode, musicBrainzGroupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
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
|
||||
@ -11,7 +9,7 @@ namespace Jellyfin.Plugin.CoverArtArchive
|
||||
/// <summary>
|
||||
/// The cover art plugin.
|
||||
/// </summary>
|
||||
public class CoverArtArchivePlugin : BasePlugin<PluginConfiguration>, IHasWebPages
|
||||
public class CoverArtArchivePlugin : BasePlugin<PluginConfiguration>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CoverArtArchivePlugin"/> class.
|
||||
@ -34,18 +32,5 @@ namespace Jellyfin.Plugin.CoverArtArchive
|
||||
/// 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"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<RootNamespace>Jellyfin.Plugin.CoverArtArchive</RootNamespace>
|
||||
<AssemblyVersion>2.0.0.0</AssemblyVersion>
|
||||
<FileVersion>2.0.0.0</FileVersion>
|
||||
<AssemblyVersion>4.0.0.0</AssemblyVersion>
|
||||
<FileVersion>4.0.0.0</FileVersion>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
@ -15,6 +15,8 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Jellyfin.Controller" Version="10.*-*" />
|
||||
<PackageReference Include="Jellyfin.Model" Version="10.*-*" />
|
||||
<PackageReference Include="MetaBrainz.Common.Json" Version="4.0.0" />
|
||||
<PackageReference Include="MetaBrainz.MusicBrainz.CoverArt" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -24,10 +26,5 @@
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -1,46 +0,0 @@
|
||||
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; }
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
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,
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
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>();
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
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,188 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Providers;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Providers;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
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;
|
||||
|
||||
/// <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
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
Converters =
|
||||
{
|
||||
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <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 GetImagesInternal($"{Constants.ApiBaseUrl}/release/{musicBrainzId}/", cancellationToken)
|
||||
.ConfigureAwait(false));
|
||||
}
|
||||
|
||||
if (list.Count == 0)
|
||||
{
|
||||
var musicBrainzGroupId = item.GetProviderId(MetadataProvider.MusicBrainzReleaseGroup);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@ category: "Metadata"
|
||||
owner: "jellyfin"
|
||||
artifacts:
|
||||
- "Jellyfin.Plugin.CoverArtArchive.dll"
|
||||
- "MetaBrainz.Common.Json.dll"
|
||||
- "MetaBrainz.MusicBrainz.CoverArt.dll"
|
||||
changelog: |2-
|
||||
### New features and improvements ###
|
||||
- chore: plugin images (#5) @h1dden-da3m0n
|
||||
|
Loading…
Reference in New Issue
Block a user