diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 0ef06804d1..4810d4e9ce 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Api /// /// Class BaseApiService /// - public class BaseApiService : IHasResultFactory, IRestfulService, IHasSession + public class BaseApiService : IHasResultFactory, IService, IHasSession { /// /// Gets or sets the logger. diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index 7467fc39e4..cf20f7bbb9 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -208,7 +208,6 @@ - diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs index 97c5dd31b6..8c503c199b 100644 --- a/MediaBrowser.Controller/Net/IHttpServer.cs +++ b/MediaBrowser.Controller/Net/IHttpServer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { @@ -46,7 +47,7 @@ namespace MediaBrowser.Controller.Net /// /// Inits this instance. /// - void Init(IEnumerable services); + void Init(IEnumerable services); /// /// If set, all requests will respond with this message diff --git a/MediaBrowser.Controller/Net/IRestfulService.cs b/MediaBrowser.Controller/Net/IRestfulService.cs deleted file mode 100644 index 01eefe792d..0000000000 --- a/MediaBrowser.Controller/Net/IRestfulService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using MediaBrowser.Model.Services; - -namespace MediaBrowser.Controller.Net -{ - /// - /// Interface IRestfulService - /// - [Logged] - public interface IRestfulService : IService - { - } -} diff --git a/MediaBrowser.Controller/Net/LoggedAttribute.cs b/MediaBrowser.Controller/Net/LoggedAttribute.cs index c5b9d1cba6..6a2a5e2e3b 100644 --- a/MediaBrowser.Controller/Net/LoggedAttribute.cs +++ b/MediaBrowser.Controller/Net/LoggedAttribute.cs @@ -7,12 +7,20 @@ using MediaBrowser.Model.Services; namespace MediaBrowser.Controller.Net { - public class LoggedAttribute : Attribute, IHasRequestFilter + public class LoggedAttribute : IRequestFilter { - public ILogger Logger { get; set; } - public IUserManager UserManager { get; set; } - public ISessionManager SessionManager { get; set; } - public IAuthorizationContext AuthorizationContext { get; set; } + public LoggedAttribute(ILogger logger, IUserManager userManager, ISessionManager sessionManager, IAuthorizationContext authorizationContext) + { + Logger = logger; + UserManager = userManager; + SessionManager = sessionManager; + AuthorizationContext = authorizationContext; + } + + public ILogger Logger { get; private set; } + public IUserManager UserManager { get; private set; } + public ISessionManager SessionManager { get; private set; } + public IAuthorizationContext AuthorizationContext { get; private set; } /// /// The request filter is executed before the service. @@ -20,7 +28,7 @@ namespace MediaBrowser.Controller.Net /// The http request wrapper /// The http response wrapper /// The request DTO - public void RequestFilter(IRequest request, IResponse response, object requestDto) + public void Filter(IRequest request, IResponse response, object requestDto) { var serviceRequest = new ServiceRequest(request); @@ -51,25 +59,5 @@ namespace MediaBrowser.Controller.Net } } } - - /// - /// A new shallow copy of this filter is used on every request. - /// - /// IHasRequestFilter. - public IHasRequestFilter Copy() - { - return this; - } - - /// - /// Order in which Request Filters are executed. - /// <0 Executed before global request filters - /// >0 Executed after global request filters - /// - /// The priority. - public int Priority - { - get { return 0; } - } } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 37269473e3..dca74298e3 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -167,6 +167,9 @@ + + + @@ -174,6 +177,7 @@ + diff --git a/MediaBrowser.Model/Plugins/IHasWebPages.cs b/MediaBrowser.Model/Plugins/IHasWebPages.cs new file mode 100644 index 0000000000..0745c3c602 --- /dev/null +++ b/MediaBrowser.Model/Plugins/IHasWebPages.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace MediaBrowser.Model.Plugins +{ + public interface IHasWebPages + { + IEnumerable GetPages(); + } +} diff --git a/MediaBrowser.Model/Plugins/PluginPageInfo.cs b/MediaBrowser.Model/Plugins/PluginPageInfo.cs new file mode 100644 index 0000000000..4b91e07917 --- /dev/null +++ b/MediaBrowser.Model/Plugins/PluginPageInfo.cs @@ -0,0 +1,9 @@ +namespace MediaBrowser.Model.Plugins +{ + public class PluginPageInfo + { + public string Name { get; set; } + + public string EmbeddedResourcePath { get; set; } + } +} diff --git a/MediaBrowser.Model/Reflection/IAssemblyInfo.cs b/MediaBrowser.Model/Reflection/IAssemblyInfo.cs new file mode 100644 index 0000000000..1c65985cb2 --- /dev/null +++ b/MediaBrowser.Model/Reflection/IAssemblyInfo.cs @@ -0,0 +1,10 @@ +using System; +using System.IO; + +namespace MediaBrowser.Model.Reflection +{ + public interface IAssemblyInfo + { + Stream GetManifestResourceStream(Type type, string resource); + } +} diff --git a/MediaBrowser.Model/Services/IRequestFilter.cs b/MediaBrowser.Model/Services/IRequestFilter.cs new file mode 100644 index 0000000000..7f6db2e4d6 --- /dev/null +++ b/MediaBrowser.Model/Services/IRequestFilter.cs @@ -0,0 +1,8 @@ + +namespace MediaBrowser.Model.Services +{ + public interface IRequestFilter + { + void Filter(IRequest request, IResponse response, object requestDto); + } +} diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index d1954a5279..3fcdbf1c75 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -53,10 +53,7 @@ - - - False diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs index 999634a92e..71704f8e29 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -17,9 +17,9 @@ using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Common.Security; +using MediaBrowser.Controller; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Services; @@ -34,7 +34,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private readonly ILogger _logger; public IEnumerable UrlPrefixes { get; private set; } - private readonly List _restServices = new List(); + private readonly List _restServices = new List(); private IHttpListener _listener; @@ -49,13 +49,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer private readonly INetworkManager _networkManager; private readonly IMemoryStreamProvider _memoryStreamProvider; - public HttpListenerHost(IApplicationHost applicationHost, + private readonly IServerApplicationHost _appHost; + + public HttpListenerHost(IServerApplicationHost applicationHost, ILogManager logManager, IServerConfigurationManager config, string serviceName, string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamProvider memoryStreamProvider, params Assembly[] assembliesWithServices) : base(serviceName, assembliesWithServices) { + _appHost = applicationHost; DefaultRedirectPath = defaultRedirectPath; _networkManager = networkManager; _memoryStreamProvider = memoryStreamProvider; @@ -116,6 +119,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer // } //}); + var requestFilters = _appHost.GetExports().ToList(); + foreach (var filter in requestFilters) + { + HostContext.GlobalRequestFilters.Add(filter.Filter); + } + HostContext.GlobalResponseFilters.Add(new ResponseFilter(_logger).FilterResponse); } @@ -569,7 +578,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// Adds the rest handlers. /// /// The services. - public void Init(IEnumerable services) + public void Init(IEnumerable services) { _restServices.AddRange(services); diff --git a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs index b2cbf2387e..4dff2d5a3c 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs @@ -1,6 +1,5 @@ -using MediaBrowser.Common; -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; @@ -18,17 +17,17 @@ namespace MediaBrowser.Server.Implementations.HttpServer /// Creates the server. /// /// IHttpServer. - public static IHttpServer CreateServer(IApplicationHost applicationHost, + public static IHttpServer CreateServer(IServerApplicationHost applicationHost, ILogManager logManager, IServerConfigurationManager config, - INetworkManager _networkmanager, + INetworkManager networkmanager, IMemoryStreamProvider streamProvider, string serverName, string defaultRedirectpath) { LogManager.LogFactory = new ServerLogFactory(logManager); - return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, _networkmanager, streamProvider); + return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, networkmanager, streamProvider); } } } diff --git a/MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs b/MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs index 7d4d0a9684..54ee5fbb21 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs @@ -5,7 +5,7 @@ using MediaBrowser.Model.Services; namespace MediaBrowser.Server.Implementations.HttpServer { - public class SwaggerService : IHasResultFactory, IRestfulService + public class SwaggerService : IHasResultFactory, IService { private readonly IServerApplicationPaths _appPaths; diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index fd978f3d66..23d373ac45 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -270,6 +270,7 @@ + diff --git a/MediaBrowser.Server.Implementations/Reflection/AssemblyInfo.cs b/MediaBrowser.Server.Implementations/Reflection/AssemblyInfo.cs new file mode 100644 index 0000000000..ec25e7951e --- /dev/null +++ b/MediaBrowser.Server.Implementations/Reflection/AssemblyInfo.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; +using MediaBrowser.Model.Reflection; + +namespace MediaBrowser.Server.Implementations.Reflection +{ + public class AssemblyInfo : IAssemblyInfo + { + public Stream GetManifestResourceStream(Type type, string resource) + { + return type.Assembly.GetManifestResourceStream(resource); + } + } +} diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 4372dc2839..f8294a24d7 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -111,9 +111,12 @@ using MediaBrowser.Model.Activity; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Net; using MediaBrowser.Model.News; +using MediaBrowser.Model.Reflection; using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.Services; using MediaBrowser.Model.Social; using MediaBrowser.Model.Xml; +using MediaBrowser.Server.Implementations.Reflection; using MediaBrowser.Server.Implementations.Xml; namespace MediaBrowser.Server.Startup.Common @@ -634,6 +637,7 @@ namespace MediaBrowser.Server.Startup.Common RegisterSingleInstance(() => new BdInfoExaminer()); RegisterSingleInstance(new XmlReaderSettingsFactory()); + RegisterSingleInstance(new AssemblyInfo()); UserDataManager = new UserDataManager(LogManager, ServerConfigurationManager); RegisterSingleInstance(UserDataManager); @@ -985,7 +989,7 @@ namespace MediaBrowser.Server.Startup.Common base.FindParts(); - HttpServer.Init(GetExports(false)); + HttpServer.Init(GetExports(false)); ServerManager.AddWebSocketListeners(GetExports(false)); diff --git a/MediaBrowser.WebDashboard/Api/ConfigurationPageInfo.cs b/MediaBrowser.WebDashboard/Api/ConfigurationPageInfo.cs index 16aa14cb71..33289e76c8 100644 --- a/MediaBrowser.WebDashboard/Api/ConfigurationPageInfo.cs +++ b/MediaBrowser.WebDashboard/Api/ConfigurationPageInfo.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Controller.Plugins; +using MediaBrowser.Common.Plugins; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Plugins; namespace MediaBrowser.WebDashboard.Api { @@ -30,5 +32,13 @@ namespace MediaBrowser.WebDashboard.Api // Don't use "N" because it needs to match Plugin.Id PluginId = page.Plugin.Id.ToString(); } + + public ConfigurationPageInfo(IPlugin plugin, PluginPageInfo page) + { + Name = page.Name; + + // Don't use "N" because it needs to match Plugin.Id + PluginId = plugin.Id.ToString(); + } } } diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs index 5af580340a..6803ad3062 100644 --- a/MediaBrowser.WebDashboard/Api/DashboardService.cs +++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs @@ -12,8 +12,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; +using MediaBrowser.Common.Plugins; using MediaBrowser.Model.IO; using MediaBrowser.Model.Globalization; +using MediaBrowser.Model.Plugins; +using MediaBrowser.Model.Reflection; using MediaBrowser.Model.Services; namespace MediaBrowser.WebDashboard.Api @@ -76,7 +79,7 @@ namespace MediaBrowser.WebDashboard.Api /// /// Class DashboardService /// - public class DashboardService : IRestfulService, IHasResultFactory + public class DashboardService : IService, IHasResultFactory { /// /// Gets or sets the logger. @@ -109,6 +112,7 @@ namespace MediaBrowser.WebDashboard.Api private readonly IFileSystem _fileSystem; private readonly ILocalizationManager _localization; private readonly IJsonSerializer _jsonSerializer; + private readonly IAssemblyInfo _assemblyInfo; /// /// Initializes a new instance of the class. @@ -116,13 +120,14 @@ namespace MediaBrowser.WebDashboard.Api /// The app host. /// The server configuration manager. /// The file system. - public DashboardService(IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem, ILocalizationManager localization, IJsonSerializer jsonSerializer) + public DashboardService(IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem, ILocalizationManager localization, IJsonSerializer jsonSerializer, IAssemblyInfo assemblyInfo) { _appHost = appHost; _serverConfigurationManager = serverConfigurationManager; _fileSystem = fileSystem; _localization = localization; _jsonSerializer = jsonSerializer; + _assemblyInfo = assemblyInfo; } /// @@ -132,9 +137,32 @@ namespace MediaBrowser.WebDashboard.Api /// System.Object. public Task Get(GetDashboardConfigurationPage request) { - var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase)); + IPlugin plugin = null; + Stream stream = null; - return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml("dummy.html", page.GetHtmlStream(), null, _appHost.ApplicationVersion.ToString(), null, false)); + var page = ServerEntryPoint.Instance.PluginConfigurationPages.FirstOrDefault(p => string.Equals(p.Name, request.Name, StringComparison.OrdinalIgnoreCase)); + if (page != null) + { + plugin = page.Plugin; + stream = page.GetHtmlStream(); + } + + if (plugin == null) + { + var altPage = GetPluginPages().FirstOrDefault(p => string.Equals(p.Item1.Name, request.Name, StringComparison.OrdinalIgnoreCase)); + if (altPage != null) + { + plugin = altPage.Item2; + stream = _assemblyInfo.GetManifestResourceStream(plugin.GetType(), altPage.Item1.EmbeddedResourcePath); + } + } + + if (plugin != null && stream != null) + { + return ResultFactory.GetStaticResult(Request, plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml("dummy.html", stream, null, _appHost.ApplicationVersion.ToString(), null, false)); + } + + throw new ResourceNotFoundException(); } /// @@ -162,7 +190,7 @@ namespace MediaBrowser.WebDashboard.Api if (request.PageType.HasValue) { - pages = pages.Where(p => p.ConfigurationPageType == request.PageType.Value); + pages = pages.Where(p => p.ConfigurationPageType == request.PageType.Value).ToList(); } // Don't allow a failing plugin to fail them all @@ -182,9 +210,33 @@ namespace MediaBrowser.WebDashboard.Api .Where(i => i != null) .ToList(); + configPages.AddRange(_appHost.Plugins.SelectMany(GetConfigPages)); + return ResultFactory.GetOptimizedResult(Request, configPages); } + private IEnumerable> GetPluginPages() + { + return _appHost.Plugins.SelectMany(GetPluginPages); + } + + private IEnumerable> GetPluginPages(IPlugin plugin) + { + var hasConfig = plugin as IHasWebPages; + + if (hasConfig == null) + { + return new List>(); + } + + return hasConfig.GetPages().Select(i => new Tuple(i, plugin)); + } + + private IEnumerable GetConfigPages(IPlugin plugin) + { + return GetPluginPages(plugin).Select(i => new ConfigurationPageInfo(plugin, i.Item1)); + } + public object Get(GetRobotsTxt request) { return Get(new GetDashboardResource diff --git a/MediaBrowser.WebDashboard/ServerEntryPoint.cs b/MediaBrowser.WebDashboard/ServerEntryPoint.cs index 690c07d8ff..b939e41070 100644 --- a/MediaBrowser.WebDashboard/ServerEntryPoint.cs +++ b/MediaBrowser.WebDashboard/ServerEntryPoint.cs @@ -1,6 +1,7 @@ using MediaBrowser.Common; using MediaBrowser.Controller.Plugins; using System.Collections.Generic; +using System.Linq; namespace MediaBrowser.WebDashboard { @@ -10,7 +11,7 @@ namespace MediaBrowser.WebDashboard /// Gets the list of plugin configuration pages /// /// The configuration pages. - public IEnumerable PluginConfigurationPages { get; private set; } + public List PluginConfigurationPages { get; private set; } private readonly IApplicationHost _appHost; @@ -24,7 +25,7 @@ namespace MediaBrowser.WebDashboard public void Run() { - PluginConfigurationPages = _appHost.GetExports(); + PluginConfigurationPages = _appHost.GetExports().ToList(); } public void Dispose() diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 57b18c3389..292c80a7c4 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common.Internal - 3.0.676 + 3.0.680 Emby.Common.Internal Luke ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption. Copyright © Emby 2013 - + diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 05c9c4afc8..111cb0a2a0 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.676 + 3.0.680 Emby.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 67607af50d..fec8b7722d 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.676 + 3.0.680 Emby.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,10 +12,11 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + + \ No newline at end of file