mirror of
https://github.com/C9Glax/tranga.git
synced 2025-05-07 15:42:10 +02:00
Compare commits
6 Commits
4cb48dd1b4
...
94678e744f
Author | SHA1 | Date | |
---|---|---|---|
94678e744f | |||
73eb02e7cb | |||
c3ebd6acac | |||
a694b9f5ab | |||
b24d2e12fc | |||
6909c367e5 |
@ -40,41 +40,41 @@ public class JobController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Get all Jobs in requested State
|
||||
/// </summary>
|
||||
/// <param name="state">Requested Job-State</param>
|
||||
/// <param name="JobState">Requested Job-State</param>
|
||||
/// <response code="200"></response>
|
||||
[HttpGet("State/{state}")]
|
||||
[HttpGet("State/{JobState}")]
|
||||
[ProducesResponseType<Job[]>(Status200OK, "application/json")]
|
||||
public IActionResult GetJobsInState(JobState state)
|
||||
public IActionResult GetJobsInState(JobState JobState)
|
||||
{
|
||||
Job[] jobsInState = context.Jobs.Where(job => job.state == state).ToArray();
|
||||
Job[] jobsInState = context.Jobs.Where(job => job.state == JobState).ToArray();
|
||||
return Ok(jobsInState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all Jobs of requested Type
|
||||
/// </summary>
|
||||
/// <param name="type">Requested Job-Type</param>
|
||||
/// <param name="JobType">Requested Job-Type</param>
|
||||
/// <response code="200"></response>
|
||||
[HttpGet("Type/{type}")]
|
||||
[HttpGet("Type/{JobType}")]
|
||||
[ProducesResponseType<Job[]>(Status200OK, "application/json")]
|
||||
public IActionResult GetJobsOfType(JobType type)
|
||||
public IActionResult GetJobsOfType(JobType JobType)
|
||||
{
|
||||
Job[] jobsOfType = context.Jobs.Where(job => job.JobType == type).ToArray();
|
||||
Job[] jobsOfType = context.Jobs.Where(job => job.JobType == JobType).ToArray();
|
||||
return Ok(jobsOfType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return Job with ID
|
||||
/// </summary>
|
||||
/// <param name="id">Job-ID</param>
|
||||
/// <param name="JobId">Job-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">Job with ID could not be found</response>
|
||||
[HttpGet("{id}")]
|
||||
[HttpGet("{JobId}")]
|
||||
[ProducesResponseType<Job>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetJob(string id)
|
||||
public IActionResult GetJob(string JobId)
|
||||
{
|
||||
Job? ret = context.Jobs.Find(id);
|
||||
Job? ret = context.Jobs.Find(JobId);
|
||||
return (ret is not null) switch
|
||||
{
|
||||
true => Ok(ret),
|
||||
@ -85,46 +85,46 @@ public class JobController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Create a new CreateNewDownloadChapterJob
|
||||
/// </summary>
|
||||
/// <param name="mangaId">ID of Manga</param>
|
||||
/// <param name="MangaId">ID of Manga</param>
|
||||
/// <param name="recurrenceTime">How often should we check for new chapters</param>
|
||||
/// <response code="201">Created new Job</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPut("NewDownloadChapterJob/{mangaId}")]
|
||||
[HttpPut("NewDownloadChapterJob/{MangaId}")]
|
||||
[ProducesResponseType(Status201Created)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateNewDownloadChapterJob(string mangaId, [FromBody]ulong recurrenceTime)
|
||||
public IActionResult CreateNewDownloadChapterJob(string MangaId, [FromBody]ulong recurrenceTime)
|
||||
{
|
||||
Job job = new DownloadNewChaptersJob(recurrenceTime, mangaId);
|
||||
Job job = new DownloadNewChaptersJob(recurrenceTime, MangaId);
|
||||
return AddJob(job);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new DownloadSingleChapterJob
|
||||
/// </summary>
|
||||
/// <param name="chapterId">ID of the Chapter</param>
|
||||
/// <param name="ChapterId">ID of the Chapter</param>
|
||||
/// <response code="201">Created new Job</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPut("DownloadSingleChapterJob/{chapterId}")]
|
||||
[HttpPut("DownloadSingleChapterJob/{ChapterId}")]
|
||||
[ProducesResponseType(Status201Created)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateNewDownloadChapterJob(string chapterId)
|
||||
public IActionResult CreateNewDownloadChapterJob(string ChapterId)
|
||||
{
|
||||
Job job = new DownloadSingleChapterJob(chapterId);
|
||||
Job job = new DownloadSingleChapterJob(ChapterId);
|
||||
return AddJob(job);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new UpdateMetadataJob
|
||||
/// </summary>
|
||||
/// <param name="mangaId">ID of the Manga</param>
|
||||
/// <param name="MangaId">ID of the Manga</param>
|
||||
/// <response code="201">Created new Job</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPut("UpdateMetadataJob/{mangaId}")]
|
||||
[HttpPut("UpdateMetadataJob/{MangaId}")]
|
||||
[ProducesResponseType(Status201Created)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult CreateUpdateMetadataJob(string mangaId)
|
||||
public IActionResult CreateUpdateMetadataJob(string MangaId)
|
||||
{
|
||||
Job job = new UpdateMetadataJob(0, mangaId);
|
||||
Job job = new UpdateMetadataJob(0, MangaId);
|
||||
return AddJob(job);
|
||||
}
|
||||
|
||||
@ -169,22 +169,22 @@ public class JobController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Delete Job with ID and all children
|
||||
/// </summary>
|
||||
/// <param name="id">Job-ID</param>
|
||||
/// <param name="JobId">Job-ID</param>
|
||||
/// <response code="200">Job(s) deleted</response>
|
||||
/// <response code="404">Job could not be found</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpDelete("{id}")]
|
||||
[HttpDelete("{JobId}")]
|
||||
[ProducesResponseType<string[]>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult DeleteJob(string id)
|
||||
public IActionResult DeleteJob(string JobId)
|
||||
{
|
||||
try
|
||||
{
|
||||
Job? ret = context.Jobs.Find(id);
|
||||
Job? ret = context.Jobs.Find(JobId);
|
||||
if(ret is null)
|
||||
return NotFound();
|
||||
IQueryable<Job> children = GetChildJobs(id);
|
||||
IQueryable<Job> children = GetChildJobs(JobId);
|
||||
|
||||
context.RemoveRange(children);
|
||||
context.Remove(ret);
|
||||
@ -209,22 +209,22 @@ public class JobController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Modify Job with ID
|
||||
/// </summary>
|
||||
/// <param name="id">Job-ID</param>
|
||||
/// <param name="JobId">Job-ID</param>
|
||||
/// <param name="modifyJobRecord">Fields to modify, set to null to keep previous value</param>
|
||||
/// <response code="202">Job modified</response>
|
||||
/// <response code="400">Malformed request</response>
|
||||
/// <response code="404">Job with ID not found</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPatch("{id}/")]
|
||||
[HttpPatch("{JobId}")]
|
||||
[ProducesResponseType<Job>(Status202Accepted, "application/json")]
|
||||
[ProducesResponseType(Status400BadRequest)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult ModifyJob(string id, [FromBody]ModifyJobRecord modifyJobRecord)
|
||||
public IActionResult ModifyJob(string JobId, [FromBody]ModifyJobRecord modifyJobRecord)
|
||||
{
|
||||
try
|
||||
{
|
||||
Job? ret = context.Jobs.Find(id);
|
||||
Job? ret = context.Jobs.Find(JobId);
|
||||
if(ret is null)
|
||||
return NotFound();
|
||||
|
||||
@ -243,19 +243,19 @@ public class JobController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Starts the Job with the requested ID
|
||||
/// </summary>
|
||||
/// <param name="id">Job-ID</param>
|
||||
/// <param name="JobId">Job-ID</param>
|
||||
/// <response code="202">Job started</response>
|
||||
/// <response code="404">Job with ID not found</response>
|
||||
/// <response code="409">Job was already running</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPost("{id}/Start")]
|
||||
[HttpPost("{JobId}/Start")]
|
||||
[ProducesResponseType(Status202Accepted)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType(Status409Conflict)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult StartJob(string id)
|
||||
public IActionResult StartJob(string JobId)
|
||||
{
|
||||
Job? ret = context.Jobs.Find(id);
|
||||
Job? ret = context.Jobs.Find(JobId);
|
||||
if (ret is null)
|
||||
return NotFound();
|
||||
try
|
||||
@ -275,10 +275,10 @@ public class JobController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Stops the Job with the requested ID
|
||||
/// </summary>
|
||||
/// <param name="id">Job-ID</param>
|
||||
/// <param name="JobId">Job-ID</param>
|
||||
/// <remarks>NOT IMPLEMENTED</remarks>
|
||||
[HttpPost("{id}/Stop")]
|
||||
public IActionResult StopJob(string id)
|
||||
[HttpPost("{JobId}/Stop")]
|
||||
public IActionResult StopJob(string JobId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -26,15 +26,15 @@ public class LibraryConnectorController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Returns Library-Connector with requested ID
|
||||
/// </summary>
|
||||
/// <param name="id">Library-Connector-ID</param>
|
||||
/// <param name="LibraryControllerId">Library-Connector-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">Connector with ID not found.</response>
|
||||
[HttpGet("{id}")]
|
||||
[HttpGet("{LibraryControllerId}")]
|
||||
[ProducesResponseType<LibraryConnector>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetConnector(string id)
|
||||
public IActionResult GetConnector(string LibraryControllerId)
|
||||
{
|
||||
LibraryConnector? ret = context.LibraryConnectors.Find(id);
|
||||
LibraryConnector? ret = context.LibraryConnectors.Find(LibraryControllerId);
|
||||
return (ret is not null) switch
|
||||
{
|
||||
true => Ok(ret),
|
||||
@ -68,19 +68,19 @@ public class LibraryConnectorController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Deletes the Library-Connector with the requested ID
|
||||
/// </summary>
|
||||
/// <param name="id">Library-Connector-ID</param>
|
||||
/// <param name="LibraryControllerId">Library-Connector-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">Connector with ID not found.</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpDelete("{id}")]
|
||||
[HttpDelete("{LibraryControllerId}")]
|
||||
[ProducesResponseType(Status200OK)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult DeleteConnector(string id)
|
||||
public IActionResult DeleteConnector(string LibraryControllerId)
|
||||
{
|
||||
try
|
||||
{
|
||||
LibraryConnector? ret = context.LibraryConnectors.Find(id);
|
||||
LibraryConnector? ret = context.LibraryConnectors.Find(LibraryControllerId);
|
||||
if (ret is null)
|
||||
return NotFound();
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class MangaConnectorController(PgsqlContext context) : Controller
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">Connector with ID not found.</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPatch("{id}/SetEnabled/{enabled}")]
|
||||
[HttpPatch("{MangaConnectorName}/SetEnabled/{enabled}")]
|
||||
[ProducesResponseType(Status200OK)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
|
@ -44,15 +44,15 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Return Manga with ID
|
||||
/// </summary>
|
||||
/// <param name="id">Manga-ID</param>
|
||||
/// <param name="MangaId">Manga-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">Manga with ID not found</response>
|
||||
[HttpGet("{id}")]
|
||||
[HttpGet("{MangaId}")]
|
||||
[ProducesResponseType<Manga>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetManga(string id)
|
||||
public IActionResult GetManga(string MangaId)
|
||||
{
|
||||
Manga? ret = context.Manga.Find(id);
|
||||
Manga? ret = context.Manga.Find(MangaId);
|
||||
if (ret is null)
|
||||
return NotFound();
|
||||
return Ok(ret);
|
||||
@ -61,19 +61,19 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Delete Manga with ID
|
||||
/// </summary>
|
||||
/// <param name="id">Manga-ID</param>
|
||||
/// <param name="MangaId">Manga-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">Manga with ID not found</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpDelete("{id}")]
|
||||
[HttpDelete("{MangaId}")]
|
||||
[ProducesResponseType(Status200OK)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult DeleteManga(string id)
|
||||
public IActionResult DeleteManga(string MangaId)
|
||||
{
|
||||
try
|
||||
{
|
||||
Manga? ret = context.Manga.Find(id);
|
||||
Manga? ret = context.Manga.Find(MangaId);
|
||||
if (ret is null)
|
||||
return NotFound();
|
||||
|
||||
@ -90,20 +90,20 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Returns Cover of Manga
|
||||
/// </summary>
|
||||
/// <param name="id">Manga-ID</param>
|
||||
/// <param name="MangaId">Manga-ID</param>
|
||||
/// <param name="formatRequest">Formatting/Resizing Request</param>
|
||||
/// <response code="200">JPEG Image</response>
|
||||
/// <response code="204">Cover not loaded</response>
|
||||
/// <response code="400">The formatting-request was invalid</response>
|
||||
/// <response code="404">Manga with ID not found</response>
|
||||
[HttpPost("{id}/Cover")]
|
||||
[HttpPost("{MangaId}/Cover")]
|
||||
[ProducesResponseType<byte[]>(Status200OK,"image/jpeg")]
|
||||
[ProducesResponseType(Status204NoContent)]
|
||||
[ProducesResponseType(Status400BadRequest)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetCover(string id, [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)]CoverFormatRequestRecord? formatRequest)
|
||||
public IActionResult GetCover(string MangaId, [FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)]CoverFormatRequestRecord? formatRequest)
|
||||
{
|
||||
Manga? m = context.Manga.Find(id);
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
if (!System.IO.File.Exists(m.CoverFileNameInCache))
|
||||
@ -130,15 +130,15 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Returns all Chapters of Manga
|
||||
/// </summary>
|
||||
/// <param name="id">Manga-ID</param>
|
||||
/// <param name="MangaId">Manga-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">Manga with ID not found</response>
|
||||
[HttpGet("{id}/Chapters")]
|
||||
[HttpGet("{MangaId}/Chapters")]
|
||||
[ProducesResponseType<Chapter[]>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetChapters(string id)
|
||||
public IActionResult GetChapters(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(id);
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -149,19 +149,19 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Returns the latest Chapter of requested Manga available on Website
|
||||
/// </summary>
|
||||
/// <param name="id">Manga-ID</param>
|
||||
/// <param name="MangaId">Manga-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="204">No available chapters</response>
|
||||
/// <response code="404">Manga with ID not found.</response>
|
||||
/// <response code="500">Could not retrieve the maximum chapter-number</response>
|
||||
[HttpGet("{id}/Chapter/LatestAvailable")]
|
||||
[HttpGet("{MangaId}/Chapter/LatestAvailable")]
|
||||
[ProducesResponseType<Chapter>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status204NoContent)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult GetLatestChapter(string id)
|
||||
public IActionResult GetLatestChapter(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(id);
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -179,19 +179,19 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Returns the latest Chapter of requested Manga that is downloaded
|
||||
/// </summary>
|
||||
/// <param name="id">Manga-ID</param>
|
||||
/// <param name="MangaId">Manga-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="204">No available chapters</response>
|
||||
/// <response code="404">Manga with ID not found.</response>
|
||||
/// <response code="500">Could not retrieve the maximum chapter-number</response>
|
||||
[HttpGet("{id}/Chapter/LatestDownloaded")]
|
||||
[HttpGet("{MangaId}/Chapter/LatestDownloaded")]
|
||||
[ProducesResponseType<Chapter>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status204NoContent)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult GetLatestChapterDownloaded(string id)
|
||||
public IActionResult GetLatestChapterDownloaded(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(id);
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
|
||||
@ -209,15 +209,15 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Configure the cut-off for Manga
|
||||
/// </summary>
|
||||
/// <param name="id">Manga-ID</param>
|
||||
/// <param name="MangaId">Manga-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">Manga with ID not found.</response>
|
||||
[HttpPatch("{id}/IgnoreChaptersBefore")]
|
||||
[HttpPatch("{MangaId}/IgnoreChaptersBefore")]
|
||||
[ProducesResponseType<float>(Status200OK, "text/plain")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult IgnoreChaptersBefore(string id)
|
||||
public IActionResult IgnoreChaptersBefore(string MangaId)
|
||||
{
|
||||
Manga? m = context.Manga.Find(id);
|
||||
Manga? m = context.Manga.Find(MangaId);
|
||||
if (m is null)
|
||||
return NotFound();
|
||||
return Ok(m.IgnoreChapterBefore);
|
||||
@ -226,11 +226,11 @@ public class MangaController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Move the Directory the .cbz-files are located in
|
||||
/// </summary>
|
||||
/// <param name="id">Manga-ID</param>
|
||||
/// <param name="MangaId">Manga-ID</param>
|
||||
/// <param name="folder">New Directory-Path</param>
|
||||
/// <remarks>NOT IMPLEMENTED</remarks>
|
||||
[HttpPost("{id}/MoveFolder")]
|
||||
public IActionResult MoveFolder(string id, [FromBody]string folder)
|
||||
[HttpPost("{MangaId}/MoveFolder")]
|
||||
public IActionResult MoveFolder(string MangaId, [FromBody]string folder)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -29,15 +29,15 @@ public class NotificationConnectorController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Returns Notification-Connector with requested ID
|
||||
/// </summary>
|
||||
/// <param name="id">Notification-Connector-ID</param>
|
||||
/// <param name="NotificationConnectorId">Notification-Connector-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">NotificationConnector with ID not found</response>
|
||||
[HttpGet("{id}")]
|
||||
[HttpGet("{NotificationConnectorId}")]
|
||||
[ProducesResponseType<NotificationConnector>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
public IActionResult GetConnector(string id)
|
||||
public IActionResult GetConnector(string NotificationConnectorId)
|
||||
{
|
||||
NotificationConnector? ret = context.NotificationConnectors.Find(id);
|
||||
NotificationConnector? ret = context.NotificationConnectors.Find(NotificationConnectorId);
|
||||
return (ret is not null) switch
|
||||
{
|
||||
true => Ok(ret),
|
||||
@ -161,19 +161,19 @@ public class NotificationConnectorController(PgsqlContext context) : Controller
|
||||
/// <summary>
|
||||
/// Deletes the Notification-Connector with the requested ID
|
||||
/// </summary>
|
||||
/// <param name="id">Notification-Connector-ID</param>
|
||||
/// <param name="NotificationConnectorId">Notification-Connector-ID</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="404">NotificationConnector with ID not found</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpDelete("{id}")]
|
||||
[HttpDelete("{NotificationConnectorId}")]
|
||||
[ProducesResponseType(Status200OK)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult DeleteConnector(string id)
|
||||
public IActionResult DeleteConnector(string NotificationConnectorId)
|
||||
{
|
||||
try
|
||||
{
|
||||
NotificationConnector? ret = context.NotificationConnectors.Find(id);
|
||||
NotificationConnector? ret = context.NotificationConnectors.Find(NotificationConnectorId);
|
||||
if(ret is null)
|
||||
return NotFound();
|
||||
|
||||
|
@ -20,10 +20,10 @@ public class SearchController(PgsqlContext context) : Controller
|
||||
/// <param name="name">Name/Title of the Manga</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPost("{name}")]
|
||||
[HttpPost("Name")]
|
||||
[ProducesResponseType<Manga[]>(Status200OK, "application/json")]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult SearchMangaGlobal(string name)
|
||||
public IActionResult SearchMangaGlobal([FromBody]string name)
|
||||
{
|
||||
List<(Manga, List<Author>?, List<MangaTag>?, List<Link>?, List<MangaAltTitle>?)> allManga = new();
|
||||
foreach (MangaConnector contextMangaConnector in context.MangaConnectors.Where(connector => connector.Enabled))
|
||||
@ -55,7 +55,7 @@ public class SearchController(PgsqlContext context) : Controller
|
||||
/// <response code="404">MangaConnector with ID not found</response>
|
||||
/// <response code="406">MangaConnector with ID is disabled</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPost("{id}/{name}")]
|
||||
[HttpPost("{MangaConnectorName}/{SearchName}")]
|
||||
[ProducesResponseType<Manga[]>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType(Status406NotAcceptable)]
|
||||
@ -86,6 +86,45 @@ public class SearchController(PgsqlContext context) : Controller
|
||||
|
||||
return Ok(retMangas.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Manga from MangaConnector associated with URL
|
||||
/// </summary>
|
||||
/// <param name="url">Manga-Page URL</param>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="300">Multiple connectors found for URL</response>
|
||||
/// <response code="400">No Manga at URL</response>
|
||||
/// <response code="404">No connector found for URL</response>
|
||||
/// <response code="500">Error during Database Operation</response>
|
||||
[HttpPost("Url")]
|
||||
[ProducesResponseType<Manga>(Status200OK, "application/json")]
|
||||
[ProducesResponseType(Status300MultipleChoices)]
|
||||
[ProducesResponseType(Status400BadRequest)]
|
||||
[ProducesResponseType(Status404NotFound)]
|
||||
[ProducesResponseType<string>(Status500InternalServerError, "text/plain")]
|
||||
public IActionResult GetMangaFromUrl([FromBody]string url)
|
||||
{
|
||||
List<MangaConnector> connectors = context.MangaConnectors.AsEnumerable().Where(c => c.ValidateUrl(url)).ToList();
|
||||
if (connectors.Count == 0)
|
||||
return NotFound();
|
||||
else if (connectors.Count > 1)
|
||||
return StatusCode(Status300MultipleChoices);
|
||||
|
||||
(Manga manga, List<Author>? authors, List<MangaTag>? tags, List<Link>? links, List<MangaAltTitle>? altTitles)? x = connectors.First().GetMangaFromUrl(url);
|
||||
if (x is null)
|
||||
return BadRequest();
|
||||
try
|
||||
{
|
||||
Manga? add = AddMangaToContext(x.Value.manga, x.Value.authors, x.Value.tags, x.Value.links, x.Value.altTitles);
|
||||
if (add is not null)
|
||||
return Ok(add);
|
||||
return StatusCode(500);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return StatusCode(500, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private Manga? AddMangaToContext(Manga? manga, List<Author>? authors, List<MangaTag>? tags, List<Link>? links,
|
||||
List<MangaAltTitle>? altTitles)
|
||||
|
689
API/Migrations/20250308121028_dev-080325-1.Designer.cs
generated
Normal file
689
API/Migrations/20250308121028_dev-080325-1.Designer.cs
generated
Normal file
@ -0,0 +1,689 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using API.Schema;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace API.Migrations
|
||||
{
|
||||
[DbContext(typeof(PgsqlContext))]
|
||||
[Migration("20250308121028_dev-080325-1")]
|
||||
partial class dev0803251
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.2")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "hstore");
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("API.Schema.Author", b =>
|
||||
{
|
||||
b.Property<string>("AuthorId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("AuthorId");
|
||||
|
||||
b.ToTable("Authors");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Chapter", b =>
|
||||
{
|
||||
b.Property<string>("ChapterId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("ArchiveFileName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ChapterNumber")
|
||||
.IsRequired()
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("character varying(10)");
|
||||
|
||||
b.Property<bool>("Downloaded")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("ParentMangaId")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int?>("VolumeNumber")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.HasKey("ChapterId");
|
||||
|
||||
b.HasIndex("ParentMangaId");
|
||||
|
||||
b.ToTable("Chapters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.Job", b =>
|
||||
{
|
||||
b.Property<string>("JobId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.PrimitiveCollection<string[]>("DependsOnJobsIds")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("JobId1")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<byte>("JobType")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.Property<DateTime>("LastExecution")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("ParentJobId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<decimal>("RecurrenceMs")
|
||||
.HasColumnType("numeric(20,0)");
|
||||
|
||||
b.Property<byte>("state")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.HasKey("JobId");
|
||||
|
||||
b.HasIndex("JobId1");
|
||||
|
||||
b.HasIndex("ParentJobId");
|
||||
|
||||
b.ToTable("Jobs");
|
||||
|
||||
b.HasDiscriminator<byte>("JobType");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.LibraryConnectors.LibraryConnector", b =>
|
||||
{
|
||||
b.Property<string>("LibraryConnectorId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("Auth")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("BaseUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<byte>("LibraryType")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.HasKey("LibraryConnectorId");
|
||||
|
||||
b.ToTable("LibraryConnectors");
|
||||
|
||||
b.HasDiscriminator<byte>("LibraryType");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Link", b =>
|
||||
{
|
||||
b.Property<string>("LinkId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("LinkProvider")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LinkUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasKey("LinkId");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("Link");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Manga", b =>
|
||||
{
|
||||
b.Property<string>("MangaId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.PrimitiveCollection<string[]>("AltTitleIds")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.PrimitiveCollection<string[]>("AuthorIds")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<string>("ConnectorId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("CoverFileNameInCache")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CoverUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("FolderName")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<float>("IgnoreChapterBefore")
|
||||
.HasColumnType("real");
|
||||
|
||||
b.PrimitiveCollection<string[]>("LinkIds")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<string>("MangaConnectorId")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(32)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("OriginalLanguage")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<byte>("ReleaseStatus")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.PrimitiveCollection<string[]>("TagIds")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<string>("WebsiteUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<long>("Year")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.HasKey("MangaId");
|
||||
|
||||
b.HasIndex("MangaConnectorId");
|
||||
|
||||
b.ToTable("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaAltTitle", b =>
|
||||
{
|
||||
b.Property<string>("AltTitleId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("Language")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8)
|
||||
.HasColumnType("character varying(8)");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("AltTitleId");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("AltTitles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.MangaConnector", b =>
|
||||
{
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("character varying(32)");
|
||||
|
||||
b.PrimitiveCollection<string[]>("BaseUris")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("IconUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.PrimitiveCollection<string[]>("SupportedLanguages")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.HasKey("Name");
|
||||
|
||||
b.ToTable("MangaConnectors");
|
||||
|
||||
b.HasDiscriminator<string>("Name").HasValue("MangaConnector");
|
||||
|
||||
b.UseTphMappingStrategy();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaTag", b =>
|
||||
{
|
||||
b.Property<string>("Tag")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Tag");
|
||||
|
||||
b.ToTable("Tags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Notification", b =>
|
||||
{
|
||||
b.Property<string>("NotificationId")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<DateTime>("Date")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<byte>("Urgency")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.HasKey("NotificationId");
|
||||
|
||||
b.ToTable("Notifications");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.NotificationConnectors.NotificationConnector", b =>
|
||||
{
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("Body")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<Dictionary<string, string>>("Headers")
|
||||
.IsRequired()
|
||||
.HasColumnType("hstore");
|
||||
|
||||
b.Property<string>("HttpMethod")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Name");
|
||||
|
||||
b.ToTable("NotificationConnectors");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AuthorManga", b =>
|
||||
{
|
||||
b.Property<string>("AuthorsAuthorId")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasKey("AuthorsAuthorId", "MangaId");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("AuthorManga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MangaMangaTag", b =>
|
||||
{
|
||||
b.Property<string>("MangaId")
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.Property<string>("TagsTag")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("MangaId", "TagsTag");
|
||||
|
||||
b.HasIndex("TagsTag");
|
||||
|
||||
b.ToTable("MangaMangaTag");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadMangaCoverJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("Jobs", t =>
|
||||
{
|
||||
t.Property("MangaId")
|
||||
.HasColumnName("DownloadMangaCoverJob_MangaId");
|
||||
});
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)4);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadNewChaptersJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)1);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadSingleChapterJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("ChapterId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("ChapterId");
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)0);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.MoveFileOrFolderJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("FromLocation")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ToLocation")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)3);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.UpdateMetadataJob", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.Jobs.Job");
|
||||
|
||||
b.Property<string>("MangaId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.HasIndex("MangaId");
|
||||
|
||||
b.ToTable("Jobs", t =>
|
||||
{
|
||||
t.Property("MangaId")
|
||||
.HasColumnName("UpdateMetadataJob_MangaId");
|
||||
});
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)2);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.LibraryConnectors.Kavita", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.LibraryConnectors.LibraryConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)1);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.LibraryConnectors.Komga", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.LibraryConnectors.LibraryConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue((byte)0);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.AsuraToon", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("AsuraToon");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.Bato", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("Bato");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.MangaDex", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("MangaDex");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.MangaHere", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("MangaHere");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.MangaKatana", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("MangaKatana");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.Mangaworld", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("Mangaworld");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.ManhuaPlus", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("ManhuaPlus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaConnectors.Weebcentral", b =>
|
||||
{
|
||||
b.HasBaseType("API.Schema.MangaConnectors.MangaConnector");
|
||||
|
||||
b.HasDiscriminator().HasValue("Weebcentral");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Chapter", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "ParentManga")
|
||||
.WithMany()
|
||||
.HasForeignKey("ParentMangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("ParentManga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.Job", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Jobs.Job", null)
|
||||
.WithMany("DependsOnJobs")
|
||||
.HasForeignKey("JobId1");
|
||||
|
||||
b.HasOne("API.Schema.Jobs.Job", "ParentJob")
|
||||
.WithMany()
|
||||
.HasForeignKey("ParentJobId");
|
||||
|
||||
b.Navigation("ParentJob");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Link", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", null)
|
||||
.WithMany("Links")
|
||||
.HasForeignKey("MangaId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Manga", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.MangaConnectors.MangaConnector", "MangaConnector")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaConnectorId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("MangaConnector");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.MangaAltTitle", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", null)
|
||||
.WithMany("AltTitles")
|
||||
.HasForeignKey("MangaId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AuthorManga", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Author", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("AuthorsAuthorId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("API.Schema.Manga", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("MangaMangaTag", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("API.Schema.MangaTag", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("TagsTag")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadMangaCoverJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadNewChaptersJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.DownloadSingleChapterJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Chapter", "Chapter")
|
||||
.WithMany()
|
||||
.HasForeignKey("ChapterId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Chapter");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.UpdateMetadataJob", b =>
|
||||
{
|
||||
b.HasOne("API.Schema.Manga", "Manga")
|
||||
.WithMany()
|
||||
.HasForeignKey("MangaId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Manga");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Jobs.Job", b =>
|
||||
{
|
||||
b.Navigation("DependsOnJobs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("API.Schema.Manga", b =>
|
||||
{
|
||||
b.Navigation("AltTitles");
|
||||
|
||||
b.Navigation("Links");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
62
API/Migrations/20250308121028_dev-080325-1.cs
Normal file
62
API/Migrations/20250308121028_dev-080325-1.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace API.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class dev0803251 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string[]>(
|
||||
name: "AltTitleIds",
|
||||
table: "Manga",
|
||||
type: "text[]",
|
||||
nullable: false,
|
||||
defaultValue: new string[0]);
|
||||
|
||||
migrationBuilder.AddColumn<string[]>(
|
||||
name: "AuthorIds",
|
||||
table: "Manga",
|
||||
type: "text[]",
|
||||
nullable: false,
|
||||
defaultValue: new string[0]);
|
||||
|
||||
migrationBuilder.AddColumn<string[]>(
|
||||
name: "LinkIds",
|
||||
table: "Manga",
|
||||
type: "text[]",
|
||||
nullable: false,
|
||||
defaultValue: new string[0]);
|
||||
|
||||
migrationBuilder.AddColumn<string[]>(
|
||||
name: "TagIds",
|
||||
table: "Manga",
|
||||
type: "text[]",
|
||||
nullable: false,
|
||||
defaultValue: new string[0]);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AltTitleIds",
|
||||
table: "Manga");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AuthorIds",
|
||||
table: "Manga");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LinkIds",
|
||||
table: "Manga");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TagIds",
|
||||
table: "Manga");
|
||||
}
|
||||
}
|
||||
}
|
@ -179,6 +179,14 @@ namespace API.Migrations
|
||||
.HasMaxLength(64)
|
||||
.HasColumnType("character varying(64)");
|
||||
|
||||
b.PrimitiveCollection<string[]>("AltTitleIds")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.PrimitiveCollection<string[]>("AuthorIds")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<string>("ConnectorId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(64)
|
||||
@ -202,6 +210,10 @@ namespace API.Migrations
|
||||
b.Property<float>("IgnoreChapterBefore")
|
||||
.HasColumnType("real");
|
||||
|
||||
b.PrimitiveCollection<string[]>("LinkIds")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<string>("MangaConnectorId")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(32)");
|
||||
@ -216,6 +228,10 @@ namespace API.Migrations
|
||||
b.Property<byte>("ReleaseStatus")
|
||||
.HasColumnType("smallint");
|
||||
|
||||
b.PrimitiveCollection<string[]>("TagIds")
|
||||
.IsRequired()
|
||||
.HasColumnType("text[]");
|
||||
|
||||
b.Property<string>("WebsiteUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Xml.Linq;
|
||||
using API.Schema.Jobs;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace API.Schema;
|
||||
|
||||
@ -38,6 +39,7 @@ public class Chapter : IComparable<Chapter>
|
||||
public bool Downloaded { get; internal set; } = false;
|
||||
|
||||
public string ParentMangaId { get; internal set; }
|
||||
[JsonIgnore]
|
||||
public Manga? ParentManga { get; init; }
|
||||
|
||||
public int CompareTo(Chapter? other)
|
||||
|
@ -3,6 +3,7 @@ using System.IO.Compression;
|
||||
using System.Runtime.InteropServices;
|
||||
using API.MangaDownloadClients;
|
||||
using API.Schema.MangaConnectors;
|
||||
using Newtonsoft.Json;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
@ -16,6 +17,7 @@ public class DownloadMangaCoverJob(string mangaId, string? parentJobId = null, I
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
[JsonIgnore]
|
||||
public Manga? Manga { get; init; }
|
||||
|
||||
protected override IEnumerable<Job> RunInternal(PgsqlContext context)
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using API.Schema.MangaConnectors;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace API.Schema.Jobs;
|
||||
|
||||
@ -8,6 +9,8 @@ public class DownloadNewChaptersJob(ulong recurrenceMs, string mangaId, string?
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
|
||||
[JsonIgnore]
|
||||
public Manga? Manga { get; init; }
|
||||
|
||||
protected override IEnumerable<Job> RunInternal(PgsqlContext context)
|
||||
|
@ -3,6 +3,7 @@ using System.IO.Compression;
|
||||
using System.Runtime.InteropServices;
|
||||
using API.MangaDownloadClients;
|
||||
using API.Schema.MangaConnectors;
|
||||
using Newtonsoft.Json;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
@ -16,6 +17,8 @@ public class DownloadSingleChapterJob(string chapterId, string? parentJobId = nu
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string ChapterId { get; init; } = chapterId;
|
||||
|
||||
[JsonIgnore]
|
||||
public Chapter? Chapter { get; init; }
|
||||
|
||||
protected override IEnumerable<Job> RunInternal(PgsqlContext context)
|
||||
|
@ -13,10 +13,12 @@ public abstract class Job
|
||||
|
||||
[MaxLength(64)]
|
||||
public string? ParentJobId { get; init; }
|
||||
[JsonIgnore]
|
||||
public Job? ParentJob { get; init; }
|
||||
|
||||
[MaxLength(64)]
|
||||
public ICollection<string>? DependsOnJobsIds { get; init; }
|
||||
[JsonIgnore]
|
||||
public ICollection<Job>? DependsOnJobs { get; init; }
|
||||
|
||||
public JobType JobType { get; init; }
|
||||
|
@ -1,29 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using JsonSerializer = Newtonsoft.Json.JsonSerializer;
|
||||
|
||||
namespace API.Schema.Jobs;
|
||||
|
||||
public class JobJsonDeserializer : JsonConverter<Job>
|
||||
{
|
||||
public override bool CanWrite { get; } = false;
|
||||
|
||||
public override void WriteJson(JsonWriter writer, Job? value, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Job? ReadJson(JsonReader reader, Type objectType, Job? existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
JObject j = JObject.Load(reader);
|
||||
JobType? type = Enum.Parse<JobType>(j.GetValue("jobType")!.Value<string>()!);
|
||||
return type switch
|
||||
{
|
||||
JobType.DownloadSingleChapterJob => j.ToObject<DownloadSingleChapterJob>(),
|
||||
JobType.DownloadNewChaptersJob => j.ToObject<DownloadNewChaptersJob>(),
|
||||
JobType.UpdateMetaDataJob => j.ToObject<UpdateMetadataJob>(),
|
||||
JobType.MoveFileOrFolderJob => j.ToObject<MoveFileOrFolderJob>(),
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using API.Schema.MangaConnectors;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace API.Schema.Jobs;
|
||||
|
||||
@ -8,6 +9,8 @@ public class UpdateMetadataJob(ulong recurrenceMs, string mangaId, string? paren
|
||||
{
|
||||
[MaxLength(64)]
|
||||
public string MangaId { get; init; } = mangaId;
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual Manga? Manga { get; init; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,3 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
@ -6,6 +7,7 @@ using API.MangaDownloadClients;
|
||||
using API.Schema.Jobs;
|
||||
using API.Schema.MangaConnectors;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using static System.IO.UnixFileMode;
|
||||
|
||||
namespace API.Schema;
|
||||
@ -30,15 +32,23 @@ public class Manga
|
||||
public float IgnoreChapterBefore { get; internal set; }
|
||||
|
||||
public string MangaConnectorId { get; private set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public MangaConnector? MangaConnector { get; private set; }
|
||||
|
||||
public ICollection<string> AuthorIds { get; internal set; }
|
||||
[JsonIgnore]
|
||||
public ICollection<Author>? Authors { get; internal set; }
|
||||
|
||||
public ICollection<string> TagIds { get; internal set; }
|
||||
[JsonIgnore]
|
||||
public ICollection<MangaTag>? Tags { get; internal set; }
|
||||
|
||||
public ICollection<string> LinkIds { get; internal set; }
|
||||
[JsonIgnore]
|
||||
public ICollection<Link>? Links { get; internal set; }
|
||||
|
||||
public ICollection<string> AltTitleIds { get; internal set; }
|
||||
[JsonIgnore]
|
||||
public ICollection<MangaAltTitle>? AltTitles { get; internal set; }
|
||||
|
||||
public Manga(string connectorId, string name, string description, string websiteUrl, string coverUrl,
|
||||
@ -48,9 +58,13 @@ public class Manga
|
||||
: this(connectorId, name, description, websiteUrl, coverUrl, coverFileNameInCache, year, originalLanguage,
|
||||
releaseStatus, ignoreChapterBefore, mangaConnector.Name)
|
||||
{
|
||||
this.AuthorIds = authors.Select(a => a.AuthorId) as ICollection<string>;
|
||||
this.Authors = authors;
|
||||
this.TagIds = tags.Select(t => t.Tag) as ICollection<string>;
|
||||
this.Tags = tags;
|
||||
this.LinkIds = links.Select(l => l.LinkId) as ICollection<string>;
|
||||
this.Links = links;
|
||||
this.AltTitleIds = altTitles.Select(t => t.AltTitleId) as ICollection<string>;
|
||||
this.AltTitles = altTitles;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.RegularExpressions;
|
||||
using API.MangaDownloadClients;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
@ -39,4 +40,6 @@ public abstract class MangaConnector(string name, string[] supportedLanguages, s
|
||||
}
|
||||
|
||||
internal abstract string[] GetChapterImageUrls(Chapter chapter);
|
||||
|
||||
public bool ValidateUrl(string url) => BaseUris.Any(baseUri => Regex.IsMatch(url, "https?://" + baseUri + "/.*"));
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user