diff --git a/API/Controllers/ChaptersController.cs b/API/Controllers/ChaptersController.cs
new file mode 100644
index 0000000..ec21c42
--- /dev/null
+++ b/API/Controllers/ChaptersController.cs
@@ -0,0 +1,220 @@
+using API.Controllers.DTOs;
+using API.Schema.MangaContext;
+using Asp.Versioning;
+using Microsoft.AspNetCore.Http.HttpResults;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using static Microsoft.AspNetCore.Http.StatusCodes;
+using Chapter = API.Controllers.DTOs.Chapter;
+// ReSharper disable InconsistentNaming
+
+namespace API.Controllers;
+
+[ApiVersion(2)]
+[ApiController]
+[Route("v{v:apiVersion}/[controller]")]
+public class ChaptersController(MangaContext context) : Controller
+{
+ ///
+ /// Returns all of with
+ ///
+ /// .Key
+ ///
+ /// with not found
+ [HttpGet("{MangaId}")]
+ [ProducesResponseType>(Status200OK, "application/json")]
+ [ProducesResponseType(Status404NotFound)]
+ public async Task>, NotFound>> GetChapters(string MangaId)
+ {
+ if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
+ .Where(ch => ch.ParentMangaId == MangaId)
+ .ToListAsync(HttpContext.RequestAborted)
+ is not { } dbChapters)
+ return TypedResults.NotFound(nameof(MangaId));
+
+ List chapters = dbChapters.OrderDescending().Select(c =>
+ {
+ IEnumerable ids = c.MangaConnectorIds.Select(id =>
+ new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
+ return new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName);
+ }).ToList();
+
+ return TypedResults.Ok(chapters);
+ }
+
+ ///
+ /// Returns all downloaded for with
+ ///
+ /// .Key
+ ///
+ /// with not found.
+ [HttpGet("{MangaId}/Downloaded")]
+ [ProducesResponseType(Status200OK, "application/json")]
+ [ProducesResponseType(Status404NotFound, "text/plain")]
+ public async Task>, NotFound>> GetChaptersDownloaded(string MangaId)
+ {
+ if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
+ .Where(ch => ch.ParentMangaId == MangaId && ch.Downloaded)
+ .ToListAsync(HttpContext.RequestAborted)
+ is not { } dbChapters)
+ return TypedResults.NotFound(nameof(MangaId));
+
+ List chapters = dbChapters.OrderDescending().Select(c =>
+ {
+ IEnumerable ids = c.MangaConnectorIds.Select(id =>
+ new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
+ return new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName);
+ }).ToList();
+
+ return TypedResults.Ok(chapters);
+ }
+
+ ///
+ /// Returns all not downloaded for with
+ ///
+ /// .Key
+ ///
+ /// with not found.
+ [HttpGet("{MangaId}/NotDownloaded")]
+ [ProducesResponseType>(Status200OK, "application/json")]
+ [ProducesResponseType(Status404NotFound, "text/plain")]
+ public async Task>, NoContent, NotFound>> GetChaptersNotDownloaded(string MangaId)
+ {
+ if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
+ .Where(ch => ch.ParentMangaId == MangaId && ch.Downloaded == false)
+ .ToListAsync(HttpContext.RequestAborted)
+ is not { } dbChapters)
+ return TypedResults.NotFound(nameof(MangaId));
+
+ List chapters = dbChapters.OrderDescending().Select(c =>
+ {
+ IEnumerable ids = c.MangaConnectorIds.Select(id =>
+ new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
+ return new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName);
+ }).ToList();
+
+ return TypedResults.Ok(chapters);
+ }
+
+ ///
+ /// Returns the latest of requested
+ ///
+ /// .Key
+ ///
+ /// No available chapters
+ /// with not found.
+ [HttpGet("{MangaId}/LatestAvailable")]
+ [ProducesResponseType(Status200OK, "application/json")]
+ [ProducesResponseType(Status204NoContent)]
+ [ProducesResponseType(Status404NotFound, "text/plain")]
+ public async Task, NoContent, NotFound>> GetLatestChapter(string MangaId)
+ {
+ if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
+ .Where(ch => ch.ParentMangaId == MangaId)
+ .ToListAsync(HttpContext.RequestAborted)
+ is not { } dbChapters)
+ return TypedResults.NotFound(nameof(MangaId));
+
+ Schema.MangaContext.Chapter? c = dbChapters.Max();
+ if (c is null)
+ return TypedResults.NoContent();
+
+ IEnumerable ids = c.MangaConnectorIds.Select(id =>
+ new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
+ return TypedResults.Ok(new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName));
+ }
+
+ ///
+ /// Returns the latest of requested that is downloaded
+ ///
+ /// .Key
+ ///
+ /// No available chapters
+ /// with not found.
+ /// Could not retrieve the maximum chapter-number
+ /// Retry after timeout, updating value
+ [HttpGet("{MangaId}/LatestDownloaded")]
+ [ProducesResponseType(Status200OK, "application/json")]
+ [ProducesResponseType(Status204NoContent)]
+ [ProducesResponseType(Status404NotFound, "text/plain")]
+ [ProducesResponseType(Status412PreconditionFailed)]
+ [ProducesResponseType(Status503ServiceUnavailable)]
+ public async Task, NoContent, NotFound, StatusCodeHttpResult>> GetLatestChapterDownloaded(string MangaId)
+ {
+ if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
+ .Where(ch => ch.ParentMangaId == MangaId && ch.Downloaded)
+ .ToListAsync(HttpContext.RequestAborted)
+ is not { } dbChapters)
+ return TypedResults.NotFound(nameof(MangaId));
+
+ Schema.MangaContext.Chapter? c = dbChapters.Max();
+ if (c is null)
+ return TypedResults.NoContent();
+
+ IEnumerable ids = c.MangaConnectorIds.Select(id =>
+ new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
+ return TypedResults.Ok(new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName));
+ }
+
+ ///
+ /// Configure the cut-off for
+ ///
+ /// .Key
+ /// Threshold ( ChapterNumber)
+ ///
+ /// with not found.
+ /// Error during Database Operation
+ [HttpPatch("{MangaId}/IgnoreBefore")]
+ [ProducesResponseType(Status200OK)]
+ [ProducesResponseType(Status404NotFound, "text/plain")]
+ [ProducesResponseType(Status500InternalServerError, "text/plain")]
+ public async Task, InternalServerError>> IgnoreChaptersBefore(string MangaId, [FromBody]float chapterThreshold)
+ {
+ if (await context.Mangas.FirstOrDefaultAsync(m => m.Key == MangaId, HttpContext.RequestAborted) is not { } manga)
+ return TypedResults.NotFound(nameof(MangaId));
+
+ manga.IgnoreChaptersBefore = chapterThreshold;
+ if(await context.Sync(HttpContext.RequestAborted, GetType(), System.Reflection.MethodBase.GetCurrentMethod()?.Name) is { success: false } result)
+ return TypedResults.InternalServerError(result.exceptionMessage);
+
+ return TypedResults.Ok();
+ }
+
+ ///
+ /// Returns with
+ ///
+ /// .Key
+ ///
+ /// with not found
+ [HttpGet("{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, chapter.FileName));
+ }
+
+ ///
+ /// Returns the with .Key
+ ///
+ /// Key of
+ ///
+ /// with not found
+ [HttpGet("{MangaConnectorIdId}")]
+ [ProducesResponseType(Status200OK, "application/json")]
+ [ProducesResponseType(Status404NotFound, "text/plain")]
+ public async Task, NotFound>> GetChapterMangaConnectorId (string MangaConnectorIdId)
+ {
+ if (await context.MangaConnectorToChapter.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);
+ }
+}
\ No newline at end of file
diff --git a/API/Controllers/FileLibraryController.cs b/API/Controllers/FileLibraryController.cs
index 91a9056..126b913 100644
--- a/API/Controllers/FileLibraryController.cs
+++ b/API/Controllers/FileLibraryController.cs
@@ -59,46 +59,35 @@ public class FileLibraryController(MangaContext context) : Controller
///
/// with not found.
/// Error during Database Operation
- [HttpPatch("{FileLibraryId}/ChangeBasePath")]
+ [HttpPatch("{FileLibraryId}")]
[ProducesResponseType(Status200OK)]
[ProducesResponseType(Status404NotFound, "text/plain")]
[ProducesResponseType(Status500InternalServerError, "text/plain")]
- public async Task, InternalServerError>> ChangeLibraryBasePath (string FileLibraryId, [FromBody]string newBasePath)
+ public async Task, InternalServerError>> ChangeLibraryBasePath (string FileLibraryId, [FromBody]PatchFileLibraryRecord requestData)
{
if(await context.FileLibraries.FirstOrDefaultAsync(l => l.Key == FileLibraryId, HttpContext.RequestAborted) is not { } library)
return TypedResults.NotFound(nameof(FileLibraryId));
-
- //TODO Path check
- library.BasePath = newBasePath;
+
+ if (requestData.Path is { } path)
+ library.BasePath = path;
+ if(requestData.Name is { } name)
+ library.LibraryName = name;
if(await context.Sync(HttpContext.RequestAborted, GetType(), System.Reflection.MethodBase.GetCurrentMethod()?.Name) is { success: false } result)
return TypedResults.InternalServerError(result.exceptionMessage);
return TypedResults.Ok();
}
-
- ///
- /// Changes the .LibraryName with
- ///
- /// .Key
- /// New .LibraryName
- ///
- /// with not found.
- /// Error during Database Operation
- [HttpPatch("{FileLibraryId}/ChangeName")]
- [ProducesResponseType(Status200OK)]
- [ProducesResponseType(Status404NotFound, "text/plain")]
- [ProducesResponseType(Status500InternalServerError, "text/plain")]
- public async Task, InternalServerError>> ChangeLibraryName (string FileLibraryId, [FromBody] string newName)
+
+ public record PatchFileLibraryRecord(string? Path, string? Name)
{
- if(await context.FileLibraries.FirstOrDefaultAsync(l => l.Key == FileLibraryId, HttpContext.RequestAborted) is not { } library)
- return TypedResults.NotFound(nameof(FileLibraryId));
-
- //TODO Name check
- library.LibraryName = newName;
-
- if(await context.Sync(HttpContext.RequestAborted, GetType(), System.Reflection.MethodBase.GetCurrentMethod()?.Name) is { success: false } result)
- return TypedResults.InternalServerError(result.exceptionMessage);
- return TypedResults.Ok();
+ ///
+ /// Directory Path
+ ///
+ public required string? Path { get; init; } = Path;
+ ///
+ /// Library Name
+ ///
+ public required string? Name { get; init; } = Name;
}
///
diff --git a/API/Controllers/MangaConnectorController.cs b/API/Controllers/MangaConnectorController.cs
index 4158b2a..8edc1b5 100644
--- a/API/Controllers/MangaConnectorController.cs
+++ b/API/Controllers/MangaConnectorController.cs
@@ -44,29 +44,15 @@ public class MangaConnectorController(MangaContext context) : Controller
}
///
- /// Get all enabled (Scanlation-Sites)
+ /// Get all (Scanlation-Sites) with -Status
///
///
- [HttpGet("Enabled")]
+ [HttpGet("{Enabled}")]
[ProducesResponseType>(Status200OK, "application/json")]
- public Ok> GetEnabledConnectors()
+ public Ok> GetEnabledConnectors(bool Enabled)
{
return TypedResults.Ok(Tranga.MangaConnectors
- .Where(c => c.Enabled)
- .Select(c => new MangaConnector(c.Name, c.Enabled, c.IconUrl, c.SupportedLanguages))
- .ToList());
- }
-
- ///
- /// Get all disabled (Scanlation-Sites)
- ///
- ///
- [HttpGet("Disabled")]
- [ProducesResponseType>(Status200OK, "application/json")]
- public Ok> GetDisabledConnectors()
- {
- return TypedResults.Ok(Tranga.MangaConnectors
- .Where(c => c.Enabled == false)
+ .Where(c => c.Enabled == Enabled)
.Select(c => new MangaConnector(c.Name, c.Enabled, c.IconUrl, c.SupportedLanguages))
.ToList());
}
diff --git a/API/Controllers/MangaController.cs b/API/Controllers/MangaController.cs
index 3d2a4b2..c2783ad 100644
--- a/API/Controllers/MangaController.cs
+++ b/API/Controllers/MangaController.cs
@@ -6,12 +6,11 @@ using Asp.Versioning;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.Net.Http.Headers;
+using Soenneker.Utils.String.NeedlemanWunsch;
using static Microsoft.AspNetCore.Http.StatusCodes;
using AltTitle = API.Controllers.DTOs.AltTitle;
using Author = API.Controllers.DTOs.Author;
-using Chapter = API.Controllers.DTOs.Chapter;
using Link = API.Controllers.DTOs.Link;
using Manga = API.Controllers.DTOs.Manga;
@@ -71,33 +70,6 @@ public class MangaController(MangaContext context) : Controller
return new MinimalManga(m.Key, m.Name, m.Description, m.ReleaseStatus, ids);
}).ToList());
}
-
- ///
- /// Returns all cached with
- ///
- /// Array of .Key
- ///
- /// Error during Database Operation
- [HttpPost("WithIDs")]
- [ProducesResponseType>(Status200OK, "application/json")]
- [ProducesResponseType(Status500InternalServerError)]
- public async Task>, InternalServerError>> GetMangaWithIds ([FromBody]string[] MangaIds)
- {
- if (await context.MangaIncludeAll()
- .Where(m => MangaIds.Contains(m.Key))
- .ToArrayAsync(HttpContext.RequestAborted) is not { } result)
- return TypedResults.InternalServerError();
-
- return TypedResults.Ok(result.Select(m =>
- {
- IEnumerable ids = m.MangaConnectorIds.Select(id => new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
- IEnumerable authors = m.Authors.Select(a => new Author(a.Key, a.AuthorName));
- IEnumerable tags = m.MangaTags.Select(t => t.Tag);
- IEnumerable links = m.Links.Select(l => new Link(l.Key, l.LinkProvider, l.LinkUrl));
- IEnumerable altTitles = m.AltTitles.Select(a => new AltTitle(a.Language, a.Title));
- return new Manga(m.Key, m.Name, m.Description, m.ReleaseStatus, ids, m.IgnoreChaptersBefore, m.Year, m.OriginalLanguage, m.ChapterIds, authors, tags, links, altTitles, m.LibraryId);
- }).ToList());
- }
///
/// Return with
@@ -152,7 +124,7 @@ public class MangaController(MangaContext context) : Controller
/// .Key of merging data into
///
/// with or not found
- [HttpPatch("{MangaIdFrom}/MergeInto/{MangaIdInto}")]
+ [HttpPost("{MangaIdFrom}/MergeInto/{MangaIdInto}")]
[ProducesResponseType(Status200OK)]
[ProducesResponseType(Status404NotFound, "text/plain")]
public async Task>> MergeIntoManga (string MangaIdFrom, string MangaIdInto)
@@ -219,171 +191,6 @@ public class MangaController(MangaContext context) : Controller
}
public enum CoverSize { Original, Large, Medium, Small }
- ///
- /// Returns all of with
- ///
- /// .Key
- ///
- /// with not found
- [HttpGet("{MangaId}/Chapters")]
- [ProducesResponseType>(Status200OK, "application/json")]
- [ProducesResponseType(Status404NotFound)]
- public async Task>, NotFound>> GetChapters(string MangaId)
- {
- if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
- .Where(ch => ch.ParentMangaId == MangaId)
- .ToListAsync(HttpContext.RequestAborted)
- is not { } dbChapters)
- return TypedResults.NotFound(nameof(MangaId));
-
- List chapters = dbChapters.OrderDescending().Select(c =>
- {
- IEnumerable ids = c.MangaConnectorIds.Select(id =>
- new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
- return new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName);
- }).ToList();
-
- return TypedResults.Ok(chapters);
- }
-
- ///
- /// Returns all downloaded for with
- ///
- /// .Key
- ///
- /// with not found.
- [HttpGet("{MangaId}/Chapters/Downloaded")]
- [ProducesResponseType(Status200OK, "application/json")]
- [ProducesResponseType(Status404NotFound, "text/plain")]
- public async Task>, NotFound>> GetChaptersDownloaded(string MangaId)
- {
- if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
- .Where(ch => ch.ParentMangaId == MangaId && ch.Downloaded)
- .ToListAsync(HttpContext.RequestAborted)
- is not { } dbChapters)
- return TypedResults.NotFound(nameof(MangaId));
-
- List chapters = dbChapters.OrderDescending().Select(c =>
- {
- IEnumerable ids = c.MangaConnectorIds.Select(id =>
- new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
- return new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName);
- }).ToList();
-
- return TypedResults.Ok(chapters);
- }
-
- ///
- /// Returns all not downloaded for with
- ///
- /// .Key
- ///
- /// with not found.
- [HttpGet("{MangaId}/Chapters/NotDownloaded")]
- [ProducesResponseType>(Status200OK, "application/json")]
- [ProducesResponseType(Status404NotFound, "text/plain")]
- public async Task>, NoContent, NotFound>> GetChaptersNotDownloaded(string MangaId)
- {
- if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
- .Where(ch => ch.ParentMangaId == MangaId && ch.Downloaded == false)
- .ToListAsync(HttpContext.RequestAborted)
- is not { } dbChapters)
- return TypedResults.NotFound(nameof(MangaId));
-
- List chapters = dbChapters.OrderDescending().Select(c =>
- {
- IEnumerable ids = c.MangaConnectorIds.Select(id =>
- new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
- return new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName);
- }).ToList();
-
- return TypedResults.Ok(chapters);
- }
-
- ///
- /// Returns the latest of requested
- ///
- /// .Key
- ///
- /// No available chapters
- /// with not found.
- [HttpGet("{MangaId}/Chapter/LatestAvailable")]
- [ProducesResponseType(Status200OK, "application/json")]
- [ProducesResponseType(Status204NoContent)]
- [ProducesResponseType(Status404NotFound, "text/plain")]
- public async Task, NoContent, NotFound>> GetLatestChapter(string MangaId)
- {
- if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
- .Where(ch => ch.ParentMangaId == MangaId)
- .ToListAsync(HttpContext.RequestAborted)
- is not { } dbChapters)
- return TypedResults.NotFound(nameof(MangaId));
-
- Schema.MangaContext.Chapter? c = dbChapters.Max();
- if (c is null)
- return TypedResults.NoContent();
-
- IEnumerable ids = c.MangaConnectorIds.Select(id =>
- new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
- return TypedResults.Ok(new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName));
- }
-
- ///
- /// Returns the latest of requested that is downloaded
- ///
- /// .Key
- ///
- /// No available chapters
- /// with not found.
- /// Could not retrieve the maximum chapter-number
- /// Retry after timeout, updating value
- [HttpGet("{MangaId}/Chapter/LatestDownloaded")]
- [ProducesResponseType(Status200OK, "application/json")]
- [ProducesResponseType(Status204NoContent)]
- [ProducesResponseType(Status404NotFound, "text/plain")]
- [ProducesResponseType(Status412PreconditionFailed)]
- [ProducesResponseType(Status503ServiceUnavailable)]
- public async Task, NoContent, NotFound, StatusCodeHttpResult>> GetLatestChapterDownloaded(string MangaId)
- {
- if(await context.Chapters.Include(ch => ch.MangaConnectorIds)
- .Where(ch => ch.ParentMangaId == MangaId && ch.Downloaded)
- .ToListAsync(HttpContext.RequestAborted)
- is not { } dbChapters)
- return TypedResults.NotFound(nameof(MangaId));
-
- Schema.MangaContext.Chapter? c = dbChapters.Max();
- if (c is null)
- return TypedResults.NoContent();
-
- IEnumerable ids = c.MangaConnectorIds.Select(id =>
- new MangaConnectorId(id.Key, id.MangaConnectorName, id.ObjId, id.WebsiteUrl, id.UseForDownload));
- return TypedResults.Ok(new Chapter(c.Key, c.ParentMangaId, c.VolumeNumber, c.ChapterNumber, c.Title, ids, c.Downloaded, c.FileName));
- }
-
- ///
- /// Configure the cut-off for
- ///
- /// .Key
- /// Threshold ( ChapterNumber)
- ///
- /// with not found.
- /// Error during Database Operation
- [HttpPatch("{MangaId}/IgnoreChaptersBefore")]
- [ProducesResponseType(Status200OK)]
- [ProducesResponseType(Status404NotFound, "text/plain")]
- [ProducesResponseType(Status500InternalServerError, "text/plain")]
- public async Task, InternalServerError>> IgnoreChaptersBefore(string MangaId, [FromBody]float chapterThreshold)
- {
- if (await context.Mangas.FirstOrDefaultAsync(m => m.Key == MangaId, HttpContext.RequestAborted) is not { } manga)
- return TypedResults.NotFound(nameof(MangaId));
-
- manga.IgnoreChaptersBefore = chapterThreshold;
- if(await context.Sync(HttpContext.RequestAborted, GetType(), System.Reflection.MethodBase.GetCurrentMethod()?.Name) is { success: false } result)
- return TypedResults.InternalServerError(result.exceptionMessage);
-
- return TypedResults.Ok();
- }
-
///
/// Move to different
///
@@ -422,7 +229,7 @@ public class MangaController(MangaContext context) : Controller
/// was not linked to , so nothing changed
/// is not linked to yet. Search for on first (to create a ).
/// Error during Database Operation
- [HttpPost("{MangaId}/SetAsDownloadFrom/{MangaConnectorName}/{IsRequested}")]
+ [HttpPatch("{MangaId}/DownloadFrom/{MangaConnectorName}/{IsRequested}")]
[ProducesResponseType(Status200OK)]
[ProducesResponseType(Status404NotFound, "text/plain")]
[ProducesResponseType(Status412PreconditionFailed, "text/plain")]
@@ -464,7 +271,7 @@ public class MangaController(MangaContext context) : Controller
/// exert of
/// with Name not found
/// with Name is disabled
- [HttpPost("{MangaId}/SearchOn/{MangaConnectorName}")]
+ [HttpGet("{MangaId}/OnMangaConnector/{MangaConnectorName}")]
[ProducesResponseType>(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound, "text/plain")]
[ProducesResponseType(Status406NotAcceptable)]
@@ -537,4 +344,53 @@ public class MangaController(MangaContext context) : Controller
return new Manga(m.Key, m.Name, m.Description, m.ReleaseStatus, ids, m.IgnoreChaptersBefore, m.Year, m.OriginalLanguage, m.ChapterIds, authors, tags, links, altTitles, m.LibraryId);
}).ToList());
}
+
+ ///
+ /// Returns with names similar to (identified by )
+ ///
+ /// Key of
+ ///
+ /// with not found
+ /// Error during Database Operation
+ [HttpGet("WithSimilarName/{MangaId}")]
+ [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("{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);
+ }
}
\ No newline at end of file
diff --git a/API/Controllers/QueryController.cs b/API/Controllers/QueryController.cs
index 394994d..4bb4ec8 100644
--- a/API/Controllers/QueryController.cs
+++ b/API/Controllers/QueryController.cs
@@ -15,7 +15,7 @@ namespace API.Controllers;
[ApiVersion(2)]
[ApiController]
-[Route("v{v:apiVersion}/[controller]")]
+[Route("v{v:apiVersion}/")]
public class QueryController(MangaContext context) : Controller
{
///
@@ -34,91 +34,4 @@ public class QueryController(MangaContext context) : Controller
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, chapter.FileName));
- }
-
- ///
- /// 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);
- }
}
\ No newline at end of file
diff --git a/API/Controllers/SearchController.cs b/API/Controllers/SearchController.cs
index 7407d9f..5402977 100644
--- a/API/Controllers/SearchController.cs
+++ b/API/Controllers/SearchController.cs
@@ -58,11 +58,11 @@ public class SearchController(MangaContext context) : Controller
/// exert of .
/// not found
/// Error during Database Operation
- [HttpPost("Url")]
+ [HttpGet]
[ProducesResponseType(Status200OK, "application/json")]
[ProducesResponseType(Status404NotFound, "text/plain")]
[ProducesResponseType(Status500InternalServerError, "text/plain")]
- public async Task, NotFound, InternalServerError>> GetMangaFromUrl([FromBody]string url)
+ public async Task, NotFound, InternalServerError>> GetMangaFromUrl([FromQuery]string url)
{
if(Tranga.MangaConnectors.FirstOrDefault(c => c.Name.Equals("Global", StringComparison.InvariantCultureIgnoreCase)) is not { } connector)
return TypedResults.InternalServerError("Could not find Global Connector.");
diff --git a/API/Controllers/SettingsController.cs b/API/Controllers/SettingsController.cs
index 4233ff8..ea97d3a 100644
--- a/API/Controllers/SettingsController.cs
+++ b/API/Controllers/SettingsController.cs
@@ -60,17 +60,6 @@ public class SettingsController() : Controller
return TypedResults.Ok();
}
- ///
- /// Update all Request-Limits to new values
- ///
- /// NOT IMPLEMENTED
- [HttpPatch("RequestLimits")]
- [ProducesResponseType(Status501NotImplemented)]
- public StatusCodeHttpResult SetRequestLimits()
- {
- return TypedResults.StatusCode(Status501NotImplemented);
- }
-
///
/// Returns Level of Image-Compression for Images
///
@@ -179,7 +168,7 @@ public class SettingsController() : Controller
///
/// URL of FlareSolverr-Instance
///
- [HttpPost("FlareSolverr/Url")]
+ [HttpPatch("FlareSolverr/Url")]
[ProducesResponseType(Status200OK)]
public Ok SetFlareSolverrUrl([FromBody]string flareSolverrUrl)
{
@@ -212,7 +201,7 @@ public class SettingsController() : Controller
const string knownProtectedUrl = "https://prowlarr.servarr.com/v1/ping";
FlareSolverrDownloadClient client = new(new ());
HttpResponseMessage result = await client.MakeRequest(knownProtectedUrl, RequestType.Default);
- return (int)result.StatusCode >= 200 && (int)result.StatusCode < 300 ? TypedResults.Ok() : TypedResults.InternalServerError();
+ return result.IsSuccessStatusCode ? TypedResults.Ok() : TypedResults.InternalServerError();
}
///
diff --git a/API/Controllers/WorkerController.cs b/API/Controllers/WorkerController.cs
index 41ca2e8..09c7837 100644
--- a/API/Controllers/WorkerController.cs
+++ b/API/Controllers/WorkerController.cs
@@ -21,21 +21,10 @@ public class WorkerController : Controller
[ProducesResponseType>(Status200OK, "application/json")]
public Ok> GetWorkers()
{
- IEnumerable result = Tranga.GetRunningWorkers().Select(w =>
+ IEnumerable result = Tranga.GetKnownWorkers().Select(w =>
new Worker(w.Key, w.AllDependencies.Select(d => d.Key), w.MissingDependencies.Select(d => d.Key), w.AllDependenciesFulfilled, w.State));
return TypedResults.Ok(result.ToList());
}
-
- ///
- /// Returns all .Keys
- ///
- ///
- [HttpGet("Keys")]
- [ProducesResponseType(Status200OK, "application/json")]
- public Ok> GetWorkerIds()
- {
- return TypedResults.Ok(Tranga.GetRunningWorkers().Select(w => w.Key).ToList());
- }
///
/// Get all in requested
@@ -46,7 +35,7 @@ public class WorkerController : Controller
[ProducesResponseType>(Status200OK, "application/json")]
public Ok> GetWorkersInState(WorkerExecutionState State)
{
- IEnumerable result = Tranga.GetRunningWorkers().Where(worker => worker.State == State).Select(w =>
+ IEnumerable result = Tranga.GetKnownWorkers().Where(worker => worker.State == State).Select(w =>
new Worker(w.Key, w.AllDependencies.Select(d => d.Key), w.MissingDependencies.Select(d => d.Key), w.AllDependenciesFulfilled, w.State));
return TypedResults.Ok(result.ToList());
}
@@ -62,7 +51,7 @@ public class WorkerController : Controller
[ProducesResponseType(Status404NotFound, "text/plain")]
public Results, NotFound> GetWorker(string WorkerId)
{
- if(Tranga.GetRunningWorkers().FirstOrDefault(w => w.Key == WorkerId) is not { } w)
+ if(Tranga.GetKnownWorkers().FirstOrDefault(w => w.Key == WorkerId) is not { } w)
return TypedResults.NotFound(nameof(WorkerId));
Worker result = new (w.Key, w.AllDependencies.Select(d => d.Key), w.MissingDependencies.Select(d => d.Key), w.AllDependenciesFulfilled, w.State);
@@ -70,46 +59,6 @@ public class WorkerController : Controller
return TypedResults.Ok(result);
}
- ///
- /// Delete with and all child-s
- ///
- /// .Key
- ///
- /// with could not be found
- [HttpDelete("{WorkerId}")]
- [ProducesResponseType(Status200OK)]
- [ProducesResponseType(Status404NotFound, "text/plain")]
- public Results> DeleteWorker(string WorkerId)
- {
- if(Tranga.GetRunningWorkers().FirstOrDefault(w => w.Key == WorkerId) is not { } worker)
- return TypedResults.NotFound(nameof(WorkerId));
- Tranga.StopWorker(worker);
- return TypedResults.Ok();
- }
-
- ///
- /// Starts with
- ///
- /// .Key
- ///
- /// with could not be found
- /// was already running
- [HttpPost("{WorkerId}/Start")]
- [ProducesResponseType(Status202Accepted)]
- [ProducesResponseType(Status404NotFound, "text/plain")]
- [ProducesResponseType(Status412PreconditionFailed)]
- public Results, StatusCodeHttpResult> StartWorker(string WorkerId)
- {
- if(Tranga.GetRunningWorkers().FirstOrDefault(w => w.Key == WorkerId) is not { } worker)
- return TypedResults.NotFound(nameof(WorkerId));
-
- if (worker.State >= WorkerExecutionState.Waiting)
- return TypedResults.StatusCode(Status412PreconditionFailed);
-
- Tranga.StartWorker(worker);
- return TypedResults.Ok();
- }
-
///
/// Stops with
///
diff --git a/API/Tranga.cs b/API/Tranga.cs
index 084554b..2506646 100644
--- a/API/Tranga.cs
+++ b/API/Tranga.cs
@@ -77,7 +77,11 @@ public static class Tranga
public static void AddWorker(BaseWorker worker)
{
Log.Debug($"Adding Worker {worker}");
- StartWorker(worker);
+ KnownWorkers.Add(worker);
+ if(worker is not IPeriodic)
+ StartWorker(worker, RemoveFromKnownWorkers(worker));
+ else
+ StartWorker(worker);
if(worker is IPeriodic periodic)
AddPeriodicWorker(worker, periodic);
}
@@ -109,6 +113,12 @@ public static class Tranga
PeriodicWorkers.AddOrUpdate((worker as IPeriodic)!, periodicTask, (_, _) => periodicTask);
periodicTask.Start();
};
+
+ private static Action RemoveFromKnownWorkers(BaseWorker worker) => () =>
+ {
+ if (KnownWorkers.Contains(worker))
+ KnownWorkers.Remove(worker);
+ };
public static void AddWorkers(IEnumerable workers)
{
@@ -116,6 +126,8 @@ public static class Tranga
AddWorker(baseWorker);
}
+ private static readonly HashSet KnownWorkers = new();
+ public static BaseWorker[] GetKnownWorkers() => KnownWorkers.ToArray();
private static readonly ConcurrentDictionary> RunningWorkers = new();
public static BaseWorker[] GetRunningWorkers() => RunningWorkers.Keys.ToArray();
diff --git a/API/openapi/API_v2.json b/API/openapi/API_v2.json
index 866ca40..a08d9b9 100644
--- a/API/openapi/API_v2.json
+++ b/API/openapi/API_v2.json
@@ -5,6 +5,418 @@
"version": "2.0"
},
"paths": {
+ "/v2/Chapters/{MangaId}": {
+ "get": {
+ "tags": [
+ "Chapters"
+ ],
+ "summary": "Returns all API.Schema.MangaContext.Chapter of API.Schema.MangaContext.Manga with MangaId",
+ "parameters": [
+ {
+ "name": "MangaId",
+ "in": "path",
+ "description": "API.Schema.MangaContext.Manga.Key",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Chapter"
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.Manga with MangaId not found",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "application/json; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v2/Chapters/{MangaId}/Downloaded": {
+ "get": {
+ "tags": [
+ "Chapters"
+ ],
+ "summary": "Returns all downloaded API.Controllers.DTOs.Chapter for API.Schema.MangaContext.Manga with MangaId",
+ "parameters": [
+ {
+ "name": "MangaId",
+ "in": "path",
+ "description": "API.Schema.MangaContext.Manga.Key",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Chapter"
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.Manga with MangaId not found.",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v2/Chapters/{MangaId}/NotDownloaded": {
+ "get": {
+ "tags": [
+ "Chapters"
+ ],
+ "summary": "Returns all API.Controllers.DTOs.Chapter not downloaded for API.Schema.MangaContext.Manga with MangaId",
+ "parameters": [
+ {
+ "name": "MangaId",
+ "in": "path",
+ "description": "API.Schema.MangaContext.Manga.Key",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Chapter"
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.Manga with MangaId not found.",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v2/Chapters/{MangaId}/LatestAvailable": {
+ "get": {
+ "tags": [
+ "Chapters"
+ ],
+ "summary": "Returns the latest API.Controllers.DTOs.Chapter of requested API.Schema.MangaContext.Manga",
+ "parameters": [
+ {
+ "name": "MangaId",
+ "in": "path",
+ "description": "API.Schema.MangaContext.Manga.Key",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "No available chapters"
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.Manga with MangaId not found.",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v2/Chapters/{MangaId}/LatestDownloaded": {
+ "get": {
+ "tags": [
+ "Chapters"
+ ],
+ "summary": "Returns the latest API.Controllers.DTOs.Chapter of requested API.Schema.MangaContext.Manga that is downloaded",
+ "parameters": [
+ {
+ "name": "MangaId",
+ "in": "path",
+ "description": "API.Schema.MangaContext.Manga.Key",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/Chapter"
+ }
+ }
+ }
+ },
+ "204": {
+ "description": "No available chapters"
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.Manga with MangaId not found.",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "412": {
+ "description": "Could not retrieve the maximum chapter-number",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "application/json; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ },
+ "text/json; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/ProblemDetails"
+ }
+ }
+ }
+ },
+ "503": {
+ "description": "Retry after timeout, updating value"
+ }
+ }
+ }
+ },
+ "/v2/Chapters/{MangaId}/IgnoreBefore": {
+ "patch": {
+ "tags": [
+ "Chapters"
+ ],
+ "summary": "Configure the API.Controllers.DTOs.Chapter cut-off for API.Schema.MangaContext.Manga",
+ "parameters": [
+ {
+ "name": "MangaId",
+ "in": "path",
+ "description": "API.Schema.MangaContext.Manga.Key",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "description": "Threshold (API.Controllers.DTOs.Chapter ChapterNumber)",
+ "content": {
+ "application/json-patch+json; x-version=2.0": {
+ "schema": {
+ "type": "number",
+ "format": "float"
+ }
+ },
+ "application/json; x-version=2.0": {
+ "schema": {
+ "type": "number",
+ "format": "float"
+ }
+ },
+ "text/json; x-version=2.0": {
+ "schema": {
+ "type": "number",
+ "format": "float"
+ }
+ },
+ "application/*+json; x-version=2.0": {
+ "schema": {
+ "type": "number",
+ "format": "float"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "OK"
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.Manga with MangaId not found.",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Error during Database Operation",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "202": {
+ "description": ""
+ }
+ }
+ }
+ },
+ "/v2/Chapters/{ChapterId}": {
+ "get": {
+ "tags": [
+ "Chapters"
+ ],
+ "summary": "Returns API.Controllers.DTOs.Chapter with ChapterId",
+ "parameters": [
+ {
+ "name": "ChapterId",
+ "in": "path",
+ "description": "API.Controllers.DTOs.Chapter.Key",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/Chapter"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "API.Controllers.DTOs.Chapter with ChapterId not found",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "/v2/Chapters/{MangaConnectorIdId}": {
+ "get": {
+ "tags": [
+ "Chapters"
+ ],
+ "summary": "Returns the API.Schema.MangaContext.MangaConnectorId`1 with API.Schema.MangaContext.MangaConnectorId`1.Key",
+ "parameters": [
+ {
+ "name": "MangaConnectorIdId",
+ "in": "path",
+ "description": "Key of API.Schema.MangaContext.MangaConnectorId`1",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/MangaConnectorId"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.MangaConnectorId`1 with MangaConnectorIdId not found",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/v2/FileLibrary": {
"get": {
"tags": [
@@ -127,50 +539,6 @@
}
}
},
- "delete": {
- "tags": [
- "FileLibrary"
- ],
- "summary": "Deletes the !:FileLibraryId.LibraryName with FileLibraryId",
- "parameters": [
- {
- "name": "FileLibraryId",
- "in": "path",
- "description": "API.Controllers.DTOs.FileLibrary.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": ""
- },
- "404": {
- "description": "API.Controllers.DTOs.FileLibrary with FileLibraryId not found.",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- },
- "500": {
- "description": "Error during Database Operation",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- },
- "/v2/FileLibrary/{FileLibraryId}/ChangeBasePath": {
"patch": {
"tags": [
"FileLibrary"
@@ -188,26 +556,25 @@
}
],
"requestBody": {
- "description": "New !:FileLibraryId.BasePath",
"content": {
"application/json-patch+json; x-version=2.0": {
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/PatchFileLibraryRecord"
}
},
"application/json; x-version=2.0": {
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/PatchFileLibraryRecord"
}
},
"text/json; x-version=2.0": {
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/PatchFileLibraryRecord"
}
},
"application/*+json; x-version=2.0": {
"schema": {
- "type": "string"
+ "$ref": "#/components/schemas/PatchFileLibraryRecord"
}
}
}
@@ -237,14 +604,12 @@
}
}
}
- }
- },
- "/v2/FileLibrary/{FileLibraryId}/ChangeName": {
- "patch": {
+ },
+ "delete": {
"tags": [
"FileLibrary"
],
- "summary": "Changes the !:FileLibraryId.LibraryName with FileLibraryId",
+ "summary": "Deletes the !:FileLibraryId.LibraryName with FileLibraryId",
"parameters": [
{
"name": "FileLibraryId",
@@ -256,31 +621,6 @@
}
}
],
- "requestBody": {
- "description": "New !:FileLibraryId.LibraryName",
- "content": {
- "application/json-patch+json; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- },
- "application/json; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- },
- "text/json; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- },
- "application/*+json; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- },
"responses": {
"200": {
"description": ""
@@ -519,32 +859,6 @@
}
}
},
- "/v2/Manga/Keys": {
- "get": {
- "tags": [
- "Manga"
- ],
- "summary": "Returns all cached API.Schema.MangaContext.Manga.Keys",
- "responses": {
- "200": {
- "description": "API.Schema.MangaContext.Manga Keys/IDs",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- }
- },
- "500": {
- "description": "Error during Database Operation"
- }
- }
- }
- },
"/v2/Manga/Downloading": {
"get": {
"tags": [
@@ -571,69 +885,6 @@
}
}
},
- "/v2/Manga/WithIDs": {
- "post": {
- "tags": [
- "Manga"
- ],
- "summary": "Returns all cached API.Schema.MangaContext.Manga with MangaIds",
- "requestBody": {
- "description": "Array of API.Schema.MangaContext.Manga.Key",
- "content": {
- "application/json-patch+json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "text/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- },
- "application/*+json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- }
- },
- "responses": {
- "200": {
- "description": "API.Controllers.DTOs.Manga",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Manga"
- }
- }
- }
- }
- },
- "500": {
- "description": "Error during Database Operation"
- }
- }
- }
- },
"/v2/Manga/{MangaId}": {
"get": {
"tags": [
@@ -718,7 +969,7 @@
}
},
"/v2/Manga/{MangaIdFrom}/MergeInto/{MangaIdInto}": {
- "patch": {
+ "post": {
"tags": [
"Manga"
],
@@ -837,351 +1088,6 @@
}
}
},
- "/v2/Manga/{MangaId}/Chapters": {
- "get": {
- "tags": [
- "Manga"
- ],
- "summary": "Returns all API.Controllers.DTOs.Chapter of API.Controllers.DTOs.Manga with MangaId",
- "parameters": [
- {
- "name": "MangaId",
- "in": "path",
- "description": "API.Controllers.DTOs.Manga.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Chapter"
- }
- }
- }
- }
- },
- "404": {
- "description": "API.Controllers.DTOs.Manga with MangaId not found",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- },
- "application/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- },
- "text/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- }
- }
- }
- }
- }
- },
- "/v2/Manga/{MangaId}/Chapters/Downloaded": {
- "get": {
- "tags": [
- "Manga"
- ],
- "summary": "Returns all downloaded API.Controllers.DTOs.Chapter for API.Controllers.DTOs.Manga with MangaId",
- "parameters": [
- {
- "name": "MangaId",
- "in": "path",
- "description": "API.Controllers.DTOs.Manga.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Chapter"
- }
- }
- }
- }
- },
- "204": {
- "description": "No available chapters"
- },
- "404": {
- "description": "API.Controllers.DTOs.Manga with MangaId not found.",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- },
- "/v2/Manga/{MangaId}/Chapters/NotDownloaded": {
- "get": {
- "tags": [
- "Manga"
- ],
- "summary": "Returns all API.Controllers.DTOs.Chapter not downloaded for API.Controllers.DTOs.Manga with MangaId",
- "parameters": [
- {
- "name": "MangaId",
- "in": "path",
- "description": "API.Controllers.DTOs.Manga.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Chapter"
- }
- }
- }
- }
- },
- "204": {
- "description": "No available chapters"
- },
- "404": {
- "description": "API.Controllers.DTOs.Manga with MangaId not found.",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- },
- "/v2/Manga/{MangaId}/Chapter/LatestAvailable": {
- "get": {
- "tags": [
- "Manga"
- ],
- "summary": "Returns the latest API.Controllers.DTOs.Chapter of requested API.Controllers.DTOs.Manga available on API.MangaConnectors.MangaConnector",
- "parameters": [
- {
- "name": "MangaId",
- "in": "path",
- "description": "API.Controllers.DTOs.Manga.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "integer",
- "format": "int32"
- }
- }
- }
- },
- "204": {
- "description": "No available chapters"
- },
- "404": {
- "description": "API.Controllers.DTOs.Manga with MangaId not found.",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- },
- "500": {
- "description": "Internal Server Error"
- },
- "503": {
- "description": "Retry after timeout, updating value"
- },
- "412": {
- "description": "Could not retrieve the maximum chapter-number"
- }
- }
- }
- },
- "/v2/Manga/{MangaId}/Chapter/LatestDownloaded": {
- "get": {
- "tags": [
- "Manga"
- ],
- "summary": "Returns the latest API.Controllers.DTOs.Chapter of requested API.Controllers.DTOs.Manga that is downloaded",
- "parameters": [
- {
- "name": "MangaId",
- "in": "path",
- "description": "API.Controllers.DTOs.Manga.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/Chapter"
- }
- }
- }
- },
- "204": {
- "description": "No available chapters"
- },
- "404": {
- "description": "API.Controllers.DTOs.Manga with MangaId not found.",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- },
- "412": {
- "description": "Could not retrieve the maximum chapter-number",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- },
- "application/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- },
- "text/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- }
- }
- },
- "503": {
- "description": "Retry after timeout, updating value"
- }
- }
- }
- },
- "/v2/Manga/{MangaId}/IgnoreChaptersBefore": {
- "patch": {
- "tags": [
- "Manga"
- ],
- "summary": "Configure the API.Controllers.DTOs.Chapter cut-off for API.Controllers.DTOs.Manga",
- "parameters": [
- {
- "name": "MangaId",
- "in": "path",
- "description": "API.Controllers.DTOs.Manga.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "requestBody": {
- "description": "Threshold (API.Controllers.DTOs.Chapter ChapterNumber)",
- "content": {
- "application/json-patch+json; x-version=2.0": {
- "schema": {
- "type": "number",
- "format": "float"
- }
- },
- "application/json; x-version=2.0": {
- "schema": {
- "type": "number",
- "format": "float"
- }
- },
- "text/json; x-version=2.0": {
- "schema": {
- "type": "number",
- "format": "float"
- }
- },
- "application/*+json; x-version=2.0": {
- "schema": {
- "type": "number",
- "format": "float"
- }
- }
- }
- },
- "responses": {
- "200": {
- "description": "OK"
- },
- "404": {
- "description": "API.Controllers.DTOs.Manga with MangaId not found.",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- },
- "500": {
- "description": "Error during Database Operation",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- },
- "202": {
- "description": ""
- }
- }
- }
- },
"/v2/Manga/{MangaId}/ChangeLibrary/{LibraryId}": {
"post": {
"tags": [
@@ -1228,8 +1134,8 @@
}
}
},
- "/v2/Manga/{MangaId}/SetAsDownloadFrom/{MangaConnectorName}/{IsRequested}": {
- "post": {
+ "/v2/Manga/{MangaId}/DownloadFrom/{MangaConnectorName}/{IsRequested}": {
+ "patch": {
"tags": [
"Manga"
],
@@ -1310,8 +1216,8 @@
}
}
},
- "/v2/Manga/{MangaId}/SearchOn/{MangaConnectorName}": {
- "post": {
+ "/v2/Manga/{MangaId}/OnMangaConnector/{MangaConnectorName}": {
+ "get": {
"tags": [
"Manga"
],
@@ -1480,6 +1386,94 @@
}
}
},
+ "/v2/Manga/WithSimilarName/{MangaId}": {
+ "get": {
+ "tags": [
+ "Manga"
+ ],
+ "summary": "Returns API.Schema.MangaContext.Manga with names similar to API.Schema.MangaContext.Manga (identified by MangaId)",
+ "parameters": [
+ {
+ "name": "MangaId",
+ "in": "path",
+ "description": "Key of API.Schema.MangaContext.Manga",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.Manga with MangaId not found",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Error during Database Operation"
+ }
+ }
+ }
+ },
+ "/v2/Manga/{MangaConnectorIdId}": {
+ "get": {
+ "tags": [
+ "Manga"
+ ],
+ "summary": "Returns the API.Schema.MangaContext.MangaConnectorId`1 with API.Schema.MangaContext.MangaConnectorId`1.Key",
+ "parameters": [
+ {
+ "name": "MangaConnectorIdId",
+ "in": "path",
+ "description": "Key of API.Schema.MangaContext.MangaConnectorId`1",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "",
+ "content": {
+ "application/json; x-version=2.0": {
+ "schema": {
+ "$ref": "#/components/schemas/MangaConnectorId"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "API.Schema.MangaContext.MangaConnectorId`1 with MangaConnectorIdId not found",
+ "content": {
+ "text/plain; x-version=2.0": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/v2/MangaConnector": {
"get": {
"tags": [
@@ -1544,35 +1538,22 @@
}
}
},
- "/v2/MangaConnector/Enabled": {
+ "/v2/MangaConnector/{Enabled}": {
"get": {
"tags": [
"MangaConnector"
],
- "summary": "Get all enabled API.MangaConnectors.MangaConnector (Scanlation-Sites)",
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/MangaConnector"
- }
- }
- }
+ "summary": "Get all API.MangaConnectors.MangaConnector (Scanlation-Sites) with Enabled-Status",
+ "parameters": [
+ {
+ "name": "Enabled",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "boolean"
}
}
- }
- }
- },
- "/v2/MangaConnector/Disabled": {
- "get": {
- "tags": [
- "MangaConnector"
],
- "summary": "Get all disabled API.MangaConnectors.MangaConnector (Scanlation-Sites)",
"responses": {
"200": {
"description": "",
@@ -2325,7 +2306,7 @@
}
}
},
- "/v2/Query/Author/{AuthorId}": {
+ "/v2/Author/{AuthorId}": {
"get": {
"tags": [
"Query"
@@ -2366,176 +2347,6 @@
}
}
},
- "/v2/Query/Chapter/{ChapterId}": {
- "get": {
- "tags": [
- "Query"
- ],
- "summary": "Returns API.Controllers.DTOs.Chapter with ChapterId",
- "parameters": [
- {
- "name": "ChapterId",
- "in": "path",
- "description": "API.Controllers.DTOs.Chapter.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/Chapter"
- }
- }
- }
- },
- "404": {
- "description": "API.Controllers.DTOs.Chapter with ChapterId not found",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- },
- "/v2/Query/Manga/MangaConnectorId/{MangaConnectorIdId}": {
- "get": {
- "tags": [
- "Query"
- ],
- "summary": "Returns the API.Schema.MangaContext.MangaConnectorId`1 with API.Schema.MangaContext.MangaConnectorId`1.Key",
- "parameters": [
- {
- "name": "MangaConnectorIdId",
- "in": "path",
- "description": "Key of API.Schema.MangaContext.MangaConnectorId`1",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/MangaConnectorId"
- }
- }
- }
- },
- "404": {
- "description": "API.Schema.MangaContext.MangaConnectorId`1 with MangaConnectorIdId not found",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- },
- "/v2/Query/Manga/{MangaId}/SimilarName": {
- "get": {
- "tags": [
- "Query"
- ],
- "summary": "Returns API.Schema.MangaContext.Manga with names similar to API.Schema.MangaContext.Manga (identified by MangaId)",
- "parameters": [
- {
- "name": "MangaId",
- "in": "path",
- "description": "Key of API.Schema.MangaContext.Manga",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- }
- },
- "404": {
- "description": "API.Schema.MangaContext.Manga with MangaId not found",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- },
- "500": {
- "description": "Error during Database Operation"
- }
- }
- }
- },
- "/v2/Query/Chapter/MangaConnectorId/{MangaConnectorIdId}": {
- "get": {
- "tags": [
- "Query"
- ],
- "summary": "Returns the API.Schema.MangaContext.MangaConnectorId`1 with API.Schema.MangaContext.MangaConnectorId`1.Key",
- "parameters": [
- {
- "name": "MangaConnectorIdId",
- "in": "path",
- "description": "Key of API.Schema.MangaContext.MangaConnectorId`1",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/MangaConnectorId"
- }
- }
- }
- },
- "404": {
- "description": "API.Schema.MangaContext.MangaConnectorId`1 with MangaConnectorIdId not found",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- },
"/v2/Search/{MangaConnectorName}/{Query}": {
"get": {
"tags": [
@@ -2612,37 +2423,22 @@
}
}
},
- "/v2/Search/Url": {
- "post": {
+ "/v2/Search": {
+ "get": {
"tags": [
"Search"
],
"summary": "Returns API.Schema.MangaContext.Manga from the API.Controllers.DTOs.MangaConnector associated with url",
- "requestBody": {
- "description": "",
- "content": {
- "application/json-patch+json; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- },
- "application/json; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- },
- "text/json; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- },
- "application/*+json; x-version=2.0": {
- "schema": {
- "type": "string"
- }
+ "parameters": [
+ {
+ "name": "url",
+ "in": "query",
+ "description": "",
+ "schema": {
+ "type": "string"
}
}
- },
+ ],
"responses": {
"200": {
"description": "API.Controllers.DTOs.MinimalManga exert of API.Schema.MangaContext.Manga.",
@@ -2763,20 +2559,6 @@
}
}
},
- "/v2/Settings/RequestLimits": {
- "patch": {
- "tags": [
- "Settings"
- ],
- "summary": "Update all Request-Limits to new values",
- "description": "NOT IMPLEMENTED
",
- "responses": {
- "501": {
- "description": "Not Implemented"
- }
- }
- }
- },
"/v2/Settings/ImageCompressionLevel": {
"get": {
"tags": [
@@ -2945,7 +2727,7 @@
}
},
"/v2/Settings/FlareSolverr/Url": {
- "post": {
+ "patch": {
"tags": [
"Settings"
],
@@ -3112,29 +2894,6 @@
}
}
},
- "/v2/Worker/Keys": {
- "get": {
- "tags": [
- "Worker"
- ],
- "summary": "Returns all API.Workers.BaseWorker.Keys",
- "responses": {
- "200": {
- "description": "",
- "content": {
- "application/json; x-version=2.0": {
- "schema": {
- "type": "array",
- "items": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- }
- },
"/v2/Worker/State/{State}": {
"get": {
"tags": [
@@ -3208,95 +2967,6 @@
}
}
}
- },
- "delete": {
- "tags": [
- "Worker"
- ],
- "summary": "Delete API.Workers.BaseWorker with WorkerId and all child-API.Workers.BaseWorkers",
- "parameters": [
- {
- "name": "WorkerId",
- "in": "path",
- "description": "API.Workers.BaseWorker.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "200": {
- "description": ""
- },
- "404": {
- "description": "API.Workers.BaseWorker with WorkerId could not be found",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- }
- }
- }
- },
- "/v2/Worker/{WorkerId}/Start": {
- "post": {
- "tags": [
- "Worker"
- ],
- "summary": "Starts API.Workers.BaseWorker with WorkerId",
- "parameters": [
- {
- "name": "WorkerId",
- "in": "path",
- "description": "API.Workers.BaseWorker.Key",
- "required": true,
- "schema": {
- "type": "string"
- }
- }
- ],
- "responses": {
- "202": {
- "description": "Accepted"
- },
- "404": {
- "description": "API.Workers.BaseWorker with WorkerId could not be found",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "type": "string"
- }
- }
- }
- },
- "412": {
- "description": "API.Workers.BaseWorker was already running",
- "content": {
- "text/plain; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- },
- "application/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- },
- "text/json; x-version=2.0": {
- "schema": {
- "$ref": "#/components/schemas/ProblemDetails"
- }
- }
- }
- },
- "200": {
- "description": ""
- }
- }
}
},
"/v2/Worker/{WorkerId}/Stop": {
@@ -4083,6 +3753,26 @@
},
"additionalProperties": false
},
+ "PatchFileLibraryRecord": {
+ "required": [
+ "name",
+ "path"
+ ],
+ "type": "object",
+ "properties": {
+ "path": {
+ "type": "string",
+ "description": "Directory Path",
+ "nullable": true
+ },
+ "name": {
+ "type": "string",
+ "description": "Library Name",
+ "nullable": true
+ }
+ },
+ "additionalProperties": false
+ },
"PatchLibraryRefreshRecord": {
"required": [
"setting"
@@ -4124,9 +3814,16 @@
"instance": {
"type": "string",
"nullable": true
+ },
+ "extensions": {
+ "type": "object",
+ "additionalProperties": {
+ "nullable": true
+ },
+ "nullable": true
}
},
- "additionalProperties": { }
+ "additionalProperties": false
},
"TrangaSettings": {
"type": "object",
diff --git a/docker-compose.local.yaml b/docker-compose.local.yaml
index 80c61dd..3d6b3f3 100644
--- a/docker-compose.local.yaml
+++ b/docker-compose.local.yaml
@@ -15,6 +15,7 @@ services:
condition: service_healthy
environment:
- POSTGRES_HOST=tranga-pg
+ - CHECK_CHAPTERS_BEFORE_START=false
restart: unless-stopped
logging:
driver: json-file