ソースを参照

Changes as requested

BaronGreenback 4 年 前
コミット
62702fa3eb

+ 1 - 1
Emby.Server.Implementations/ApplicationHost.cs

@@ -462,7 +462,7 @@ namespace Emby.Server.Implementations
         {
             // Convert to list so this isn't executed for each iteration
             var parts = GetExportTypes<T>()
-                .Select(defaultFunc)
+                .Select(i => defaultFunc(i))
                 .Where(i => i != null)
                 .Cast<T>()
                 .ToList();

+ 31 - 14
Emby.Server.Implementations/Plugins/PluginManager.cs

@@ -6,6 +6,7 @@ using System.Linq;
 using System.Reflection;
 using System.Text;
 using System.Text.Json;
+using System.Threading.Tasks;
 using MediaBrowser.Common;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Json;
@@ -86,7 +87,8 @@ namespace Emby.Server.Implementations.Plugins
                 var plugin = _plugins[i];
                 if (plugin.Manifest.Status == PluginStatus.Deleted && DeletePlugin(plugin))
                 {
-                    UpdateSuccessors(plugin);
+                    // See if there is another version, and if so make that active.
+                    ProcessAlternative(plugin);
                 }
             }
 
@@ -208,12 +210,19 @@ namespace Emby.Server.Implementations.Plugins
 
             if (DeletePlugin(plugin))
             {
+                ProcessAlternative(plugin);
                 return true;
             }
 
             _logger.LogWarning("Unable to delete {Path}, so marking as deleteOnStartup.", plugin.Path);
             // Unable to delete, so disable.
-            return ChangePluginState(plugin, PluginStatus.Deleted);
+            if (ChangePluginState(plugin, PluginStatus.Deleted))
+            {
+                ProcessAlternative(plugin);
+                return true;
+            }
+
+            return false;
         }
 
         /// <summary>
@@ -232,9 +241,9 @@ namespace Emby.Server.Implementations.Plugins
                 var plugins = _plugins.Where(p => p.Id.Equals(id)).ToList();
 
                 plugin = plugins.FirstOrDefault(p => p.Instance != null);
-                if (plugin == null && plugins.Length > 0)
+                if (plugin == null)
                 {
-                    plugin = plugins.OrderByDescending(p => p.Version)[0];
+                    plugin = plugins.OrderByDescending(p => p.Version).FirstOrDefault();
                 }
             }
             else
@@ -259,7 +268,8 @@ namespace Emby.Server.Implementations.Plugins
 
             if (ChangePluginState(plugin, PluginStatus.Active))
             {
-                UpdateSuccessors(plugin);
+                // See if there is another version, and if so, supercede it.
+                ProcessAlternative(plugin);
             }
         }
 
@@ -277,7 +287,8 @@ namespace Emby.Server.Implementations.Plugins
             // Update the manifest on disk
             if (ChangePluginState(plugin, PluginStatus.Disabled))
             {
-                UpdateSuccessors(plugin);
+                // If there is another version, activate it.
+                ProcessAlternative(plugin);
             }
         }
 
@@ -639,27 +650,33 @@ namespace Emby.Server.Implementations.Plugins
         /// Changes the status of the other versions of the plugin to "Superceded".
         /// </summary>
         /// <param name="plugin">The <see cref="LocalPlugin"/> that's master.</param>
-        private void UpdateSuccessors(LocalPlugin plugin)
+        private void ProcessAlternative(LocalPlugin plugin)
         {
-            // This value is memory only - so that the web will show restart required.
-            plugin.Manifest.Status = PluginStatus.Restart;
-
             // Detect whether there is another version of this plugin that needs disabling.
-            var predecessor = _plugins.OrderByDescending(p => p.Version)
+            var previousVersion = _plugins.OrderByDescending(p => p.Version)
                 .FirstOrDefault(
                     p => p.Id.Equals(plugin.Id)
                     && p.IsEnabledAndSupported
                     && p.Version != plugin.Version);
 
-            if (predecessor == null)
+            if (previousVersion == null)
             {
+                // This value is memory only - so that the web will show restart required.
+                plugin.Manifest.Status = PluginStatus.Restart;
                 return;
             }
 
-            if (predecessor.Manifest.Status == PluginStatus.Active && !ChangePluginState(predecessor, PluginStatus.Superceded))
+            if (plugin.Manifest.Status == PluginStatus.Active && !ChangePluginState(previousVersion, PluginStatus.Superceded))
+            {
+                _logger.LogError("Unable to enable version {Version} of {Name}", previousVersion.Version, previousVersion.Name);
+            }
+            else if (plugin.Manifest.Status == PluginStatus.Superceded && !ChangePluginState(previousVersion, PluginStatus.Active))
             {
-                _logger.LogError("Unable to disable version {Version} of {Name}", predecessor.Version, predecessor.Name);
+                _logger.LogError("Unable to supercede version {Version} of {Name}", previousVersion.Version, previousVersion.Name);
             }
+
+            // This value is memory only - so that the web will show restart required.
+            plugin.Manifest.Status = PluginStatus.Restart;
         }
     }
 }

+ 4 - 12
Jellyfin.Api/Controllers/PluginsController.cs

@@ -198,7 +198,7 @@ namespace Jellyfin.Api.Controllers
         /// <param name="pluginId">Plugin id.</param>
         /// <response code="204">Plugin uninstalled.</response>
         /// <response code="404">Plugin not found.</response>
-        /// <returns>An <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if the file could not be found.</returns>
+        /// <returns>An <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if the plugin could not be found.</returns>
         [HttpDelete("{pluginId}")]
         [Authorize(Policy = Policies.RequiresElevation)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
@@ -210,7 +210,7 @@ namespace Jellyfin.Api.Controllers
             var plugins = _pluginManager.Plugins.Where(p => p.Id.Equals(pluginId));
 
             // Select the un-instanced one first.
-            var plugin = plugins.FirstOrDefault(p => p.Instance != null);
+            var plugin = plugins.FirstOrDefault(p => p.Instance == null);
             if (plugin == null)
             {
                 // Then by the status.
@@ -256,11 +256,7 @@ namespace Jellyfin.Api.Controllers
         /// <param name="pluginId">Plugin id.</param>
         /// <response code="204">Plugin configuration updated.</response>
         /// <response code="404">Plugin not found or plugin does not have configuration.</response>
-        /// <returns>
-        /// A <see cref="Task" /> that represents the asynchronous operation to update plugin configuration.
-        ///    The task result contains an <see cref="NoContentResult"/> indicating success, or <see cref="NotFoundResult"/>
-        ///    when plugin not found or plugin doesn't have configuration.
-        /// </returns>
+        /// <returns>An <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if the plugin could not be found.</returns>
         [HttpPost("{pluginId}/Configuration")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
@@ -321,11 +317,7 @@ namespace Jellyfin.Api.Controllers
         /// <param name="pluginId">Plugin id.</param>
         /// <response code="204">Plugin manifest returned.</response>
         /// <response code="404">Plugin not found.</response>
-        /// <returns>
-        /// A <see cref="Task" /> that represents the asynchronous operation to get the plugin's manifest.
-        ///    The task result contains an <see cref="NoContentResult"/> indicating success, or <see cref="NotFoundResult"/>
-        ///    when plugin not found.
-        /// </returns>
+        /// <returns>A <see cref="PluginManifest"/> on success, or a <see cref="NotFoundResult"/> if the plugin could not be found.</returns>
         [HttpPost("{pluginId}/Manifest")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]

+ 0 - 1
Jellyfin.Api/Models/ConfigurationPageInfo.cs

@@ -23,7 +23,6 @@ namespace Jellyfin.Api.Models
             if (page.Plugin != null)
             {
                 DisplayName = page.Plugin.Name;
-                // Don't use "N" because it needs to match Plugin.Id
                 PluginId = page.Plugin.Id;
             }
         }

+ 5 - 15
MediaBrowser.Common/Plugins/BasePluginOfT.cs

@@ -25,8 +25,6 @@ namespace MediaBrowser.Common.Plugins
         /// </summary>
         private readonly object _configurationSaveLock = new object();
 
-        private Action<string> _directoryCreateFn;
-
         /// <summary>
         /// The configuration.
         /// </summary>
@@ -65,11 +63,6 @@ namespace MediaBrowser.Common.Plugins
                     assemblyPlugin.SetId(assemblyId);
                 }
             }
-
-            if (this is IHasPluginConfiguration hasPluginConfiguration)
-            {
-                hasPluginConfiguration.SetStartupInfo(s => Directory.CreateDirectory(s));
-            }
         }
 
         /// <summary>
@@ -145,13 +138,6 @@ namespace MediaBrowser.Common.Plugins
         /// <value>The configuration.</value>
         BasePluginConfiguration IHasPluginConfiguration.Configuration => Configuration;
 
-        /// <inheritdoc />
-        public void SetStartupInfo(Action<string> directoryCreateFn)
-        {
-            // hack alert, until the .net core transition is complete
-            _directoryCreateFn = directoryCreateFn;
-        }
-
         /// <summary>
         /// Saves the current configuration to the file system.
         /// </summary>
@@ -160,7 +146,11 @@ namespace MediaBrowser.Common.Plugins
         {
             lock (_configurationSaveLock)
             {
-                _directoryCreateFn(Path.GetDirectoryName(ConfigurationFilePath));
+                var folder = Path.GetDirectoryName(ConfigurationFilePath);
+                if (!Directory.Exists(folder))
+                {
+                    Directory.CreateDirectory(folder);
+                }
 
                 XmlSerializer.SerializeToFile(config, ConfigurationFilePath);
             }

+ 0 - 6
MediaBrowser.Common/Plugins/IHasPluginConfiguration.cs

@@ -23,11 +23,5 @@ namespace MediaBrowser.Common.Plugins
         /// </summary>
         /// <param name="configuration">The configuration.</param>
         void UpdateConfiguration(BasePluginConfiguration configuration);
-
-        /// <summary>
-        /// Sets the startup directory creation function.
-        /// </summary>
-        /// <param name="directoryCreateFn">The directory function used to create the configuration folder.</param>
-        void SetStartupInfo(Action<string> directoryCreateFn);
     }
 }

+ 1 - 0
MediaBrowser.Common/Plugins/IPluginManager.cs

@@ -3,6 +3,7 @@
 using System;
 using System.Collections.Generic;
 using System.Reflection;
+using System.Threading.Tasks;
 using Microsoft.Extensions.DependencyInjection;
 
 namespace MediaBrowser.Common.Plugins

+ 1 - 3
MediaBrowser.Common/Plugins/PluginManifest.cs

@@ -19,14 +19,12 @@ namespace MediaBrowser.Common.Plugins
             Category = string.Empty;
             Changelog = string.Empty;
             Description = string.Empty;
-            Status = PluginStatus.Active;
             Id = Guid.Empty;
             Name = string.Empty;
             Owner = string.Empty;
             Overview = string.Empty;
             TargetAbi = string.Empty;
             Version = string.Empty;
-            AutoUpdate = true;
         }
 
         /// <summary>
@@ -99,7 +97,7 @@ namespace MediaBrowser.Common.Plugins
         /// Gets or sets a value indicating whether this plugin should automatically update.
         /// </summary>
         [JsonPropertyName("autoUpdate")]
-        public bool AutoUpdate { get; set; }
+        public bool AutoUpdate { get; set; } = true; // DO NOT MOVE THIS INTO THE CONSTRUCTOR.
 
         /// <summary>
         /// Gets or sets the ImagePath