diff options
Diffstat (limited to 'Emby.Server.Implementations/Services')
9 files changed, 275 insertions, 27 deletions
diff --git a/Emby.Server.Implementations/Services/RequestHelper.cs b/Emby.Server.Implementations/Services/RequestHelper.cs index 7d2fbc3e0..24e9cbfa4 100644 --- a/Emby.Server.Implementations/Services/RequestHelper.cs +++ b/Emby.Server.Implementations/Services/RequestHelper.cs @@ -1,7 +1,7 @@ using System; using System.IO; -using Emby.Server.Implementations.HttpServer; using System.Threading.Tasks; +using Emby.Server.Implementations.HttpServer; namespace Emby.Server.Implementations.Services { diff --git a/Emby.Server.Implementations/Services/ServiceController.cs b/Emby.Server.Implementations/Services/ServiceController.cs index 46af83128..5796956d8 100644 --- a/Emby.Server.Implementations/Services/ServiceController.cs +++ b/Emby.Server.Implementations/Services/ServiceController.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Reflection; using System.Threading.Tasks; using Emby.Server.Implementations.HttpServer; -using Microsoft.Extensions.Logging; using MediaBrowser.Model.Services; namespace Emby.Server.Implementations.Services @@ -73,7 +72,7 @@ namespace Emby.Server.Implementations.Services public void RegisterRestPaths(HttpListenerHost appHost, Type requestType, Type serviceType) { var attrs = appHost.GetRouteAttributes(requestType); - foreach (RouteAttribute attr in attrs) + foreach (var attr in attrs) { var restPath = new RestPath(appHost.CreateInstance, appHost.GetParseFn, requestType, serviceType, attr.Path, attr.Verbs, attr.IsHidden, attr.Summary, attr.Description); @@ -90,8 +89,7 @@ namespace Emby.Server.Implementations.Services if (restPath.Path.IndexOfAny(InvalidRouteChars) != -1) throw new ArgumentException(string.Format("Route '{0}' on '{1}' contains invalid chars. ", restPath.Path, restPath.RequestType.GetMethodName())); - List<RestPath> pathsAtFirstMatch; - if (!RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out pathsAtFirstMatch)) + if (!RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out List<RestPath> pathsAtFirstMatch)) { pathsAtFirstMatch = new List<RestPath>(); RestPathMap[restPath.FirstMatchHashKey] = pathsAtFirstMatch; diff --git a/Emby.Server.Implementations/Services/ServiceExec.cs b/Emby.Server.Implementations/Services/ServiceExec.cs index 9516c1e38..45c918fa1 100644 --- a/Emby.Server.Implementations/Services/ServiceExec.cs +++ b/Emby.Server.Implementations/Services/ServiceExec.cs @@ -5,7 +5,6 @@ using System.Linq.Expressions; using System.Reflection; using System.Threading.Tasks; using MediaBrowser.Model.Services; -using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Services { @@ -74,8 +73,7 @@ namespace Emby.Server.Implementations.Services { var actionName = request.Verb ?? "POST"; - ServiceMethod actionContext; - if (ServiceExecGeneral.execMap.TryGetValue(ServiceMethod.Key(serviceType, actionName, requestName), out actionContext)) + if (execMap.TryGetValue(ServiceMethod.Key(serviceType, actionName, requestName), out ServiceMethod actionContext)) { if (actionContext.RequestFilters != null) { diff --git a/Emby.Server.Implementations/Services/ServiceHandler.cs b/Emby.Server.Implementations/Services/ServiceHandler.cs index 5590c51b6..7e836e22c 100644 --- a/Emby.Server.Implementations/Services/ServiceHandler.cs +++ b/Emby.Server.Implementations/Services/ServiceHandler.cs @@ -4,8 +4,8 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.HttpServer; -using Microsoft.Extensions.Logging; using MediaBrowser.Model.Services; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Services { @@ -62,8 +62,7 @@ namespace Emby.Server.Implementations.Services { if (this.RestPath == null) { - string contentType; - this.RestPath = FindMatchingRestPath(httpMethod, pathInfo, out contentType); + this.RestPath = FindMatchingRestPath(httpMethod, pathInfo, out string contentType); if (contentType != null) ResponseContentType = contentType; @@ -137,9 +136,8 @@ namespace Emby.Server.Implementations.Services public static object CreateRequest(IRequest httpReq, RestPath restPath, Dictionary<string, string> requestParams, object requestDto) { - string contentType; var pathInfo = !restPath.IsWildCardPath - ? GetSanitizedPathInfo(httpReq.PathInfo, out contentType) + ? GetSanitizedPathInfo(httpReq.PathInfo, out string contentType) : httpReq.PathInfo; return restPath.CreateRequest(pathInfo, requestParams, requestDto); @@ -239,8 +237,7 @@ namespace Emby.Server.Implementations.Services private static RestPath GetRoute(IRequest req) { - object route; - req.Items.TryGetValue("__route", out route); + req.Items.TryGetValue("__route", out var route); return route as RestPath; } } diff --git a/Emby.Server.Implementations/Services/ServiceMethod.cs b/Emby.Server.Implementations/Services/ServiceMethod.cs index fa2dd43d0..7add72815 100644 --- a/Emby.Server.Implementations/Services/ServiceMethod.cs +++ b/Emby.Server.Implementations/Services/ServiceMethod.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Emby.Server.Implementations.Services { @@ -14,4 +14,4 @@ namespace Emby.Server.Implementations.Services return serviceType.FullName + " " + method.ToUpper() + " " + requestDtoName; } } -}
\ No newline at end of file +} diff --git a/Emby.Server.Implementations/Services/ServicePath.cs b/Emby.Server.Implementations/Services/ServicePath.cs index 0222b3782..7e1993b71 100644 --- a/Emby.Server.Implementations/Services/ServicePath.cs +++ b/Emby.Server.Implementations/Services/ServicePath.cs @@ -4,8 +4,6 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; -using Microsoft.Extensions.Logging; -using MediaBrowser.Model.Extensions; namespace Emby.Server.Implementations.Services { @@ -308,8 +306,7 @@ namespace Emby.Server.Implementations.Services public int MatchScore(string httpMethod, string[] withPathInfoParts) { - int wildcardMatchCount; - var isMatch = IsMatch(httpMethod, withPathInfoParts, out wildcardMatchCount); + var isMatch = IsMatch(httpMethod, withPathInfoParts, out var wildcardMatchCount); if (!isMatch) { return -1; @@ -486,8 +483,7 @@ namespace Emby.Server.Implementations.Services continue; } - string propertyNameOnRequest; - if (!this.propertyNamesMap.TryGetValue(variableName.ToLower(), out propertyNameOnRequest)) + if (!this.propertyNamesMap.TryGetValue(variableName.ToLower(), out var propertyNameOnRequest)) { if (string.Equals("ignore", variableName, StringComparison.OrdinalIgnoreCase)) { diff --git a/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs b/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs index 2233bf918..d13935fba 100644 --- a/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs +++ b/Emby.Server.Implementations/Services/StringMapTypeDeserializer.cs @@ -11,14 +11,14 @@ namespace Emby.Server.Implementations.Services { internal class PropertySerializerEntry { - public PropertySerializerEntry(Action<object,object> propertySetFn, Func<string, object> propertyParseStringFn) + public PropertySerializerEntry(Action<object, object> propertySetFn, Func<string, object> propertyParseStringFn) { PropertySetFn = propertySetFn; PropertyParseStringFn = propertyParseStringFn; } public Action<object, object> PropertySetFn; - public Func<string,object> PropertyParseStringFn; + public Func<string, object> PropertyParseStringFn; public Type PropertyType; } diff --git a/Emby.Server.Implementations/Services/SwaggerService.cs b/Emby.Server.Implementations/Services/SwaggerService.cs new file mode 100644 index 000000000..9bceeabec --- /dev/null +++ b/Emby.Server.Implementations/Services/SwaggerService.cs @@ -0,0 +1,259 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MediaBrowser.Model.Services; + +namespace Emby.Server.Implementations.Services +{ + [Route("/swagger", "GET", Summary = "Gets the swagger specifications")] + [Route("/swagger.json", "GET", Summary = "Gets the swagger specifications")] + public class GetSwaggerSpec : IReturn<SwaggerSpec> + { + } + + public class SwaggerSpec + { + public string swagger { get; set; } + public string[] schemes { get; set; } + public SwaggerInfo info { get; set; } + public string host { get; set; } + public string basePath { get; set; } + public SwaggerTag[] tags { get; set; } + public IDictionary<string, Dictionary<string, SwaggerMethod>> paths { get; set; } + public Dictionary<string, SwaggerDefinition> definitions { get; set; } + public SwaggerComponents components { get; set; } + } + + public class SwaggerComponents + { + public Dictionary<string, SwaggerSecurityScheme> securitySchemes { get; set; } + } + + public class SwaggerSecurityScheme + { + public string name { get; set; } + public string type { get; set; } + public string @in { get; set; } + } + + public class SwaggerInfo + { + public string description { get; set; } + public string version { get; set; } + public string title { get; set; } + public string termsOfService { get; set; } + + public SwaggerConcactInfo contact { get; set; } + } + + public class SwaggerConcactInfo + { + public string email { get; set; } + public string name { get; set; } + public string url { get; set; } + } + + public class SwaggerTag + { + public string description { get; set; } + public string name { get; set; } + } + + public class SwaggerMethod + { + public string summary { get; set; } + public string description { get; set; } + public string[] tags { get; set; } + public string operationId { get; set; } + public string[] consumes { get; set; } + public string[] produces { get; set; } + public SwaggerParam[] parameters { get; set; } + public Dictionary<string, SwaggerResponse> responses { get; set; } + public Dictionary<string, string[]>[] security { get; set; } + } + + public class SwaggerParam + { + public string @in { get; set; } + public string name { get; set; } + public string description { get; set; } + public bool required { get; set; } + public string type { get; set; } + public string collectionFormat { get; set; } + } + + public class SwaggerResponse + { + public string description { get; set; } + + // ex. "$ref":"#/definitions/Pet" + public Dictionary<string, string> schema { get; set; } + } + + public class SwaggerDefinition + { + public string type { get; set; } + public Dictionary<string, SwaggerProperty> properties { get; set; } + } + + public class SwaggerProperty + { + public string type { get; set; } + public string format { get; set; } + public string description { get; set; } + public string[] @enum { get; set; } + public string @default { get; set; } + } + + public class SwaggerService : IService, IRequiresRequest + { + private SwaggerSpec _spec; + + public IRequest Request { get; set; } + + public object Get(GetSwaggerSpec request) + { + return _spec ?? (_spec = GetSpec()); + } + + private SwaggerSpec GetSpec() + { + string host = null; + Uri uri; + if (Uri.TryCreate(Request.RawUrl, UriKind.Absolute, out uri)) + { + host = uri.Host; + } + + var securitySchemes = new Dictionary<string, SwaggerSecurityScheme>(); + + securitySchemes["api_key"] = new SwaggerSecurityScheme + { + name = "api_key", + type = "apiKey", + @in = "query" + }; + + var spec = new SwaggerSpec + { + schemes = new[] { "http" }, + tags = GetTags(), + swagger = "2.0", + info = new SwaggerInfo + { + title = "Jellyfin Server API", + version = "1.0.0", + description = "Explore the Jellyfin Server API", + contact = new SwaggerConcactInfo + { + name = "Jellyfin Community", + url = "https://jellyfin.readthedocs.io/en/latest/user-docs/getting-help/" + } + }, + paths = GetPaths(), + definitions = GetDefinitions(), + basePath = "/jellyfin", + host = host, + + components = new SwaggerComponents + { + securitySchemes = securitySchemes + } + }; + + return spec; + } + + + private SwaggerTag[] GetTags() + { + return new SwaggerTag[] { }; + } + + private Dictionary<string, SwaggerDefinition> GetDefinitions() + { + return new Dictionary<string, SwaggerDefinition>(); + } + + private IDictionary<string, Dictionary<string, SwaggerMethod>> GetPaths() + { + var paths = new SortedDictionary<string, Dictionary<string, SwaggerMethod>>(); + + var all = ServiceController.Instance.RestPathMap.OrderBy(i => i.Key, StringComparer.OrdinalIgnoreCase).ToList(); + + foreach (var current in all) + { + foreach (var info in current.Value) + { + if (info.IsHidden) + { + continue; + } + + if (info.Path.StartsWith("/mediabrowser", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + if (info.Path.StartsWith("/jellyfin", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + paths[info.Path] = GetPathInfo(info); + } + } + + return paths; + } + + private Dictionary<string, SwaggerMethod> GetPathInfo(RestPath info) + { + var result = new Dictionary<string, SwaggerMethod>(); + + foreach (var verb in info.Verbs) + { + var responses = new Dictionary<string, SwaggerResponse> + { + }; + + responses["200"] = new SwaggerResponse + { + description = "OK" + }; + + var security = new List<Dictionary<string, string[]>>(); + + var apiKeySecurity = new Dictionary<string, string[]>(); + apiKeySecurity["api_key"] = Array.Empty<string>(); + + security.Add(apiKeySecurity); + + result[verb.ToLower()] = new SwaggerMethod + { + summary = info.Summary, + description = info.Description, + produces = new[] + { + "application/json" + }, + consumes = new[] + { + "application/json" + }, + operationId = info.RequestType.Name, + tags = Array.Empty<string>(), + + parameters = new SwaggerParam[] { }, + + responses = responses, + + security = security.ToArray() + }; + } + + return result; + } + } +} diff --git a/Emby.Server.Implementations/Services/UrlExtensions.cs b/Emby.Server.Implementations/Services/UrlExtensions.cs index 898dcac3e..8899fbfa3 100644 --- a/Emby.Server.Implementations/Services/UrlExtensions.cs +++ b/Emby.Server.Implementations/Services/UrlExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace Emby.Server.Implementations.Services { @@ -30,4 +30,4 @@ namespace Emby.Server.Implementations.Services : strVal.Substring(0, pos); } } -}
\ No newline at end of file +} |
