using API.Schema; using API.Schema.Jobs; using API.Schema.MangaConnectors; using Asp.Versioning; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Soenneker.Utils.String.NeedlemanWunsch; using static Microsoft.AspNetCore.Http.StatusCodes; namespace API.Controllers; [ApiVersion(2)] [ApiController] [Produces("application/json")] [Route("v{v:apiVersion}/[controller]")] public class ConnectorController(PgsqlContext context) : Controller { /// /// Get all available Connectors (Scanlation-Sites) /// /// Array of MangaConnector [HttpGet] [ProducesResponseType(Status200OK)] public IActionResult GetConnectors() { MangaConnector[] connectors = context.MangaConnectors.ToArray(); return Ok(connectors); } /// /// Initiate a search for a Manga on all Connectors /// /// Name/Title of the Manga /// Array of Manga [HttpPost("SearchManga")] [ProducesResponseType(Status500InternalServerError)] public IActionResult SearchMangaGlobal(string name) { List<(Manga, Author[], MangaTag[], Link[], MangaAltTitle[])> allManga = new(); foreach (MangaConnector contextMangaConnector in context.MangaConnectors) allManga.AddRange(contextMangaConnector.GetManga(name)); foreach ((Manga? manga, Author[]? authors, MangaTag[]? tags, Link[]? links, MangaAltTitle[]? altTitles) in allManga) { try { AddMangaToContext(manga, authors, tags, links, altTitles); } catch (DbUpdateException) { return StatusCode(500, new ProblemResponse("An error occurred while processing your request.")); } } return Ok(allManga.Select(m => context.Manga.Find(m.Item1.MangaId)).ToArray()); } /// /// Initiate a search for a Manga on a specific Connector /// /// Manga-Connector-ID /// Name/Title of the Manga /// Manga [HttpPost("{id}/SearchManga")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError)] public IActionResult SearchManga(string id, [FromBody]string name) { MangaConnector? connector = context.MangaConnectors.Find(id); if (connector is null) return NotFound(new ProblemResponse("Connector not found.")); (Manga, Author[], MangaTag[], Link[], MangaAltTitle[])[] mangas = connector.GetManga(name); foreach ((Manga? manga, Author[]? authors, MangaTag[]? tags, Link[]? links, MangaAltTitle[]? altTitles) in mangas) { try { AddMangaToContext(manga, authors, tags, links, altTitles); } catch (DbUpdateException) { return StatusCode(500, new ProblemResponse("An error occurred while processing your request.")); } } return Ok(mangas.Select(m => context.Manga.Find(m.Item1.MangaId)).ToArray()); } private void AddMangaToContext(Manga? manga, Author[]? authors, MangaTag[]? tags, Link[]? links, MangaAltTitle[]? altTitles) { if (manga is null) return; if (tags is not null) { IEnumerable newTags = tags.Where(mt => context.Tags.All(t => !t.Tag.Equals(mt.Tag))); context.Tags.AddRange(newTags); } if (authors is not null) { IEnumerable mergedAuthors = authors.Select(ma => { Author? inDb = context.Authors.FirstOrDefault(a => a.Equals(ma)); return inDb ?? ma; }); manga.Authors = mergedAuthors.ToArray(); IEnumerable newAuthors = authors.Where(ma => context.Authors.All(a => !a.Equals(ma))); context.Authors.AddRange(newAuthors); } if (links is not null) context.Link.AddRange(links); if(altTitles is not null) context.AltTitles.AddRange(altTitles); context.Manga.Add(manga); context.SaveChanges(); } }