Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow plugins to define their own api endpoints #3871

Merged
merged 6 commits into from
Aug 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 15 additions & 1 deletion Emby.Server.Implementations/ApplicationHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Chapters;
using MediaBrowser.Controller.Collections;
Expand Down Expand Up @@ -98,6 +97,7 @@
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;
Expand Down Expand Up @@ -1385,6 +1385,20 @@ public void RemovePlugin(IPlugin plugin)
_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)
cvium marked this conversation as resolved.
Show resolved Hide resolved
{
Logger.LogDebug("Found API endpoints in plugin {name}", assembly.FullName);
yield return assembly;
}
}

public virtual void LaunchUrl(string url)
{
if (!CanLaunchWebBrowser)
Expand Down
16 changes: 12 additions & 4 deletions Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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;
Expand Down Expand Up @@ -135,10 +136,11 @@ public static AuthenticationBuilder AddCustomAuthentication(this IServiceCollect
/// </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);
Expand Down Expand Up @@ -175,8 +177,14 @@ public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollecti

// From JsonDefaults.PascalCase
options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy;
})
.AddControllersAsServices();
});

foreach (Assembly pluginAssembly in pluginAssemblies)
{
mvcBuilder.AddApplicationPart(pluginAssembly);
}

return mvcBuilder.AddControllersAsServices();
}

/// <summary>
Expand Down
9 changes: 7 additions & 2 deletions Jellyfin.Server/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
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;
Expand All @@ -18,14 +20,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>
Expand All @@ -36,7 +41,7 @@ public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.AddHttpContextAccessor();
services.AddJellyfinApi(_serverConfigurationManager.Configuration.BaseUrl.TrimStart('/'));
services.AddJellyfinApi(_serverConfigurationManager.Configuration.BaseUrl.TrimStart('/'), _applicationHost.GetApiPluginAssemblies());

services.AddJellyfinApiSwagger();

Expand Down
7 changes: 7 additions & 0 deletions MediaBrowser.Common/IApplicationHost.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -76,6 +77,12 @@ public interface IApplicationHost
/// <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>
Expand Down