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; /// /// Provides images for SRF Play content. /// public class SRFImageProvider : IRemoteImageProvider, IHasOrder { private readonly IHttpClientFactory _httpClientFactory; private readonly ILogger _logger; private readonly ILoggerFactory _loggerFactory; /// /// Initializes a new instance of the class. /// /// The HTTP client factory. /// The logger factory. public SRFImageProvider(IHttpClientFactory httpClientFactory, ILoggerFactory loggerFactory) { _httpClientFactory = httpClientFactory; _loggerFactory = loggerFactory; _logger = loggerFactory.CreateLogger(); } /// public string Name => "SRF Play"; /// public int Order => 0; /// 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; } /// public IEnumerable GetSupportedImages(BaseItem item) { return new List { ImageType.Primary, ImageType.Backdrop, ImageType.Thumb }; } /// public async Task> GetImages(BaseItem item, CancellationToken cancellationToken) { var list = new List(); 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; } /// public Task GetImageResponse(string url, CancellationToken cancellationToken) { var httpClient = _httpClientFactory.CreateClient(NamedClient.Default); return httpClient.GetAsync(new Uri(url), cancellationToken); } }