mirror of
https://github.com/C9Glax/tranga.git
synced 2025-06-14 07:17:54 +02:00
#168 Multiple Base-Paths (Libraries) Support
Some checks failed
Docker Image CI / build (push) Has been cancelled
Some checks failed
Docker Image CI / build (push) Has been cancelled
This commit is contained in:
@ -100,20 +100,37 @@ public class JobController(PgsqlContext context) : Controller
|
||||
/// Create a new DownloadAvailableChaptersJob
|
||||
/// </summary>
|
||||
/// <param name="MangaId">ID of Manga</param>
|
||||
/// <param name="recurrenceTime">How often should we check for new chapters</param>
|
||||
/// <param name="record">Job-Configuration</param>
|
||||
/// <response code="201">Job-IDs</response>
|
||||
/// <response code="400">Could not find Library with ID</response>
|
||||
/// <response code="404">Could not find Manga with ID</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPut("DownloadAvailableChaptersJob/{MangaId}")]
|
||||
[ProducesResponseType<string[]>(Status201Created, "application/json")]
|
||||
[ProducesResponseType(Status400BadRequest)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateNewDownloadChapterJob(string MangaId, [FromBody]ulong recurrenceTime)
|
||||
public IActionResult CreateDownloadAvailableChaptersJob(string MangaId, [FromBody]DownloadAvailableJobsRecord record)
|
||||
{
|
||||
if (context.Manga.Find(MangaId) is null)
|
||||
if (context.Mangas.Find(MangaId) is not { } m)
|
||||
return NotFound();
|
||||
Job dep = new RetrieveChaptersJob(recurrenceTime, MangaId);
|
||||
Job job = new DownloadAvailableChaptersJob(recurrenceTime, MangaId, null, [dep.JobId]);
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
LocalLibrary? l = context.LocalLibraries.Find(record.localLibraryId);
|
||||
if (l is null)
|
||||
return BadRequest();
|
||||
m.Library = l;
|
||||
context.SaveChanges();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return StatusCode(500, e.Message);
|
||||
}
|
||||
}
|
||||
Job dep = new RetrieveChaptersJob(record.recurrenceTimeMs, MangaId);
|
||||
Job job = new DownloadAvailableChaptersJob(record.recurrenceTimeMs, MangaId, null, [dep.JobId]);
|
||||
return AddJobs([dep, job]);
|
||||
}
|
||||
|
||||
@ -149,7 +166,7 @@ public class JobController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateUpdateFilesDownloadedJob(string MangaId)
|
||||
{
|
||||
if(context.Manga.Find(MangaId) is null)
|
||||
if(context.Mangas.Find(MangaId) is null)
|
||||
return NotFound();
|
||||
Job job = new UpdateFilesDownloadedJob(0, MangaId);
|
||||
return AddJobs([job]);
|
||||
@ -165,7 +182,7 @@ public class JobController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateUpdateAllFilesDownloadedJob()
|
||||
{
|
||||
List<string> ids = context.Manga.Select(m => m.MangaId).ToList();
|
||||
List<string> ids = context.Mangas.Select(m => m.MangaId).ToList();
|
||||
List<UpdateFilesDownloadedJob> jobs = ids.Select(id => new UpdateFilesDownloadedJob(0, id)).ToList();
|
||||
try
|
||||
{
|
||||
@ -192,7 +209,7 @@ public class JobController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateUpdateMetadataJob(string MangaId)
|
||||
{
|
||||
if(context.Manga.Find(MangaId) is null)
|
||||
if(context.Mangas.Find(MangaId) is null)
|
||||
return NotFound();
|
||||
Job job = new UpdateMetadataJob(0, MangaId);
|
||||
return AddJobs([job]);
|
||||
@ -208,7 +225,7 @@ public class JobController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateUpdateAllMetadataJob()
|
||||
{
|
||||
List<string> ids = context.Manga.Select(m => m.MangaId).ToList();
|
||||
List<string> ids = context.Mangas.Select(m => m.MangaId).ToList();
|
||||
List<UpdateMetadataJob> jobs = ids.Select(id => new UpdateMetadataJob(0, id)).ToList();
|
||||
try
|
||||
{
|
||||
|
127
API/Controllers/LocalLibrariesController.cs
Normal file
127
API/Controllers/LocalLibrariesController.cs
Normal file
@ -0,0 +1,127 @@
|
||||
using API.APIEndpointRecords;
|
||||
using API.Schema;
|
||||
using Asp.Versioning;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using static Microsoft.AspNetCore.Http.StatusCodes;
|
||||
|
||||
namespace API.Controllers;
|
||||
|
||||
[ApiVersion(2)]
|
||||
[ApiController]
|
||||
[Route("v{v:apiVersion}/[controller]")]
|
||||
public class LocalLibrariesController(PgsqlContext context) : Controller
|
||||
{
|
||||
[HttpGet]
|
||||
[ProducesResponseType<LocalLibrary[]>(Status200OK, "application/json")]
|
||||
public IActionResult GetLocalLibraries()
|
||||
{
|
||||
return Ok(context.LocalLibraries);
|
||||
}
|
||||
|
||||
[HttpGet("{LibraryId}")]
|
||||
[ProducesResponseType<LocalLibrary>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetLocalLibrary(string LibraryId)
|
||||
{
|
||||
LocalLibrary? library = context.LocalLibraries.Find(LibraryId);
|
||||
if (library is null)
|
||||
return NotFound();
|
||||
return Ok(library);
|
||||
}
|
||||
|
||||
[HttpPatch("{LibraryId}/ChangeBasePath")]
|
||||
[ProducesResponseType(Status200OK)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType(Status400BadRequest)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult ChangeLibraryBasePath(string LibraryId, [FromBody] string newBasePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
LocalLibrary? library = context.LocalLibraries.Find(LibraryId);
|
||||
if (library is null)
|
||||
return NotFound();
|
||||
|
||||
if (false) //TODO implement path check
|
||||
return BadRequest();
|
||||
|
||||
library.BasePath = newBasePath;
|
||||
context.SaveChanges();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return StatusCode(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch("{LibraryId}/ChangeName")]
|
||||
[ProducesResponseType(Status200OK)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType(Status400BadRequest)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult ChangeLibraryName(string LibraryId, [FromBody] string newName)
|
||||
{
|
||||
try
|
||||
{
|
||||
LocalLibrary? library = context.LocalLibraries.Find(LibraryId);
|
||||
if (library is null)
|
||||
return NotFound();
|
||||
|
||||
if(newName.Length < 1)
|
||||
return BadRequest();
|
||||
|
||||
library.LibraryName = newName;
|
||||
context.SaveChanges();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return StatusCode(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[ProducesResponseType<LocalLibrary>(Status200OK, "application/json")]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateNewLibrary([FromBody] NewLibraryRecord library)
|
||||
{
|
||||
try
|
||||
{
|
||||
LocalLibrary newLibrary = new (library.path, library.name);
|
||||
context.LocalLibraries.Add(newLibrary);
|
||||
context.SaveChanges();
|
||||
|
||||
return Ok(newLibrary);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return StatusCode(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete("{LibraryId}")]
|
||||
[ProducesResponseType(Status200OK)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult DeleteLocalLibrary(string LibraryId)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
LocalLibrary? library = context.LocalLibraries.Find(LibraryId);
|
||||
if (library is null)
|
||||
return NotFound();
|
||||
context.Remove(library);
|
||||
context.SaveChanges();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return StatusCode(500, e.Message);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<Manga[]>(Status200OK, "application/json")]
|
||||
public IActionResult GetAllManga()
|
||||
{
|
||||
Manga[] ret = context.Manga.ToArray();
|
||||
Manga[] ret = context.Mangas.ToArray();
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<Manga[]>(Status200OK, "application/json")]
|
||||
public IActionResult GetManga([FromBody]string[] ids)
|
||||
{
|
||||
Manga[] ret = context.Manga.Where(m => ids.Contains(m.MangaId)).ToArray();
|
||||
Manga[] ret = context.Mangas.Where(m => ids.Contains(m.MangaId)).ToArray();
|
||||
return Ok(ret);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetManga(string MangaId)
|
||||
{
|
||||
Manga? ret = context.Manga.Find(MangaId);
|
||||
Manga? ret = context.Mangas.Find(MangaId);
|
||||
if (ret is null)
|
||||
return NotFound();
|
||||
return Ok(ret);
|
||||
@ -72,7 +72,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
Manga? ret = context.Manga.Find(MangaId);
|
||||
Manga? ret = context.Mangas.Find(MangaId);
|
||||
if (ret is null)
|
||||
return NotFound();
|
||||
|
||||
@ -103,7 +103,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetCover(string MangaId, [FromQuery]int? width, [FromQuery]int? height)
|
||||
{
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
Manga? m = context.Mangas.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
if (!System.IO.File.Exists(m.CoverFileNameInCache))
|
||||
@ -148,7 +148,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetChapters(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
Manga? m = context.Mangas.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -169,7 +169,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetChaptersDownloaded(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
Manga? m = context.Mangas.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -193,7 +193,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetChaptersNotDownloaded(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
Manga? m = context.Mangas.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -219,7 +219,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult GetLatestChapter(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
Manga? m = context.Mangas.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -249,7 +249,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult GetLatestChapterDownloaded(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
Manga? m = context.Mangas.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -277,7 +277,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult IgnoreChaptersBefore(string MangaId, [FromBody]float chapterThreshold)
|
||||
{
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
Manga? m = context.Mangas.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -305,7 +305,7 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult MoveFolder(string MangaId, [FromBody]string folder)
|
||||
{
|
||||
Manga? manga = context.Manga.Find(MangaId);
|
||||
Manga? manga = context.Mangas.Find(MangaId);
|
||||
if (manga is null)
|
||||
return NotFound();
|
||||
MoveFileOrFolderJob dep = manga.UpdateFolderName(TrangaSettings.downloadLocation, folder);
|
||||
|
@ -36,7 +36,7 @@ public class QueryController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<Manga[]>(Status200OK, "application/json")]
|
||||
public IActionResult GetMangaWithAuthorIds(string AuthorId)
|
||||
{
|
||||
return Ok(context.Manga.Where(m => m.AuthorIds.Contains(AuthorId)));
|
||||
return Ok(context.Mangas.Where(m => m.AuthorIds.Contains(AuthorId)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -50,7 +50,7 @@ public class QueryController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetLink(string LinkId)
|
||||
{
|
||||
Link? ret = context.Link.Find(LinkId);
|
||||
Link? ret = context.Links.Find(LinkId);
|
||||
if (ret is null)
|
||||
return NotFound();
|
||||
return Ok(ret);
|
||||
@ -82,7 +82,7 @@ public class QueryController(PgsqlContext context) : Controller
|
||||
[ProducesResponseType<Manga[]>(Status200OK, "application/json")]
|
||||
public IActionResult GetMangasWithTag(string Tag)
|
||||
{
|
||||
return Ok(context.Manga.Where(m => m.Tags.Contains(Tag)));
|
||||
return Ok(context.Mangas.Where(m => m.Tags.Contains(Tag)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -131,7 +131,7 @@ public class SearchController(PgsqlContext context) : Controller
|
||||
if (manga is null)
|
||||
return null;
|
||||
|
||||
Manga? existing = context.Manga.Find(manga.MangaId);
|
||||
Manga? existing = context.Mangas.Find(manga.MangaId);
|
||||
|
||||
if (tags is not null)
|
||||
{
|
||||
@ -163,13 +163,13 @@ public class SearchController(PgsqlContext context) : Controller
|
||||
{
|
||||
IEnumerable<Link> mergedLinks = links.Select(ml =>
|
||||
{
|
||||
Link? inDb = context.Link.Find(ml.LinkId);
|
||||
Link? inDb = context.Links.Find(ml.LinkId);
|
||||
return inDb ?? ml;
|
||||
});
|
||||
manga.Links = mergedLinks.ToList();
|
||||
IEnumerable<Link> newLinks = manga.Links
|
||||
.Where(ml => !context.Link.Select(l => l.LinkId).Contains(ml.LinkId));
|
||||
context.Link.AddRange(newLinks);
|
||||
.Where(ml => !context.Links.Select(l => l.LinkId).Contains(ml.LinkId));
|
||||
context.Links.AddRange(newLinks);
|
||||
}
|
||||
|
||||
if (altTitles is not null)
|
||||
@ -187,9 +187,9 @@ public class SearchController(PgsqlContext context) : Controller
|
||||
|
||||
existing?.UpdateWithInfo(manga);
|
||||
if(existing is not null)
|
||||
context.Manga.Update(existing);
|
||||
context.Mangas.Update(existing);
|
||||
else
|
||||
context.Manga.Add(manga);
|
||||
context.Mangas.Add(manga);
|
||||
|
||||
context.Jobs.Add(new DownloadMangaCoverJob(manga.MangaId));
|
||||
context.Jobs.Add(new RetrieveChaptersJob(0, manga.MangaId));
|
||||
|
Reference in New Issue
Block a user