using System; using System.IO; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Jellyfin.Plugin.JRay.Models; using Jellyfin.Plugin.JRay.Services.Interfaces; using MediaBrowser.Common.Configuration; using Microsoft.Extensions.Logging; namespace Jellyfin.Plugin.JRay.Services; /// /// Stores truth files pushed directly to JRay (e.g. by a remote extraction /// worker) under the plugin's configuration directory, keyed by item id. /// public sealed class ManagedTruthStore : IManagedTruthStore { private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web); private readonly IApplicationPaths _applicationPaths; private readonly ILogger _logger; /// /// Initializes a new instance of the class. /// /// The Jellyfin application paths. /// The logger. public ManagedTruthStore(IApplicationPaths applicationPaths, ILogger logger) { _applicationPaths = applicationPaths; _logger = logger; } /// public async Task LoadAsync(Guid itemId, CancellationToken cancellationToken) { var path = GetPath(itemId); if (!File.Exists(path)) { return null; } try { using var stream = File.OpenRead(path); return await JsonSerializer.DeserializeAsync(stream, JsonOptions, cancellationToken) .ConfigureAwait(false); } catch (Exception ex) when (ex is IOException or JsonException) { _logger.LogWarning(ex, "JRay: failed to read managed truth file {Path}", path); return null; } } /// public async Task SaveAsync(Guid itemId, TruthFile truth, CancellationToken cancellationToken) { var path = GetPath(itemId); var directory = Path.GetDirectoryName(path) ?? throw new InvalidOperationException("Managed truth path has no directory."); Directory.CreateDirectory(directory); var tempPath = path + ".tmp"; using (var stream = File.Create(tempPath)) { await JsonSerializer.SerializeAsync(stream, truth, JsonOptions, cancellationToken).ConfigureAwait(false); } File.Move(tempPath, path, overwrite: true); } /// public bool Delete(Guid itemId) { var path = GetPath(itemId); if (!File.Exists(path)) { return false; } File.Delete(path); return true; } private string GetPath(Guid itemId) { return Path.Combine(_applicationPaths.PluginConfigurationsPath, "JRay", "truth", itemId.ToString("D") + ".json"); } }