mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Swagger: Trying to clean the xml documentation before giving it to swashbuckle
This commit is contained in:
parent
ced12c2fe6
commit
e32dcd0f30
@ -31,14 +31,28 @@ using static Kyoo.Abstractions.Models.Utils.Constants;
|
|||||||
|
|
||||||
namespace Kyoo.Core.Api
|
namespace Kyoo.Core.Api
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Information about one or multiple <see cref="Collection"/>.
|
||||||
|
/// </summary>
|
||||||
[Route("api/collections")]
|
[Route("api/collections")]
|
||||||
[Route("api/collection", Order = AlternativeRoute)]
|
[Route("api/collection", Order = AlternativeRoute)]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[PartialPermission(nameof(CollectionApi))]
|
[PartialPermission(nameof(CollectionApi))]
|
||||||
public class CollectionApi : CrudApi<Collection>
|
public class CollectionApi : CrudApi<Collection>
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The library manager used to modify or retrieve information about the data store.
|
||||||
|
/// </summary>
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The file manager used to send images.
|
||||||
|
/// </summary>
|
||||||
private readonly IFileSystem _files;
|
private readonly IFileSystem _files;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The thumbnail manager used to retrieve images paths.
|
||||||
|
/// </summary>
|
||||||
private readonly IThumbnailsManager _thumbs;
|
private readonly IThumbnailsManager _thumbs;
|
||||||
|
|
||||||
public CollectionApi(ILibraryManager libraryManager,
|
public CollectionApi(ILibraryManager libraryManager,
|
||||||
@ -52,6 +66,20 @@ namespace Kyoo.Core.Api
|
|||||||
_thumbs = thumbs;
|
_thumbs = thumbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lists <see cref="Show"/> that are contained in the <see cref="Collection"/> with id <paramref name="id"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the <see cref="Collection"/>.</param>
|
||||||
|
/// <param name="sortBy">A key to sort shows by. See <see cref="Sort{T}"/> for more information.</param>
|
||||||
|
/// <param name="afterID">An optional show's ID to start the query from this specific item.</param>
|
||||||
|
/// <param name="where">
|
||||||
|
/// An optional list of filters. See <see cref="ApiHelper.ParseWhere{T}"/> for more details.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="limit">The number of shows to return.</param>
|
||||||
|
/// <returns>A page of shows.</returns>
|
||||||
|
/// <response code="200">A page of shows.</response>
|
||||||
|
/// <response code="400"><paramref name="sortBy"/> or <paramref name="where"/> is invalid.</response>
|
||||||
|
/// <response code="404">No collection with the ID <paramref name="id"/> could be found.</response>
|
||||||
[HttpGet("{id:int}/shows")]
|
[HttpGet("{id:int}/shows")]
|
||||||
[HttpGet("{id:int}/show", Order = AlternativeRoute)]
|
[HttpGet("{id:int}/show", Order = AlternativeRoute)]
|
||||||
[PartialPermission(Kind.Read)]
|
[PartialPermission(Kind.Read)]
|
||||||
|
@ -28,21 +28,47 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
|
|
||||||
namespace Kyoo.Core.Api
|
namespace Kyoo.Core.Api
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A base class to handle CRUD operations on a specific resource type <typeparamref name="T"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of resource to make CRUD apis for.</typeparam>
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[ResourceView]
|
[ResourceView]
|
||||||
public class CrudApi<T> : ControllerBase
|
public class CrudApi<T> : ControllerBase
|
||||||
where T : class, IResource
|
where T : class, IResource
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The repository of the resource, used to retrieve, save and do operations on the baking store.
|
||||||
|
/// </summary>
|
||||||
private readonly IRepository<T> _repository;
|
private readonly IRepository<T> _repository;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The base URL of Kyoo. This will be used to create links for images and <see cref="Abstractions.Models.Page{T}"/>.
|
||||||
|
/// </summary>
|
||||||
protected Uri BaseURL { get; }
|
protected Uri BaseURL { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new <see cref="CrudApi{T}"/> using the given repository and base url.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="repository">
|
||||||
|
/// The repository to use as a baking store for the type <typeparamref name="T"/>.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="baseURL">
|
||||||
|
/// The base URL of Kyoo to use to create links.
|
||||||
|
/// </param>
|
||||||
public CrudApi(IRepository<T> repository, Uri baseURL)
|
public CrudApi(IRepository<T> repository, Uri baseURL)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_repository = repository;
|
||||||
BaseURL = baseURL;
|
BaseURL = baseURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a <typeparamref name="T"/> by ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the resource to retrieve.</param>
|
||||||
|
/// <returns>The retrieved <typeparamref name="T"/>.</returns>
|
||||||
|
/// <response code="200">The <typeparamref name="T"/> exist and is returned.</response>
|
||||||
|
/// <response code="404">A resource with the ID <paramref name="id"/> does not exist.</response>
|
||||||
[HttpGet("{id:int}")]
|
[HttpGet("{id:int}")]
|
||||||
[PartialPermission(Kind.Read)]
|
[PartialPermission(Kind.Read)]
|
||||||
public virtual async Task<ActionResult<T>> Get(int id)
|
public virtual async Task<ActionResult<T>> Get(int id)
|
||||||
|
@ -66,9 +66,7 @@ namespace Kyoo.Swagger
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (string documentation in Directory.GetFiles(AppContext.BaseDirectory, "*.xml"))
|
options.LoadXmlDocumentation();
|
||||||
options.IncludeXmlComments(documentation);
|
|
||||||
|
|
||||||
options.UseAllOfForInheritance();
|
options.UseAllOfForInheritance();
|
||||||
options.SwaggerGeneratorOptions.SortKeySelector = x => x.RelativePath;
|
options.SwaggerGeneratorOptions.SortKeySelector = x => x.RelativePath;
|
||||||
options.DocInclusionPredicate((_, apiDescription)
|
options.DocInclusionPredicate((_, apiDescription)
|
||||||
|
68
src/Kyoo.Swagger/XmlDocumentationLoader.cs
Normal file
68
src/Kyoo.Swagger/XmlDocumentationLoader.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Kyoo - A portable and vast media library solution.
|
||||||
|
// Copyright (c) Kyoo.
|
||||||
|
//
|
||||||
|
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||||
|
//
|
||||||
|
// Kyoo is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// Kyoo is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using System.Xml.XPath;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
|
||||||
|
namespace Kyoo.Swagger
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A static class containing a custom way to include XML to Swagger.
|
||||||
|
/// </summary>
|
||||||
|
public static class XmlDocumentationLoader
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Inject human-friendly descriptions for Operations, Parameters and Schemas based on XML Comment files
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The swagger generator to add documentation to.</param>
|
||||||
|
public static void LoadXmlDocumentation(this SwaggerGenOptions options)
|
||||||
|
{
|
||||||
|
ICollection<XDocument> docs = Directory.GetFiles(AppContext.BaseDirectory, "*.xml")
|
||||||
|
.Select(XDocument.Load)
|
||||||
|
.ToList();
|
||||||
|
Dictionary<string, XElement> elements = docs
|
||||||
|
.SelectMany(x => x.XPathSelectElements("/doc/members/member[@name and not(inheritdoc)]"))
|
||||||
|
.ToDictionary(x => x.Attribute("name")!.Value, x => x);
|
||||||
|
|
||||||
|
foreach (XElement doc in docs
|
||||||
|
.SelectMany(x => x.XPathSelectElements("/doc/members/member[inheritdoc[@cref]]")))
|
||||||
|
{
|
||||||
|
if (elements.TryGetValue(doc.Attribute("cref")!.Value, out XElement member))
|
||||||
|
doc.Element("inheritdoc")!.ReplaceWith(member);
|
||||||
|
}
|
||||||
|
foreach (XElement doc in docs.SelectMany(x => x.XPathSelectElements("//see[@cref]")))
|
||||||
|
{
|
||||||
|
string fullName = doc.Attribute("cref")!.Value;
|
||||||
|
string shortName = fullName[(fullName.LastIndexOf('.') + 1)..];
|
||||||
|
// TODO won't work with fully qualified methods.
|
||||||
|
if (fullName.StartsWith("M:"))
|
||||||
|
shortName += "()";
|
||||||
|
doc.ReplaceWith(shortName);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (XDocument doc in docs)
|
||||||
|
options.IncludeXmlComments(() => new XPathDocument(doc.CreateReader()), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user