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 { } 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> paths { get; set; } public Dictionary definitions { get; set; } public SwaggerComponents components { get; set; } } public class SwaggerComponents { public Dictionary 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 responses { get; set; } public Dictionary[] 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 schema { get; set; } } public class SwaggerDefinition { public string type { get; set; } public Dictionary 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(); 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 GetDefinitions() { return new Dictionary(); } private IDictionary> GetPaths() { var paths = new SortedDictionary>(); 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 GetPathInfo(RestPath info) { var result = new Dictionary(); foreach (var verb in info.Verbs) { var responses = new Dictionary { }; responses["200"] = new SwaggerResponse { description = "OK" }; var security = new List>(); var apiKeySecurity = new Dictionary(); apiKeySecurity["api_key"] = Array.Empty(); 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(), parameters = new SwaggerParam[] { }, responses = responses, security = security.ToArray() }; } return result; } } }