using API.Schema; using Asp.Versioning; using Microsoft.AspNetCore.Mvc; using static Microsoft.AspNetCore.Http.StatusCodes; namespace API.Controllers; [ApiVersion(2)] [ApiController] [Produces("application/json")] [Route("v{v:apiVersion}/[controller]")] public class MangaController(PgsqlContext context) : Controller { /// /// Returns all cached Manga with IDs /// /// Array of Manga-IDs /// Array of Manga [HttpPost("WithIDs")] [ProducesResponseType(Status200OK)] public IActionResult GetManga([FromBody]string[] ids) { Manga[] ret = context.Manga.Where(m => ids.Contains(m.MangaId)).ToArray(); return Ok(ret); } /// /// Return Manga with ID /// /// Manga-ID /// Manga [HttpGet("{id}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] public IActionResult GetManga(string id) { Manga? ret = context.Manga.Find(id); return (ret is not null) switch { true => Ok(ret), false => NotFound() }; } /// /// Delete Manga with ID /// /// Manga-ID /// Nothing [HttpDelete("{id}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError)] public IActionResult DeleteManga(string id) { try { Manga? ret = context.Manga.Find(id); switch (ret is not null) { case true: context.Remove(ret); context.SaveChanges(); return Ok(); case false: return NotFound(); } } catch (Exception e) { return StatusCode(500, e.Message); } } /// /// Create new Manga /// /// Manga /// Nothing [HttpPut] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status500InternalServerError)] public IActionResult CreateManga([FromBody] Manga manga) { try { context.Manga.Add(manga); context.SaveChanges(); return Ok(); } catch (Exception e) { return StatusCode(500, e.Message); } } /// /// Update Manga MetaData /// /// Manga-ID /// New Manga-Info /// Nothing [HttpPatch("{id}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError)] public IActionResult UpdateMangaMetadata(string id, [FromBody]Manga manga) { try { Manga? ret = context.Manga.Find(id); switch (ret is not null) { case true: ret.UpdateWithInfo(manga); context.Update(ret); context.SaveChanges(); return Ok(); case false: return NotFound(); } } catch (Exception e) { return StatusCode(500, e.Message); } } /// /// Returns URL of Cover of Manga /// /// Manga-ID /// URL of Cover [HttpGet("{id}/Cover")] [ProducesResponseType(Status500InternalServerError)] public IActionResult GetCover(string id) { return StatusCode(500, "Not implemented"); //TODO } /// /// Returns all Chapters of Manga /// /// Manga-ID /// Array of Chapters [HttpGet("{id}/Chapters")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] public IActionResult GetChapters(string id) { Manga? m = context.Manga.Find(id); if (m is null) return NotFound("Manga could not be found"); Chapter[] ret = context.Chapters.Where(c => c.ParentMangaId == m.MangaId).ToArray(); return Ok(ret); } /// /// Adds/Creates new Chapter for Manga /// /// Manga-ID /// Array of Chapters /// Manga-ID and all Chapters have to be the same /// Nothing [HttpPut("{id}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError)] public IActionResult CreateChapters(string id, [FromBody]Chapter[] chapters) { try { Manga? ret = context.Manga.Find(id); if(ret is null) return NotFound("Manga could not be found"); if(chapters.All(c => c.ParentMangaId == ret.MangaId)) return BadRequest("Chapters belong to different Manga."); context.Chapters.AddRange(chapters); context.SaveChanges(); return Ok(); } catch (Exception e) { return StatusCode(500, e.Message); } } /// /// Returns the latest Chapter of requested Manga /// /// Manga-ID /// Latest Chapter [HttpGet("{id}/Chapter/Latest")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] public IActionResult GetLatestChapter(string id) { Manga? m = context.Manga.Find(id); if (m is null) return NotFound("Manga could not be found"); Chapter? c = context.Chapters.Find(m.LatestChapterAvailableId); if (c is null) return NotFound("Chapter could not be found"); return Ok(c); } /// /// Configure the cut-off for Manga /// /// This is important for the DownloadNewChapters-Job /// Manga-ID /// Nothing [HttpPatch("{id}/IgnoreChaptersBefore")] [ProducesResponseType(Status200OK)] public IActionResult IgnoreChaptersBefore(string id) { Manga? m = context.Manga.Find(id); if (m is null) return NotFound("Manga could not be found"); return Ok(m.IgnoreChapterBefore); } /// /// Move the Directory the .cbz-files are located in /// /// Manga-ID /// New Directory-Path /// Nothing [HttpPost("{id}/MoveFolder")] [ProducesResponseType(Status500InternalServerError)] public IActionResult MoveFolder(string id, [FromBody]string folder) { return StatusCode(500, "Not implemented"); //TODO } }