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 4 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
15 changes: 14 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,19 @@ public void RemovePlugin(IPlugin plugin)
_plugins = list.ToArray();
}

public IEnumerable<Assembly> GetApiPluginAssemblies()
{
var types = _allConcreteTypes
.Where(i => typeof(ControllerBase).IsAssignableFrom(i))
.Distinct();

foreach (var type in types)
{
Logger.LogDebug("Found API endpoints in plugin {name}", type.Assembly.FullName);
yield return type.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="applicationHost">The application host.</param>
/// <returns>The MVC builder.</returns>
public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl)
public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl, IApplicationHost applicationHost)
{
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 applicationHost.GetApiPluginAssemblies())
{
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);

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