Files
jRay/Jellyfin.Plugin.JRay/Plugin.cs
dtourolleandClaude Opus 5 d9a38bb7fb
🏗️ Build Plugin / build (push) Successful in 59s
Latest Release / latest-release (push) Successful in 30s
🧪 Test Plugin / test (push) Successful in 22s
JR-021, JR-022, JR-023: File Transformation is a hard dependency
Deletes the on-disk index.html injection rather than leaving it switched off.
Plugin.cs had already stopped calling it, but an unreachable write path with a
live signature is the one a later refactor re-enables by accident, and it was
still the behaviour the README and the release changelog advertised.

Patching index.html on disk is destructive in ways a plugin cannot clean up
after: the patch outlives an uninstall, a web-client upgrade discards it
silently, and it races any other plugin touching the same file. It is also a
second code path, and the one nobody runs is the one that rots.

WebClientPatchService is now removal-only. The strip is factored out as
RemoveInjection so it is testable without a filesystem. Removal is the one
write JR-021 permits -- an earlier JRay did patch the file, and those users
must not be left with a stale injection pointing at endpoints that have since
changed. It keys on JRay's own marker, so it touches nothing another plugin
added.

JR-021 is a requirement to *not do* something, which no unit test can
demonstrate, so scripts/checks/no-index-injection.sh verifies it by absence.
The check was confirmed to fail on a reintroduced Apply() and on reintroduced
ReplaceLast injection -- a check that has only ever passed is not evidence.

Jellyfin has no plugin dependency mechanism, so nothing installs File
Transformation for the user and a log warning alone is one nobody reads.
GET /Plugins/JRay/Status/Dependencies reports whether the dependency is
satisfied, and the configuration page renders it with the repository URL and
what to do with it. Absent the plugin only the overlay is disabled; every
other feature works.

JR-022 and JR-023 stay In Progress rather than Done: neither has a test that
executes, and this repo has no test project yet.

TRACES: JR-021, JR-022, JR-023 | PR-004

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 18:58:12 +02:00

93 lines
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using Jellyfin.Plugin.JRay.Configuration;
using Jellyfin.Plugin.JRay.Services;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.Plugins;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Plugin.JRay;
/// <summary>
/// The main plugin.
/// </summary>
public class Plugin : BasePlugin<PluginConfiguration>, IHasWebPages
{
private readonly ILogger<Plugin> _logger;
private readonly bool _usingFileTransformation;
/// <summary>
/// Initializes a new instance of the <see cref="Plugin"/> class.
/// </summary>
/// <param name="applicationPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
/// <param name="xmlSerializer">Instance of the <see cref="IXmlSerializer"/> interface.</param>
/// <param name="logger">The logger.</param>
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer, ILogger<Plugin> logger)
: base(applicationPaths, xmlSerializer)
{
Instance = this;
_logger = logger;
// The File Transformation plugin rewrites index.html as it is served.
// Registration is unconditional: the transformation itself checks
// EnableOverlay at request time, so toggling the setting takes effect
// without re-registering.
_usingFileTransformation = FileTransformationRegistration.TryRegister(_logger);
if (!_usingFileTransformation)
{
_logger.LogWarning(
"JRay: the pause overlay is disabled because the File Transformation plugin " +
"is not available. Install it from " +
"https://github.com/IAmParadox27/jellyfin-plugin-file-transformation. " +
"All other JRay features are unaffected.");
}
// JRay never injects into index.html. This only ever *removes* a patch
// left by an earlier version of JRay, identified by its own marker —
// see SPEC.md JR-021/JR-022.
WebClientPatchService.RemoveLegacyPatch(ApplicationPaths, _logger);
}
/// <inheritdoc />
public override string Name => "JRay";
/// <inheritdoc />
public override Guid Id => Guid.Parse("96a22d9d-23fd-49bb-8970-5e153817d223");
/// <summary>
/// Gets the current plugin instance.
/// </summary>
public static Plugin? Instance { get; private set; }
/// <summary>
/// Gets a value indicating whether the pause overlay should currently be
/// served. Read by the File Transformation callback at request time, so
/// toggling the setting takes effect without re-registering.
/// </summary>
internal static bool OverlayEnabled => Instance?.Configuration.EnableOverlay ?? false;
/// <summary>
/// Gets a value indicating whether the File Transformation plugin was found
/// at startup. When it was not, the overlay is disabled and every other JRay
/// feature continues to work.
/// </summary>
internal static bool FileTransformationAvailable => Instance?._usingFileTransformation ?? false;
/// <inheritdoc />
public IEnumerable<PluginPageInfo> GetPages()
{
return
[
new PluginPageInfo
{
Name = Name,
EmbeddedResourcePath = string.Format(CultureInfo.InvariantCulture, "{0}.Configuration.configPage.html", GetType().Namespace)
}
];
}
}