Răsfoiți Sursa

Delete plugin working.

Greenback 4 ani în urmă
părinte
comite
a246a77ada

+ 32 - 19
Emby.Server.Implementations/Plugins/PluginManager.cs

@@ -78,8 +78,27 @@ namespace Emby.Server.Implementations
         /// <returns>An IEnumerable{Assembly}.</returns>
         public IEnumerable<Assembly> LoadAssemblies()
         {
+            // Attempt to remove any deleted plugins and change any successors to be active.
+            for (int a = _plugins.Count - 1; a >= 0; a--)
+            {
+                var plugin = _plugins[a];
+                if (plugin.Manifest.Status == PluginStatus.DeleteOnStartup && DeletePlugin(plugin))
+                {
+                    UpdateSuccessors(plugin);
+                }
+            }
+
+            // Now load the assemblies..
             foreach (var plugin in _plugins)
             {
+                CheckIfStillSuperceded(plugin);
+
+                if (plugin.IsEnabledAndSupported == false)
+                {
+                    _logger.LogInformation("Skipping disabled plugin {Version} of {Name} ", plugin.Version, plugin.Name);
+                    continue;
+                }
+
                 foreach (var file in plugin.DllFiles)
                 {
                     try
@@ -183,15 +202,13 @@ namespace Emby.Server.Implementations
                 throw new ArgumentNullException(nameof(plugin));
             }
 
-            plugin.Instance?.OnUninstalling();
-
             if (DeletePlugin(plugin))
             {
                 return true;
             }
 
             // Unable to delete, so disable.
-            return ChangePluginState(plugin, PluginStatus.Disabled);
+            return ChangePluginState(plugin, PluginStatus.DeleteOnStartup);
         }
 
         /// <summary>
@@ -205,11 +222,18 @@ namespace Emby.Server.Implementations
         {
             if (version == null)
             {
-                // If no version is given, return the largest version number. (This is for backwards compatibility).
-                plugin = _plugins.Where(p => p.Id.Equals(id)).OrderByDescending(p => p.Version).FirstOrDefault();
+                // If no version is given, return the current instance.
+                var plugins = _plugins.Where(p => p.Id.Equals(id));
+
+                plugin = plugins.FirstOrDefault(p => p.Instance != null);
+                if (plugin == null)
+                {
+                    plugin = plugins.OrderByDescending(p => p.Version).FirstOrDefault();
+                }
             }
             else
             {
+                // Match id and version number.
                 plugin = _plugins.FirstOrDefault(p => p.Id.Equals(id) && p.Version.Equals(version));
             }
 
@@ -264,7 +288,6 @@ namespace Emby.Server.Implementations
             var predecessor = _plugins.OrderByDescending(p => p.Version)
                 .FirstOrDefault(
                     p => p.Id.Equals(plugin.Id)
-                    && p.Name.Equals(plugin.Name, StringComparison.OrdinalIgnoreCase)
                     && p.IsEnabledAndSupported
                     && p.Version != plugin.Version);
 
@@ -381,17 +404,6 @@ namespace Emby.Server.Implementations
             // Find the record for this plugin.
             var plugin = GetPluginByType(type);
 
-            if (plugin != null)
-            {
-                CheckIfStillSuperceded(plugin);
-
-                if (plugin.IsEnabledAndSupported == true)
-                {
-                    _logger.LogInformation("Skipping disabled plugin {Version} of {Name} ", plugin.Version, plugin.Name);
-                    return null;
-                }
-            }
-
             try
             {
                 _logger.LogDebug("Creating instance of {Type}", type);
@@ -489,6 +501,7 @@ namespace Emby.Server.Implementations
             {
                 _logger.LogDebug("Deleting {Path}", plugin.Path);
                 Directory.Delete(plugin.Path, true);
+                _plugins.Remove(plugin);
             }
 #pragma warning disable CA1031 // Do not catch general exception types
             catch (Exception e)
@@ -661,8 +674,8 @@ namespace Emby.Server.Implementations
                         continue;
                     }
 
-                    // Update the manifest so its not loaded next time.
-                    manifest.Status = PluginStatus.Disabled;
+                    manifest.Status = PluginStatus.DeleteOnStartup;
+
                     SaveManifest(manifest, entry.Path);
                 }
             }

+ 0 - 3
Jellyfin.Api/Controllers/PackageController.cs

@@ -46,7 +46,6 @@ namespace Jellyfin.Api.Controllers
         /// <returns>A <see cref="PackageInfo"/> containing package information.</returns>
         [HttpGet("Packages/{name}")]
         [ProducesResponseType(StatusCodes.Status200OK)]
-        [Produces(JsonDefaults.CamelCaseMediaType)]
         public async Task<ActionResult<PackageInfo>> GetPackageInfo(
             [FromRoute, Required] string name,
             [FromQuery] Guid? assemblyGuid)
@@ -73,7 +72,6 @@ namespace Jellyfin.Api.Controllers
         /// <returns>An <see cref="PackageInfo"/> containing available packages information.</returns>
         [HttpGet("Packages")]
         [ProducesResponseType(StatusCodes.Status200OK)]
-        [Produces(JsonDefaults.CamelCaseMediaType)]
         public async Task<IEnumerable<PackageInfo>> GetPackages()
         {
             IEnumerable<PackageInfo> packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false);
@@ -148,7 +146,6 @@ namespace Jellyfin.Api.Controllers
         /// <returns>An <see cref="OkResult"/> containing the list of package repositories.</returns>
         [HttpGet("Repositories")]
         [ProducesResponseType(StatusCodes.Status200OK)]
-        [Produces(JsonDefaults.CamelCaseMediaType)]
         public ActionResult<IEnumerable<RepositoryInfo>> GetRepositories()
         {
             return _serverConfigurationManager.Configuration.PluginRepositories;

+ 14 - 18
Jellyfin.Api/Controllers/PluginsController.cs

@@ -14,7 +14,6 @@ using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Json;
 using MediaBrowser.Common.Plugins;
 using MediaBrowser.Common.Updates;
-using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Net;
 using MediaBrowser.Model.Plugins;
@@ -130,7 +129,7 @@ namespace Jellyfin.Api.Controllers
         /// <response code="204">Plugin enabled.</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>
-        [HttpPost("{pluginId}/Enable")]
+        [HttpPost("{pluginId}/{version}/Enable")]
         [Authorize(Policy = Policies.RequiresElevation)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
@@ -153,7 +152,7 @@ namespace Jellyfin.Api.Controllers
         /// <response code="204">Plugin disabled.</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>
-        [HttpPost("{pluginId}/Disable")]
+        [HttpPost("{pluginId}/{version}/Disable")]
         [Authorize(Policy = Policies.RequiresElevation)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
@@ -176,11 +175,11 @@ namespace Jellyfin.Api.Controllers
         /// <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>
-        [HttpDelete("{pluginId}")]
+        [HttpDelete("{pluginId}/{version}")]
         [Authorize(Policy = Policies.RequiresElevation)]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
-        public ActionResult UninstallPlugin([FromRoute, Required] Guid pluginId, Version version)
+        public ActionResult UninstallPlugin([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version)
         {
             if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin))
             {
@@ -195,7 +194,6 @@ namespace Jellyfin.Api.Controllers
         /// Gets plugin configuration.
         /// </summary>
         /// <param name="pluginId">Plugin id.</param>
-        /// <param name="version">Plugin version.</param>
         /// <response code="200">Plugin configuration returned.</response>
         /// <response code="404">Plugin not found or plugin configuration not found.</response>
         /// <returns>Plugin configuration.</returns>
@@ -203,9 +201,9 @@ namespace Jellyfin.Api.Controllers
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [ProducesFile(MediaTypeNames.Application.Json)]
-        public ActionResult<BasePluginConfiguration> GetPluginConfiguration([FromRoute, Required] Guid pluginId, [FromRoute] Version? version)
+        public ActionResult<BasePluginConfiguration> GetPluginConfiguration([FromRoute, Required] Guid pluginId)
         {
-            if (_pluginManager.TryGetPlugin(pluginId, version, out var plugin)
+            if (_pluginManager.TryGetPlugin(pluginId, null, out var plugin)
                 && plugin!.Instance is IHasPluginConfiguration configPlugin)
             {
                 return configPlugin.Configuration;
@@ -221,7 +219,6 @@ namespace Jellyfin.Api.Controllers
         /// Accepts plugin configuration as JSON body.
         /// </remarks>
         /// <param name="pluginId">Plugin id.</param>
-        /// <param name="version">Plugin version.</param>
         /// <response code="204">Plugin configuration updated.</response>
         /// <response code="404">Plugin not found or plugin does not have configuration.</response>
         /// <returns>
@@ -232,9 +229,9 @@ namespace Jellyfin.Api.Controllers
         [HttpPost("{pluginId}/Configuration")]
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
-        public async Task<ActionResult> UpdatePluginConfiguration([FromRoute, Required] Guid pluginId, [FromRoute] Version? version)
+        public async Task<ActionResult> UpdatePluginConfiguration([FromRoute, Required] Guid pluginId)
         {
-            if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin)
+            if (!_pluginManager.TryGetPlugin(pluginId, null, out var plugin)
                          || plugin?.Instance is not IHasPluginConfiguration configPlugin)
             {
                 return NotFound();
@@ -258,12 +255,12 @@ namespace Jellyfin.Api.Controllers
         /// <param name="version">Plugin version.</param>
         /// <response code="200">Plugin image returned.</response>
         /// <returns>Plugin's image.</returns>
-        [HttpGet("{pluginId}/Image")]
+        [HttpGet("{pluginId}/{version}/Image")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [ProducesImageFile]
         [AllowAnonymous]
-        public ActionResult GetPluginImage([FromRoute, Required] Guid pluginId, [FromRoute] Version? version)
+        public ActionResult GetPluginImage([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version)
         {
             if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin))
             {
@@ -292,12 +289,12 @@ namespace Jellyfin.Api.Controllers
         /// <param name="version">Plugin version.</param>
         /// <response code="200">Plugin image returned.</response>
         /// <returns>Plugin's image.</returns>
-        [HttpGet("{pluginId}/StatusImage")]
+        [HttpGet("{pluginId}/{version}/StatusImage")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [ProducesImageFile]
         [AllowAnonymous]
-        public ActionResult GetPluginStatusImage([FromRoute, Required] Guid pluginId, [FromRoute] Version? version)
+        public ActionResult GetPluginStatusImage([FromRoute, Required] Guid pluginId, [FromRoute, Required] Version version)
         {
             if (!_pluginManager.TryGetPlugin(pluginId, version, out var plugin))
             {
@@ -316,7 +313,6 @@ namespace Jellyfin.Api.Controllers
         /// Gets a plugin's manifest.
         /// </summary>
         /// <param name="pluginId">Plugin id.</param>
-        /// <param name="version">Plugin version.</param>
         /// <response code="204">Plugin manifest returned.</response>
         /// <response code="404">Plugin not found.</response>
         /// <returns>
@@ -328,9 +324,9 @@ namespace Jellyfin.Api.Controllers
         [ProducesResponseType(StatusCodes.Status204NoContent)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [ProducesFile(MediaTypeNames.Application.Json)]
-        public ActionResult<PluginManifest> GetPluginManifest([FromRoute, Required] Guid pluginId, [FromRoute] Version? version)
+        public ActionResult<PluginManifest> GetPluginManifest([FromRoute, Required] Guid pluginId)
         {
-            if (_pluginManager.TryGetPlugin(pluginId, version, out var plugin))
+            if (_pluginManager.TryGetPlugin(pluginId, null, out var plugin))
             {
                 return Ok(plugin!.Manifest);
             }

+ 2 - 1
MediaBrowser.Model/Plugins/PluginStatus.cs

@@ -12,6 +12,7 @@ namespace MediaBrowser.Model.Plugins
         Disabled = -1,
         NotSupported = -2,
         Malfunction = -3,
-        Superceded = -4
+        Superceded = -4,
+        DeleteOnStartup = -5
     }
 }