Fix TrangaBaseContext.Sync

This commit is contained in:
2025-07-03 22:39:06 +02:00
parent cf2dbeaf6a
commit e8d612557f
14 changed files with 33 additions and 86 deletions

View File

@ -9,7 +9,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class FileLibraryController(IServiceScope scope) : Controller public class FileLibraryController(MangaContext context) : Controller
{ {
/// <summary> /// <summary>
/// Returns all <see cref="FileLibrary"/> /// Returns all <see cref="FileLibrary"/>
@ -19,8 +19,6 @@ public class FileLibraryController(IServiceScope scope) : Controller
[ProducesResponseType<FileLibrary[]>(Status200OK, "application/json")] [ProducesResponseType<FileLibrary[]>(Status200OK, "application/json")]
public IActionResult GetFileLibraries() public IActionResult GetFileLibraries()
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
return Ok(context.FileLibraries.ToArray()); return Ok(context.FileLibraries.ToArray());
} }
@ -35,7 +33,6 @@ public class FileLibraryController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetFileLibrary(string FileLibraryId) public IActionResult GetFileLibrary(string FileLibraryId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.FileLibraries.Find(FileLibraryId) is not { } library) if (context.FileLibraries.Find(FileLibraryId) is not { } library)
return NotFound(); return NotFound();
@ -56,14 +53,13 @@ public class FileLibraryController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult ChangeLibraryBasePath(string FileLibraryId, [FromBody]string newBasePath) public IActionResult ChangeLibraryBasePath(string FileLibraryId, [FromBody]string newBasePath)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.FileLibraries.Find(FileLibraryId) is not { } library) if (context.FileLibraries.Find(FileLibraryId) is not { } library)
return NotFound(); return NotFound();
//TODO Path check //TODO Path check
library.BasePath = newBasePath; library.BasePath = newBasePath;
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Ok(); return Ok();
} }
@ -83,14 +79,13 @@ public class FileLibraryController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult ChangeLibraryName(string FileLibraryId, [FromBody] string newName) public IActionResult ChangeLibraryName(string FileLibraryId, [FromBody] string newName)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.FileLibraries.Find(FileLibraryId) is not { } library) if (context.FileLibraries.Find(FileLibraryId) is not { } library)
return NotFound(); return NotFound();
//TODO Name check //TODO Name check
library.LibraryName = newName; library.LibraryName = newName;
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Ok(); return Ok();
} }
@ -106,12 +101,11 @@ public class FileLibraryController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult CreateNewLibrary([FromBody]FileLibrary library) public IActionResult CreateNewLibrary([FromBody]FileLibrary library)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
//TODO Parameter check //TODO Parameter check
context.FileLibraries.Add(library); context.FileLibraries.Add(library);
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Created(); return Created();
} }
@ -128,13 +122,12 @@ public class FileLibraryController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult DeleteLocalLibrary(string FileLibraryId) public IActionResult DeleteLocalLibrary(string FileLibraryId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.FileLibraries.Find(FileLibraryId) is not { } library) if (context.FileLibraries.Find(FileLibraryId) is not { } library)
return NotFound(); return NotFound();
context.FileLibraries.Remove(library); context.FileLibraries.Remove(library);
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Ok(); return Ok();
} }

View File

@ -10,7 +10,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class LibraryConnectorController(IServiceScope scope) : Controller public class LibraryConnectorController(LibraryContext context) : Controller
{ {
/// <summary> /// <summary>
/// Gets all configured <see cref="LibraryConnector"/> /// Gets all configured <see cref="LibraryConnector"/>
@ -20,8 +20,6 @@ public class LibraryConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<LibraryConnector[]>(Status200OK, "application/json")] [ProducesResponseType<LibraryConnector[]>(Status200OK, "application/json")]
public IActionResult GetAllConnectors() public IActionResult GetAllConnectors()
{ {
LibraryContext context = scope.ServiceProvider.GetRequiredService<LibraryContext>();
LibraryConnector[] connectors = context.LibraryConnectors.ToArray(); LibraryConnector[] connectors = context.LibraryConnectors.ToArray();
return Ok(connectors); return Ok(connectors);
@ -38,7 +36,6 @@ public class LibraryConnectorController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetConnector(string LibraryConnectorId) public IActionResult GetConnector(string LibraryConnectorId)
{ {
LibraryContext context = scope.ServiceProvider.GetRequiredService<LibraryContext>();
if (context.LibraryConnectors.Find(LibraryConnectorId) is not { } connector) if (context.LibraryConnectors.Find(LibraryConnectorId) is not { } connector)
return NotFound(); return NotFound();
@ -56,11 +53,10 @@ public class LibraryConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult CreateConnector([FromBody]LibraryConnector libraryConnector) public IActionResult CreateConnector([FromBody]LibraryConnector libraryConnector)
{ {
LibraryContext context = scope.ServiceProvider.GetRequiredService<LibraryContext>();
context.LibraryConnectors.Add(libraryConnector); context.LibraryConnectors.Add(libraryConnector);
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Created(); return Created();
} }
@ -78,13 +74,12 @@ public class LibraryConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult DeleteConnector(string LibraryConnectorId) public IActionResult DeleteConnector(string LibraryConnectorId)
{ {
LibraryContext context = scope.ServiceProvider.GetRequiredService<LibraryContext>();
if (context.LibraryConnectors.Find(LibraryConnectorId) is not { } connector) if (context.LibraryConnectors.Find(LibraryConnectorId) is not { } connector)
return NotFound(); return NotFound();
context.LibraryConnectors.Remove(connector); context.LibraryConnectors.Remove(connector);
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Ok(); return Ok();
} }

View File

@ -10,7 +10,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class MangaConnectorController(IServiceScope scope) : Controller public class MangaConnectorController(MangaContext context) : Controller
{ {
/// <summary> /// <summary>
/// Get all <see cref="MangaConnector"/> (Scanlation-Sites) /// Get all <see cref="MangaConnector"/> (Scanlation-Sites)
@ -20,7 +20,6 @@ public class MangaConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<MangaConnector[]>(Status200OK, "application/json")] [ProducesResponseType<MangaConnector[]>(Status200OK, "application/json")]
public IActionResult GetConnectors() public IActionResult GetConnectors()
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
return Ok(context.MangaConnectors.Select(c => c.Name).ToArray()); return Ok(context.MangaConnectors.Select(c => c.Name).ToArray());
} }
@ -35,7 +34,6 @@ public class MangaConnectorController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetConnector(string MangaConnectorName) public IActionResult GetConnector(string MangaConnectorName)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector) if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector)
return NotFound(); return NotFound();
@ -50,7 +48,6 @@ public class MangaConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<MangaConnector[]>(Status200OK, "application/json")] [ProducesResponseType<MangaConnector[]>(Status200OK, "application/json")]
public IActionResult GetEnabledConnectors() public IActionResult GetEnabledConnectors()
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
return Ok(context.MangaConnectors.Where(c => c.Enabled).ToArray()); return Ok(context.MangaConnectors.Where(c => c.Enabled).ToArray());
} }
@ -63,7 +60,6 @@ public class MangaConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<MangaConnector[]>(Status200OK, "application/json")] [ProducesResponseType<MangaConnector[]>(Status200OK, "application/json")]
public IActionResult GetDisabledConnectors() public IActionResult GetDisabledConnectors()
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
return Ok(context.MangaConnectors.Where(c => c.Enabled == false).ToArray()); return Ok(context.MangaConnectors.Where(c => c.Enabled == false).ToArray());
} }
@ -82,13 +78,12 @@ public class MangaConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult SetEnabled(string MangaConnectorName, bool Enabled) public IActionResult SetEnabled(string MangaConnectorName, bool Enabled)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector) if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector)
return NotFound(); return NotFound();
connector.Enabled = Enabled; connector.Enabled = Enabled;
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Accepted(); return Accepted();
} }

View File

@ -16,7 +16,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class MangaController(IServiceScope scope) : Controller public class MangaController(MangaContext context) : Controller
{ {
/// <summary> /// <summary>
/// Returns all cached <see cref="Manga"/> /// Returns all cached <see cref="Manga"/>
@ -26,7 +26,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType<Manga[]>(Status200OK, "application/json")] [ProducesResponseType<Manga[]>(Status200OK, "application/json")]
public IActionResult GetAllManga() public IActionResult GetAllManga()
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
Manga[] ret = context.Mangas.ToArray(); Manga[] ret = context.Mangas.ToArray();
return Ok(ret); return Ok(ret);
} }
@ -40,7 +39,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType<Manga[]>(Status200OK, "application/json")] [ProducesResponseType<Manga[]>(Status200OK, "application/json")]
public IActionResult GetManga([FromBody]string[] MangaIds) public IActionResult GetManga([FromBody]string[] MangaIds)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
Manga[] ret = context.Mangas.Where(m => MangaIds.Contains(m.Key)).ToArray(); Manga[] ret = context.Mangas.Where(m => MangaIds.Contains(m.Key)).ToArray();
return Ok(ret); return Ok(ret);
} }
@ -56,7 +54,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetManga(string MangaId) public IActionResult GetManga(string MangaId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
return Ok(manga); return Ok(manga);
@ -75,13 +72,12 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult DeleteManga(string MangaId) public IActionResult DeleteManga(string MangaId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
context.Mangas.Remove(manga); context.Mangas.Remove(manga);
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Ok(); return Ok();
} }
@ -99,7 +95,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult MergeIntoManga(string MangaIdFrom, string MangaIdInto) public IActionResult MergeIntoManga(string MangaIdFrom, string MangaIdInto)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaIdFrom) is not { } from) if (context.Mangas.Find(MangaIdFrom) is not { } from)
return NotFound(nameof(MangaIdFrom)); return NotFound(nameof(MangaIdFrom));
if (context.Mangas.Find(MangaIdInto) is not { } into) if (context.Mangas.Find(MangaIdInto) is not { } into)
@ -130,7 +125,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType<int>(Status503ServiceUnavailable, "text/plain")] [ProducesResponseType<int>(Status503ServiceUnavailable, "text/plain")]
public IActionResult GetCover(string MangaId, [FromQuery]int? width, [FromQuery]int? height) public IActionResult GetCover(string MangaId, [FromQuery]int? width, [FromQuery]int? height)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
@ -176,7 +170,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetChapters(string MangaId) public IActionResult GetChapters(string MangaId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
@ -197,7 +190,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetChaptersDownloaded(string MangaId) public IActionResult GetChaptersDownloaded(string MangaId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
@ -221,7 +213,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetChaptersNotDownloaded(string MangaId) public IActionResult GetChaptersNotDownloaded(string MangaId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
@ -249,7 +240,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType<int>(Status503ServiceUnavailable, "text/plain")] [ProducesResponseType<int>(Status503ServiceUnavailable, "text/plain")]
public IActionResult GetLatestChapter(string MangaId) public IActionResult GetLatestChapter(string MangaId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
@ -288,7 +278,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType<int>(Status503ServiceUnavailable, "text/plain")] [ProducesResponseType<int>(Status503ServiceUnavailable, "text/plain")]
public IActionResult GetLatestChapterDownloaded(string MangaId) public IActionResult GetLatestChapterDownloaded(string MangaId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
@ -324,12 +313,11 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult IgnoreChaptersBefore(string MangaId, [FromBody]float chapterThreshold) public IActionResult IgnoreChaptersBefore(string MangaId, [FromBody]float chapterThreshold)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(); return NotFound();
manga.IgnoreChaptersBefore = chapterThreshold; manga.IgnoreChaptersBefore = chapterThreshold;
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Accepted(); return Accepted();
@ -347,13 +335,12 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult MoveFolder(string MangaId, string LibraryId) public IActionResult MoveFolder(string MangaId, string LibraryId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is not { } manga) if (context.Mangas.Find(MangaId) is not { } manga)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
if(context.FileLibraries.Find(LibraryId) is not { } library) if(context.FileLibraries.Find(LibraryId) is not { } library)
return NotFound(nameof(LibraryId)); return NotFound(nameof(LibraryId));
MoveMangaLibraryWorker moveLibrary = new(manga, library, scope); MoveMangaLibraryWorker moveLibrary = new(manga, library);
Tranga.AddWorkers([moveLibrary]); Tranga.AddWorkers([moveLibrary]);
@ -379,7 +366,6 @@ public class MangaController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult MarkAsRequested(string MangaId, string MangaConnectorName, bool IsRequested) public IActionResult MarkAsRequested(string MangaId, string MangaConnectorName, bool IsRequested)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Mangas.Find(MangaId) is null) if (context.Mangas.Find(MangaId) is null)
return NotFound(nameof(MangaId)); return NotFound(nameof(MangaId));
if(context.MangaConnectors.Find(MangaConnectorName) is null) if(context.MangaConnectors.Find(MangaConnectorName) is null)
@ -392,7 +378,7 @@ public class MangaController(IServiceScope scope) : Controller
return StatusCode(Status412PreconditionFailed, "Not linked anyways."); return StatusCode(Status412PreconditionFailed, "Not linked anyways.");
mcId.UseForDownload = IsRequested; mcId.UseForDownload = IsRequested;
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
DownloadCoverFromMangaconnectorWorker downloadCover = new(mcId); DownloadCoverFromMangaconnectorWorker downloadCover = new(mcId);

View File

@ -11,7 +11,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class MetadataFetcherController(IServiceScope scope) : Controller public class MetadataFetcherController(MangaContext context) : Controller
{ {
/// <summary> /// <summary>
/// Get all <see cref="MetadataFetcher"/> (Metadata-Sites) /// Get all <see cref="MetadataFetcher"/> (Metadata-Sites)
@ -32,8 +32,6 @@ public class MetadataFetcherController(IServiceScope scope) : Controller
[ProducesResponseType<MetadataEntry[]>(Status200OK, "application/json")] [ProducesResponseType<MetadataEntry[]>(Status200OK, "application/json")]
public IActionResult GetLinkedEntries() public IActionResult GetLinkedEntries()
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
return Ok(context.MetadataEntries.ToArray()); return Ok(context.MetadataEntries.ToArray());
} }
@ -52,7 +50,6 @@ public class MetadataFetcherController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult SearchMangaMetadata(string MangaId, string MetadataFetcherName, [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)]string? searchTerm = null) public IActionResult SearchMangaMetadata(string MangaId, string MetadataFetcherName, [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)]string? searchTerm = null)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if(context.Mangas.Find(MangaId) is not { } manga) if(context.Mangas.Find(MangaId) is not { } manga)
return NotFound(); return NotFound();
if(Tranga.MetadataFetchers.FirstOrDefault(f => f.Name == MetadataFetcherName) is not { } fetcher) if(Tranga.MetadataFetchers.FirstOrDefault(f => f.Name == MetadataFetcherName) is not { } fetcher)
@ -79,7 +76,6 @@ public class MetadataFetcherController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult LinkMangaMetadata(string MangaId, string MetadataFetcherName, [FromBody]string Identifier) public IActionResult LinkMangaMetadata(string MangaId, string MetadataFetcherName, [FromBody]string Identifier)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if(context.Mangas.Find(MangaId) is not { } manga) if(context.Mangas.Find(MangaId) is not { } manga)
return NotFound(); return NotFound();
if(Tranga.MetadataFetchers.FirstOrDefault(f => f.Name == MetadataFetcherName) is not { } fetcher) if(Tranga.MetadataFetchers.FirstOrDefault(f => f.Name == MetadataFetcherName) is not { } fetcher)
@ -88,7 +84,7 @@ public class MetadataFetcherController(IServiceScope scope) : Controller
MetadataEntry entry = fetcher.CreateMetadataEntry(manga, Identifier); MetadataEntry entry = fetcher.CreateMetadataEntry(manga, Identifier);
context.MetadataEntries.Add(entry); context.MetadataEntries.Add(entry);
if(context.Sync().Result is { } errorMessage) if(context.Sync() is { } errorMessage)
return StatusCode(Status500InternalServerError, errorMessage); return StatusCode(Status500InternalServerError, errorMessage);
return Ok(entry); return Ok(entry);
} }
@ -109,7 +105,6 @@ public class MetadataFetcherController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult UnlinkMangaMetadata(string MangaId, string MetadataFetcherName) public IActionResult UnlinkMangaMetadata(string MangaId, string MetadataFetcherName)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if(context.Mangas.Find(MangaId) is null) if(context.Mangas.Find(MangaId) is null)
return NotFound(); return NotFound();
if(Tranga.MetadataFetchers.FirstOrDefault(f => f.Name == MetadataFetcherName) is null) if(Tranga.MetadataFetchers.FirstOrDefault(f => f.Name == MetadataFetcherName) is null)
@ -119,7 +114,7 @@ public class MetadataFetcherController(IServiceScope scope) : Controller
context.Remove(entry); context.Remove(entry);
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Ok(); return Ok();
} }

View File

@ -13,7 +13,7 @@ namespace API.Controllers;
[ApiController] [ApiController]
[Produces("application/json")] [Produces("application/json")]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class NotificationConnectorController(IServiceScope scope) : Controller public class NotificationConnectorController(NotificationsContext context) : Controller
{ {
/// <summary> /// <summary>
/// Gets all configured <see cref="NotificationConnector"/> /// Gets all configured <see cref="NotificationConnector"/>
@ -23,7 +23,6 @@ public class NotificationConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<NotificationConnector[]>(Status200OK, "application/json")] [ProducesResponseType<NotificationConnector[]>(Status200OK, "application/json")]
public IActionResult GetAllConnectors() public IActionResult GetAllConnectors()
{ {
NotificationsContext context = scope.ServiceProvider.GetRequiredService<NotificationsContext>();
return Ok(context.NotificationConnectors.ToArray()); return Ok(context.NotificationConnectors.ToArray());
} }
@ -39,7 +38,6 @@ public class NotificationConnectorController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetConnector(string Name) public IActionResult GetConnector(string Name)
{ {
NotificationsContext context = scope.ServiceProvider.GetRequiredService<NotificationsContext>();
if(context.NotificationConnectors.Find(Name) is not { } connector) if(context.NotificationConnectors.Find(Name) is not { } connector)
return NotFound(); return NotFound();
@ -58,11 +56,10 @@ public class NotificationConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult CreateConnector([FromBody]NotificationConnector notificationConnector) public IActionResult CreateConnector([FromBody]NotificationConnector notificationConnector)
{ {
NotificationsContext context = scope.ServiceProvider.GetRequiredService<NotificationsContext>();
context.NotificationConnectors.Add(notificationConnector); context.NotificationConnectors.Add(notificationConnector);
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Created(); return Created();
} }
@ -150,13 +147,12 @@ public class NotificationConnectorController(IServiceScope scope) : Controller
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")] [ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
public IActionResult DeleteConnector(string Name) public IActionResult DeleteConnector(string Name)
{ {
NotificationsContext context = scope.ServiceProvider.GetRequiredService<NotificationsContext>();
if(context.NotificationConnectors.Find(Name) is not { } connector) if(context.NotificationConnectors.Find(Name) is not { } connector)
return NotFound(); return NotFound();
context.NotificationConnectors.Remove(connector); context.NotificationConnectors.Remove(connector);
if(context.Sync().Result is { success: false } result) if(context.Sync() is { success: false } result)
return StatusCode(Status500InternalServerError, result.exceptionMessage); return StatusCode(Status500InternalServerError, result.exceptionMessage);
return Created(); return Created();
} }

View File

@ -9,7 +9,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class QueryController(IServiceScope scope) : Controller public class QueryController(MangaContext context) : Controller
{ {
/// <summary> /// <summary>
/// Returns the <see cref="Author"/> with <paramref name="AuthorId"/> /// Returns the <see cref="Author"/> with <paramref name="AuthorId"/>
@ -22,7 +22,6 @@ public class QueryController(IServiceScope scope) : Controller
[ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status404NotFound)]
public IActionResult GetAuthor(string AuthorId) public IActionResult GetAuthor(string AuthorId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Authors.Find(AuthorId) is not { } author) if (context.Authors.Find(AuthorId) is not { } author)
return NotFound(); return NotFound();
@ -39,7 +38,6 @@ public class QueryController(IServiceScope scope) : Controller
[ProducesResponseType<Manga[]>(Status200OK, "application/json")] [ProducesResponseType<Manga[]>(Status200OK, "application/json")]
public IActionResult GetMangaWithAuthorIds(string AuthorId) public IActionResult GetMangaWithAuthorIds(string AuthorId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Authors.Find(AuthorId) is not { } author) if (context.Authors.Find(AuthorId) is not { } author)
return NotFound(); return NotFound();
@ -56,7 +54,6 @@ public class QueryController(IServiceScope scope) : Controller
[ProducesResponseType<Manga[]>(Status200OK, "application/json")] [ProducesResponseType<Manga[]>(Status200OK, "application/json")]
public IActionResult GetMangasWithTag(string Tag) public IActionResult GetMangasWithTag(string Tag)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Tags.Find(Tag) is not { } tag) if (context.Tags.Find(Tag) is not { } tag)
return NotFound(); return NotFound();
@ -73,7 +70,6 @@ public class QueryController(IServiceScope scope) : Controller
[ProducesResponseType<Chapter>(Status200OK, "application/json")] [ProducesResponseType<Chapter>(Status200OK, "application/json")]
public IActionResult GetChapter(string ChapterId) public IActionResult GetChapter(string ChapterId)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.Chapters.Find(ChapterId) is not { } chapter) if (context.Chapters.Find(ChapterId) is not { } chapter)
return NotFound(); return NotFound();

View File

@ -10,7 +10,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class SearchController(IServiceScope scope) : Controller public class SearchController(MangaContext context) : Controller
{ {
/// <summary> /// <summary>
/// Initiate a search for a <see cref="Manga"/> on <see cref="MangaConnector"/> with searchTerm /// Initiate a search for a <see cref="Manga"/> on <see cref="MangaConnector"/> with searchTerm
@ -26,7 +26,6 @@ public class SearchController(IServiceScope scope) : Controller
[ProducesResponseType(Status406NotAcceptable)] [ProducesResponseType(Status406NotAcceptable)]
public IActionResult SearchManga(string MangaConnectorName, string Query) public IActionResult SearchManga(string MangaConnectorName, string Query)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector) if(context.MangaConnectors.Find(MangaConnectorName) is not { } connector)
return NotFound(); return NotFound();
if (connector.Enabled is false) if (connector.Enabled is false)
@ -57,7 +56,6 @@ public class SearchController(IServiceScope scope) : Controller
[ProducesResponseType(Status500InternalServerError)] [ProducesResponseType(Status500InternalServerError)]
public IActionResult GetMangaFromUrl([FromBody]string url) public IActionResult GetMangaFromUrl([FromBody]string url)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>();
if (context.MangaConnectors.Find("Global") is not { } connector) if (context.MangaConnectors.Find("Global") is not { } connector)
return StatusCode(Status500InternalServerError, "Could not find Global Connector."); return StatusCode(Status500InternalServerError, "Could not find Global Connector.");

View File

@ -1,6 +1,4 @@
using API.MangaDownloadClients; using API.MangaDownloadClients;
using API.Schema.MangaContext;
using API.Workers;
using Asp.Versioning; using Asp.Versioning;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using static Microsoft.AspNetCore.Http.StatusCodes; using static Microsoft.AspNetCore.Http.StatusCodes;
@ -11,7 +9,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{v:apiVersion}/[controller]")] [Route("v{v:apiVersion}/[controller]")]
public class SettingsController(IServiceScope scope) : Controller public class SettingsController() : Controller
{ {
/// <summary> /// <summary>
/// Get all <see cref="Tranga.Settings"/> /// Get all <see cref="Tranga.Settings"/>
@ -221,13 +219,8 @@ public class SettingsController(IServiceScope scope) : Controller
[ProducesResponseType(Status200OK)] [ProducesResponseType(Status200OK)]
public IActionResult SetCustomNamingScheme([FromBody]string namingScheme) public IActionResult SetCustomNamingScheme([FromBody]string namingScheme)
{ {
MangaContext context = scope.ServiceProvider.GetRequiredService<MangaContext>(); //TODO Move old Chapters
Dictionary<Chapter, string> oldPaths = context.Chapters.ToDictionary(c => c, c => c.FullArchiveFilePath);
Tranga.Settings.SetChapterNamingScheme(namingScheme); Tranga.Settings.SetChapterNamingScheme(namingScheme);
MoveFileOrFolderWorker[] newJobs = oldPaths
.Select(kv => new MoveFileOrFolderWorker(kv.Value, kv.Key.FullArchiveFilePath)).ToArray();
Tranga.AddWorkers(newJobs);
return Ok(); return Ok();
} }

View File

@ -11,7 +11,7 @@ namespace API.Controllers;
[ApiVersion(2)] [ApiVersion(2)]
[ApiController] [ApiController]
[Route("v{version:apiVersion}/[controller]")] [Route("v{version:apiVersion}/[controller]")]
public class WorkerController(ILog Log) : Controller public class WorkerController() : Controller
{ {
/// <summary> /// <summary>
/// Returns all <see cref="BaseWorker"/> /// Returns all <see cref="BaseWorker"/>

View File

@ -67,7 +67,7 @@ public class MyAnimeList : MetadataFetcher
dbManga.Authors.Clear(); dbManga.Authors.Clear();
dbManga.Authors = resultData.Authors.Select(a => new Author(a.Name)).ToList(); dbManga.Authors = resultData.Authors.Select(a => new Author(a.Name)).ToList();
dbContext.SaveChanges(); dbContext.Sync();
} }
catch (DbUpdateException e) catch (DbUpdateException e)
{ {

View File

@ -22,11 +22,11 @@ public abstract class TrangaBaseContext<T> : DbContext where T : DbContext
}, Array.Empty<string>(), LogLevel.Warning, DbContextLoggerOptions.Level | DbContextLoggerOptions.Category | DbContextLoggerOptions.UtcTime); }, Array.Empty<string>(), LogLevel.Warning, DbContextLoggerOptions.Level | DbContextLoggerOptions.Category | DbContextLoggerOptions.UtcTime);
} }
internal async Task<(bool success, string? exceptionMessage)> Sync() internal (bool success, string? exceptionMessage) Sync()
{ {
try try
{ {
await this.SaveChangesAsync(); this.SaveChanges();
return (true, null); return (true, null);
} }
catch (Exception e) catch (Exception e)

View File

@ -174,7 +174,7 @@ public static class Tranga
if(context.MangaConnectorToManga.Find(addMcId.Key) is null) if(context.MangaConnectorToManga.Find(addMcId.Key) is null)
context.MangaConnectorToManga.Add(mcId); context.MangaConnectorToManga.Add(mcId);
if (context.Sync().Result is { success: false }) if (context.Sync() is { success: false })
return false; return false;
return true; return true;
} }
@ -191,7 +191,7 @@ public static class Tranga
if(context.MangaConnectorToChapter.Find(chId.Key) is null) if(context.MangaConnectorToChapter.Find(chId.Key) is null)
context.MangaConnectorToChapter.Add(chId); context.MangaConnectorToChapter.Add(chId);
if (context.Sync().Result is { success: false }) if (context.Sync() is { success: false })
return false; return false;
return true; return true;
} }

View File

@ -2,7 +2,7 @@ using API.Schema.MangaContext;
namespace API.Workers; namespace API.Workers;
public class MoveMangaLibraryWorker(Manga manga, FileLibrary toLibrary, IServiceScope scope, IEnumerable<BaseWorker>? dependsOn = null) public class MoveMangaLibraryWorker(Manga manga, FileLibrary toLibrary, IEnumerable<BaseWorker>? dependsOn = null)
: BaseWorkerWithContext<MangaContext>(dependsOn) : BaseWorkerWithContext<MangaContext>(dependsOn)
{ {
protected override BaseWorker[] DoWorkInternal() protected override BaseWorker[] DoWorkInternal()
@ -10,7 +10,7 @@ public class MoveMangaLibraryWorker(Manga manga, FileLibrary toLibrary, IService
Dictionary<Chapter, string> oldPath = manga.Chapters.ToDictionary(c => c, c => c.FullArchiveFilePath); Dictionary<Chapter, string> oldPath = manga.Chapters.ToDictionary(c => c, c => c.FullArchiveFilePath);
manga.Library = toLibrary; manga.Library = toLibrary;
if (DbContext.Sync().Result is { success: false }) if (DbContext.Sync() is { success: false })
return []; return [];
return manga.Chapters.Select(c => new MoveFileOrFolderWorker(c.FullArchiveFilePath, oldPath[c])).ToArray<BaseWorker>(); return manga.Chapters.Select(c => new MoveFileOrFolderWorker(c.FullArchiveFilePath, oldPath[c])).ToArray<BaseWorker>();