jRay/Jellyfin.Plugin.JRay/Services/ManagedTruthStore.cs
Duncan Tourolle a38122e993
All checks were successful
🏗️ Build Plugin / build (push) Successful in 1m13s
🧪 Test Plugin / test (push) Successful in 20s
Latest Release / latest-release (push) Successful in 25s
first commit
2026-06-12 18:16:47 +02:00

91 lines
2.9 KiB
C#

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;
/// <summary>
/// Stores truth files pushed directly to JRay (e.g. by a remote extraction
/// worker) under the plugin's configuration directory, keyed by item id.
/// </summary>
public sealed class ManagedTruthStore : IManagedTruthStore
{
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
private readonly IApplicationPaths _applicationPaths;
private readonly ILogger<ManagedTruthStore> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="ManagedTruthStore"/> class.
/// </summary>
/// <param name="applicationPaths">The Jellyfin application paths.</param>
/// <param name="logger">The logger.</param>
public ManagedTruthStore(IApplicationPaths applicationPaths, ILogger<ManagedTruthStore> logger)
{
_applicationPaths = applicationPaths;
_logger = logger;
}
/// <inheritdoc />
public async Task<TruthFile?> 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<TruthFile>(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;
}
}
/// <inheritdoc />
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);
}
/// <inheritdoc />
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");
}
}