using System; using System.Collections.Generic; using MediaBrowser.Model.Plugins; namespace MediaBrowser.Common.Plugins { /// <summary> /// Local plugin class. /// </summary> public class LocalPlugin : IEquatable<LocalPlugin> { private readonly bool _supported; private Version? _version; /// <summary> /// Initializes a new instance of the <see cref="LocalPlugin"/> class. /// </summary> /// <param name="path">The plugin path.</param> /// <param name="isSupported"><b>True</b> if Jellyfin supports this version of the plugin.</param> /// <param name="manifest">The manifest record for this plugin, or null if one does not exist.</param> public LocalPlugin(string path, bool isSupported, PluginManifest manifest) { Path = path; DllFiles = Array.Empty<string>(); _supported = isSupported; Manifest = manifest; } /// <summary> /// Gets the plugin id. /// </summary> public Guid Id => Manifest.Id; /// <summary> /// Gets the plugin name. /// </summary> public string Name => Manifest.Name; /// <summary> /// Gets the plugin version. /// </summary> public Version Version { get { if (_version is null) { _version = Version.Parse(Manifest.Version); } return _version; } } /// <summary> /// Gets the plugin path. /// </summary> public string Path { get; } /// <summary> /// Gets or sets the list of dll files for this plugin. /// </summary> public IReadOnlyList<string> DllFiles { get; set; } /// <summary> /// Gets or sets the instance of this plugin. /// </summary> public IPlugin? Instance { get; set; } /// <summary> /// Gets a value indicating whether Jellyfin supports this version of the plugin, and it's enabled. /// </summary> public bool IsEnabledAndSupported => _supported && Manifest.Status >= PluginStatus.Active; /// <summary> /// Gets a value indicating whether the plugin has a manifest. /// </summary> public PluginManifest Manifest { get; } /// <summary> /// Compare two <see cref="LocalPlugin"/>. /// </summary> /// <param name="a">The first item.</param> /// <param name="b">The second item.</param> /// <returns>Comparison result.</returns> public static int Compare(LocalPlugin a, LocalPlugin b) { if (a is null || b is null) { throw new ArgumentNullException(a is null ? nameof(a) : nameof(b)); } var compare = string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase); // Id is not equal but name is. if (!a.Id.Equals(b.Id) && compare == 0) { compare = a.Id.CompareTo(b.Id); } return compare == 0 ? a.Version.CompareTo(b.Version) : compare; } /// <summary> /// Returns the plugin information. /// </summary> /// <returns>A <see cref="PluginInfo"/> instance containing the information.</returns> public PluginInfo GetPluginInfo() { var inst = Instance?.GetPluginInfo() ?? new PluginInfo(Manifest.Name, Version, Manifest.Description, Manifest.Id, true); inst.Status = Manifest.Status; inst.HasImage = !string.IsNullOrEmpty(Manifest.ImagePath); return inst; } /// <inheritdoc /> public override bool Equals(object? obj) { return obj is LocalPlugin other && this.Equals(other); } /// <inheritdoc /> public override int GetHashCode() { return Name.GetHashCode(StringComparison.OrdinalIgnoreCase); } /// <inheritdoc /> public bool Equals(LocalPlugin? other) { if (other is null) { return false; } return Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase) && Id.Equals(other.Id) && Version.Equals(other.Version); } } }