Ver código fonte

Merge pull request #3871 from Ullmie02/plugins-api

Allow plugins to define their own api endpoints
Bond-009 4 anos atrás
pai
commit
95142643f6

+ 15 - 0
Emby.Server.Implementations/ApplicationHost.cs

@@ -97,6 +97,7 @@ using MediaBrowser.Providers.Plugins.TheTvdb;
 using MediaBrowser.Providers.Subtitles;
 using MediaBrowser.XbmcMetadata.Providers;
 using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 using Prometheus.DotNetRuntime;
@@ -1393,6 +1394,20 @@ namespace Emby.Server.Implementations
             _plugins = list.ToArray();
         }
 
+        public IEnumerable<Assembly> GetApiPluginAssemblies()
+        {
+            var assemblies = _allConcreteTypes
+                .Where(i => typeof(ControllerBase).IsAssignableFrom(i))
+                .Select(i => i.Assembly)
+                .Distinct();
+
+            foreach (var assembly in assemblies)
+            {
+                Logger.LogDebug("Found API endpoints in plugin {name}", assembly.FullName);
+                yield return assembly;
+            }
+        }
+
         public virtual void LaunchUrl(string url)
         {
             if (!CanLaunchWebBrowser)

+ 12 - 4
Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs

@@ -18,6 +18,7 @@ using Jellyfin.Api.Constants;
 using Jellyfin.Api.Controllers;
 using Jellyfin.Server.Formatters;
 using Jellyfin.Server.Models;
+using MediaBrowser.Common;
 using MediaBrowser.Common.Json;
 using MediaBrowser.Model.Entities;
 using Microsoft.AspNetCore.Authentication;
@@ -135,10 +136,11 @@ namespace Jellyfin.Server.Extensions
         /// </summary>
         /// <param name="serviceCollection">The service collection.</param>
         /// <param name="baseUrl">The base url for the API.</param>
+        /// <param name="pluginAssemblies">An IEnumberable containing all plugin assemblies with API controllers.</param>
         /// <returns>The MVC builder.</returns>
-        public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl)
+        public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl, IEnumerable<Assembly> pluginAssemblies)
         {
-            return serviceCollection
+            IMvcBuilder mvcBuilder = serviceCollection
                 .AddCors(options =>
                 {
                     options.AddPolicy(ServerCorsPolicy.DefaultPolicyName, ServerCorsPolicy.DefaultPolicy);
@@ -179,8 +181,14 @@ namespace Jellyfin.Server.Extensions
 
                     // From JsonDefaults.PascalCase
                     options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy;
-                })
-                .AddControllersAsServices();
+                });
+
+            foreach (Assembly pluginAssembly in pluginAssemblies)
+            {
+                mvcBuilder.AddApplicationPart(pluginAssembly);
+            }
+
+            return mvcBuilder.AddControllersAsServices();
         }
 
         /// <summary>

+ 7 - 2
Jellyfin.Server/Startup.cs

@@ -4,8 +4,10 @@ using Jellyfin.Api.TypeConverters;
 using Jellyfin.Server.Extensions;
 using Jellyfin.Server.Middleware;
 using Jellyfin.Server.Models;
+using MediaBrowser.Common;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Model.Serialization;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.Extensions.DependencyInjection;
@@ -20,14 +22,17 @@ namespace Jellyfin.Server
     public class Startup
     {
         private readonly IServerConfigurationManager _serverConfigurationManager;
+        private readonly IApplicationHost _applicationHost;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="Startup" /> class.
         /// </summary>
         /// <param name="serverConfigurationManager">The server configuration manager.</param>
-        public Startup(IServerConfigurationManager serverConfigurationManager)
+        /// <param name="applicationHost">The application host.</param>
+        public Startup(IServerConfigurationManager serverConfigurationManager, IApplicationHost applicationHost)
         {
             _serverConfigurationManager = serverConfigurationManager;
+            _applicationHost = applicationHost;
         }
 
         /// <summary>
@@ -38,7 +43,7 @@ namespace Jellyfin.Server
         {
             services.AddResponseCompression();
             services.AddHttpContextAccessor();
-            services.AddJellyfinApi(_serverConfigurationManager.Configuration.BaseUrl.TrimStart('/'));
+            services.AddJellyfinApi(_serverConfigurationManager.Configuration.BaseUrl.TrimStart('/'), _applicationHost.GetApiPluginAssemblies());
 
             services.AddJellyfinApiSwagger();
 

+ 7 - 0
MediaBrowser.Common/IApplicationHost.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Reflection;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Plugins;
 using Microsoft.Extensions.DependencyInjection;
@@ -76,6 +77,12 @@ namespace MediaBrowser.Common
         /// <value>The plugins.</value>
         IReadOnlyList<IPlugin> Plugins { get; }
 
+        /// <summary>
+        /// Gets all plugin assemblies which implement a custom rest api.
+        /// </summary>
+        /// <returns>An <see cref="IEnumerable{Assembly}"/> containing the plugin assemblies.</returns>
+        IEnumerable<Assembly> GetApiPluginAssemblies();
+
         /// <summary>
         /// Notifies the pending restart.
         /// </summary>