using API.Controllers.DTOs; using API.Schema.MangaContext; using Asp.Versioning; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Soenneker.Utils.String.NeedlemanWunsch; using static Microsoft.AspNetCore.Http.StatusCodes; using Author = API.Controllers.DTOs.Author; using Chapter = API.Controllers.DTOs.Chapter; // ReSharper disable InconsistentNaming namespace API.Controllers; [ApiVersion(2)] [ApiController] [Route("v{v:apiVersion}/[controller]")] public class QueryController(MangaContext context) : Controller { /// /// Returns the with /// /// .Key /// /// with not found [HttpGet("Author/{AuthorId}")] [ProducesResponseType(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound, "text/plain")] public async Task, NotFound>> GetAuthor (string AuthorId) { if (await context.Authors.FirstOrDefaultAsync(a => a.Key == AuthorId, HttpContext.RequestAborted) is not { } author) return TypedResults.NotFound(nameof(AuthorId)); return TypedResults.Ok(new Author(author.Key, author.AuthorName)); } /// /// Returns with /// /// .Key /// /// with not found [HttpGet("Chapter/{ChapterId}")] [ProducesResponseType(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound, "text/plain")] public async Task, NotFound>> GetChapter (string ChapterId) { if (await context.Chapters.FirstOrDefaultAsync(c => c.Key == ChapterId, HttpContext.RequestAborted) is not { } chapter) return TypedResults.NotFound(nameof(ChapterId)); IEnumerable ids = chapter.MangaConnectorIds.Select(id => new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload)); return TypedResults.Ok(new Chapter(chapter.Key, chapter.ParentMangaId, chapter.VolumeNumber, chapter.ChapterNumber, chapter.Title,ids, chapter.Downloaded)); } /// /// Returns the with .Key /// /// Key of /// /// with not found [HttpGet("Manga/MangaConnectorId/{MangaConnectorIdId}")] [ProducesResponseType(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound, "text/plain")] public async Task, NotFound>> GetMangaMangaConnectorId (string MangaConnectorIdId) { if (await context.MangaConnectorToManga.FirstOrDefaultAsync(c => c.Key == MangaConnectorIdId, HttpContext.RequestAborted) is not { } mcIdManga) return TypedResults.NotFound(nameof(MangaConnectorIdId)); MangaConnectorId result = new (mcIdManga.Key, mcIdManga.MangaConnectorName, mcIdManga.ObjId, mcIdManga.WebsiteUrl, mcIdManga.UseForDownload); return TypedResults.Ok(result); } /// /// Returns with names similar to (identified by ) /// /// Key of /// /// with not found /// Error during Database Operation [HttpGet("Manga/{MangaId}/SimilarName")] [ProducesResponseType>(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound, "text/plain")] [ProducesResponseType(Status500InternalServerError)] public async Task>, NotFound, InternalServerError>> GetSimilarManga (string MangaId) { if (await context.Mangas.FirstOrDefaultAsync(m => m.Key == MangaId, HttpContext.RequestAborted) is not { } manga) return TypedResults.NotFound(nameof(MangaId)); string name = manga.Name; if (await context.Mangas.Where(m => m.Key != MangaId) .ToDictionaryAsync(m => m.Key, m => m.Name, HttpContext.RequestAborted) is not { } mangaNames) return TypedResults.InternalServerError(); List similarIds = mangaNames .Where(kv => NeedlemanWunschStringUtil.CalculateSimilarityPercentage(name, kv.Value) > 0.8) .Select(kv => kv.Key) .ToList(); return TypedResults.Ok(similarIds); } /// /// Returns the with .Key /// /// Key of /// /// with not found [HttpGet("Chapter/MangaConnectorId/{MangaConnectorIdId}")] [ProducesResponseType(Status200OK, "application/json")] [ProducesResponseType(Status404NotFound, "text/plain")] public async Task, NotFound>> GetChapterMangaConnectorId (string MangaConnectorIdId) { if (await context.MangaConnectorToManga.FirstOrDefaultAsync(c => c.Key == MangaConnectorIdId, HttpContext.RequestAborted) is not { } mcIdChapter) return TypedResults.NotFound(nameof(MangaConnectorIdId)); MangaConnectorId result = new(mcIdChapter.Key, mcIdChapter.MangaConnectorName, mcIdChapter.ObjId, mcIdChapter.WebsiteUrl, mcIdChapter.UseForDownload); return TypedResults.Ok(result); } }