From 2e4db7554041ecf481d3a38656fccc309e13eb5b Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Sat, 23 Feb 2013 17:31:51 -0500 Subject: extracted http server, web socket server and udp server dependancies --- MediaBrowser.Common/Kernel/BaseKernel.cs | 4 +- MediaBrowser.Common/Kernel/IApplicationHost.cs | 16 +- MediaBrowser.Common/Kernel/TcpManager.cs | 114 +- MediaBrowser.Common/MediaBrowser.Common.csproj | 49 +- MediaBrowser.Common/Net/AlchemyWebSocket.cs | 132 -- MediaBrowser.Common/Net/HttpServer.cs | 489 -------- MediaBrowser.Common/Net/IHttpServer.cs | 44 + MediaBrowser.Common/Net/IUdpServer.cs | 43 +- MediaBrowser.Common/Net/IWebSocketServer.cs | 26 + .../Net/UdpMessageReceivedEventArgs.cs | 21 + MediaBrowser.Common/Net/UdpServer.cs | 142 --- .../Net/WebSocketConnectEventArgs.cs | 22 + MediaBrowser.Common/Net/WebSocketConnection.cs | 6 +- MediaBrowser.Common/README.txt | 41 - MediaBrowser.Common/packages.config | 7 - MediaBrowser.Common/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 MediaBrowser.Common/swagger-ui/index.html | 88 -- MediaBrowser.Common/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 - MediaBrowser.Common/swagger-ui/lib/jquery.min.js | 4 - .../swagger-ui/lib/jquery.slideto.min.js | 1 - .../swagger-ui/lib/jquery.wiggle.min.js | 8 - MediaBrowser.Common/swagger-ui/lib/swagger.js | 507 -------- .../swagger-ui/lib/underscore-min.js | 32 - MediaBrowser.Common/swagger-ui/swagger-ui.js | 1309 -------------------- MediaBrowser.Common/swagger-ui/swagger-ui.min.js | 1 - MediaBrowser.Controller/Kernel.cs | 2 +- .../MediaBrowser.Controller.csproj | 1 - .../Management/NetworkManager.cs | 112 ++ .../MediaBrowser.Networking.csproj | 86 ++ MediaBrowser.Networking/README.txt | 41 + MediaBrowser.Networking/Udp/UdpServer.cs | 167 +++ MediaBrowser.Networking/Web/HttpServer.cs | 537 ++++++++ MediaBrowser.Networking/WebSocket/AlchemyServer.cs | 105 ++ .../WebSocket/AlchemyWebSocket.cs | 133 ++ MediaBrowser.Networking/packages.config | 15 + MediaBrowser.Networking/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 MediaBrowser.Networking/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 + MediaBrowser.Networking/swagger-ui/lib/swagger.js | 507 ++++++++ .../swagger-ui/lib/underscore-min.js | 32 + MediaBrowser.Networking/swagger-ui/swagger-ui.js | 1309 ++++++++++++++++++++ .../swagger-ui/swagger-ui.min.js | 1 + MediaBrowser.ServerApplication/App.xaml.cs | 50 +- .../MediaBrowser.ServerApplication.csproj | 30 + MediaBrowser.ServerApplication/packages.config | 5 + 56 files changed, 4675 insertions(+), 4141 deletions(-) delete mode 100644 MediaBrowser.Common/Net/AlchemyWebSocket.cs delete mode 100644 MediaBrowser.Common/Net/HttpServer.cs create mode 100644 MediaBrowser.Common/Net/IHttpServer.cs create mode 100644 MediaBrowser.Common/Net/IWebSocketServer.cs create mode 100644 MediaBrowser.Common/Net/UdpMessageReceivedEventArgs.cs delete mode 100644 MediaBrowser.Common/Net/UdpServer.cs create mode 100644 MediaBrowser.Common/Net/WebSocketConnectEventArgs.cs delete mode 100644 MediaBrowser.Common/README.txt delete mode 100644 MediaBrowser.Common/swagger-ui/css/screen.css delete mode 100644 MediaBrowser.Common/swagger-ui/images/pet_store_api.png delete mode 100644 MediaBrowser.Common/swagger-ui/images/wordnik_api.png delete mode 100644 MediaBrowser.Common/swagger-ui/index.html delete mode 100644 MediaBrowser.Common/swagger-ui/lib/backbone-min.js delete mode 100644 MediaBrowser.Common/swagger-ui/lib/handlebars.runtime-1.0.0.beta.6.js delete mode 100644 MediaBrowser.Common/swagger-ui/lib/jquery.ba-bbq.min.js delete mode 100644 MediaBrowser.Common/swagger-ui/lib/jquery.min.js delete mode 100644 MediaBrowser.Common/swagger-ui/lib/jquery.slideto.min.js delete mode 100644 MediaBrowser.Common/swagger-ui/lib/jquery.wiggle.min.js delete mode 100644 MediaBrowser.Common/swagger-ui/lib/swagger.js delete mode 100644 MediaBrowser.Common/swagger-ui/lib/underscore-min.js delete mode 100644 MediaBrowser.Common/swagger-ui/swagger-ui.js delete mode 100644 MediaBrowser.Common/swagger-ui/swagger-ui.min.js create mode 100644 MediaBrowser.Networking/README.txt create mode 100644 MediaBrowser.Networking/Udp/UdpServer.cs create mode 100644 MediaBrowser.Networking/Web/HttpServer.cs create mode 100644 MediaBrowser.Networking/WebSocket/AlchemyServer.cs create mode 100644 MediaBrowser.Networking/WebSocket/AlchemyWebSocket.cs create mode 100644 MediaBrowser.Networking/packages.config create mode 100644 MediaBrowser.Networking/swagger-ui/css/screen.css create mode 100644 MediaBrowser.Networking/swagger-ui/images/pet_store_api.png create mode 100644 MediaBrowser.Networking/swagger-ui/images/wordnik_api.png create mode 100644 MediaBrowser.Networking/swagger-ui/index.html create mode 100644 MediaBrowser.Networking/swagger-ui/lib/backbone-min.js create mode 100644 MediaBrowser.Networking/swagger-ui/lib/handlebars.runtime-1.0.0.beta.6.js create mode 100644 MediaBrowser.Networking/swagger-ui/lib/jquery.ba-bbq.min.js create mode 100644 MediaBrowser.Networking/swagger-ui/lib/jquery.min.js create mode 100644 MediaBrowser.Networking/swagger-ui/lib/jquery.slideto.min.js create mode 100644 MediaBrowser.Networking/swagger-ui/lib/jquery.wiggle.min.js create mode 100644 MediaBrowser.Networking/swagger-ui/lib/swagger.js create mode 100644 MediaBrowser.Networking/swagger-ui/lib/underscore-min.js create mode 100644 MediaBrowser.Networking/swagger-ui/swagger-ui.js create mode 100644 MediaBrowser.Networking/swagger-ui/swagger-ui.min.js diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs index 08e8c3e75..28ccd8602 100644 --- a/MediaBrowser.Common/Kernel/BaseKernel.cs +++ b/MediaBrowser.Common/Kernel/BaseKernel.cs @@ -504,8 +504,8 @@ namespace MediaBrowser.Common.Kernel /// The container. protected virtual void RegisterExportedValues() { - ApplicationHost.Register(this); - ApplicationHost.Register(TaskManager); + ApplicationHost.RegisterSingleInstance(this); + ApplicationHost.RegisterSingleInstance(TaskManager); } /// diff --git a/MediaBrowser.Common/Kernel/IApplicationHost.cs b/MediaBrowser.Common/Kernel/IApplicationHost.cs index dccb65b2a..fe2f00a12 100644 --- a/MediaBrowser.Common/Kernel/IApplicationHost.cs +++ b/MediaBrowser.Common/Kernel/IApplicationHost.cs @@ -56,8 +56,22 @@ namespace MediaBrowser.Common.Kernel /// /// /// The obj. - void Register(T obj) where T : class; + void RegisterSingleInstance(T obj) where T : class; + /// + /// Registers the single instance. + /// + /// + /// The func. + void RegisterSingleInstance(Func func) where T : class; + + /// + /// Registers the specified func. + /// + /// + /// The func. + void Register(Func func) where T : class; + /// /// Registers the specified service type. /// diff --git a/MediaBrowser.Common/Kernel/TcpManager.cs b/MediaBrowser.Common/Kernel/TcpManager.cs index 0b171c492..9a998823f 100644 --- a/MediaBrowser.Common/Kernel/TcpManager.cs +++ b/MediaBrowser.Common/Kernel/TcpManager.cs @@ -1,6 +1,4 @@ -using Alchemy; -using Alchemy.Classes; -using MediaBrowser.Common.Net; +using MediaBrowser.Common.Net; using MediaBrowser.Common.Serialization; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; @@ -28,20 +26,14 @@ namespace MediaBrowser.Common.Kernel /// This is the udp server used for server discovery by clients /// /// The UDP server. - private UdpServer UdpServer { get; set; } - - /// - /// Gets or sets the UDP listener. - /// - /// The UDP listener. - private IDisposable UdpListener { get; set; } + 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. - public HttpServer HttpServer { get; private set; } + private IHttpServer HttpServer { get; set; } /// /// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it @@ -58,7 +50,7 @@ namespace MediaBrowser.Common.Kernel /// Gets or sets the external web socket server. /// /// The external web socket server. - private WebSocketServer ExternalWebSocketServer { get; set; } + private IWebSocketServer ExternalWebSocketServer { get; set; } /// /// The _logger @@ -69,46 +61,24 @@ namespace MediaBrowser.Common.Kernel /// The _network manager /// private readonly INetworkManager _networkManager; - + /// /// The _application host /// private readonly IApplicationHost _applicationHost; - - /// - /// The _supports native web socket - /// - private bool? _supportsNativeWebSocket; /// /// The _kernel /// private readonly IKernel _kernel; - + /// /// Gets a value indicating whether [supports web socket]. /// /// true if [supports web socket]; otherwise, false. internal bool SupportsNativeWebSocket { - get - { - if (!_supportsNativeWebSocket.HasValue) - { - try - { - new ClientWebSocket(); - - _supportsNativeWebSocket = true; - } - catch (PlatformNotSupportedException) - { - _supportsNativeWebSocket = false; - } - } - - return _supportsNativeWebSocket.Value; - } + get { return HttpServer != null && HttpServer.SupportsWebSockets; } } /// @@ -145,7 +115,7 @@ namespace MediaBrowser.Common.Kernel { throw new ArgumentNullException("logger"); } - + _logger = logger; _kernel = kernel; _applicationHost = applicationHost; @@ -178,26 +148,10 @@ namespace MediaBrowser.Common.Kernel DisposeExternalWebSocketServer(); - ExternalWebSocketServer = new WebSocketServer(_kernel.Configuration.LegacyWebSocketPortNumber, IPAddress.Any) - { - OnConnected = OnAlchemyWebSocketClientConnected, - TimeOut = TimeSpan.FromMinutes(60) - }; - - ExternalWebSocketServer.Start(); + ExternalWebSocketServer = _applicationHost.Resolve(); - _logger.Info("Alchemy Web Socket Server started"); - } - - /// - /// Called when [alchemy web socket client connected]. - /// - /// The context. - private void OnAlchemyWebSocketClientConnected(UserContext context) - { - var connection = new WebSocketConnection(new AlchemyWebSocket(context, _logger), context.ClientAddress, ProcessWebSocketMessageReceived, _logger); - - _webSocketConnections.Add(connection); + ExternalWebSocketServer.Start(_kernel.Configuration.LegacyWebSocketPortNumber); + ExternalWebSocketServer.WebSocketConnected += HttpServer_WebSocketConnected; } /// @@ -218,7 +172,9 @@ namespace MediaBrowser.Common.Kernel try { - HttpServer = new HttpServer(_kernel.HttpServerUrlPrefix, "Media Browser", _applicationHost, _kernel, _logger); + HttpServer = _applicationHost.Resolve(); + HttpServer.EnableHttpRequestLogging = _kernel.Configuration.EnableHttpLevelLogging; + HttpServer.Start(_kernel.HttpServerUrlPrefix); } catch (HttpListenerException ex) { @@ -295,7 +251,8 @@ namespace MediaBrowser.Common.Kernel try { // The port number can't be in configuration because we don't want it to ever change - UdpServer = new UdpServer(new IPEndPoint(IPAddress.Any, _kernel.UdpServerPortNumber)); + UdpServer = _applicationHost.Resolve(); + UdpServer.Start(_kernel.UdpServerPortNumber); } catch (SocketException ex) { @@ -303,21 +260,28 @@ namespace MediaBrowser.Common.Kernel return; } - UdpListener = UdpServer.Subscribe(async res => - { - var expectedMessage = String.Format("who is MediaBrowser{0}?", _kernel.KernelContext); - var expectedMessageBytes = Encoding.UTF8.GetBytes(expectedMessage); + UdpServer.MessageReceived += UdpServer_MessageReceived; + } - if (expectedMessageBytes.SequenceEqual(res.Buffer)) - { - _logger.Info("Received UDP server request from " + res.RemoteEndPoint.ToString()); + /// + /// 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); - // Send a response back with our ip address and port - var response = String.Format("MediaBrowser{0}|{1}:{2}", _kernel.KernelContext, _networkManager.GetLocalIpAddress(), _kernel.UdpServerPortNumber); + if (expectedMessageBytes.SequenceEqual(e.Bytes)) + { + _logger.Info("Received UDP server request from " + e.RemoteEndPoint); - await UdpServer.SendAsync(response, res.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); + } } /// @@ -407,13 +371,9 @@ namespace MediaBrowser.Common.Kernel { if (UdpServer != null) { + UdpServer.MessageReceived -= UdpServer_MessageReceived; UdpServer.Dispose(); } - - if (UdpListener != null) - { - UdpListener.Dispose(); - } } /// @@ -523,6 +483,8 @@ namespace MediaBrowser.Common.Kernel /// The new config. public void OnApplicationConfigurationChanged(BaseApplicationConfiguration oldConfig, BaseApplicationConfiguration newConfig) { + HttpServer.EnableHttpRequestLogging = newConfig.EnableHttpLevelLogging; + if (oldConfig.HttpServerPortNumber != newConfig.HttpServerPortNumber) { ReloadHttpServer(); diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj index 57b30eedc..28789a816 100644 --- a/MediaBrowser.Common/MediaBrowser.Common.csproj +++ b/MediaBrowser.Common/MediaBrowser.Common.csproj @@ -38,13 +38,6 @@ - - ..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll - - - ..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll - - False ..\packages\protobuf-net.2.0.0.621\lib\net40\protobuf-net.dll @@ -53,9 +46,6 @@ False ..\packages\ServiceStack.3.9.37\lib\net35\ServiceStack.dll - - ..\packages\ServiceStack.Api.Swagger.3.9.35\lib\net35\ServiceStack.Api.Swagger.dll - False ..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll @@ -64,9 +54,6 @@ False ..\packages\ServiceStack.Common.3.9.37\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.37\lib\ServiceStack.OrmLite.dll @@ -93,18 +80,6 @@ - - False - ..\packages\Rx-Core.2.0.21114\lib\Net45\System.Reactive.Core.dll - - - False - ..\packages\Rx-Interfaces.2.0.21114\lib\Net45\System.Reactive.Interfaces.dll - - - False - ..\packages\Rx-Linq.2.0.21114\lib\Net45\System.Reactive.Linq.dll - @@ -129,19 +104,21 @@ - + + - + + @@ -165,7 +142,6 @@ - @@ -196,23 +172,6 @@ Designer - - - - - - - - - - - - - - - - - diff --git a/MediaBrowser.Common/Net/AlchemyWebSocket.cs b/MediaBrowser.Common/Net/AlchemyWebSocket.cs deleted file mode 100644 index 584efa999..000000000 --- a/MediaBrowser.Common/Net/AlchemyWebSocket.cs +++ /dev/null @@ -1,132 +0,0 @@ -using Alchemy.Classes; -using MediaBrowser.Common.Serialization; -using MediaBrowser.Model.Logging; -using System; -using System.Net.WebSockets; -using System.Threading; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - /// 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 messageResult = JsonSerializer.DeserializeFromString(json); - - OnReceiveDelegate(messageResult); - } - 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/Net/HttpServer.cs b/MediaBrowser.Common/Net/HttpServer.cs deleted file mode 100644 index 20ee615ad..000000000 --- a/MediaBrowser.Common/Net/HttpServer.cs +++ /dev/null @@ -1,489 +0,0 @@ -using Funq; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Kernel; -using MediaBrowser.Model.Logging; -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.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Reactive.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - /// Class HttpServer - /// - public class HttpServer : HttpListenerBase - { - /// - /// The logger - /// - private readonly ILogger _logger; - - /// - /// Gets the URL prefix. - /// - /// The URL prefix. - public string UrlPrefix { get; private set; } - - /// - /// Gets or sets the kernel. - /// - /// The kernel. - private IKernel Kernel { get; set; } - - /// - /// 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; } - - /// - /// Occurs when [web socket connected]. - /// - public event EventHandler WebSocketConnected; - - /// - /// Gets the default redirect path. - /// - /// The default redirect path. - public string DefaultRedirectPath { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - /// The URL. - /// Name of the product. - /// The application host. - /// The kernel. - /// The logger. - /// The default redirectpath. - /// urlPrefix - public HttpServer(string urlPrefix, string serverName, IApplicationHost applicationHost, IKernel kernel, ILogger logger, string defaultRedirectpath = null) - : base() - { - if (string.IsNullOrEmpty(urlPrefix)) - { - throw new ArgumentNullException("urlPrefix"); - } - if (kernel == null) - { - throw new ArgumentNullException("kernel"); - } - if (logger == null) - { - throw new ArgumentNullException("logger"); - } - if (applicationHost == null) - { - throw new ArgumentNullException("applicationHost"); - } - - DefaultRedirectPath = defaultRedirectpath; - _logger = logger; - ApplicationHost = applicationHost; - - EndpointHostConfig.Instance.ServiceStackHandlerFactoryPath = null; - EndpointHostConfig.Instance.MetadataRedirectPath = "metadata"; - - UrlPrefix = urlPrefix; - Kernel = kernel; - - EndpointHost.ConfigureHost(this, serverName, CreateServiceManager()); - - ContentTypeFilters.Register(ContentType.ProtoBuf, (reqCtx, res, stream) => Kernel.ProtobufSerializer.SerializeToStream(res, stream), (type, stream) => Kernel.ProtobufSerializer.DeserializeFromStream(stream, type)); - - Init(); - Start(urlPrefix); - } - - /// - /// 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(); - } - - /// - /// Configures the specified container. - /// - /// The container. - public override void Configure(Container container) - { - if (!string.IsNullOrEmpty(DefaultRedirectPath)) - { - SetConfig(new EndpointHostConfig - { - DefaultRedirectPath = DefaultRedirectPath, - - // Tell SS to bubble exceptions up to here - WriteErrorsToResponse = false, - - DebugMode = true - }); - } - - container.Adapter = new ContainerAdapter(ApplicationHost); - - container.Register(Kernel); - container.Register(_logger); - container.Register(ApplicationHost); - - foreach (var service in Kernel.RestServices) - { - service.Configure(this); - } - - Plugins.Add(new SwaggerFeature()); - Plugins.Add(new CorsFeature()); - - Serialization.JsonSerializer.Configure(); - - 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) - { - // *** Already running - just leave it in place - if (IsStarted) - { - return; - } - - if (Listener == null) - { - Listener = new HttpListener(); - } - - EndpointHost.Config.ServiceStackHandlerFactoryPath = HttpListenerRequestWrapper.GetHandlerPathIfAny(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 }); - } - } - 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 (Kernel.Configuration.EnableHttpLevelLogging) - { - _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 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); - httpRes.Close(); - return; - } - - throw new NotImplementedException("Cannot execute handler: " + handler + " at PathInfo: " + httpReq.PathInfo); - } - - /// - /// Logs the response. - /// - /// The CTX. - private void LogResponse(HttpListenerContext ctx) - { - var statusode = ctx.Response.StatusCode; - - var log = new StringBuilder(); - - log.AppendLine(string.Format("Url: {0}", ctx.Request.Url)); - - log.AppendLine("Headers: " + string.Join(",", ctx.Response.Headers.AllKeys.Select(k => k + "=" + ctx.Response.Headers[k]))); - - var msg = "Http Response Sent (" + statusode + ") to " + ctx.Request.RemoteEndPoint; - - if (Kernel.Configuration.EnableHttpLevelLogging) - { - _logger.LogMultiline(msg, LogSeverity.Debug, log); - } - } - - /// - /// Creates the service manager. - /// - /// The assemblies with services. - /// ServiceManager. - protected override ServiceManager CreateServiceManager(params Assembly[] assembliesWithServices) - { - var types = Kernel.RestServices.Select(r => r.GetType()).ToArray(); - - return new ServiceManager(new Container(), new ServiceController(() => types)); - } - } - - /// - /// Class WebSocketConnectEventArgs - /// - public class WebSocketConnectEventArgs : EventArgs - { - /// - /// Gets or sets the web socket. - /// - /// The web socket. - public IWebSocket WebSocket { get; set; } - /// - /// Gets or sets the endpoint. - /// - /// The endpoint. - public IPEndPoint Endpoint { get; set; } - } - - class ContainerAdapter : IContainerAdapter - { - private readonly IApplicationHost _appHost; - - public ContainerAdapter(IApplicationHost appHost) - { - _appHost = appHost; - } - public T Resolve() - { - return _appHost.Resolve(); - } - - public T TryResolve() - { - return _appHost.TryResolve(); - } - } -} \ No newline at end of file diff --git a/MediaBrowser.Common/Net/IHttpServer.cs b/MediaBrowser.Common/Net/IHttpServer.cs new file mode 100644 index 000000000..a640fb262 --- /dev/null +++ b/MediaBrowser.Common/Net/IHttpServer.cs @@ -0,0 +1,44 @@ +using System; + +namespace MediaBrowser.Common.Net +{ + /// + /// Interface IHttpServer + /// + public interface IHttpServer : IDisposable + { + /// + /// Gets the URL prefix. + /// + /// The URL prefix. + string UrlPrefix { get; } + + /// + /// Starts the specified server name. + /// + /// The URL. + void Start(string urlPrefix); + + /// + /// Gets a value indicating whether [supports web sockets]. + /// + /// true if [supports web sockets]; otherwise, false. + bool SupportsWebSockets { get; } + + /// + /// Stops this instance. + /// + void Stop(); + + /// + /// Gets or sets a value indicating whether [enable HTTP request logging]. + /// + /// true if [enable HTTP request logging]; otherwise, false. + bool EnableHttpRequestLogging { get; set; } + + /// + /// Occurs when [web socket connected]. + /// + event EventHandler WebSocketConnected; + } +} \ No newline at end of file diff --git a/MediaBrowser.Common/Net/IUdpServer.cs b/MediaBrowser.Common/Net/IUdpServer.cs index 01a8ef021..036977eab 100644 --- a/MediaBrowser.Common/Net/IUdpServer.cs +++ b/MediaBrowser.Common/Net/IUdpServer.cs @@ -1,7 +1,46 @@ - +using System; +using System.Threading.Tasks; + namespace MediaBrowser.Common.Net { - public interface IUdpServer + /// + /// Interface IUdpServer + /// + public interface IUdpServer : IDisposable { + /// + /// Occurs when [message received]. + /// + event EventHandler MessageReceived; + + /// + /// Starts the specified port. + /// + /// The port. + void Start(int port); + + /// + /// Stops this instance. + /// + void Stop(); + + /// + /// Sends the async. + /// + /// The bytes. + /// The remote end point. + /// Task. + /// data + Task SendAsync(byte[] bytes, string remoteEndPoint); + + /// + /// Sends the async. + /// + /// The bytes. + /// The ip address. + /// The port. + /// Task. + /// bytes + Task SendAsync(byte[] bytes, string ipAddress, int port); } } diff --git a/MediaBrowser.Common/Net/IWebSocketServer.cs b/MediaBrowser.Common/Net/IWebSocketServer.cs new file mode 100644 index 000000000..5ce571fbb --- /dev/null +++ b/MediaBrowser.Common/Net/IWebSocketServer.cs @@ -0,0 +1,26 @@ +using System; + +namespace MediaBrowser.Common.Net +{ + /// + /// Interface IWebSocketServer + /// + public interface IWebSocketServer : IDisposable + { + /// + /// Starts the specified port number. + /// + /// The port number. + void Start(int portNumber); + + /// + /// Stops this instance. + /// + void Stop(); + + /// + /// Occurs when [web socket connected]. + /// + event EventHandler WebSocketConnected; + } +} diff --git a/MediaBrowser.Common/Net/UdpMessageReceivedEventArgs.cs b/MediaBrowser.Common/Net/UdpMessageReceivedEventArgs.cs new file mode 100644 index 000000000..bd5034c47 --- /dev/null +++ b/MediaBrowser.Common/Net/UdpMessageReceivedEventArgs.cs @@ -0,0 +1,21 @@ +using System; + +namespace MediaBrowser.Common.Net +{ + /// + /// Class UdpMessageReceivedEventArgs + /// + public class UdpMessageReceivedEventArgs : EventArgs + { + /// + /// Gets or sets the bytes. + /// + /// The bytes. + public byte[] Bytes { get; set; } + /// + /// Gets or sets the remote end point. + /// + /// The remote end point. + public string RemoteEndPoint { get; set; } + } +} diff --git a/MediaBrowser.Common/Net/UdpServer.cs b/MediaBrowser.Common/Net/UdpServer.cs deleted file mode 100644 index a3c6a8a78..000000000 --- a/MediaBrowser.Common/Net/UdpServer.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System; -using System.Net; -using System.Net.Sockets; -using System.Reactive.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MediaBrowser.Common.Net -{ - /// - /// Provides a Udp Server - /// - public class UdpServer : IObservable, IDisposable - { - /// - /// The _udp client - /// - private readonly UdpClient _udpClient; - /// - /// The _stream - /// - private readonly IObservable _stream; - - /// - /// Initializes a new instance of the class. - /// - /// The end point. - /// endPoint - public UdpServer(IPEndPoint endPoint) - { - if (endPoint == null) - { - throw new ArgumentNullException("endPoint"); - } - - _udpClient = new UdpClient(endPoint); - - _udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); - //_udpClient.ExclusiveAddressUse = false; - - _stream = CreateObservable(); - } - - /// - /// Creates the observable. - /// - /// IObservable{UdpReceiveResult}. - private IObservable CreateObservable() - { - return Observable.Create(obs => - Observable.FromAsync(() => _udpClient.ReceiveAsync()) - .Subscribe(obs)) - .Repeat() - .Retry() - .Publish() - .RefCount(); - } - - /// - /// Subscribes the specified observer. - /// - /// The observer. - /// IDisposable. - /// observer - public IDisposable Subscribe(IObserver observer) - { - if (observer == null) - { - throw new ArgumentNullException("observer"); - } - - return _stream.Subscribe(observer); - } - - /// - /// 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) - { - _udpClient.Close(); - } - } - - /// - /// Sends the async. - /// - /// The data. - /// The end point. - /// Task{System.Int32}. - /// data - public async Task SendAsync(string data, IPEndPoint endPoint) - { - if (data == null) - { - throw new ArgumentNullException("data"); - } - - if (endPoint == null) - { - throw new ArgumentNullException("endPoint"); - } - - var bytes = Encoding.UTF8.GetBytes(data); - - return await _udpClient.SendAsync(bytes, bytes.Length, endPoint).ConfigureAwait(false); - } - - /// - /// Sends the async. - /// - /// The bytes. - /// The end point. - /// Task{System.Int32}. - /// bytes - public async Task SendAsync(byte[] bytes, IPEndPoint endPoint) - { - if (bytes == null) - { - throw new ArgumentNullException("bytes"); - } - - if (endPoint == null) - { - throw new ArgumentNullException("endPoint"); - } - - return await _udpClient.SendAsync(bytes, bytes.Length, endPoint).ConfigureAwait(false); - } - } -} diff --git a/MediaBrowser.Common/Net/WebSocketConnectEventArgs.cs b/MediaBrowser.Common/Net/WebSocketConnectEventArgs.cs new file mode 100644 index 000000000..711da7a50 --- /dev/null +++ b/MediaBrowser.Common/Net/WebSocketConnectEventArgs.cs @@ -0,0 +1,22 @@ +using System; +using System.Net; + +namespace MediaBrowser.Common.Net +{ + /// + /// Class WebSocketConnectEventArgs + /// + public class WebSocketConnectEventArgs : EventArgs + { + /// + /// Gets or sets the web socket. + /// + /// The web socket. + public IWebSocket WebSocket { get; set; } + /// + /// Gets or sets the endpoint. + /// + /// The endpoint. + public string Endpoint { get; set; } + } +} diff --git a/MediaBrowser.Common/Net/WebSocketConnection.cs b/MediaBrowser.Common/Net/WebSocketConnection.cs index d274d390d..ab691c823 100644 --- a/MediaBrowser.Common/Net/WebSocketConnection.cs +++ b/MediaBrowser.Common/Net/WebSocketConnection.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Common.Net /// /// The _remote end point /// - public readonly EndPoint RemoteEndPoint; + public readonly string RemoteEndPoint; /// /// The _cancellation token source @@ -45,13 +45,13 @@ namespace MediaBrowser.Common.Net /// The remote end point. /// The receive action. /// socket - public WebSocketConnection(IWebSocket socket, EndPoint remoteEndPoint, Action receiveAction, ILogger logger) + public WebSocketConnection(IWebSocket socket, string remoteEndPoint, Action receiveAction, ILogger logger) { if (socket == null) { throw new ArgumentNullException("socket"); } - if (remoteEndPoint == null) + if (string.IsNullOrEmpty(remoteEndPoint)) { throw new ArgumentNullException("remoteEndPoint"); } diff --git a/MediaBrowser.Common/README.txt b/MediaBrowser.Common/README.txt deleted file mode 100644 index e8ce34205..000000000 --- a/MediaBrowser.Common/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/packages.config b/MediaBrowser.Common/packages.config index 536640094..0ebaf6297 100644 --- a/MediaBrowser.Common/packages.config +++ b/MediaBrowser.Common/packages.config @@ -1,15 +1,8 @@  - - - - - - - diff --git a/MediaBrowser.Common/swagger-ui/css/screen.css b/MediaBrowser.Common/swagger-ui/css/screen.css deleted file mode 100644 index 07773f9ef..000000000 --- a/MediaBrowser.Common/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/swagger-ui/images/pet_store_api.png b/MediaBrowser.Common/swagger-ui/images/pet_store_api.png deleted file mode 100644 index f9f9cd4ae..000000000 Binary files a/MediaBrowser.Common/swagger-ui/images/pet_store_api.png and /dev/null differ diff --git a/MediaBrowser.Common/swagger-ui/images/wordnik_api.png b/MediaBrowser.Common/swagger-ui/images/wordnik_api.png deleted file mode 100644 index dca4f1455..000000000 Binary files a/MediaBrowser.Common/swagger-ui/images/wordnik_api.png and /dev/null differ diff --git a/MediaBrowser.Common/swagger-ui/index.html b/MediaBrowser.Common/swagger-ui/index.html deleted file mode 100644 index 5d2a8d88d..000000000 --- a/MediaBrowser.Common/swagger-ui/index.html +++ /dev/null @@ -1,88 +0,0 @@ - - - Swagger UI - - - - - - - - - - - - - - - - - - - - -
-   -
- -
- -
- - - - diff --git a/MediaBrowser.Common/swagger-ui/lib/backbone-min.js b/MediaBrowser.Common/swagger-ui/lib/backbone-min.js deleted file mode 100644 index c1c0d4fff..000000000 --- a/MediaBrowser.Common/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('