83 lines
2.8 KiB
C#
83 lines
2.8 KiB
C#
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Jellyfin.Plugin.SRFPlay.Api;
|
|
using Jellyfin.Plugin.SRFPlay.Api.Models;
|
|
using Jellyfin.Plugin.SRFPlay.Services.Interfaces;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Jellyfin.Plugin.SRFPlay.Services;
|
|
|
|
/// <summary>
|
|
/// Service for fetching media composition with caching support.
|
|
/// This consolidates the cache-check → API-fetch → cache-store pattern.
|
|
/// </summary>
|
|
public class MediaCompositionFetcher : IMediaCompositionFetcher
|
|
{
|
|
private readonly ILogger<MediaCompositionFetcher> _logger;
|
|
private readonly IMetadataCache _metadataCache;
|
|
private readonly ISRFApiClientFactory _apiClientFactory;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="MediaCompositionFetcher"/> class.
|
|
/// </summary>
|
|
/// <param name="logger">The logger.</param>
|
|
/// <param name="metadataCache">The metadata cache.</param>
|
|
/// <param name="apiClientFactory">The API client factory.</param>
|
|
public MediaCompositionFetcher(
|
|
ILogger<MediaCompositionFetcher> logger,
|
|
IMetadataCache metadataCache,
|
|
ISRFApiClientFactory apiClientFactory)
|
|
{
|
|
_logger = logger;
|
|
_metadataCache = metadataCache;
|
|
_apiClientFactory = apiClientFactory;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<MediaComposition?> GetMediaCompositionAsync(
|
|
string urn,
|
|
CancellationToken cancellationToken,
|
|
int? cacheDurationOverride = null)
|
|
{
|
|
if (string.IsNullOrEmpty(urn))
|
|
{
|
|
_logger.LogDebug("GetMediaCompositionAsync called with null/empty URN");
|
|
return null;
|
|
}
|
|
|
|
var config = Plugin.Instance?.Configuration;
|
|
if (config == null)
|
|
{
|
|
_logger.LogWarning("Plugin configuration is null, cannot fetch media composition");
|
|
return null;
|
|
}
|
|
|
|
var cacheDuration = cacheDurationOverride ?? config.CacheDurationMinutes;
|
|
|
|
// Try cache first
|
|
var mediaComposition = _metadataCache.GetMediaComposition(urn, cacheDuration);
|
|
if (mediaComposition != null)
|
|
{
|
|
_logger.LogDebug("Cache hit for URN: {Urn}", urn);
|
|
return mediaComposition;
|
|
}
|
|
|
|
// Fetch from API
|
|
_logger.LogDebug("Cache miss for URN: {Urn}, fetching from API", urn);
|
|
using var apiClient = _apiClientFactory.CreateClient();
|
|
mediaComposition = await apiClient.GetMediaCompositionByUrnAsync(urn, cancellationToken).ConfigureAwait(false);
|
|
|
|
if (mediaComposition != null)
|
|
{
|
|
_metadataCache.SetMediaComposition(urn, mediaComposition);
|
|
_logger.LogDebug("Cached media composition for URN: {Urn}", urn);
|
|
}
|
|
else
|
|
{
|
|
_logger.LogWarning("Failed to fetch media composition for URN: {Urn}", urn);
|
|
}
|
|
|
|
return mediaComposition;
|
|
}
|
|
}
|