using System.Collections.ObjectModel; using MediaBrowser.Model.Plugins; namespace Jellyfin.Plugin.JRay.Configuration; /// /// Plugin configuration. /// /// /// Every manifest-exchange switch here defaults to off, including the /// pre-configured community server, so no traffic leaves an installation until /// an admin acts. Fetching and contributing each reveal to a server operator /// that some instance holds a given title; that is inherent to the exchange, so /// the defaults bound the exposure rather than pretending to remove it. /// // TRACES: JR-036, JR-038 | PR-005 public class PluginConfiguration : BasePluginConfiguration { /// /// The community manifest exchange. Shipped pre-configured but /// disabled, so no traffic leaves an installation until an admin opts /// in (public server specification, §9). /// public const string CommunityServerUrl = "https://jray.tourolle.paris"; /// /// Display name for . /// public const string CommunityServerName = "JRay Community"; /// /// Initializes a new instance of the class. /// public PluginConfiguration() { TruthFileSuffix = ".jray.json"; CacheDurationMinutes = 60; EnableOverlay = true; // Manifest sharing is a network egress feature, so every part of it is // off by default (public server specification, §9 "Configuration"). EnableManifestSharing = false; ContributeManifests = false; ComputeAudioSignatures = false; MinimumMatchTier = MatchTier.Runtime; // Pre-configured but disabled: the admin opts in by enabling it, rather // than by having to discover and type a URL. Servers.Add(new ManifestServer { Url = CommunityServerUrl, Name = CommunityServerName, Enabled = false, AllowContribute = false, TrustLevel = ServerTrustLevel.FetchOnly, }); } /// /// Gets or sets the filename suffix used to find a scene-actor-extraction /// "truth" file for a media item. The plugin looks for a file named /// "<media file basename><TruthFileSuffix>" next to the media file, /// e.g. "Movie.mkv" -> "Movie.jray.json". /// public string TruthFileSuffix { get; set; } /// /// Gets or sets how long (in minutes) a loaded truth file is cached in /// memory before being re-read from disk. /// public int CacheDurationMinutes { get; set; } /// /// Gets or sets a value indicating whether JRay should inject its /// pause-overlay script into the web client's index.html. When disabled, /// any previously injected script is removed. /// public bool EnableOverlay { get; set; } /// /// Gets or sets a value indicating whether JRay may fetch actor-timeline /// manifests from the configured servers. Off by default — this is a network /// egress feature and must be opt-in. /// /// /// Fetching reveals to a server operator that some instance holds a given /// title. That is inherent to the exchange, and each configured server /// multiplies the exposure, which the configuration page states plainly. /// public bool EnableManifestSharing { get; set; } /// /// Gets or sets a value indicating whether locally generated manifests may be /// contributed back. A separate opt-in from downloading, and off by default. /// /// /// Contribution additionally requires /// on the specific server and a token for it. Uploads are never fanned out to /// every configured server. /// public bool ContributeManifests { get; set; } /// /// Gets or sets the minimum cut-match tier a fetched manifest must reach /// before it is stored. /// /// /// Defaults to . /// admits manifests whose runtime differs by up to 30s, which may be a /// different trim of the same cut — usable, but it should be surfaced as a /// caveat rather than applied silently. /// public MatchTier MinimumMatchTier { get; set; } /// /// Gets or sets a value indicating whether the plugin computes audio /// signatures for library items, enabling content-based cut matching and /// identification of files whose providence is unknown. /// /// /// Off by default. Uses the FFmpeg binary Jellyfin already ships (via /// IMediaEncoder.EncoderPath), so there is no extra dependency, but it /// costs roughly a second or two of I/O per item and is therefore opt-in. /// public bool ComputeAudioSignatures { get; set; } /// /// Gets the ordered list of manifest servers. /// /// /// Order is the user's trust ranking: for a fetch, servers are tried in order /// and the first result clearing wins. For a /// series, first-match applies per episode, so a later server is /// queried only for the episodes earlier ones lacked. /// public Collection Servers { get; } = new(); }