Duncan Tourolle ac6a3842dd
Some checks failed
🏗️ Build Plugin / call (push) Failing after 0s
📝 Create/Update Release Draft & Release Bump PR / call (push) Failing after 0s
🧪 Test Plugin / call (push) Failing after 0s
🔬 Run CodeQL / call (push) Failing after 0s
first commit
2025-11-12 22:05:36 +01:00

153 lines
5.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Plugin.SRFPlay.Api;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Plugin.SRFPlay.Providers;
/// <summary>
/// Provides images for SRF Play content.
/// </summary>
public class SRFImageProvider : IRemoteImageProvider, IHasOrder
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<SRFImageProvider> _logger;
private readonly ILoggerFactory _loggerFactory;
/// <summary>
/// Initializes a new instance of the <see cref="SRFImageProvider"/> class.
/// </summary>
/// <param name="httpClientFactory">The HTTP client factory.</param>
/// <param name="loggerFactory">The logger factory.</param>
public SRFImageProvider(IHttpClientFactory httpClientFactory, ILoggerFactory loggerFactory)
{
_httpClientFactory = httpClientFactory;
_loggerFactory = loggerFactory;
_logger = loggerFactory.CreateLogger<SRFImageProvider>();
}
/// <inheritdoc />
public string Name => "SRF Play";
/// <inheritdoc />
public int Order => 0;
/// <inheritdoc />
public bool Supports(BaseItem item)
{
// Support movies and episodes for now
return item is MediaBrowser.Controller.Entities.Movies.Movie ||
item is MediaBrowser.Controller.Entities.TV.Episode ||
item is MediaBrowser.Controller.Entities.TV.Series;
}
/// <inheritdoc />
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new List<ImageType>
{
ImageType.Primary,
ImageType.Backdrop,
ImageType.Thumb
};
}
/// <inheritdoc />
public async Task<IEnumerable<RemoteImageInfo>> GetImages(BaseItem item, CancellationToken cancellationToken)
{
var list = new List<RemoteImageInfo>();
try
{
// Check if item has SRF URN in provider IDs
if (!item.ProviderIds.TryGetValue("SRF", out var urn) || string.IsNullOrEmpty(urn))
{
_logger.LogDebug("No SRF URN found for item: {ItemName}", item.Name);
return list;
}
_logger.LogDebug("Fetching images for SRF URN: {Urn}", urn);
// Fetch media composition to get image URLs
using var apiClient = new SRFApiClient(_loggerFactory);
var mediaComposition = await apiClient.GetMediaCompositionByUrnAsync(urn, cancellationToken).ConfigureAwait(false);
if (mediaComposition == null)
{
_logger.LogWarning("Failed to fetch media composition for URN: {Urn}", urn);
return list;
}
// Extract images from chapters
if (mediaComposition.ChapterList != null && mediaComposition.ChapterList.Count > 0)
{
var chapter = mediaComposition.ChapterList[0];
if (!string.IsNullOrEmpty(chapter.ImageUrl))
{
list.Add(new RemoteImageInfo
{
Url = chapter.ImageUrl,
Type = ImageType.Primary,
ProviderName = Name
});
list.Add(new RemoteImageInfo
{
Url = chapter.ImageUrl,
Type = ImageType.Thumb,
ProviderName = Name
});
}
}
// Extract images from show
if (mediaComposition.Show != null)
{
if (!string.IsNullOrEmpty(mediaComposition.Show.ImageUrl))
{
list.Add(new RemoteImageInfo
{
Url = mediaComposition.Show.ImageUrl,
Type = ImageType.Primary,
ProviderName = Name
});
}
if (!string.IsNullOrEmpty(mediaComposition.Show.BannerImageUrl))
{
list.Add(new RemoteImageInfo
{
Url = mediaComposition.Show.BannerImageUrl,
Type = ImageType.Backdrop,
ProviderName = Name
});
}
}
_logger.LogDebug("Found {Count} images for URN: {Urn}", list.Count, urn);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error fetching images for item: {ItemName}", item.Name);
}
return list;
}
/// <inheritdoc />
public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken)
{
var httpClient = _httpClientFactory.CreateClient(NamedClient.Default);
return httpClient.GetAsync(new Uri(url), cancellationToken);
}
}