From 4f67fc4aefc11c1a4293227c70de922dbe03c652 Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Thu, 7 Mar 2013 00:34:00 -0500 Subject: removed base kernel and ikernel --- MediaBrowser.Api/EnvironmentService.cs | 4 +- MediaBrowser.Api/Images/ImageService.cs | 2 +- .../Javascript/JavascriptApiClientService.cs | 2 +- MediaBrowser.Api/Library/LibraryService.cs | 4 +- .../Library/LibraryStructureService.cs | 4 +- MediaBrowser.Api/LocalizationService.cs | 4 +- MediaBrowser.Api/MediaBrowser.Api.csproj | 8 +- MediaBrowser.Api/PackageService.cs | 2 +- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Api/PluginService.cs | 2 +- .../ScheduledTasks/ScheduledTaskService.cs | 19 +- .../ScheduledTasksWebSocketListener.cs | 2 +- MediaBrowser.Api/SystemService.cs | 10 +- .../UserLibrary/BaseItemsByNameService.cs | 4 +- MediaBrowser.Api/UserLibrary/ItemsService.cs | 5 +- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 5 +- MediaBrowser.Api/UserService.cs | 2 +- MediaBrowser.Api/WeatherService.cs | 4 +- .../WebSocket/LogFileWebSocketListener.cs | 2 +- .../WebSocket/SystemInfoWebSocketListener.cs | 11 +- .../BaseApplicationHost.cs | 94 +- .../BaseApplicationPaths.cs | 1 - .../HttpClientManager/HttpClientManager.cs | 2 - .../HttpServer/BaseRestService.cs | 458 ------- .../HttpServer/HttpServer.cs | 570 --------- .../HttpServer/NativeWebSocket.cs | 165 --- .../HttpServer/ServerFactory.cs | 27 - .../HttpServer/StreamWriter.cs | 48 - .../HttpServer/SwaggerService.cs | 38 - .../MediaBrowser.Common.Implementations.csproj | 106 +- MediaBrowser.Common.Implementations/README.txt | 41 - .../ScheduledTasks/ScheduledTaskWorker.cs | 28 +- .../ScheduledTasks/TaskManager.cs | 73 +- .../ScheduledTasks/Tasks/SystemUpdateTask.cs | 13 +- .../Security/PluginSecurityManager.cs | 23 +- .../ServerManager/RegisterServer.bat | 28 - .../ServerManager/ServerManager.cs | 542 -------- .../ServerManager/WebSocketConnection.cs | 225 ---- .../Udp/UdpServer.cs | 203 --- .../Updates/ApplicationUpdater.cs | 32 + .../WebSocket/AlchemyServer.cs | 113 -- .../WebSocket/AlchemyWebSocket.cs | 132 -- .../packages.config | 10 - .../swagger-ui/css/screen.css | 959 -------------- .../swagger-ui/images/pet_store_api.png | Bin 824 -> 0 bytes .../swagger-ui/images/wordnik_api.png | Bin 980 -> 0 bytes .../swagger-ui/index.html | 88 -- .../swagger-ui/lib/backbone-min.js | 38 - .../lib/handlebars.runtime-1.0.0.beta.6.js | 223 ---- .../swagger-ui/lib/jquery.ba-bbq.min.js | 18 - .../swagger-ui/lib/jquery.min.js | 4 - .../swagger-ui/lib/jquery.slideto.min.js | 1 - .../swagger-ui/lib/jquery.wiggle.min.js | 8 - .../swagger-ui/lib/swagger.js | 507 -------- .../swagger-ui/lib/underscore-min.js | 32 - .../swagger-ui/swagger-ui.js | 1309 -------------------- .../swagger-ui/swagger-ui.min.js | 1 - MediaBrowser.Common/IApplicationHost.cs | 21 + MediaBrowser.Common/Kernel/BaseKernel.cs | 167 --- .../Kernel/BasePeriodicWebSocketListener.cs | 251 ---- MediaBrowser.Common/Kernel/IKernel.cs | 74 -- MediaBrowser.Common/Kernel/IServerManager.cs | 61 - MediaBrowser.Common/Kernel/IWebSocketListener.cs | 18 - MediaBrowser.Common/Kernel/KernelContext.cs | 18 - MediaBrowser.Common/MediaBrowser.Common.csproj | 11 +- .../Net/BasePeriodicWebSocketListener.cs | 250 ++++ MediaBrowser.Common/Net/IServerManager.cs | 61 + MediaBrowser.Common/Net/IWebSocketListener.cs | 17 + .../ScheduledTasks/IScheduledTaskWorker.cs | 19 - MediaBrowser.Common/ScheduledTasks/ITaskManager.cs | 11 +- .../ScheduledTasks/TaskCompletionEventArgs.cs | 12 + MediaBrowser.Common/Updates/ApplicationUpdater.cs | 38 - MediaBrowser.Controller/BaseManager.cs | 50 - MediaBrowser.Controller/IO/FileSystemManager.cs | 20 +- MediaBrowser.Controller/IServerApplicationHost.cs | 10 + MediaBrowser.Controller/IServerApplicationPaths.cs | 1 - MediaBrowser.Controller/Kernel.cs | 56 +- .../MediaBrowser.Controller.csproj | 2 +- .../Providers/ProviderManager.cs | 15 +- .../Configuration/BaseApplicationConfiguration.cs | 26 - .../Configuration/ServerConfiguration.cs | 25 + .../HttpServer/BaseRestService.cs | 458 +++++++ .../HttpServer/HttpServer.cs | 570 +++++++++ .../HttpServer/NativeWebSocket.cs | 165 +++ .../HttpServer/ServerFactory.cs | 27 + .../HttpServer/StreamWriter.cs | 48 + .../HttpServer/SwaggerService.cs | 38 + .../MediaBrowser.Server.Implementations.csproj | 101 ++ MediaBrowser.Server.Implementations/README.txt | 41 + .../ServerManager/RegisterServer.bat | 28 + .../ServerManager/ServerManager.cs | 525 ++++++++ .../ServerManager/WebSocketConnection.cs | 225 ++++ .../Sqlite/SQLiteDisplayPreferencesRepository.cs | 1 - .../Sqlite/SQLiteItemRepository.cs | 1 - .../Sqlite/SQLiteUserDataRepository.cs | 1 - .../Sqlite/SQLiteUserRepository.cs | 1 - .../Udp/UdpServer.cs | 203 +++ .../Updates/InstallationManager.cs | 14 +- .../WebSocket/AlchemyServer.cs | 113 ++ .../WebSocket/AlchemyWebSocket.cs | 132 ++ .../packages.config | 12 + .../swagger-ui/css/screen.css | 959 ++++++++++++++ .../swagger-ui/images/pet_store_api.png | Bin 0 -> 824 bytes .../swagger-ui/images/wordnik_api.png | Bin 0 -> 980 bytes .../swagger-ui/index.html | 88 ++ .../swagger-ui/lib/backbone-min.js | 38 + .../lib/handlebars.runtime-1.0.0.beta.6.js | 223 ++++ .../swagger-ui/lib/jquery.ba-bbq.min.js | 18 + .../swagger-ui/lib/jquery.min.js | 4 + .../swagger-ui/lib/jquery.slideto.min.js | 1 + .../swagger-ui/lib/jquery.wiggle.min.js | 8 + .../swagger-ui/lib/swagger.js | 507 ++++++++ .../swagger-ui/lib/underscore-min.js | 32 + .../swagger-ui/swagger-ui.js | 1309 ++++++++++++++++++++ .../swagger-ui/swagger-ui.min.js | 1 + MediaBrowser.ServerApplication/App.xaml.cs | 13 +- MediaBrowser.ServerApplication/ApplicationHost.cs | 89 +- MediaBrowser.ServerApplication/StartupWizard.cs | 6 +- MediaBrowser.ServerApplication/WebSocketEvents.cs | 36 +- .../Api/DashboardInfoWebSocketListener.cs | 14 +- MediaBrowser.WebDashboard/Api/DashboardService.cs | 14 +- MediaBrowser.WebDashboard/Html/css/site.css | 2 +- MediaBrowser.WebDashboard/Html/itemList.html | 6 +- .../MediaBrowser.WebDashboard.csproj | 8 +- Nuget/MediaBrowser.Common.Internal.nuspec | 12 +- 125 files changed, 6633 insertions(+), 6951 deletions(-) delete mode 100644 MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs delete mode 100644 MediaBrowser.Common.Implementations/HttpServer/HttpServer.cs delete mode 100644 MediaBrowser.Common.Implementations/HttpServer/NativeWebSocket.cs delete mode 100644 MediaBrowser.Common.Implementations/HttpServer/ServerFactory.cs delete mode 100644 MediaBrowser.Common.Implementations/HttpServer/StreamWriter.cs delete mode 100644 MediaBrowser.Common.Implementations/HttpServer/SwaggerService.cs delete mode 100644 MediaBrowser.Common.Implementations/README.txt delete mode 100644 MediaBrowser.Common.Implementations/ServerManager/RegisterServer.bat delete mode 100644 MediaBrowser.Common.Implementations/ServerManager/ServerManager.cs delete mode 100644 MediaBrowser.Common.Implementations/ServerManager/WebSocketConnection.cs delete mode 100644 MediaBrowser.Common.Implementations/Udp/UdpServer.cs create mode 100644 MediaBrowser.Common.Implementations/Updates/ApplicationUpdater.cs delete mode 100644 MediaBrowser.Common.Implementations/WebSocket/AlchemyServer.cs delete mode 100644 MediaBrowser.Common.Implementations/WebSocket/AlchemyWebSocket.cs delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/css/screen.css delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/images/pet_store_api.png delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/images/wordnik_api.png delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/index.html delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/lib/backbone-min.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/lib/handlebars.runtime-1.0.0.beta.6.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/lib/jquery.ba-bbq.min.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/lib/jquery.min.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/lib/jquery.slideto.min.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/lib/jquery.wiggle.min.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/lib/swagger.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/lib/underscore-min.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/swagger-ui.js delete mode 100644 MediaBrowser.Common.Implementations/swagger-ui/swagger-ui.min.js delete mode 100644 MediaBrowser.Common/Kernel/BaseKernel.cs delete mode 100644 MediaBrowser.Common/Kernel/BasePeriodicWebSocketListener.cs delete mode 100644 MediaBrowser.Common/Kernel/IKernel.cs delete mode 100644 MediaBrowser.Common/Kernel/IServerManager.cs delete mode 100644 MediaBrowser.Common/Kernel/IWebSocketListener.cs delete mode 100644 MediaBrowser.Common/Kernel/KernelContext.cs create mode 100644 MediaBrowser.Common/Net/BasePeriodicWebSocketListener.cs create mode 100644 MediaBrowser.Common/Net/IServerManager.cs create mode 100644 MediaBrowser.Common/Net/IWebSocketListener.cs create mode 100644 MediaBrowser.Common/ScheduledTasks/TaskCompletionEventArgs.cs delete mode 100644 MediaBrowser.Common/Updates/ApplicationUpdater.cs delete mode 100644 MediaBrowser.Controller/BaseManager.cs create mode 100644 MediaBrowser.Controller/IServerApplicationHost.cs create mode 100644 MediaBrowser.Server.Implementations/HttpServer/BaseRestService.cs create mode 100644 MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs create mode 100644 MediaBrowser.Server.Implementations/HttpServer/NativeWebSocket.cs create mode 100644 MediaBrowser.Server.Implementations/HttpServer/ServerFactory.cs create mode 100644 MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs create mode 100644 MediaBrowser.Server.Implementations/HttpServer/SwaggerService.cs create mode 100644 MediaBrowser.Server.Implementations/README.txt create mode 100644 MediaBrowser.Server.Implementations/ServerManager/RegisterServer.bat create mode 100644 MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs create mode 100644 MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs create mode 100644 MediaBrowser.Server.Implementations/Udp/UdpServer.cs create mode 100644 MediaBrowser.Server.Implementations/WebSocket/AlchemyServer.cs create mode 100644 MediaBrowser.Server.Implementations/WebSocket/AlchemyWebSocket.cs create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/css/screen.css create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/images/pet_store_api.png create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/images/wordnik_api.png create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/index.html create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/lib/backbone-min.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/lib/handlebars.runtime-1.0.0.beta.6.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/lib/jquery.ba-bbq.min.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/lib/jquery.min.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/lib/jquery.slideto.min.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/lib/jquery.wiggle.min.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/lib/swagger.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/lib/underscore-min.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/swagger-ui.js create mode 100644 MediaBrowser.Server.Implementations/swagger-ui/swagger-ui.min.js diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index 56be18d866..6296711ed3 100644 --- a/MediaBrowser.Api/EnvironmentService.cs +++ b/MediaBrowser.Api/EnvironmentService.cs @@ -1,8 +1,8 @@ -using MediaBrowser.Common.Implementations.HttpServer; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net; using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; using MediaBrowser.Model.Net; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 1c0e6c68da..d2a612cb9d 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -1,11 +1,11 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; -using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using ServiceStack.Text.Controller; using System; diff --git a/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs b/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs index 165574d747..7c4d0d84f6 100644 --- a/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs +++ b/MediaBrowser.Api/Javascript/JavascriptApiClientService.cs @@ -1,6 +1,6 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Common.Net; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.IO; diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index b49cc568fe..39cbe64901 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -1,10 +1,8 @@ using MediaBrowser.Common; -using MediaBrowser.Common.Implementations.HttpServer; -using MediaBrowser.Common.Kernel; -using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs index df8b2907d8..0ae73ed457 100644 --- a/MediaBrowser.Api/Library/LibraryStructureService.cs +++ b/MediaBrowser.Api/Library/LibraryStructureService.cs @@ -1,7 +1,7 @@ -using MediaBrowser.Common.Implementations.HttpServer; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Entities; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/LocalizationService.cs b/MediaBrowser.Api/LocalizationService.cs index 18c33a90a4..1493e8e44f 100644 --- a/MediaBrowser.Api/LocalizationService.cs +++ b/MediaBrowser.Api/LocalizationService.cs @@ -1,7 +1,7 @@ -using MediaBrowser.Common.Implementations.HttpServer; -using MediaBrowser.Controller.Localization; +using MediaBrowser.Controller.Localization; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; +using MediaBrowser.Server.Implementations.HttpServer; using MoreLinq; using ServiceStack.ServiceHost; using System.Collections.Generic; diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index c7bba4e9a8..5cedbf85fb 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -121,10 +121,6 @@ - - {c4d2573a-3fd3-441f-81af-174ac4cd4e1d} - MediaBrowser.Common.Implementations - {9142eefa-7570-41e1-bfcc-468bb571af2f} MediaBrowser.Common @@ -137,6 +133,10 @@ {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model + + {2e781478-814d-4a48-9d80-bff206441a65} + MediaBrowser.Server.Implementations + diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index 1c0508c6d9..e8ff02539c 100644 --- a/MediaBrowser.Api/PackageService.cs +++ b/MediaBrowser.Api/PackageService.cs @@ -1,8 +1,8 @@ using MediaBrowser.Common; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Controller.Updates; using MediaBrowser.Model.Updates; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 5107d13c21..796366181e 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Common.IO; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; @@ -15,6 +14,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Server.Implementations.HttpServer; namespace MediaBrowser.Api.Playback { diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs index bec6835e0b..847478beb1 100644 --- a/MediaBrowser.Api/PluginService.cs +++ b/MediaBrowser.Api/PluginService.cs @@ -1,11 +1,11 @@ using MediaBrowser.Common; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Common.Security; using MediaBrowser.Controller.Updates; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Plugins; using MediaBrowser.Model.Serialization; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using ServiceStack.Text.Controller; using System; diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs index 0c18725faa..5117dc7ac8 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs @@ -1,8 +1,8 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Tasks; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using ServiceStack.Text.Controller; using System; @@ -84,30 +84,19 @@ namespace MediaBrowser.Api.ScheduledTasks /// The task manager. private ITaskManager TaskManager { get; set; } - /// - /// The _json serializer - /// - private readonly IJsonSerializer _jsonSerializer; - /// /// Initializes a new instance of the class. /// /// The task manager. - /// The json serializer. /// taskManager - public ScheduledTaskService(ITaskManager taskManager, IJsonSerializer jsonSerializer) + public ScheduledTaskService(ITaskManager taskManager) { if (taskManager == null) { throw new ArgumentNullException("taskManager"); } - if (jsonSerializer == null) - { - throw new ArgumentNullException("jsonSerializer"); - } TaskManager = taskManager; - _jsonSerializer = jsonSerializer; } /// @@ -157,7 +146,7 @@ namespace MediaBrowser.Api.ScheduledTasks throw new ResourceNotFoundException("Task not found"); } - task.Execute(); + TaskManager.Execute(task); } /// @@ -174,7 +163,7 @@ namespace MediaBrowser.Api.ScheduledTasks throw new ResourceNotFoundException("Task not found"); } - task.Cancel(); + TaskManager.Cancel(task); } /// diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index 4ef791e23b..20634301a3 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -1,4 +1,4 @@ -using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Net; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Tasks; diff --git a/MediaBrowser.Api/SystemService.cs b/MediaBrowser.Api/SystemService.cs index 96ed70b8f1..3fdf621c0f 100644 --- a/MediaBrowser.Api/SystemService.cs +++ b/MediaBrowser.Api/SystemService.cs @@ -1,11 +1,11 @@ using MediaBrowser.Common; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.IO; @@ -66,7 +66,7 @@ namespace MediaBrowser.Api /// /// The _app host /// - private readonly IApplicationHost _appHost; + private readonly IServerApplicationHost _appHost; /// /// The _configuration manager @@ -80,7 +80,7 @@ namespace MediaBrowser.Api /// The app host. /// The configuration manager. /// jsonSerializer - public SystemService(IJsonSerializer jsonSerializer, IApplicationHost appHost, IServerConfigurationManager configurationManager) + public SystemService(IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IServerConfigurationManager configurationManager) : base() { if (jsonSerializer == null) @@ -104,7 +104,7 @@ namespace MediaBrowser.Api /// System.Object. public object Get(GetSystemInfo request) { - var result = Kernel.Instance.GetSystemInfo(); + var result = _appHost.GetSystemInfo(); return ToOptimizedResult(result); } @@ -132,7 +132,7 @@ namespace MediaBrowser.Api Task.Run(async () => { await Task.Delay(100); - Kernel.Instance.PerformPendingRestart(); + _appHost.PerformPendingRestart(); }); } diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index e2dd0519ab..9d056c699b 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -1,8 +1,8 @@ -using MediaBrowser.Common.Implementations.HttpServer; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index b89715d1c1..c2b01f9b0e 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -1,10 +1,9 @@ -using MediaBrowser.Common.Implementations.HttpServer; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index c40e599989..ca439b346c 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -1,12 +1,11 @@ -using MediaBrowser.Common.Implementations.HttpServer; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Connectivity; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Serialization; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using ServiceStack.Text.Controller; using System; diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index abf07f9244..d1606f954c 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -1,8 +1,8 @@ using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Serialization; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using ServiceStack.Text.Controller; using System; diff --git a/MediaBrowser.Api/WeatherService.cs b/MediaBrowser.Api/WeatherService.cs index d719511826..f2ba68113e 100644 --- a/MediaBrowser.Api/WeatherService.cs +++ b/MediaBrowser.Api/WeatherService.cs @@ -1,6 +1,6 @@ -using MediaBrowser.Common.Implementations.HttpServer; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Model.Weather; +using MediaBrowser.Server.Implementations.HttpServer; using ServiceStack.ServiceHost; using System.Linq; using System.Threading; diff --git a/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs b/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs index 2480b2af8b..f11bae5239 100644 --- a/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs +++ b/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs @@ -1,5 +1,5 @@ using MediaBrowser.Common.IO; -using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Net; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; diff --git a/MediaBrowser.Api/WebSocket/SystemInfoWebSocketListener.cs b/MediaBrowser.Api/WebSocket/SystemInfoWebSocketListener.cs index 40c3f2f247..ae8f41c363 100644 --- a/MediaBrowser.Api/WebSocket/SystemInfoWebSocketListener.cs +++ b/MediaBrowser.Api/WebSocket/SystemInfoWebSocketListener.cs @@ -1,4 +1,4 @@ -using MediaBrowser.Common.Kernel; +using MediaBrowser.Common.Net; using MediaBrowser.Controller; using MediaBrowser.Model.Logging; using MediaBrowser.Model.System; @@ -23,17 +23,16 @@ namespace MediaBrowser.Api.WebSocket /// /// The _kernel /// - private readonly IKernel _kernel; + private readonly IServerApplicationHost _appHost; /// /// Initializes a new instance of the class. /// - /// The kernel. /// The logger. - public SystemInfoWebSocketListener(Kernel kernel, ILogger logger) + public SystemInfoWebSocketListener(ILogger logger, IServerApplicationHost appHost) : base(logger) { - _kernel = kernel; + _appHost = appHost; } /// @@ -43,7 +42,7 @@ namespace MediaBrowser.Api.WebSocket /// Task{SystemInfo}. protected override Task GetDataToSend(object state) { - return Task.FromResult(_kernel.GetSystemInfo()); + return Task.FromResult(_appHost.GetSystemInfo()); } } } diff --git a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs index 77ff4f1885..a5af2ff66a 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationHost.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationHost.cs @@ -1,13 +1,11 @@ using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Events; using MediaBrowser.Common.Implementations.Logging; using MediaBrowser.Common.Implementations.NetworkManagement; using MediaBrowser.Common.Implementations.ScheduledTasks; using MediaBrowser.Common.Implementations.Security; using MediaBrowser.Common.Implementations.Serialization; -using MediaBrowser.Common.Implementations.Udp; using MediaBrowser.Common.Implementations.Updates; -using MediaBrowser.Common.Implementations.WebSocket; -using MediaBrowser.Common.Kernel; using MediaBrowser.Common.Net; using MediaBrowser.Common.Plugins; using MediaBrowser.Common.ScheduledTasks; @@ -15,6 +13,7 @@ using MediaBrowser.Common.Security; using MediaBrowser.Common.Updates; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; +using MediaBrowser.Model.System; using MediaBrowser.Model.Updates; using SimpleInjector; using System; @@ -30,6 +29,22 @@ namespace MediaBrowser.Common.Implementations public abstract class BaseApplicationHost : IApplicationHost where TApplicationPathsType : class, IApplicationPaths, new() { + /// + /// Occurs when [has pending restart changed]. + /// + public event EventHandler HasPendingRestartChanged; + + /// + /// Occurs when [application updated]. + /// + public event EventHandler> ApplicationUpdated; + + /// + /// Gets or sets a value indicating whether this instance has changes that require the entire application to restart. + /// + /// true if this instance has pending application restart; otherwise, false. + public bool HasPendingRestart { get; private set; } + /// /// Gets or sets the logger. /// @@ -132,11 +147,11 @@ namespace MediaBrowser.Common.Implementations /// Gets the kernel. /// /// The kernel. - protected IKernel Kernel { get; private set; } protected ITaskManager TaskManager { get; private set; } protected ISecurityManager SecurityManager { get; private set; } protected IPackageManager PackageManager { get; private set; } protected IHttpClient HttpClient { get; private set; } + protected INetworkManager NetworkManager { get; private set; } protected IConfigurationManager ConfigurationManager { get; private set; } @@ -168,15 +183,11 @@ namespace MediaBrowser.Common.Implementations Logger.Info("Version {0} initializing", ApplicationVersion); - Kernel = GetKernel(); - await RegisterResources().ConfigureAwait(false); FindParts(); Task.Run(() => ConfigureAutoRunAtStartup()); - - Kernel.Init(); } /// @@ -191,7 +202,6 @@ namespace MediaBrowser.Common.Implementations /// The name of the log file prefix. protected abstract string LogFilePrefixName { get; } - protected abstract IKernel GetKernel(); protected abstract IConfigurationManager GetConfigurationManager(); /// @@ -199,10 +209,6 @@ namespace MediaBrowser.Common.Implementations /// protected virtual void FindParts() { - Resolve().Init(GetExports(false)); - Resolve().AddWebSocketListeners(GetExports(false)); - - Resolve().Start(); Resolve().AddTasks(GetExports(false)); Plugins = GetExports(); @@ -239,11 +245,7 @@ namespace MediaBrowser.Common.Implementations RegisterSingleInstance(ApplicationPaths); - var networkManager = new NetworkManager(); - - var serverManager = new ServerManager.ServerManager(this, Kernel, networkManager, JsonSerializer, Logger, ConfigurationManager); - - TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, Logger, serverManager); + TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, Logger); RegisterSingleInstance(JsonSerializer); RegisterSingleInstance(XmlSerializer); @@ -251,25 +253,22 @@ namespace MediaBrowser.Common.Implementations RegisterSingleInstance(LogManager); RegisterSingleInstance(Logger); - RegisterSingleInstance(Kernel); - RegisterSingleInstance(TaskManager); - RegisterSingleInstance(() => new AlchemyServer(Logger)); RegisterSingleInstance(ProtobufSerializer); - RegisterSingleInstance(new UdpServer(Logger), false); HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, Logger); RegisterSingleInstance(HttpClient); - RegisterSingleInstance(networkManager); - RegisterSingleInstance(serverManager); + NetworkManager = new NetworkManager(); - SecurityManager = new PluginSecurityManager(Kernel, HttpClient, JsonSerializer, ApplicationPaths); + RegisterSingleInstance(NetworkManager); + + SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths); RegisterSingleInstance(SecurityManager); - PackageManager = new PackageManager(SecurityManager, networkManager, HttpClient, ApplicationPaths, JsonSerializer, Logger); + PackageManager = new PackageManager(SecurityManager, NetworkManager, HttpClient, ApplicationPaths, JsonSerializer, Logger); RegisterSingleInstance(PackageManager); }); @@ -450,6 +449,34 @@ namespace MediaBrowser.Common.Implementations Plugins = list; } + /// + /// Performs the pending restart. + /// + /// Task. + public void PerformPendingRestart() + { + if (HasPendingRestart) + { + Logger.Info("Restarting the application"); + + Restart(); + } + else + { + Logger.Info("PerformPendingRestart - not needed"); + } + } + + /// + /// Notifies that the kernel that a change has been made that requires a restart + /// + public void NotifyPendingRestart() + { + HasPendingRestart = true; + + EventHelper.QueueEventIfNotNull(HasPendingRestartChanged, this, EventArgs.Empty, Logger); + } + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -488,7 +515,20 @@ namespace MediaBrowser.Common.Implementations public abstract Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress); - public abstract Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress progress); + /// + /// Updates the application. + /// + /// The package that contains the update + /// The cancellation token. + /// The progress. + /// Task. + public async Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress progress) + { + var pkgManager = Resolve(); + await pkgManager.InstallPackage(progress, package, cancellationToken).ConfigureAwait(false); + + EventHelper.QueueEventIfNotNull(ApplicationUpdated, this, new GenericEventArgs { Argument = package.version }, Logger); + } public abstract void Shutdown(); } diff --git a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs index d169336162..56e699b358 100644 --- a/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs +++ b/MediaBrowser.Common.Implementations/BaseApplicationPaths.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Kernel; using System; using System.Configuration; using System.IO; diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs index d2af8fa205..d653a5c9b8 100644 --- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs +++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; -using MediaBrowser.Common.Kernel; using MediaBrowser.Common.Net; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Net; @@ -9,7 +8,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net; using System.Net.Cache; using System.Net.Http; using System.Text; diff --git a/MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs b/MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs deleted file mode 100644 index 382183b580..0000000000 --- a/MediaBrowser.Common.Implementations/HttpServer/BaseRestService.cs +++ /dev/null @@ -1,458 +0,0 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using ServiceStack.Common; -using ServiceStack.Common.Web; -using ServiceStack.ServiceHost; -using ServiceStack.ServiceInterface; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using MimeTypes = MediaBrowser.Common.Net.MimeTypes; - -namespace MediaBrowser.Common.Implementations.HttpServer -{ - /// - /// Class BaseRestService - /// - public class BaseRestService : Service, IRestfulService - { - /// - /// Gets or sets the logger. - /// - /// The logger. - public ILogger Logger { get; set; } - - /// - /// Gets a value indicating whether this instance is range request. - /// - /// true if this instance is range request; otherwise, false. - protected bool IsRangeRequest - { - get - { - return Request.Headers.AllKeys.Contains("Range"); - } - } - - /// - /// To the optimized result. - /// - /// - /// The result. - /// System.Object. - /// result - protected object ToOptimizedResult(T result) - where T : class - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - Response.AddHeader("Vary", "Accept-Encoding"); - - return RequestContext.ToOptimizedResult(result); - } - - /// - /// To the optimized result using cache. - /// - /// - /// The cache key. - /// The last date modified. - /// Duration of the cache. - /// The factory fn. - /// System.Object. - /// cacheKey - protected object ToOptimizedResultUsingCache(Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func factoryFn) - where T : class - { - if (cacheKey == Guid.Empty) - { - throw new ArgumentNullException("cacheKey"); - } - if (factoryFn == null) - { - throw new ArgumentNullException("factoryFn"); - } - - var key = cacheKey.ToString("N"); - - var result = PreProcessCachedResult(cacheKey, key, lastDateModified, cacheDuration, string.Empty); - - if (result != null) - { - // Return null so that service stack won't do anything - return null; - } - - return ToOptimizedResult(factoryFn()); - } - - /// - /// To the cached result. - /// - /// - /// The cache key. - /// The last date modified. - /// Duration of the cache. - /// The factory fn. - /// Type of the content. - /// System.Object. - /// cacheKey - protected object ToCachedResult(Guid cacheKey, DateTime lastDateModified, TimeSpan? cacheDuration, Func factoryFn, string contentType) - where T : class - { - if (cacheKey == Guid.Empty) - { - throw new ArgumentNullException("cacheKey"); - } - if (factoryFn == null) - { - throw new ArgumentNullException("factoryFn"); - } - - var key = cacheKey.ToString("N"); - - var result = PreProcessCachedResult(cacheKey, key, lastDateModified, cacheDuration, contentType); - - if (result != null) - { - // Return null so that service stack won't do anything - return null; - } - - return factoryFn(); - } - - /// - /// To the static file result. - /// - /// The path. - /// System.Object. - /// path - protected object ToStaticFileResult(string path) - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentNullException("path"); - } - - var dateModified = File.GetLastWriteTimeUtc(path); - - var cacheKey = path + dateModified.Ticks; - - return ToStaticResult(cacheKey.GetMD5(), dateModified, null, MimeTypes.GetMimeType(path), () => Task.FromResult(GetFileStream(path))); - } - - /// - /// Gets the file stream. - /// - /// The path. - /// Stream. - private Stream GetFileStream(string path) - { - return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, FileOptions.Asynchronous); - } - - /// - /// To the static result. - /// - /// The cache key. - /// The last date modified. - /// Duration of the cache. - /// Type of the content. - /// The factory fn. - /// System.Object. - /// cacheKey - protected object ToStaticResult(Guid cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType, Func> factoryFn) - { - if (cacheKey == Guid.Empty) - { - throw new ArgumentNullException("cacheKey"); - } - if (factoryFn == null) - { - throw new ArgumentNullException("factoryFn"); - } - - var key = cacheKey.ToString("N"); - - var result = PreProcessCachedResult(cacheKey, key, lastDateModified, cacheDuration, contentType); - - if (result != null) - { - // Return null so that service stack won't do anything - return null; - } - - var compress = ShouldCompressResponse(contentType); - - if (compress) - { - Response.AddHeader("Vary", "Accept-Encoding"); - } - - return ToStaticResult(contentType, factoryFn, compress).Result; - } - - /// - /// Shoulds the compress response. - /// - /// Type of the content. - /// true if XXXX, false otherwise - private bool ShouldCompressResponse(string contentType) - { - // It will take some work to support compression with byte range requests - if (IsRangeRequest) - { - return false; - } - - // Don't compress media - if (contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - // Don't compress images - if (contentType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - if (contentType.StartsWith("font/", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - if (contentType.StartsWith("application/", StringComparison.OrdinalIgnoreCase)) - { - return false; - } - - return true; - } - - /// - /// To the static result. - /// - /// Type of the content. - /// The factory fn. - /// if set to true [compress]. - /// System.Object. - private async Task ToStaticResult(string contentType, Func> factoryFn, bool compress) - { - if (!compress || string.IsNullOrEmpty(RequestContext.CompressionType)) - { - Response.ContentType = contentType; - - var stream = await factoryFn().ConfigureAwait(false); - - return new StreamWriter(stream); - } - - string content; - - using (var stream = await factoryFn().ConfigureAwait(false)) - { - using (var reader = new StreamReader(stream)) - { - content = await reader.ReadToEndAsync().ConfigureAwait(false); - } - } - - var contents = content.Compress(RequestContext.CompressionType); - - return new CompressedResult(contents, RequestContext.CompressionType, contentType); - } - - /// - /// Pres the process optimized result. - /// - /// The cache key. - /// The cache key string. - /// The last date modified. - /// Duration of the cache. - /// Type of the content. - /// System.Object. - private object PreProcessCachedResult(Guid cacheKey, string cacheKeyString, DateTime? lastDateModified, TimeSpan? cacheDuration, string contentType) - { - Response.AddHeader("ETag", cacheKeyString); - - if (IsNotModified(cacheKey, lastDateModified, cacheDuration)) - { - AddAgeHeader(lastDateModified); - AddExpiresHeader(cacheKeyString, cacheDuration); - //ctx.Response.SendChunked = false; - - if (!string.IsNullOrEmpty(contentType)) - { - Response.ContentType = contentType; - } - - Response.StatusCode = 304; - - return new byte[]{}; - } - - SetCachingHeaders(cacheKeyString, lastDateModified, cacheDuration); - - return null; - } - - /// - /// Determines whether [is not modified] [the specified cache key]. - /// - /// The cache key. - /// The last date modified. - /// Duration of the cache. - /// true if [is not modified] [the specified cache key]; otherwise, false. - private bool IsNotModified(Guid? cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration) - { - var isNotModified = true; - - if (Request.Headers.AllKeys.Contains("If-Modified-Since")) - { - DateTime ifModifiedSince; - - if (DateTime.TryParse(Request.Headers["If-Modified-Since"], out ifModifiedSince)) - { - isNotModified = IsNotModified(ifModifiedSince.ToUniversalTime(), cacheDuration, lastDateModified); - } - } - - // Validate If-None-Match - if (isNotModified && (cacheKey.HasValue || !string.IsNullOrEmpty(Request.Headers["If-None-Match"]))) - { - Guid ifNoneMatch; - - if (Guid.TryParse(Request.Headers["If-None-Match"] ?? string.Empty, out ifNoneMatch)) - { - if (cacheKey.HasValue && cacheKey.Value == ifNoneMatch) - { - return true; - } - } - } - - return false; - } - - /// - /// Determines whether [is not modified] [the specified if modified since]. - /// - /// If modified since. - /// Duration of the cache. - /// The date modified. - /// true if [is not modified] [the specified if modified since]; otherwise, false. - private bool IsNotModified(DateTime ifModifiedSince, TimeSpan? cacheDuration, DateTime? dateModified) - { - if (dateModified.HasValue) - { - var lastModified = NormalizeDateForComparison(dateModified.Value); - ifModifiedSince = NormalizeDateForComparison(ifModifiedSince); - - return lastModified <= ifModifiedSince; - } - - if (cacheDuration.HasValue) - { - var cacheExpirationDate = ifModifiedSince.Add(cacheDuration.Value); - - if (DateTime.UtcNow < cacheExpirationDate) - { - return true; - } - } - - return false; - } - - - /// - /// When the browser sends the IfModifiedDate, it's precision is limited to seconds, so this will account for that - /// - /// The date. - /// DateTime. - private DateTime NormalizeDateForComparison(DateTime date) - { - return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind); - } - - /// - /// Sets the caching headers. - /// - /// The cache key. - /// The last date modified. - /// Duration of the cache. - private void SetCachingHeaders(string cacheKey, DateTime? lastDateModified, TimeSpan? cacheDuration) - { - // Don't specify both last modified and Etag, unless caching unconditionally. They are redundant - // https://developers.google.com/speed/docs/best-practices/caching#LeverageBrowserCaching - if (lastDateModified.HasValue && (string.IsNullOrEmpty(cacheKey) || cacheDuration.HasValue)) - { - AddAgeHeader(lastDateModified); - Response.AddHeader("LastModified", lastDateModified.Value.ToString("r")); - } - - if (cacheDuration.HasValue) - { - Response.AddHeader("Cache-Control", "public, max-age=" + Convert.ToInt32(cacheDuration.Value.TotalSeconds)); - } - else if (!string.IsNullOrEmpty(cacheKey)) - { - Response.AddHeader("Cache-Control", "public"); - } - else - { - Response.AddHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - Response.AddHeader("pragma", "no-cache, no-store, must-revalidate"); - } - - AddExpiresHeader(cacheKey, cacheDuration); - } - - /// - /// Adds the expires header. - /// - /// The cache key. - /// Duration of the cache. - private void AddExpiresHeader(string cacheKey, TimeSpan? cacheDuration) - { - if (cacheDuration.HasValue) - { - Response.AddHeader("Expires", DateTime.UtcNow.Add(cacheDuration.Value).ToString("r")); - } - else if (string.IsNullOrEmpty(cacheKey)) - { - Response.AddHeader("Expires", "-1"); - } - } - - /// - /// Adds the age header. - /// - /// The last date modified. - private void AddAgeHeader(DateTime? lastDateModified) - { - if (lastDateModified.HasValue) - { - Response.AddHeader("Age", Convert.ToInt64((DateTime.UtcNow - lastDateModified.Value).TotalSeconds).ToString(CultureInfo.InvariantCulture)); - } - } - - /// - /// Gets the routes. - /// - /// IEnumerable{RouteInfo}. - public IEnumerable GetRoutes() - { - return new RouteInfo[] {}; - } - } -} diff --git a/MediaBrowser.Common.Implementations/HttpServer/HttpServer.cs b/MediaBrowser.Common.Implementations/HttpServer/HttpServer.cs deleted file mode 100644 index 785ca56c66..0000000000 --- a/MediaBrowser.Common.Implementations/HttpServer/HttpServer.cs +++ /dev/null @@ -1,570 +0,0 @@ -using Funq; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Kernel; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; -using ServiceStack.Api.Swagger; -using ServiceStack.Common.Web; -using ServiceStack.Configuration; -using ServiceStack.Logging.NLogger; -using ServiceStack.ServiceHost; -using ServiceStack.ServiceInterface.Cors; -using ServiceStack.Text; -using ServiceStack.WebHost.Endpoints; -using ServiceStack.WebHost.Endpoints.Extensions; -using ServiceStack.WebHost.Endpoints.Support; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.WebSockets; -using System.Reactive.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Implementations.HttpServer -{ - /// - /// Class HttpServer - /// - public class HttpServer : HttpListenerBase, IHttpServer - { - /// - /// The logger - /// - private readonly ILogger _logger; - - /// - /// Gets the URL prefix. - /// - /// The URL prefix. - public string UrlPrefix { get; private set; } - - /// - /// The _rest services - /// - private readonly List _restServices = new List(); - - /// - /// Gets or sets the application host. - /// - /// The application host. - private IApplicationHost ApplicationHost { get; set; } - - /// - /// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it - /// - /// The HTTP listener. - private IDisposable HttpListener { get; set; } - - /// - /// Gets or sets the protobuf serializer. - /// - /// The protobuf serializer. - private IProtobufSerializer ProtobufSerializer { get; set; } - - /// - /// Occurs when [web socket connected]. - /// - public event EventHandler WebSocketConnected; - - /// - /// Gets the default redirect path. - /// - /// The default redirect path. - private string DefaultRedirectPath { get; set; } - - /// - /// Gets or sets the name of the server. - /// - /// The name of the server. - private string ServerName { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The application host. - /// The protobuf serializer. - /// The logger. - /// Name of the server. - /// The default redirectpath. - /// urlPrefix - public HttpServer(IApplicationHost applicationHost, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath) - : base() - { - if (protobufSerializer == null) - { - throw new ArgumentNullException("protobufSerializer"); - } - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - if (applicationHost == null) - { - throw new ArgumentNullException("applicationHost"); - } - if (string.IsNullOrEmpty(serverName)) - { - throw new ArgumentNullException("serverName"); - } - if (string.IsNullOrEmpty(defaultRedirectpath)) - { - throw new ArgumentNullException("defaultRedirectpath"); - } - - ServerName = serverName; - DefaultRedirectPath = defaultRedirectpath; - ProtobufSerializer = protobufSerializer; - _logger = logger; - ApplicationHost = applicationHost; - - EndpointHostConfig.Instance.ServiceStackHandlerFactoryPath = null; - EndpointHostConfig.Instance.MetadataRedirectPath = "metadata"; - } - - /// - /// Configures the specified container. - /// - /// The container. - public override void Configure(Container container) - { - JsConfig.DateHandler = JsonDateHandler.ISO8601; - JsConfig.ExcludeTypeInfo = true; - JsConfig.IncludeNullValues = false; - - SetConfig(new EndpointHostConfig - { - DefaultRedirectPath = DefaultRedirectPath, - - // Tell SS to bubble exceptions up to here - WriteErrorsToResponse = false, - - DebugMode = true - }); - - container.Adapter = new ContainerAdapter(ApplicationHost); - - Plugins.Add(new SwaggerFeature()); - Plugins.Add(new CorsFeature()); - - ServiceStack.Logging.LogManager.LogFactory = new NLogFactory(); - } - - /// - /// Starts the Web Service - /// - /// A Uri that acts as the base that the server is listening on. - /// Format should be: http://127.0.0.1:8080/ or http://127.0.0.1:8080/somevirtual/ - /// Note: the trailing slash is required! For more info see the - /// HttpListener.Prefixes property on MSDN. - public override void Start(string urlBase) - { - if (string.IsNullOrEmpty(urlBase)) - { - throw new ArgumentNullException("urlBase"); - } - - // *** Already running - just leave it in place - if (IsStarted) - { - return; - } - - if (Listener == null) - { - Listener = new HttpListener(); - } - - EndpointHost.Config.ServiceStackHandlerFactoryPath = HttpListenerRequestWrapper.GetHandlerPathIfAny(urlBase); - - UrlPrefix = urlBase; - - Listener.Prefixes.Add(urlBase); - - IsStarted = true; - Listener.Start(); - - HttpListener = CreateObservableStream().Subscribe(ProcessHttpRequestAsync); - } - - /// - /// Creates the observable stream. - /// - /// IObservable{HttpListenerContext}. - private IObservable CreateObservableStream() - { - return Observable.Create(obs => - Observable.FromAsync(() => Listener.GetContextAsync()) - .Subscribe(obs)) - .Repeat() - .Retry() - .Publish() - .RefCount(); - } - - /// - /// Processes incoming http requests by routing them to the appropiate handler - /// - /// The CTX. - private async void ProcessHttpRequestAsync(HttpListenerContext context) - { - LogHttpRequest(context); - - if (context.Request.IsWebSocketRequest) - { - await ProcessWebSocketRequest(context).ConfigureAwait(false); - return; - } - - - Task.Run(() => - { - RaiseReceiveWebRequest(context); - - try - { - ProcessRequest(context); - } - catch (InvalidOperationException ex) - { - HandleException(context.Response, ex, 422); - - throw; - } - catch (ResourceNotFoundException ex) - { - HandleException(context.Response, ex, 404); - - throw; - } - catch (FileNotFoundException ex) - { - HandleException(context.Response, ex, 404); - - throw; - } - catch (DirectoryNotFoundException ex) - { - HandleException(context.Response, ex, 404); - - throw; - } - catch (UnauthorizedAccessException ex) - { - HandleException(context.Response, ex, 401); - - throw; - } - catch (ArgumentException ex) - { - HandleException(context.Response, ex, 400); - - throw; - } - catch (Exception ex) - { - HandleException(context.Response, ex, 500); - - throw; - } - }); - } - - /// - /// Processes the web socket request. - /// - /// The CTX. - /// Task. - private async Task ProcessWebSocketRequest(HttpListenerContext ctx) - { - try - { - var webSocketContext = await ctx.AcceptWebSocketAsync(null).ConfigureAwait(false); - - if (WebSocketConnected != null) - { - WebSocketConnected(this, new WebSocketConnectEventArgs { WebSocket = new NativeWebSocket(webSocketContext.WebSocket, _logger), Endpoint = ctx.Request.RemoteEndPoint.ToString() }); - } - } - catch (Exception ex) - { - _logger.ErrorException("AcceptWebSocketAsync error", ex); - - ctx.Response.StatusCode = 500; - ctx.Response.Close(); - } - } - - /// - /// Logs the HTTP request. - /// - /// The CTX. - private void LogHttpRequest(HttpListenerContext ctx) - { - var log = new StringBuilder(); - - log.AppendLine("Url: " + ctx.Request.Url); - log.AppendLine("Headers: " + string.Join(",", ctx.Request.Headers.AllKeys.Select(k => k + "=" + ctx.Request.Headers[k]))); - - var type = ctx.Request.IsWebSocketRequest ? "Web Socket" : "HTTP " + ctx.Request.HttpMethod; - - if (EnableHttpRequestLogging) - { - _logger.LogMultiline(type + " request received from " + ctx.Request.RemoteEndPoint, LogSeverity.Debug, log); - } - } - - /// - /// Appends the error message. - /// - /// The response. - /// The ex. - /// The status code. - private void HandleException(HttpListenerResponse response, Exception ex, int statusCode) - { - _logger.ErrorException("Error processing request", ex); - - response.StatusCode = statusCode; - - response.Headers.Add("Status", statusCode.ToString(new CultureInfo("en-US"))); - - response.Headers.Remove("Age"); - response.Headers.Remove("Expires"); - response.Headers.Remove("Cache-Control"); - response.Headers.Remove("Etag"); - response.Headers.Remove("Last-Modified"); - - response.ContentType = "text/plain"; - - if (!string.IsNullOrEmpty(ex.Message)) - { - response.AddHeader("X-Application-Error-Code", ex.Message); - } - - // This could fail, but try to add the stack trace as the body content - try - { - var sb = new StringBuilder(); - sb.AppendLine("{"); - sb.AppendLine("\"ResponseStatus\":{"); - sb.AppendFormat(" \"ErrorCode\":{0},\n", ex.GetType().Name.EncodeJson()); - sb.AppendFormat(" \"Message\":{0},\n", ex.Message.EncodeJson()); - sb.AppendFormat(" \"StackTrace\":{0}\n", ex.StackTrace.EncodeJson()); - sb.AppendLine("}"); - sb.AppendLine("}"); - - response.StatusCode = 500; - response.ContentType = ContentType.Json; - var sbBytes = sb.ToString().ToUtf8Bytes(); - response.OutputStream.Write(sbBytes, 0, sbBytes.Length); - response.Close(); - } - catch (Exception errorEx) - { - _logger.ErrorException("Error processing failed request", errorEx); - } - } - - - /// - /// Overridable method that can be used to implement a custom hnandler - /// - /// The context. - /// Cannot execute handler: + handler + at PathInfo: + httpReq.PathInfo - protected override void ProcessRequest(HttpListenerContext context) - { - if (string.IsNullOrEmpty(context.Request.RawUrl)) return; - - var operationName = context.Request.GetOperationName(); - - var httpReq = new HttpListenerRequestWrapper(operationName, context.Request); - var httpRes = new HttpListenerResponseWrapper(context.Response); - var handler = ServiceStackHttpHandlerFactory.GetHandler(httpReq); - - var url = context.Request.Url.ToString(); - var endPoint = context.Request.RemoteEndPoint; - - var serviceStackHandler = handler as IServiceStackHttpHandler; - - if (serviceStackHandler != null) - { - var restHandler = serviceStackHandler as RestHandler; - if (restHandler != null) - { - httpReq.OperationName = operationName = restHandler.RestPath.RequestType.Name; - } - serviceStackHandler.ProcessRequest(httpReq, httpRes, operationName); - LogResponse(context, url, endPoint); - httpRes.Close(); - return; - } - - throw new NotImplementedException("Cannot execute handler: " + handler + " at PathInfo: " + httpReq.PathInfo); - } - - /// - /// Logs the response. - /// - /// The CTX. - private void LogResponse(HttpListenerContext ctx, string url, IPEndPoint endPoint) - { - if (!EnableHttpRequestLogging) - { - return; - } - - var statusode = ctx.Response.StatusCode; - - var log = new StringBuilder(); - - log.AppendLine(string.Format("Url: {0}", url)); - - log.AppendLine("Headers: " + string.Join(",", ctx.Response.Headers.AllKeys.Select(k => k + "=" + ctx.Response.Headers[k]))); - - var msg = "Http Response Sent (" + statusode + ") to " + endPoint; - - _logger.LogMultiline(msg, LogSeverity.Debug, log); - } - - /// - /// Creates the service manager. - /// - /// The assemblies with services. - /// ServiceManager. - protected override ServiceManager CreateServiceManager(params Assembly[] assembliesWithServices) - { - var types = _restServices.Select(r => r.GetType()).ToArray(); - - return new ServiceManager(new Container(), new ServiceController(() => types)); - } - - /// - /// Shut down the Web Service - /// - public override void Stop() - { - if (HttpListener != null) - { - HttpListener.Dispose(); - HttpListener = null; - } - - if (Listener != null) - { - Listener.Prefixes.Remove(UrlPrefix); - } - - base.Stop(); - } - - /// - /// The _supports native web socket - /// - private bool? _supportsNativeWebSocket; - - /// - /// Gets a value indicating whether [supports web sockets]. - /// - /// true if [supports web sockets]; otherwise, false. - public bool SupportsWebSockets - { - get - { - if (!_supportsNativeWebSocket.HasValue) - { - try - { - new ClientWebSocket(); - - _supportsNativeWebSocket = true; - } - catch (PlatformNotSupportedException) - { - _supportsNativeWebSocket = false; - } - } - - return _supportsNativeWebSocket.Value; - } - } - - - /// - /// Gets or sets a value indicating whether [enable HTTP request logging]. - /// - /// true if [enable HTTP request logging]; otherwise, false. - public bool EnableHttpRequestLogging { get; set; } - - /// - /// Adds the rest handlers. - /// - /// The services. - public void Init(IEnumerable services) - { - _restServices.AddRange(services); - - EndpointHost.ConfigureHost(this, ServerName, CreateServiceManager()); - ContentTypeFilters.Register(ContentType.ProtoBuf, (reqCtx, res, stream) => ProtobufSerializer.SerializeToStream(res, stream), (type, stream) => ProtobufSerializer.DeserializeFromStream(stream, type)); - - foreach (var route in services.SelectMany(i => i.GetRoutes())) - { - Routes.Add(route.RequestType, route.Path, route.Verbs); - } - - Init(); - } - } - - /// - /// Class ContainerAdapter - /// - class ContainerAdapter : IContainerAdapter, IRelease - { - /// - /// The _app host - /// - private readonly IApplicationHost _appHost; - - /// - /// Initializes a new instance of the class. - /// - /// The app host. - public ContainerAdapter(IApplicationHost appHost) - { - _appHost = appHost; - } - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T Resolve() - { - return _appHost.Resolve(); - } - - /// - /// Tries the resolve. - /// - /// - /// ``0. - public T TryResolve() - { - return _appHost.TryResolve(); - } - - /// - /// Releases the specified instance. - /// - /// The instance. - public void Release(object instance) - { - // Leave this empty so SS doesn't try to dispose our objects - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/HttpServer/NativeWebSocket.cs b/MediaBrowser.Common.Implementations/HttpServer/NativeWebSocket.cs deleted file mode 100644 index 97bab96f85..0000000000 --- a/MediaBrowser.Common.Implementations/HttpServer/NativeWebSocket.cs +++ /dev/null @@ -1,165 +0,0 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using System; -using System.Net.WebSockets; -using System.Threading; -using System.Threading.Tasks; -using WebSocketMessageType = MediaBrowser.Common.Net.WebSocketMessageType; -using WebSocketState = MediaBrowser.Common.Net.WebSocketState; - -namespace MediaBrowser.Common.Implementations.HttpServer -{ - /// - /// Class NativeWebSocket - /// - public class NativeWebSocket : IWebSocket - { - /// - /// The logger - /// - private readonly ILogger _logger; - - /// - /// Gets or sets the web socket. - /// - /// The web socket. - private System.Net.WebSockets.WebSocket WebSocket { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The socket. - /// The logger. - /// socket - public NativeWebSocket(System.Net.WebSockets.WebSocket socket, ILogger logger) - { - if (socket == null) - { - throw new ArgumentNullException("socket"); - } - - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - - _logger = logger; - WebSocket = socket; - - Receive(); - } - - /// - /// Gets or sets the state. - /// - /// The state. - public WebSocketState State - { - get - { - WebSocketState commonState; - - if (!Enum.TryParse(WebSocket.State.ToString(), true, out commonState)) - { - _logger.Warn("Unrecognized WebSocketState: {0}", WebSocket.State.ToString()); - } - - return commonState; - } - } - - /// - /// Receives this instance. - /// - private async void Receive() - { - while (true) - { - byte[] bytes; - - try - { - bytes = await ReceiveBytesAsync(CancellationToken.None).ConfigureAwait(false); - } - catch (WebSocketException ex) - { - _logger.ErrorException("Error reveiving web socket message", ex); - - break; - } - - if (OnReceiveDelegate != null) - { - OnReceiveDelegate(bytes); - } - } - } - - /// - /// Receives the async. - /// - /// The cancellation token. - /// Task{WebSocketMessageInfo}. - /// Connection closed - private async Task ReceiveBytesAsync(CancellationToken cancellationToken) - { - var bytes = new byte[4096]; - var buffer = new ArraySegment(bytes); - - var result = await WebSocket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false); - - if (result.CloseStatus.HasValue) - { - throw new WebSocketException("Connection closed"); - } - - return buffer.Array; - } - - /// - /// Sends the async. - /// - /// The bytes. - /// The type. - /// if set to true [end of message]. - /// The cancellation token. - /// Task. - public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken) - { - System.Net.WebSockets.WebSocketMessageType nativeType; - - if (!Enum.TryParse(type.ToString(), true, out nativeType)) - { - _logger.Warn("Unrecognized WebSocketMessageType: {0}", type.ToString()); - } - - return WebSocket.SendAsync(new ArraySegment(bytes), nativeType, true, cancellationToken); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - WebSocket.Dispose(); - } - } - - /// - /// Gets or sets the receive action. - /// - /// The receive action. - public Action OnReceiveDelegate { get; set; } - } -} diff --git a/MediaBrowser.Common.Implementations/HttpServer/ServerFactory.cs b/MediaBrowser.Common.Implementations/HttpServer/ServerFactory.cs deleted file mode 100644 index 743bd60c4c..0000000000 --- a/MediaBrowser.Common.Implementations/HttpServer/ServerFactory.cs +++ /dev/null @@ -1,27 +0,0 @@ -using MediaBrowser.Common.Kernel; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; - -namespace MediaBrowser.Common.Implementations.HttpServer -{ - /// - /// Class ServerFactory - /// - public static class ServerFactory - { - /// - /// Creates the server. - /// - /// The application host. - /// The protobuf serializer. - /// The logger. - /// Name of the server. - /// The default redirectpath. - /// IHttpServer. - public static IHttpServer CreateServer(IApplicationHost applicationHost, IProtobufSerializer protobufSerializer, ILogger logger, string serverName, string defaultRedirectpath) - { - return new HttpServer(applicationHost, protobufSerializer, logger, serverName, defaultRedirectpath); - } - } -} diff --git a/MediaBrowser.Common.Implementations/HttpServer/StreamWriter.cs b/MediaBrowser.Common.Implementations/HttpServer/StreamWriter.cs deleted file mode 100644 index c92bfe0b96..0000000000 --- a/MediaBrowser.Common.Implementations/HttpServer/StreamWriter.cs +++ /dev/null @@ -1,48 +0,0 @@ -using ServiceStack.Service; -using System.IO; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Implementations.HttpServer -{ - /// - /// Class StreamWriter - /// - public class StreamWriter : IStreamWriter - { - /// - /// Gets or sets the source stream. - /// - /// The source stream. - public Stream SourceStream { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The source. - public StreamWriter(Stream source) - { - SourceStream = source; - } - - /// - /// Writes to. - /// - /// The response stream. - public void WriteTo(Stream responseStream) - { - var task = WriteToAsync(responseStream); - - Task.WaitAll(task); - } - - /// - /// Writes to async. - /// - /// The response stream. - /// Task. - private Task WriteToAsync(Stream responseStream) - { - return SourceStream.CopyToAsync(responseStream); - } - } -} diff --git a/MediaBrowser.Common.Implementations/HttpServer/SwaggerService.cs b/MediaBrowser.Common.Implementations/HttpServer/SwaggerService.cs deleted file mode 100644 index a4808834df..0000000000 --- a/MediaBrowser.Common.Implementations/HttpServer/SwaggerService.cs +++ /dev/null @@ -1,38 +0,0 @@ -using ServiceStack.ServiceHost; -using System.Diagnostics; -using System.IO; - -namespace MediaBrowser.Common.Implementations.HttpServer -{ - /// - /// Class GetDashboardResource - /// - [Route("/swagger-ui/{ResourceName*}", "GET")] - public class GetSwaggerResource - { - /// - /// Gets or sets the name. - /// - /// The name. - public string ResourceName { get; set; } - } - - public class SwaggerService : BaseRestService - { - /// - /// Gets the specified request. - /// - /// The request. - /// System.Object. - public object Get(GetSwaggerResource request) - { - var runningDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); - - var swaggerDirectory = Path.Combine(runningDirectory, "swagger-ui"); - - var requestedFile = Path.Combine(swaggerDirectory, request.ResourceName.Replace('/', '\\')); - - return ToStaticFileResult(requestedFile); - } - } -} diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj index 2f3ebdf190..f73dac71fd 100644 --- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj +++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj @@ -35,9 +35,6 @@ Always - - ..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll - ..\ThirdParty\PluginSecurity\Mediabrowser.PluginSecurity.dll @@ -47,41 +44,6 @@ ..\packages\protobuf-net.2.0.0.621\lib\net40\protobuf-net.dll - - False - ..\packages\ServiceStack.3.9.38\lib\net35\ServiceStack.dll - - - False - ..\packages\ServiceStack.Api.Swagger.3.9.38\lib\net35\ServiceStack.Api.Swagger.dll - - - False - ..\packages\ServiceStack.Common.3.9.38\lib\net35\ServiceStack.Common.dll - - - False - ..\packages\ServiceStack.Common.3.9.38\lib\net35\ServiceStack.Interfaces.dll - - - ..\packages\ServiceStack.Logging.NLog.1.0.6.0\lib\net35\ServiceStack.Logging.NLog.dll - - - False - ..\packages\ServiceStack.OrmLite.SqlServer.3.9.39\lib\ServiceStack.OrmLite.dll - - - False - ..\packages\ServiceStack.OrmLite.SqlServer.3.9.39\lib\ServiceStack.OrmLite.SqlServer.dll - - - False - ..\packages\ServiceStack.Redis.3.9.38\lib\net35\ServiceStack.Redis.dll - - - False - ..\packages\ServiceStack.3.9.38\lib\net35\ServiceStack.ServiceInterface.dll - False ..\packages\ServiceStack.Text.3.9.38\lib\net35\ServiceStack.Text.dll @@ -97,16 +59,6 @@ - - ..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll - - - ..\packages\Rx-Interfaces.2.1.30214.0\lib\Net45\System.Reactive.Interfaces.dll - - - ..\packages\Rx-Linq.2.1.30214.0\lib\Net45\System.Reactive.Linq.dll - - @@ -117,12 +69,6 @@ - - - - - - @@ -140,12 +86,8 @@ - - - + - - @@ -159,52 +101,6 @@ - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - diff --git a/MediaBrowser.Common.Implementations/README.txt b/MediaBrowser.Common.Implementations/README.txt deleted file mode 100644 index e8ce34205d..0000000000 --- a/MediaBrowser.Common.Implementations/README.txt +++ /dev/null @@ -1,41 +0,0 @@ -ServiceStack services should be available under '/api' path. If it's a brand new MVC project -install NuGet Package: ServiceStack.Host.Mvc. The package prepares ServiceStack default services. Make sure -that you added ignore for MVC routes: - - routes.IgnoreRoute("api/{*pathInfo}"); - -If it's MVC4 project, then don't forget to disable WebAPI: - - //WebApiConfig.Register(GlobalConfiguration.Configuration); - -Enable Swagger plugin in AppHost.cs with: - - public override void Configure(Container container) - { - ... - - Plugins.Add(new SwaggerFeature()); - // uncomment CORS feature if it's has to be available from external sites - //Plugins.Add(new CorsFeature()); - ... - - } - -Compile it. Now you can access swagger UI with: - -http://localost:port/swagger-ui/index.html - -or - -http://yoursite/swagger-ui/index.html - - -For more info about ServiceStack please visit: http://www.servicestack.net - -Feel free to ask questions about ServiceStack on: -http://stackoverflow.com/ - -or on the mailing Group at: -http://groups.google.com/group/servicestack - -Enjoy! \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index d5adf32658..f57d48f07a 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -1,6 +1,5 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Kernel; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; @@ -49,12 +48,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// The task manager. private ITaskManager TaskManager { get; set; } - /// - /// Gets or sets the server manager. - /// - /// The server manager. - private IServerManager ServerManager { get; set; } - /// /// Initializes a new instance of the class. /// @@ -64,7 +57,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// The json serializer. /// The logger. /// The server manager. - public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger, IServerManager serverManager) + public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, IJsonSerializer jsonSerializer, ILogger logger) { if (scheduledTask == null) { @@ -86,17 +79,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks { throw new ArgumentNullException("logger"); } - if (serverManager == null) - { - throw new ArgumentNullException("serverManager"); - } ScheduledTask = scheduledTask; ApplicationPaths = applicationPaths; TaskManager = taskManager; JsonSerializer = jsonSerializer; Logger = logger; - ServerManager = serverManager; ReloadTriggerEvents(true); } @@ -331,6 +319,8 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks Logger.Info("Executing {0}", Name); + ((TaskManager)TaskManager).OnTaskExecuting(ScheduledTask); + var progress = new Progress(); progress.ProgressChanged += progress_ProgressChanged; @@ -338,8 +328,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks TaskCompletionStatus status; CurrentExecutionStartTime = DateTime.UtcNow; - ServerManager.SendWebSocketMessage("ScheduledTaskBeginExecute", Name); - try { await ExecuteTask(CurrentCancellationTokenSource.Token, progress).ConfigureAwait(false); @@ -517,8 +505,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// The start time. /// The end time. /// The status. - /// if set to true [send notification]. - private void OnTaskCompleted(DateTime startTime, DateTime endTime, TaskCompletionStatus status, bool sendNotification = true) + private void OnTaskCompleted(DateTime startTime, DateTime endTime, TaskCompletionStatus status) { var elapsedTime = endTime - startTime; @@ -537,10 +524,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks LastExecutionResult = result; - if (sendNotification) - { - ServerManager.SendWebSocketMessage("ScheduledTaskEndExecute", result); - } + ((TaskManager) TaskManager).OnTaskCompleted(ScheduledTask, result); } /// @@ -564,7 +548,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks if (State == TaskState.Running) { - OnTaskCompleted(CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted, false); + OnTaskCompleted(CurrentExecutionStartTime, DateTime.UtcNow, TaskCompletionStatus.Aborted); } if (CurrentCancellationTokenSource != null) diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs index 946887303c..61e1f63299 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/TaskManager.cs @@ -1,5 +1,6 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Kernel; +using System.Threading.Tasks; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Events; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; @@ -15,6 +16,9 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// public class TaskManager : ITaskManager { + public event EventHandler TaskExecuting; + public event EventHandler> TaskCompleted; + /// /// Gets the list of Scheduled Tasks /// @@ -44,26 +48,18 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks /// The logger. private ILogger Logger { get; set; } - /// - /// Gets or sets the server manager. - /// - /// The server manager. - private IServerManager ServerManager { get; set; } - /// /// Initializes a new instance of the class. /// /// The application paths. /// The json serializer. /// The logger. - /// The server manager. /// kernel - public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger, IServerManager serverManager) + public TaskManager(IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, ILogger logger) { ApplicationPaths = applicationPaths; JsonSerializer = jsonSerializer; Logger = logger; - ServerManager = serverManager; ScheduledTasks = new IScheduledTaskWorker[] { }; } @@ -75,7 +71,9 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks public void CancelIfRunningAndQueue() where T : IScheduledTask { - ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)).CancelIfRunning(); + var task = ScheduledTasks.First(t => t.ScheduledTask.GetType() == typeof(T)); + ((ScheduledTaskWorker)task).CancelIfRunning(); + QueueScheduledTask(); } @@ -101,7 +99,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks QueueScheduledTask(scheduledTask); } - + /// /// Queues the scheduled task. /// @@ -115,7 +113,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks // If it's idle just execute immediately if (task.State == TaskState.Idle) { - task.Execute(); + ((ScheduledTaskWorker)task).Execute(); return; } @@ -131,31 +129,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks } } - /// - /// Called when [task completed]. - /// - /// The task. - public void OnTaskCompleted(IScheduledTask task) - { - // Execute queued tasks - lock (_taskQueue) - { - var copy = _taskQueue.ToList(); - - foreach (var type in copy) - { - var scheduledTask = ScheduledTasks.First(t => t.GetType() == type); - - if (scheduledTask.State == TaskState.Idle) - { - scheduledTask.Execute(); - - _taskQueue.Remove(type); - } - } - } - } - /// /// Adds the tasks. /// @@ -164,7 +137,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks { var myTasks = ScheduledTasks.ToList(); - myTasks.AddRange(tasks.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger, ServerManager))); + myTasks.AddRange(tasks.Select(t => new ScheduledTaskWorker(t, ApplicationPaths, this, JsonSerializer, Logger))); ScheduledTasks = myTasks.ToArray(); } @@ -189,5 +162,25 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks task.Dispose(); } } + + public void Cancel(IScheduledTaskWorker task) + { + ((ScheduledTaskWorker)task).Cancel(); + } + + public Task Execute(IScheduledTaskWorker task) + { + return ((ScheduledTaskWorker)task).Execute(); + } + + internal void OnTaskExecuting(IScheduledTask task) + { + EventHelper.QueueEventIfNotNull(TaskExecuting, task, EventArgs.Empty, Logger); + } + + internal void OnTaskCompleted(IScheduledTask task, TaskResult result) + { + EventHelper.QueueEventIfNotNull(TaskExecuting, task, new GenericEventArgs { Argument = result }, Logger); + } } } diff --git a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs index 7da1b9c5a5..e74693f938 100644 --- a/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs +++ b/MediaBrowser.Common.Implementations/ScheduledTasks/Tasks/SystemUpdateTask.cs @@ -1,5 +1,4 @@ using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Kernel; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Model.Logging; using System; @@ -30,25 +29,17 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks /// The logger. private ILogger Logger { get; set; } - /// - /// Gets or sets the kernel. - /// - /// The kernel. - private IKernel Kernel { get; set; } - /// /// Initializes a new instance of the class. /// /// The app host. /// The configuration manager. /// The logger. - /// The kernel. - public SystemUpdateTask(IApplicationHost appHost, IConfigurationManager configurationManager, ILogger logger, IKernel kernel) + public SystemUpdateTask(IApplicationHost appHost, IConfigurationManager configurationManager, ILogger logger) { _appHost = appHost; ConfigurationManager = configurationManager; Logger = logger; - Kernel = kernel; } /// @@ -110,8 +101,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks.Tasks // Release the event handler innerProgress.ProgressChanged -= innerProgressHandler; - - Kernel.OnApplicationUpdated(updateInfo.AvailableVersion); } else { diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs index d1a4940ef4..0404ee7fe8 100644 --- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs +++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs @@ -3,7 +3,6 @@ using MediaBrowser.Common.Security; using MediaBrowser.Model.Serialization; using Mediabrowser.Model.Entities; using Mediabrowser.PluginSecurity; -using MediaBrowser.Common.Kernel; using MediaBrowser.Common.Net; using System; using System.Threading; @@ -44,29 +43,19 @@ namespace MediaBrowser.Common.Implementations.Security private IHttpClient _httpClient; private IJsonSerializer _jsonSerializer; - - /// - /// The _kernel - /// - private readonly IKernel _kernel; + private IApplicationHost _appHost; /// /// Initializes a new instance of the class. /// - /// The kernel. - public PluginSecurityManager(IKernel kernel, IHttpClient httpClient, IJsonSerializer jsonSerializer, IApplicationPaths appPaths) + public PluginSecurityManager(IApplicationHost appHost, IHttpClient httpClient, IJsonSerializer jsonSerializer, IApplicationPaths appPaths) { - if (kernel == null) - { - throw new ArgumentNullException("kernel"); - } - if (httpClient == null) { throw new ArgumentNullException("httpClient"); } - - _kernel = kernel; + + _appHost = appHost; _httpClient = httpClient; _jsonSerializer = jsonSerializer; MBRegistration.Init(appPaths); @@ -98,7 +87,7 @@ namespace MediaBrowser.Common.Implementations.Security // Clear this so it will re-evaluate ResetSupporterInfo(); // And we'll need to restart to re-evaluate the status of plug-ins - _kernel.NotifyPendingRestart(); + _appHost.NotifyPendingRestart(); } } @@ -115,7 +104,7 @@ namespace MediaBrowser.Common.Implementations.Security { MBRegistration.LegacyKey = value; // And we'll need to restart to re-evaluate the status of plug-ins - _kernel.NotifyPendingRestart(); + _appHost.NotifyPendingRestart(); } } diff --git a/MediaBrowser.Common.Implementations/ServerManager/RegisterServer.bat b/MediaBrowser.Common.Implementations/ServerManager/RegisterServer.bat deleted file mode 100644 index d762dfaf76..0000000000 --- a/MediaBrowser.Common.Implementations/ServerManager/RegisterServer.bat +++ /dev/null @@ -1,28 +0,0 @@ -rem %1 = http server port -rem %2 = http server url -rem %3 = udp server port -rem %4 = tcp server port (web socket) - -if [%1]==[] GOTO DONE - -netsh advfirewall firewall delete rule name="Port %1" protocol=TCP localport=%1 -netsh advfirewall firewall add rule name="Port %1" dir=in action=allow protocol=TCP localport=%1 - -if [%2]==[] GOTO DONE - -netsh http del urlacl url="%2" user="NT AUTHORITY\Authenticated Users" -netsh http add urlacl url="%2" user="NT AUTHORITY\Authenticated Users" - -if [%3]==[] GOTO DONE - -netsh advfirewall firewall delete rule name="Port %3" protocol=UDP localport=%3 -netsh advfirewall firewall add rule name="Port %3" dir=in action=allow protocol=UDP localport=%3 - -if [%4]==[] GOTO DONE - -netsh advfirewall firewall delete rule name="Port %4" protocol=TCP localport=%4 -netsh advfirewall firewall add rule name="Port %4" dir=in action=allow protocol=TCP localport=%4 - - -:DONE -Exit \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/ServerManager/ServerManager.cs b/MediaBrowser.Common.Implementations/ServerManager/ServerManager.cs deleted file mode 100644 index d18971f72e..0000000000 --- a/MediaBrowser.Common.Implementations/ServerManager/ServerManager.cs +++ /dev/null @@ -1,542 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Kernel; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Implementations.ServerManager -{ - /// - /// Manages the Http Server, Udp Server and WebSocket connections - /// - public class ServerManager : IServerManager, IDisposable - { - /// - /// This is the udp server used for server discovery by clients - /// - /// The UDP server. - private IUdpServer UdpServer { get; set; } - - /// - /// Both the Ui and server will have a built-in HttpServer. - /// People will inevitably want remote control apps so it's needed in the Ui too. - /// - /// The HTTP server. - private IHttpServer HttpServer { get; set; } - - /// - /// Gets or sets the json serializer. - /// - /// The json serializer. - private readonly IJsonSerializer _jsonSerializer; - - /// - /// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it - /// - /// The HTTP listener. - private IDisposable HttpListener { get; set; } - - /// - /// The web socket connections - /// - private readonly List _webSocketConnections = new List(); - - /// - /// Gets or sets the external web socket server. - /// - /// The external web socket server. - private IWebSocketServer ExternalWebSocketServer { get; set; } - - /// - /// The _logger - /// - private readonly ILogger _logger; - - /// - /// The _network manager - /// - private readonly INetworkManager _networkManager; - - /// - /// The _application host - /// - private readonly IApplicationHost _applicationHost; - - /// - /// The _kernel - /// - private readonly IKernel _kernel; - - /// - /// Gets or sets the configuration manager. - /// - /// The configuration manager. - private IConfigurationManager ConfigurationManager { get; set; } - - /// - /// Gets a value indicating whether [supports web socket]. - /// - /// true if [supports web socket]; otherwise, false. - public bool SupportsNativeWebSocket - { - get { return HttpServer != null && HttpServer.SupportsWebSockets; } - } - - /// - /// Gets the web socket port number. - /// - /// The web socket port number. - public int WebSocketPortNumber - { - get { return SupportsNativeWebSocket ? ConfigurationManager.CommonConfiguration.HttpServerPortNumber : ConfigurationManager.CommonConfiguration.LegacyWebSocketPortNumber; } - } - - /// - /// Gets the web socket listeners. - /// - /// The web socket listeners. - private readonly List _webSocketListeners = new List(); - - /// - /// Initializes a new instance of the class. - /// - /// The application host. - /// The kernel. - /// The network manager. - /// The json serializer. - /// The logger. - /// The configuration manager. - /// applicationHost - public ServerManager(IApplicationHost applicationHost, IKernel kernel, INetworkManager networkManager, IJsonSerializer jsonSerializer, ILogger logger, IConfigurationManager configurationManager) - { - if (applicationHost == null) - { - throw new ArgumentNullException("applicationHost"); - } - if (kernel == null) - { - throw new ArgumentNullException("kernel"); - } - if (networkManager == null) - { - throw new ArgumentNullException("networkManager"); - } - if (jsonSerializer == null) - { - throw new ArgumentNullException("jsonSerializer"); - } - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - - _logger = logger; - _jsonSerializer = jsonSerializer; - _kernel = kernel; - _applicationHost = applicationHost; - _networkManager = networkManager; - ConfigurationManager = configurationManager; - } - - /// - /// Starts this instance. - /// - public void Start() - { - if (_applicationHost.IsFirstRun) - { - RegisterServerWithAdministratorAccess(); - } - - ReloadUdpServer(); - ReloadHttpServer(); - - if (!SupportsNativeWebSocket) - { - ReloadExternalWebSocketServer(); - } - - ConfigurationManager.ConfigurationUpdated += _kernel_ConfigurationUpdated; - } - - /// - /// Starts the external web socket server. - /// - private void ReloadExternalWebSocketServer() - { - // Avoid windows firewall prompts in the ui - if (_kernel.KernelContext != KernelContext.Server) - { - return; - } - - DisposeExternalWebSocketServer(); - - ExternalWebSocketServer = _applicationHost.Resolve(); - - ExternalWebSocketServer.Start(ConfigurationManager.CommonConfiguration.LegacyWebSocketPortNumber); - ExternalWebSocketServer.WebSocketConnected += HttpServer_WebSocketConnected; - } - - /// - /// Restarts the Http Server, or starts it if not currently running - /// - /// if set to true [register server on failure]. - private void ReloadHttpServer(bool registerServerOnFailure = true) - { - // Only reload if the port has changed, so that we don't disconnect any active users - if (HttpServer != null && HttpServer.UrlPrefix.Equals(_kernel.HttpServerUrlPrefix, StringComparison.OrdinalIgnoreCase)) - { - return; - } - - DisposeHttpServer(); - - _logger.Info("Loading Http Server"); - - try - { - HttpServer = _applicationHost.Resolve(); - HttpServer.EnableHttpRequestLogging = ConfigurationManager.CommonConfiguration.EnableHttpLevelLogging; - HttpServer.Start(_kernel.HttpServerUrlPrefix); - } - catch (HttpListenerException ex) - { - _logger.ErrorException("Error starting Http Server", ex); - - if (registerServerOnFailure) - { - RegisterServerWithAdministratorAccess(); - - // Don't get stuck in a loop - ReloadHttpServer(false); - - return; - } - - throw; - } - - HttpServer.WebSocketConnected += HttpServer_WebSocketConnected; - } - - /// - /// Handles the WebSocketConnected event of the HttpServer control. - /// - /// The source of the event. - /// The instance containing the event data. - void HttpServer_WebSocketConnected(object sender, WebSocketConnectEventArgs e) - { - var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger) { OnReceive = ProcessWebSocketMessageReceived }; - - _webSocketConnections.Add(connection); - } - - /// - /// Processes the web socket message received. - /// - /// The result. - private async void ProcessWebSocketMessageReceived(WebSocketMessageInfo result) - { - var tasks = _webSocketListeners.Select(i => Task.Run(async () => - { - try - { - await i.ProcessMessage(result).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("{0} failed processing WebSocket message {1}", ex, i.GetType().Name, result.MessageType); - } - })); - - await Task.WhenAll(tasks).ConfigureAwait(false); - } - - /// - /// Starts or re-starts the udp server - /// - private void ReloadUdpServer() - { - // For now, there's no reason to keep reloading this over and over - if (UdpServer != null) - { - return; - } - - // Avoid windows firewall prompts in the ui - if (_kernel.KernelContext != KernelContext.Server) - { - return; - } - - DisposeUdpServer(); - - try - { - // The port number can't be in configuration because we don't want it to ever change - UdpServer = _applicationHost.Resolve(); - UdpServer.Start(_kernel.UdpServerPortNumber); - } - catch (SocketException ex) - { - _logger.ErrorException("Failed to start UDP Server", ex); - return; - } - - UdpServer.MessageReceived += UdpServer_MessageReceived; - } - - /// - /// Handles the MessageReceived event of the UdpServer control. - /// - /// The source of the event. - /// The instance containing the event data. - async void UdpServer_MessageReceived(object sender, UdpMessageReceivedEventArgs e) - { - var expectedMessage = String.Format("who is MediaBrowser{0}?", _kernel.KernelContext); - var expectedMessageBytes = Encoding.UTF8.GetBytes(expectedMessage); - - if (expectedMessageBytes.SequenceEqual(e.Bytes)) - { - _logger.Info("Received UDP server request from " + e.RemoteEndPoint); - - // Send a response back with our ip address and port - var response = String.Format("MediaBrowser{0}|{1}:{2}", _kernel.KernelContext, _networkManager.GetLocalIpAddress(), _kernel.UdpServerPortNumber); - - await UdpServer.SendAsync(Encoding.UTF8.GetBytes(response), e.RemoteEndPoint); - } - } - - /// - /// Sends a message to all clients currently connected via a web socket - /// - /// - /// Type of the message. - /// The data. - /// Task. - public void SendWebSocketMessage(string messageType, T data) - { - SendWebSocketMessage(messageType, () => data); - } - - /// - /// Sends a message to all clients currently connected via a web socket - /// - /// - /// Type of the message. - /// The function that generates the data to send, if there are any connected clients - public void SendWebSocketMessage(string messageType, Func dataFunction) - { - Task.Run(async () => await SendWebSocketMessageAsync(messageType, dataFunction, CancellationToken.None).ConfigureAwait(false)); - } - - /// - /// Sends a message to all clients currently connected via a web socket - /// - /// - /// Type of the message. - /// The function that generates the data to send, if there are any connected clients - /// The cancellation token. - /// Task. - /// messageType - public async Task SendWebSocketMessageAsync(string messageType, Func dataFunction, CancellationToken cancellationToken) - { - if (string.IsNullOrEmpty(messageType)) - { - throw new ArgumentNullException("messageType"); - } - - if (dataFunction == null) - { - throw new ArgumentNullException("dataFunction"); - } - - if (cancellationToken == null) - { - throw new ArgumentNullException("cancellationToken"); - } - - cancellationToken.ThrowIfCancellationRequested(); - - var connections = _webSocketConnections.Where(s => s.State == WebSocketState.Open).ToList(); - - if (connections.Count > 0) - { - _logger.Info("Sending web socket message {0}", messageType); - - var message = new WebSocketMessage { MessageType = messageType, Data = dataFunction() }; - var bytes = _jsonSerializer.SerializeToBytes(message); - - var tasks = connections.Select(s => Task.Run(() => - { - try - { - s.SendAsync(bytes, cancellationToken); - } - catch (OperationCanceledException) - { - throw; - } - catch (Exception ex) - { - _logger.ErrorException("Error sending web socket message {0} to {1}", ex, messageType, s.RemoteEndPoint); - } - })); - - await Task.WhenAll(tasks).ConfigureAwait(false); - } - } - - /// - /// Disposes the udp server - /// - private void DisposeUdpServer() - { - if (UdpServer != null) - { - UdpServer.MessageReceived -= UdpServer_MessageReceived; - UdpServer.Dispose(); - } - } - - /// - /// Disposes the current HttpServer - /// - private void DisposeHttpServer() - { - foreach (var socket in _webSocketConnections) - { - // Dispose the connection - socket.Dispose(); - } - - _webSocketConnections.Clear(); - - if (HttpServer != null) - { - HttpServer.WebSocketConnected -= HttpServer_WebSocketConnected; - HttpServer.Dispose(); - } - - if (HttpListener != null) - { - HttpListener.Dispose(); - } - - DisposeExternalWebSocketServer(); - } - - /// - /// Registers the server with administrator access. - /// - private void RegisterServerWithAdministratorAccess() - { - // Create a temp file path to extract the bat file to - var tmpFile = Path.Combine(ConfigurationManager.CommonApplicationPaths.TempDirectory, Guid.NewGuid() + ".bat"); - - // Extract the bat file - using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.Common.Implementations.ServerManager.RegisterServer.bat")) - { - using (var fileStream = File.Create(tmpFile)) - { - stream.CopyTo(fileStream); - } - } - - var startInfo = new ProcessStartInfo - { - FileName = tmpFile, - - Arguments = string.Format("{0} {1} {2} {3}", ConfigurationManager.CommonConfiguration.HttpServerPortNumber, - _kernel.HttpServerUrlPrefix, - _kernel.UdpServerPortNumber, - ConfigurationManager.CommonConfiguration.LegacyWebSocketPortNumber), - - CreateNoWindow = true, - WindowStyle = ProcessWindowStyle.Hidden, - Verb = "runas", - ErrorDialog = false - }; - - using (var process = Process.Start(startInfo)) - { - process.WaitForExit(); - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - DisposeUdpServer(); - DisposeHttpServer(); - } - } - - /// - /// Disposes the external web socket server. - /// - private void DisposeExternalWebSocketServer() - { - if (ExternalWebSocketServer != null) - { - ExternalWebSocketServer.Dispose(); - } - } - - /// - /// Handles the ConfigurationUpdated event of the _kernel control. - /// - /// The source of the event. - /// The instance containing the event data. - /// - void _kernel_ConfigurationUpdated(object sender, EventArgs e) - { - HttpServer.EnableHttpRequestLogging = ConfigurationManager.CommonConfiguration.EnableHttpLevelLogging; - - if (!string.Equals(HttpServer.UrlPrefix, _kernel.HttpServerUrlPrefix, StringComparison.OrdinalIgnoreCase)) - { - ReloadHttpServer(); - } - - if (!SupportsNativeWebSocket && ExternalWebSocketServer != null && ExternalWebSocketServer.Port != ConfigurationManager.CommonConfiguration.LegacyWebSocketPortNumber) - { - ReloadExternalWebSocketServer(); - } - } - - /// - /// Adds the web socket listeners. - /// - /// The listeners. - public void AddWebSocketListeners(IEnumerable listeners) - { - _webSocketListeners.AddRange(listeners); - } - } -} diff --git a/MediaBrowser.Common.Implementations/ServerManager/WebSocketConnection.cs b/MediaBrowser.Common.Implementations/ServerManager/WebSocketConnection.cs deleted file mode 100644 index f826b02cc1..0000000000 --- a/MediaBrowser.Common.Implementations/ServerManager/WebSocketConnection.cs +++ /dev/null @@ -1,225 +0,0 @@ -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; -using System; -using System.IO; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Implementations.ServerManager -{ - /// - /// Class WebSocketConnection - /// - public class WebSocketConnection : IWebSocketConnection - { - /// - /// The _socket - /// - private readonly IWebSocket _socket; - - /// - /// The _remote end point - /// - public string RemoteEndPoint { get; private set; } - - /// - /// The _cancellation token source - /// - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - - /// - /// The _send semaphore - /// - private readonly SemaphoreSlim _sendSemaphore = new SemaphoreSlim(1,1); - - /// - /// The logger - /// - private readonly ILogger _logger; - - /// - /// The _json serializer - /// - private readonly IJsonSerializer _jsonSerializer; - - /// - /// Gets or sets the receive action. - /// - /// The receive action. - public Action OnReceive { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The socket. - /// The remote end point. - /// The json serializer. - /// The logger. - /// socket - public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger) - { - if (socket == null) - { - throw new ArgumentNullException("socket"); - } - if (string.IsNullOrEmpty(remoteEndPoint)) - { - throw new ArgumentNullException("remoteEndPoint"); - } - if (jsonSerializer == null) - { - throw new ArgumentNullException("jsonSerializer"); - } - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - - _jsonSerializer = jsonSerializer; - _socket = socket; - _socket.OnReceiveDelegate = OnReceiveInternal; - RemoteEndPoint = remoteEndPoint; - _logger = logger; - } - - /// - /// Called when [receive]. - /// - /// The bytes. - private void OnReceiveInternal(byte[] bytes) - { - if (OnReceive == null) - { - return; - } - try - { - WebSocketMessageInfo info; - - using (var memoryStream = new MemoryStream(bytes)) - { - info = (WebSocketMessageInfo)_jsonSerializer.DeserializeFromStream(memoryStream, typeof(WebSocketMessageInfo)); - } - - info.Connection = this; - - OnReceive(info); - } - catch (Exception ex) - { - _logger.ErrorException("Error processing web socket message", ex); - } - } - - /// - /// Sends a message asynchronously. - /// - /// - /// The message. - /// The cancellation token. - /// Task. - /// message - public Task SendAsync(WebSocketMessage message, CancellationToken cancellationToken) - { - if (message == null) - { - throw new ArgumentNullException("message"); - } - - var bytes = _jsonSerializer.SerializeToBytes(message); - - return SendAsync(bytes, cancellationToken); - } - - /// - /// Sends a message asynchronously. - /// - /// The buffer. - /// The cancellation token. - /// Task. - public Task SendAsync(byte[] buffer, CancellationToken cancellationToken) - { - return SendAsync(buffer, WebSocketMessageType.Text, cancellationToken); - } - - /// - /// Sends a message asynchronously. - /// - /// The buffer. - /// The type. - /// The cancellation token. - /// Task. - /// buffer - public async Task SendAsync(byte[] buffer, WebSocketMessageType type, CancellationToken cancellationToken) - { - if (buffer == null) - { - throw new ArgumentNullException("buffer"); - } - - if (cancellationToken == null) - { - throw new ArgumentNullException("cancellationToken"); - } - - cancellationToken.ThrowIfCancellationRequested(); - - // Per msdn docs, attempting to send simultaneous messages will result in one failing. - // This should help us workaround that and ensure all messages get sent - await _sendSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - - try - { - await _socket.SendAsync(buffer, type, true, cancellationToken); - } - catch (OperationCanceledException) - { - _logger.Info("WebSocket message to {0} was cancelled", RemoteEndPoint); - - throw; - } - catch (Exception ex) - { - _logger.ErrorException("Error sending WebSocket message {0}", ex, RemoteEndPoint); - - throw; - } - finally - { - _sendSemaphore.Release(); - } - } - - /// - /// Gets the state. - /// - /// The state. - public WebSocketState State - { - get { return _socket.State; } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - _cancellationTokenSource.Dispose(); - _socket.Dispose(); - } - } - } -} diff --git a/MediaBrowser.Common.Implementations/Udp/UdpServer.cs b/MediaBrowser.Common.Implementations/Udp/UdpServer.cs deleted file mode 100644 index e0435ab3cb..0000000000 --- a/MediaBrowser.Common.Implementations/Udp/UdpServer.cs +++ /dev/null @@ -1,203 +0,0 @@ -using MediaBrowser.Common.Implementations.NetworkManagement; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using System; -using System.Net; -using System.Net.Sockets; -using System.Reactive.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Implementations.Udp -{ - /// - /// Provides a Udp Server - /// - public class UdpServer : IUdpServer - { - /// - /// Occurs when [message received]. - /// - public event EventHandler MessageReceived; - - /// - /// Gets or sets the logger. - /// - /// The logger. - private ILogger Logger { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The logger. - public UdpServer(ILogger logger) - { - Logger = logger; - } - - /// - /// Raises the event. - /// - /// The instance containing the event data. - protected virtual void OnMessageReceived(UdpMessageReceivedEventArgs e) - { - EventHandler handler = MessageReceived; - if (handler != null) handler(this, e); - } - - /// - /// The _udp client - /// - private UdpClient _udpClient; - - /// - /// Starts the specified port. - /// - /// The port. - public void Start(int port) - { - _udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, port)); - - _udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - - CreateObservable().Subscribe(OnMessageReceived); - } - - /// - /// Creates the observable. - /// - /// IObservable{UdpReceiveResult}. - private IObservable CreateObservable() - { - return Observable.Create(obs => - Observable.FromAsync(() => - { - try - { - return _udpClient.ReceiveAsync(); - } - catch (ObjectDisposedException) - { - return Task.FromResult(new UdpReceiveResult(new byte[]{}, new IPEndPoint(IPAddress.Any, 0))); - } - catch (Exception ex) - { - Logger.ErrorException("Error receiving udp message", ex); - return Task.FromResult(new UdpReceiveResult(new byte[] { }, new IPEndPoint(IPAddress.Any, 0))); - } - }) - - .Subscribe(obs)) - .Repeat() - .Retry() - .Publish() - .RefCount(); - } - - /// - /// Called when [message received]. - /// - /// The message. - private void OnMessageReceived(UdpReceiveResult message) - { - if (message.RemoteEndPoint.Port == 0) - { - return; - } - var bytes = message.Buffer; - - OnMessageReceived(new UdpMessageReceivedEventArgs - { - Bytes = bytes, - RemoteEndPoint = message.RemoteEndPoint.ToString() - }); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Stops this instance. - /// - public void Stop() - { - _udpClient.Close(); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - Stop(); - } - } - - /// - /// Sends the async. - /// - /// The data. - /// The ip address. - /// The port. - /// Task{System.Int32}. - /// data - public Task SendAsync(string data, string ipAddress, int port) - { - return SendAsync(Encoding.UTF8.GetBytes(data), ipAddress, port); - } - - /// - /// Sends the async. - /// - /// The bytes. - /// The ip address. - /// The port. - /// Task{System.Int32}. - /// bytes - public Task SendAsync(byte[] bytes, string ipAddress, int port) - { - if (bytes == null) - { - throw new ArgumentNullException("bytes"); - } - - if (string.IsNullOrEmpty(ipAddress)) - { - throw new ArgumentNullException("ipAddress"); - } - - return _udpClient.SendAsync(bytes, bytes.Length, ipAddress, port); - } - - /// - /// Sends the async. - /// - /// The bytes. - /// The remote end point. - /// Task. - public Task SendAsync(byte[] bytes, string remoteEndPoint) - { - if (bytes == null) - { - throw new ArgumentNullException("bytes"); - } - - if (string.IsNullOrEmpty(remoteEndPoint)) - { - throw new ArgumentNullException("remoteEndPoint"); - } - - return _udpClient.SendAsync(bytes, bytes.Length, new NetworkManager().Parse(remoteEndPoint)); - } - } - -} diff --git a/MediaBrowser.Common.Implementations/Updates/ApplicationUpdater.cs b/MediaBrowser.Common.Implementations/Updates/ApplicationUpdater.cs new file mode 100644 index 0000000000..3b06f2006d --- /dev/null +++ b/MediaBrowser.Common.Implementations/Updates/ApplicationUpdater.cs @@ -0,0 +1,32 @@ +using MediaBrowser.Common.Configuration; +using System.Diagnostics; +using System.IO; + +namespace MediaBrowser.Common.Implementations.Updates +{ + public enum MBApplication + { + MBServer, + MBTheater + } + + /// + /// Update the specified application using the specified archive + /// + public class ApplicationUpdater + { + private const string UpdaterExe = "Mediabrowser.Installer.exe"; + public void UpdateApplication(MBApplication app, IApplicationPaths appPaths, string archive) + { + // Use our installer passing it the specific archive + // We need to copy to a temp directory and execute it there + var source = Path.Combine(appPaths.ProgramSystemPath, UpdaterExe); + var target = Path.Combine(Path.GetTempPath(), UpdaterExe); + var product = app == MBApplication.MBTheater ? "mbt" : "server"; + File.Copy(source, target, true); + Process.Start(UpdaterExe, string.Format("product={0} archive=\"{1}\" caller={2}", product, archive, Process.GetCurrentProcess().Id)); + + // That's it. The installer will do the work once we exit + } + } +} diff --git a/MediaBrowser.Common.Implementations/WebSocket/AlchemyServer.cs b/MediaBrowser.Common.Implementations/WebSocket/AlchemyServer.cs deleted file mode 100644 index 236bd27b7b..0000000000 --- a/MediaBrowser.Common.Implementations/WebSocket/AlchemyServer.cs +++ /dev/null @@ -1,113 +0,0 @@ -using Alchemy; -using Alchemy.Classes; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using System; -using System.Net; - -namespace MediaBrowser.Common.Implementations.WebSocket -{ - /// - /// Class AlchemyServer - /// - public class AlchemyServer : IWebSocketServer - { - /// - /// Occurs when [web socket connected]. - /// - public event EventHandler WebSocketConnected; - - /// - /// Gets or sets the web socket server. - /// - /// The web socket server. - private WebSocketServer WebSocketServer { get; set; } - - /// - /// The _logger - /// - private readonly ILogger _logger; - - /// - /// Initializes a new instance of the class. - /// - /// The logger. - /// logger - public AlchemyServer(ILogger logger) - { - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - _logger = logger; - } - - /// - /// Gets the port. - /// - /// The port. - public int Port { get; private set; } - - /// - /// Starts the specified port number. - /// - /// The port number. - public void Start(int portNumber) - { - WebSocketServer = new WebSocketServer(portNumber, IPAddress.Any) - { - OnConnected = OnAlchemyWebSocketClientConnected, - TimeOut = TimeSpan.FromMinutes(60) - }; - - WebSocketServer.Start(); - - Port = portNumber; - - _logger.Info("Alchemy Web Socket Server started"); - } - - /// - /// Called when [alchemy web socket client connected]. - /// - /// The context. - private void OnAlchemyWebSocketClientConnected(UserContext context) - { - if (WebSocketConnected != null) - { - var socket = new AlchemyWebSocket(context, _logger); - - WebSocketConnected(this, new WebSocketConnectEventArgs - { - WebSocket = socket, - Endpoint = context.ClientAddress.ToString() - }); - } - } - - /// - /// Stops this instance. - /// - public void Stop() - { - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - - } - } -} diff --git a/MediaBrowser.Common.Implementations/WebSocket/AlchemyWebSocket.cs b/MediaBrowser.Common.Implementations/WebSocket/AlchemyWebSocket.cs deleted file mode 100644 index 1ecc38f2c2..0000000000 --- a/MediaBrowser.Common.Implementations/WebSocket/AlchemyWebSocket.cs +++ /dev/null @@ -1,132 +0,0 @@ -using Alchemy.Classes; -using MediaBrowser.Common.Net; -using MediaBrowser.Model.Logging; -using System; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Implementations.WebSocket -{ - /// - /// Class AlchemyWebSocket - /// - public class AlchemyWebSocket : IWebSocket - { - /// - /// The logger - /// - private readonly ILogger _logger; - - /// - /// Gets or sets the web socket. - /// - /// The web socket. - private UserContext UserContext { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The context. - /// The logger. - /// context - public AlchemyWebSocket(UserContext context, ILogger logger) - { - if (context == null) - { - throw new ArgumentNullException("context"); - } - - _logger = logger; - UserContext = context; - - context.SetOnDisconnect(OnDisconnected); - context.SetOnReceive(OnReceive); - - _logger.Info("Client connected from {0}", context.ClientAddress); - } - - /// - /// The _disconnected - /// - private bool _disconnected = false; - /// - /// Gets or sets the state. - /// - /// The state. - public WebSocketState State - { - get { return _disconnected ? WebSocketState.Closed : WebSocketState.Open; } - } - - /// - /// Called when [disconnected]. - /// - /// The context. - private void OnDisconnected(UserContext context) - { - _disconnected = true; - } - - /// - /// Called when [receive]. - /// - /// The context. - private void OnReceive(UserContext context) - { - if (OnReceiveDelegate != null) - { - var json = context.DataFrame.ToString(); - - if (!string.IsNullOrWhiteSpace(json)) - { - try - { - var bytes = Encoding.UTF8.GetBytes(json); - - OnReceiveDelegate(bytes); - } - catch (Exception ex) - { - _logger.ErrorException("Error processing web socket message", ex); - } - } - } - } - - /// - /// Sends the async. - /// - /// The bytes. - /// The type. - /// if set to true [end of message]. - /// The cancellation token. - /// Task. - public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken) - { - return Task.Run(() => UserContext.Send(bytes)); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - } - - /// - /// Gets or sets the receive action. - /// - /// The receive action. - public Action OnReceiveDelegate { get; set; } - } -} diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config index 2d6276a8e2..0c064f3e45 100644 --- a/MediaBrowser.Common.Implementations/packages.config +++ b/MediaBrowser.Common.Implementations/packages.config @@ -1,17 +1,7 @@  - - - - - - - - - - \ No newline at end of file diff --git a/MediaBrowser.Common.Implementations/swagger-ui/css/screen.css b/MediaBrowser.Common.Implementations/swagger-ui/css/screen.css deleted file mode 100644 index 07773f9efe..0000000000 --- a/MediaBrowser.Common.Implementations/swagger-ui/css/screen.css +++ /dev/null @@ -1,959 +0,0 @@ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; } - -body { - line-height: 1; } - -ol, ul { - list-style: none; } - -table { - border-collapse: collapse; - border-spacing: 0; } - -caption, th, td { - text-align: left; - font-weight: normal; - vertical-align: middle; } - -q, blockquote { - quotes: none; } - q:before, q:after, blockquote:before, blockquote:after { - content: ""; - content: none; } - -a img { - border: none; } - -article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary { - display: block; } - -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { - text-decoration: none; } - h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover { - text-decoration: underline; } -h1 span.divider, h2 span.divider, h3 span.divider, h4 span.divider, h5 span.divider, h6 span.divider { - color: #aaaaaa; } - -h1 { - color: #547f00; - color: black; - font-size: 1.5em; - line-height: 1.3em; - padding: 10px 0 10px 0; - font-family: "Droid Sans", sans-serif; - font-weight: bold; } - -h2 { - color: #89bf04; - color: black; - font-size: 1.3em; - padding: 10px 0 10px 0; } - h2 a { - color: black; } - h2 span.sub { - font-size: 0.7em; - color: #999999; - font-style: italic; } - h2 span.sub a { - color: #777777; } - -h3 { - color: black; - font-size: 1.1em; - padding: 10px 0 10px 0; } - -div.heading_with_menu { - float: none; - clear: both; - overflow: hidden; - display: block; } - div.heading_with_menu h1, div.heading_with_menu h2, div.heading_with_menu h3, div.heading_with_menu h4, div.heading_with_menu h5, div.heading_with_menu h6 { - display: block; - clear: none; - float: left; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - width: 60%; } - div.heading_with_menu ul { - display: block; - clear: none; - float: right; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - margin-top: 10px; } - -.body-textarea { - width: 300px; - height: 100px; -} - -p { - line-height: 1.4em; - padding: 0 0 10px 0; - color: #333333; } - -ol { - margin: 0px 0 10px 0; - padding: 0 0 0 18px; - list-style-type: decimal; } - ol li { - padding: 5px 0px; - font-size: 0.9em; - color: #333333; } - -.markdown h3 { - color: #547f00; } -.markdown h4 { - color: #666666; } -.markdown pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - background-color: #fcf6db; - border: 1px solid black; - border-color: #e5e0c6; - padding: 10px; - margin: 0 0 10px 0; } - .markdown pre code { - line-height: 1.6em; } -.markdown p code, .markdown li code { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - background-color: #f0f0f0; - color: black; - padding: 1px 3px; } -.markdown ol, .markdown ul { - font-family: "Droid Sans", sans-serif; - margin: 5px 0 10px 0; - padding: 0 0 0 18px; - list-style-type: disc; } - .markdown ol li, .markdown ul li { - padding: 3px 0px; - line-height: 1.4em; - color: #333333; } - -div.gist { - margin: 20px 0 25px 0 !important; } - -p.big, div.big p { - font-size: 1 em; - margin-bottom: 10px; } - -span.weak { - color: #666666; } -span.blank, span.empty { - color: #888888; - font-style: italic; } - -a { - color: #547f00; } - -strong { - font-family: "Droid Sans", sans-serif; - font-weight: bold; - font-weight: bold; } - -.code { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; } - -pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - background-color: #fcf6db; - border: 1px solid black; - border-color: #e5e0c6; - padding: 10px; - /* white-space: pre-line */ } - pre code { - line-height: 1.6em; } - -.required { - font-weight: bold; } - -table.fullwidth { - width: 100%; } -table thead tr th { - padding: 5px; - font-size: 0.9em; - color: #666666; - border-bottom: 1px solid #999999; } -table tbody tr.offset { - background-color: #f5f5f5; } -table tbody tr td { - padding: 6px; - font-size: 0.9em; - border-bottom: 1px solid #cccccc; - vertical-align: top; - line-height: 1.3em; } -table tbody tr:last-child td { - border-bottom: none; } -table tbody tr.offset { - background-color: #f0f0f0; } - -form.form_box { - background-color: #ebf3f9; - border: 1px solid black; - border-color: #c3d9ec; - padding: 10px; } - form.form_box label { - color: #0f6ab4 !important; } - form.form_box input[type=submit] { - display: block; - padding: 10px; } - form.form_box p { - font-size: 0.9em; - padding: 0 0 15px 0; - color: #7e7b6d; } - form.form_box p a { - color: #646257; } - form.form_box p strong { - color: black; } - form.form_box p.weak { - font-size: 0.8em; } -form.formtastic fieldset.inputs ol li p.inline-hints { - margin-left: 0; - font-style: italic; - font-size: 0.9em; - margin: 0; } -form.formtastic fieldset.inputs ol li label { - display: block; - clear: both; - width: auto; - padding: 0 0 3px 0; - color: #666666; } - form.formtastic fieldset.inputs ol li label abbr { - padding-left: 3px; - color: #888888; } -form.formtastic fieldset.inputs ol li.required label { - color: black; } -form.formtastic fieldset.inputs ol li.string input, form.formtastic fieldset.inputs ol li.url input, form.formtastic fieldset.inputs ol li.numeric input { - display: block; - padding: 4px; - width: auto; - clear: both; } - form.formtastic fieldset.inputs ol li.string input.title, form.formtastic fieldset.inputs ol li.url input.title, form.formtastic fieldset.inputs ol li.numeric input.title { - font-size: 1.3em; } -form.formtastic fieldset.inputs ol li.text textarea { - font-family: "Droid Sans", sans-serif; - height: 250px; - padding: 4px; - display: block; - clear: both; } -form.formtastic fieldset.inputs ol li.select select { - display: block; - clear: both; } -form.formtastic fieldset.inputs ol li.boolean { - float: none; - clear: both; - overflow: hidden; - display: block; } - form.formtastic fieldset.inputs ol li.boolean input { - display: block; - float: left; - clear: none; - margin: 0 5px 0 0; } - form.formtastic fieldset.inputs ol li.boolean label { - display: block; - float: left; - clear: none; - margin: 0; - padding: 0; } -form.formtastic fieldset.buttons { - margin: 0; - padding: 0; } -form.fullwidth ol li.string input, form.fullwidth ol li.url input, form.fullwidth ol li.text textarea, form.fullwidth ol li.numeric input { - width: 500px !important; } - -body { - font-family: "Droid Sans", sans-serif; } - body #content_message { - margin: 10px 15px; - font-style: italic; - color: #999999; } - body #header { - background-color: #89bf04; - padding: 14px; } - body #header a#logo { - font-size: 1.5em; - font-weight: bold; - text-decoration: none; - background: transparent url(http://swagger.wordnik.com/images/logo_small.png) no-repeat left center; - padding: 20px 0 20px 40px; - color: white; } - body #header form#api_selector { - display: block; - clear: none; - float: right; } - body #header form#api_selector .input { - display: block; - clear: none; - float: left; - margin: 0 10px 0 0; } - body #header form#api_selector .input input { - font-size: 0.9em; - padding: 3px; - margin: 0; } - body #header form#api_selector .input input#input_baseUrl { - width: 400px; } - body #header form#api_selector .input input#input_apiKey { - width: 200px; } - body #header form#api_selector .input a#explore { - display: block; - text-decoration: none; - font-weight: bold; - padding: 6px 8px; - font-size: 0.9em; - color: white; - background-color: #547f00; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -o-border-radius: 4px; - -ms-border-radius: 4px; - -khtml-border-radius: 4px; - border-radius: 4px; } - body #header form#api_selector .input a#explore:hover { - background-color: #547f00; } - body p#colophon { - margin: 0 15px 40px 15px; - padding: 10px 0; - font-size: 0.8em; - border-top: 1px solid #dddddd; - font-family: "Droid Sans", sans-serif; - color: #999999; - font-style: italic; } - body p#colophon a { - text-decoration: none; - color: #547f00; } - body ul#resources { - font-family: "Droid Sans", sans-serif; - font-size: 0.9em; } - body ul#resources li.resource { - border-bottom: 1px solid #dddddd; } - body ul#resources li.resource:last-child { - border-bottom: none; } - body ul#resources li.resource div.heading { - border: 1px solid transparent; - float: none; - clear: both; - overflow: hidden; - display: block; } - body ul#resources li.resource div.heading h2 { - color: #999999; - padding-left: 0px; - display: block; - clear: none; - float: left; - font-family: "Droid Sans", sans-serif; - font-weight: bold; } - body ul#resources li.resource div.heading h2 a { - color: #999999; } - body ul#resources li.resource div.heading h2 a:hover { - color: black; } - body ul#resources li.resource div.heading ul.options { - float: none; - clear: both; - overflow: hidden; - margin: 0; - padding: 0; - display: block; - clear: none; - float: right; - margin: 14px 10px 0 0; } - body ul#resources li.resource div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; } - body ul#resources li.resource div.heading ul.options li:first-child, body ul#resources li.resource div.heading ul.options li.first { - padding-left: 0; } - body ul#resources li.resource div.heading ul.options li:last-child, body ul#resources li.resource div.heading ul.options li.last { - padding-right: 0; - border-right: none; } - body ul#resources li.resource div.heading ul.options li { - color: #666666; - font-size: 0.9em; } - body ul#resources li.resource div.heading ul.options li a { - color: #aaaaaa; - text-decoration: none; } - body ul#resources li.resource div.heading ul.options li a:hover { - text-decoration: underline; - color: black; } - body ul#resources li.resource:hover div.heading h2 a, body ul#resources li.resource.active div.heading h2 a { - color: black; } - body ul#resources li.resource:hover div.heading ul.options li a, body ul#resources li.resource.active div.heading ul.options li a { - color: #555555; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px 0; - padding: 0 0 0 0px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 0 0; - padding: 0; - background-color: #e7f0f7; - border: 1px solid black; - border-color: #c3d9ec; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span { - margin: 0; - padding: 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #0f6ab4; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.path { - padding-left: 10px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.path a { - color: black; - text-decoration: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.path a:hover { - text-decoration: underline; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options { - float: none; - clear: both; - overflow: hidden; - margin: 0; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.first { - padding-left: 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last { - padding-right: 0; - border-right: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { - border-right-color: #c3d9ec; - color: #0f6ab4; - font-size: 0.9em; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a { - color: #0f6ab4; - text-decoration: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a.active { - text-decoration: underline; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content { - background-color: #ebf3f9; - border: 1px solid black; - border-color: #c3d9ec; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 { - color: #0f6ab4; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px 0px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header img { - display: block; - display: block; - clear: none; - float: right; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #6fa5d2; - display: inline-block; - font-size: 0.9em; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.response div.block { - background-color: #fcf6db; - border: 1px solid black; - border-color: #e5e0c6; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px 0; - padding: 0 0 0 0px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 0 0; - padding: 0; - background-color: #e7f6ec; - border: 1px solid black; - border-color: #c3e8d1; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span { - margin: 0; - padding: 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #10a54a; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.path { - padding-left: 10px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.path a { - color: black; - text-decoration: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.path a:hover { - text-decoration: underline; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options { - float: none; - clear: both; - overflow: hidden; - margin: 0; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.first { - padding-left: 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last { - padding-right: 0; - border-right: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { - border-right-color: #c3e8d1; - color: #10a54a; - font-size: 0.9em; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a { - color: #10a54a; - text-decoration: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a.active { - text-decoration: underline; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content { - background-color: #ebf7f0; - border: 1px solid black; - border-color: #c3e8d1; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 { - color: #10a54a; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px 0px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header img { - display: block; - display: block; - clear: none; - float: right; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #6fc992; - display: inline-block; - font-size: 0.9em; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.response div.block { - background-color: #fcf6db; - border: 1px solid black; - border-color: #e5e0c6; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px 0; - padding: 0 0 0 0px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 0 0; - padding: 0; - background-color: #f9f2e9; - border: 1px solid black; - border-color: #f0e0ca; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span { - margin: 0; - padding: 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #c5862b; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.path { - padding-left: 10px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.path a { - color: black; - text-decoration: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.path a:hover { - text-decoration: underline; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options { - float: none; - clear: both; - overflow: hidden; - margin: 0; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.first { - padding-left: 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last { - padding-right: 0; - border-right: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { - border-right-color: #f0e0ca; - color: #c5862b; - font-size: 0.9em; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a { - color: #c5862b; - text-decoration: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a.active { - text-decoration: underline; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content { - background-color: #faf5ee; - border: 1px solid black; - border-color: #f0e0ca; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 { - color: #c5862b; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px 0px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header img { - display: block; - display: block; - clear: none; - float: right; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #dcb67f; - display: inline-block; - font-size: 0.9em; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.response div.block { - background-color: #fcf6db; - border: 1px solid black; - border-color: #e5e0c6; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px 0; - padding: 0 0 0 0px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 0 0; - padding: 0; - background-color: #f5e8e8; - border: 1px solid black; - border-color: #e8c6c7; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span { - margin: 0; - padding: 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #a41e22; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.path { - padding-left: 10px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.path a { - color: black; - text-decoration: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.path a:hover { - text-decoration: underline; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options { - float: none; - clear: both; - overflow: hidden; - margin: 0; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.first { - padding-left: 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last { - padding-right: 0; - border-right: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { - border-right-color: #e8c6c7; - color: #a41e22; - font-size: 0.9em; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a { - color: #a41e22; - text-decoration: none; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a.active { - text-decoration: underline; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { - background-color: #f7eded; - border: 1px solid black; - border-color: #e8c6c7; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px 0; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 { - color: #a41e22; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px 0px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header img { - display: block; - display: block; - clear: none; - float: right; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #c8787a; - display: inline-block; - font-size: 0.9em; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.response div.block { - background-color: #fcf6db; - border: 1px solid black; - border-color: #e5e0c6; } - body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; } diff --git a/MediaBrowser.Common.Implementations/swagger-ui/images/pet_store_api.png b/MediaBrowser.Common.Implementations/swagger-ui/images/pet_store_api.png deleted file mode 100644 index f9f9cd4aeb..0000000000 Binary files a/MediaBrowser.Common.Implementations/swagger-ui/images/pet_store_api.png and /dev/null differ diff --git a/MediaBrowser.Common.Implementations/swagger-ui/images/wordnik_api.png b/MediaBrowser.Common.Implementations/swagger-ui/images/wordnik_api.png deleted file mode 100644 index dca4f1455a..0000000000 Binary files a/MediaBrowser.Common.Implementations/swagger-ui/images/wordnik_api.png and /dev/null differ diff --git a/MediaBrowser.Common.Implementations/swagger-ui/index.html b/MediaBrowser.Common.Implementations/swagger-ui/index.html deleted file mode 100644 index 0b2b02b10e..0000000000 --- a/MediaBrowser.Common.Implementations/swagger-ui/index.html +++ /dev/null @@ -1,88 +0,0 @@ - - - Swagger UI - - - - - - - - - - - - - - - - - - - - -
-   -
- -
- -
- - - - diff --git a/MediaBrowser.Common.Implementations/swagger-ui/lib/backbone-min.js b/MediaBrowser.Common.Implementations/swagger-ui/lib/backbone-min.js deleted file mode 100644 index c1c0d4fff2..0000000000 --- a/MediaBrowser.Common.Implementations/swagger-ui/lib/backbone-min.js +++ /dev/null @@ -1,38 +0,0 @@ -// Backbone.js 0.9.2 - -// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Backbone may be freely distributed under the MIT license. -// For all details and documentation: -// http://backbonejs.org -(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks= -{});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g= -z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent= -{};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null== -b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent: -b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)}; -a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error, -h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t(); -return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending= -{};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length|| -!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator); -this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c=b))this.iframe=i('