From 24a45c0b72364b601210be3751ac9caf18a49fcc Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Wed, 29 Sep 2021 16:22:53 +0200 Subject: [PATCH] API: Doucmenting subtitles's API --- src/Kyoo.Core/Views/SubtitleApi.cs | 121 +++++++++++++++++++---------- 1 file changed, 82 insertions(+), 39 deletions(-) diff --git a/src/Kyoo.Core/Views/SubtitleApi.cs b/src/Kyoo.Core/Views/SubtitleApi.cs index 784a9022..41b25063 100644 --- a/src/Kyoo.Core/Views/SubtitleApi.cs +++ b/src/Kyoo.Core/Views/SubtitleApi.cs @@ -22,39 +22,79 @@ using System.Linq; using System.Threading.Tasks; using Kyoo.Abstractions.Controllers; using Kyoo.Abstractions.Models; +using Kyoo.Abstractions.Models.Attributes; using Kyoo.Abstractions.Models.Permissions; +using Kyoo.Abstractions.Models.Utils; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using static Kyoo.Abstractions.Models.Utils.Constants; namespace Kyoo.Core.Api { - [Route("subtitle")] + /// + /// An endpoint to retrieve subtitles for a specific episode. + /// + [Route("subtitles")] + [Route("subtitle", Order = AlternativeRoute)] + [PartialPermission(nameof(SubtitleApi))] [ApiController] + [ApiDefinition("Subtitles", Group = WatchGroup)] public class SubtitleApi : ControllerBase { + /// + /// The library manager used to modify or retrieve information about the data store. + /// private readonly ILibraryManager _libraryManager; + + /// + /// The file manager used to send subtitles files. + /// private readonly IFileSystem _files; + /// + /// Create a new . + /// + /// The library manager used to interact with the data store. + /// The file manager used to send subtitle files. public SubtitleApi(ILibraryManager libraryManager, IFileSystem files) { _libraryManager = libraryManager; _files = files; } - [HttpGet("{id:int}")] - [Permission(nameof(SubtitleApi), Kind.Read)] - public async Task GetSubtitle(int id) + /// + /// Get subtitle + /// + /// + /// Get the subtitle file with the given identifier. + /// The extension is optional and can be used to ask Kyoo to convert the subtitle file on the fly. + /// + /// + /// The ID or slug of the subtitle (the same as the corresponding ). + /// + /// An optional extension for the subtitle file. + /// The subtitle file + /// No subtitle exist with the given ID or slug. + [HttpGet("{identifier:id}", Order = AlternativeRoute)] + [HttpGet("{identifier:id}.{extension}")] + [PartialPermission(Kind.Read)] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetSubtitle(Identifier identifier, string extension) { - Track subtitle = await _libraryManager.GetOrDefault(id); - return subtitle != null - ? _files.FileResult(subtitle.Path) - : NotFound(); - } + Track subtitle = await identifier.Match( + id => _libraryManager.GetOrDefault(id), + slug => + { + if (slug.Count(x => x == '.') == 3) + { + int idx = slug.LastIndexOf('.'); + extension = slug[(idx + 1)..]; + slug = slug[..idx]; + } + return _libraryManager.GetOrDefault(Track.BuildSlug(slug, StreamType.Subtitle)); + }); - [HttpGet("{id:int}.{extension}")] - [Permission(nameof(SubtitleApi), Kind.Read)] - public async Task GetSubtitle(int id, string extension) - { - Track subtitle = await _libraryManager.GetOrDefault(id); if (subtitle == null) return NotFound(); if (subtitle.Codec == "subrip" && extension == "vtt") @@ -62,38 +102,37 @@ namespace Kyoo.Core.Api return _files.FileResult(subtitle.Path); } - [HttpGet("{slug}")] - [Permission(nameof(SubtitleApi), Kind.Read)] - public async Task GetSubtitle(string slug) - { - string extension = null; - - if (slug.Count(x => x == '.') == 3) - { - int idx = slug.LastIndexOf('.'); - extension = slug[(idx + 1)..]; - slug = slug[..idx]; - } - - Track subtitle = await _libraryManager.GetOrDefault(Track.BuildSlug(slug, StreamType.Subtitle)); - if (subtitle == null) - return NotFound(); - if (subtitle.Codec == "subrip" && extension == "vtt") - return new ConvertSubripToVtt(subtitle.Path, _files); - return _files.FileResult(subtitle.Path); - } - - public class ConvertSubripToVtt : IActionResult + /// + /// An action result that convert a subrip subtitle to vtt. + /// + private class ConvertSubripToVtt : IActionResult { + /// + /// The path of the file to convert. It can be any path supported by a . + /// private readonly string _path; + + /// + /// The file system used to manipulate the given file. + /// private readonly IFileSystem _files; + /// + /// Create a new . + /// + /// + /// The path of the subtitle file. It can be any path supported by the given . + /// + /// + /// The file system used to interact with the file at the given . + /// public ConvertSubripToVtt(string subtitlePath, IFileSystem files) { _path = subtitlePath; _files = files; } + /// public async Task ExecuteResultAsync(ActionContext context) { List lines = new(); @@ -127,7 +166,12 @@ namespace Kyoo.Core.Api await context.HttpContext.Response.Body.FlushAsync(); } - private static IEnumerable _ConvertBlock(IList lines) + /// + /// Convert a block from subrip to vtt. + /// + /// All the lines in the block. + /// The given block, converted to vtt. + private static IList _ConvertBlock(IList lines) { if (lines.Count < 3) return lines; @@ -150,8 +194,7 @@ namespace Kyoo.Core.Api } if (lines[2].StartsWith("{\\an")) - lines[2] = lines[2].Substring(6); - + lines[2] = lines[2][6..]; return lines; } }