From 03e90eccd32fbb04b1d55543324844af0bcf30a0 Mon Sep 17 00:00:00 2001 From: Glax Date: Mon, 22 Apr 2024 04:21:30 +0200 Subject: [PATCH] No longer require connector name to create job --- Tranga/Jobs/DownloadNewChapters.cs | 6 +-- Tranga/Jobs/JobJsonConverter.cs | 67 +++++++++++---------------- Tranga/Jobs/UpdateMetadata.cs | 2 +- Tranga/Manga.cs | 10 ++-- Tranga/MangaConnectors/Bato.cs | 4 +- Tranga/MangaConnectors/MangaDex.cs | 9 ++-- Tranga/MangaConnectors/MangaKatana.cs | 4 +- Tranga/MangaConnectors/MangaLife.cs | 4 +- Tranga/MangaConnectors/Manganato.cs | 4 +- Tranga/MangaConnectors/Mangasee.cs | 5 +- Tranga/MangaConnectors/Mangaworld.cs | 4 +- Tranga/Server/Server.cs | 4 +- Tranga/Server/v2Jobs.cs | 24 +++------- docs/API_Calls_v2.md | 1 - 14 files changed, 62 insertions(+), 86 deletions(-) diff --git a/Tranga/Jobs/DownloadNewChapters.cs b/Tranga/Jobs/DownloadNewChapters.cs index ebcbde7..a202c49 100644 --- a/Tranga/Jobs/DownloadNewChapters.cs +++ b/Tranga/Jobs/DownloadNewChapters.cs @@ -7,8 +7,8 @@ public class DownloadNewChapters : Job public Manga manga { get; set; } public string translatedLanguage { get; init; } - public DownloadNewChapters(GlobalBase clone, MangaConnector connector, Manga manga, DateTime lastExecution, - bool recurring = false, TimeSpan? recurrence = null, string? parentJobId = null, string translatedLanguage = "en") : base(clone, JobType.DownloadNewChaptersJob, connector, lastExecution, recurring, + public DownloadNewChapters(GlobalBase clone, Manga manga, DateTime lastExecution, + bool recurring = false, TimeSpan? recurrence = null, string? parentJobId = null, string translatedLanguage = "en") : base(clone, JobType.DownloadNewChaptersJob, manga.mangaConnector, lastExecution, recurring, recurrence, parentJobId) { this.manga = manga; @@ -43,7 +43,7 @@ public class DownloadNewChapters : Job DownloadChapter downloadChapterJob = new(this, this.mangaConnector, chapter, parentJobId: this.id); jobs.Add(downloadChapterJob); } - UpdateMetadata updateMetadataJob = new(this, this.mangaConnector, this.manga, parentJobId: this.id); + UpdateMetadata updateMetadataJob = new(this, this.manga, parentJobId: this.id); jobs.Add(updateMetadataJob); progressToken.Complete(); return jobs; diff --git a/Tranga/Jobs/JobJsonConverter.cs b/Tranga/Jobs/JobJsonConverter.cs index 5b12143..9b37258 100644 --- a/Tranga/Jobs/JobJsonConverter.cs +++ b/Tranga/Jobs/JobJsonConverter.cs @@ -23,53 +23,42 @@ public class JobJsonConverter : JsonConverter public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { JObject jo = JObject.Load(reader); + + if(!jo.ContainsKey("jobType")) + throw new Exception(); - if (jo.ContainsKey("jobType") && jo["jobType"]!.Value() == (byte)Job.JobType.UpdateMetaDataJob) + return Enum.Parse(jo["jobType"]!.Value().ToString()) switch { - return new UpdateMetadata(this._clone, + Job.JobType.UpdateMetaDataJob => new UpdateMetadata(_clone, + jo.GetValue("manga")!.ToObject(JsonSerializer.Create(new JsonSerializerSettings() + { + Converters = { this._mangaConnectorJsonConverter } + })), + jo.GetValue("parentJobId")!.Value()), + Job.JobType.DownloadChapterJob => new DownloadChapter(this._clone, jo.GetValue("mangaConnector")!.ToObject(JsonSerializer.Create(new JsonSerializerSettings() { - Converters = - { - this._mangaConnectorJsonConverter - } + Converters = { this._mangaConnectorJsonConverter } }))!, - jo.GetValue("manga")!.ToObject(), - jo.GetValue("parentJobId")!.Value()); - }else if ((jo.ContainsKey("jobType") && jo["jobType"]!.Value() == (byte)Job.JobType.DownloadNewChaptersJob) || jo.ContainsKey("translatedLanguage"))//TODO change to jobType - { - DateTime lastExecution = jo.GetValue("lastExecution") is {} le - ? le.ToObject() - : DateTime.UnixEpoch; //TODO do null checks on all variables - return new DownloadNewChapters(this._clone, - jo.GetValue("mangaConnector")!.ToObject(JsonSerializer.Create(new JsonSerializerSettings() + jo.GetValue("chapter")!.ToObject(JsonSerializer.Create(new JsonSerializerSettings() { - Converters = - { - this._mangaConnectorJsonConverter - } - }))!, - jo.GetValue("manga")!.ToObject(), - lastExecution, + Converters = { this._mangaConnectorJsonConverter } + })), + DateTime.UnixEpoch, + jo.GetValue("parentJobId")!.Value()), + Job.JobType.DownloadNewChaptersJob => new DownloadNewChapters(this._clone, + jo.GetValue("manga")!.ToObject(JsonSerializer.Create(new JsonSerializerSettings() + { + Converters = { this._mangaConnectorJsonConverter } + })), + jo.GetValue("lastExecution") is {} le + ? le.ToObject() + : DateTime.UnixEpoch, jo.GetValue("recurring")!.Value(), jo.GetValue("recurrenceTime")!.ToObject(), - jo.GetValue("parentJobId")!.Value()); - }else if ((jo.ContainsKey("jobType") && jo["jobType"]!.Value() == (byte)Job.JobType.DownloadChapterJob) || jo.ContainsKey("chapter"))//TODO change to jobType - { - return new DownloadChapter(this._clone, - jo.GetValue("mangaConnector")!.ToObject(JsonSerializer.Create(new JsonSerializerSettings() - { - Converters = - { - this._mangaConnectorJsonConverter - } - }))!, - jo.GetValue("chapter")!.ToObject(), - DateTime.UnixEpoch, - jo.GetValue("parentJobId")!.Value()); - } - - throw new Exception(); + jo.GetValue("parentJobId")!.Value()), + _ => throw new Exception() + }; } public override bool CanWrite => false; diff --git a/Tranga/Jobs/UpdateMetadata.cs b/Tranga/Jobs/UpdateMetadata.cs index e9107ce..121ce47 100644 --- a/Tranga/Jobs/UpdateMetadata.cs +++ b/Tranga/Jobs/UpdateMetadata.cs @@ -6,7 +6,7 @@ public class UpdateMetadata : Job { public Manga manga { get; set; } - public UpdateMetadata(GlobalBase clone, MangaConnector connector, Manga manga, string? parentJobId = null) : base(clone, JobType.UpdateMetaDataJob, connector, parentJobId: parentJobId) + public UpdateMetadata(GlobalBase clone, Manga manga, string? parentJobId = null) : base(clone, JobType.UpdateMetaDataJob, manga.mangaConnector, parentJobId: parentJobId) { this.manga = manga; } diff --git a/Tranga/Manga.cs b/Tranga/Manga.cs index a29f2b6..d1a0e85 100644 --- a/Tranga/Manga.cs +++ b/Tranga/Manga.cs @@ -2,6 +2,7 @@ using System.Text; using System.Text.RegularExpressions; using Newtonsoft.Json; +using Tranga.MangaConnectors; using static System.IO.UnixFileMode; namespace Tranga; @@ -26,8 +27,6 @@ public struct Manga // ReSharper disable once MemberCanBePrivate.Global public int? year { get; private set; } public string? originalLanguage { get; } - // ReSharper disable twice MemberCanBePrivate.Global - public string status { get; private set; } public ReleaseStatusByte releaseStatus { get; private set; } public enum ReleaseStatusByte : byte { @@ -43,14 +42,15 @@ public struct Manga public float ignoreChaptersBelow { get; set; } public float latestChapterDownloaded { get; set; } public float latestChapterAvailable { get; set; } - public string websiteUrl { get; private set; } + public MangaConnector mangaConnector { get; private set; } private static readonly Regex LegalCharacters = new (@"[A-Za-zÀ-ÖØ-öø-ÿ0-9 \.\-,'\'\)\(~!\+]*"); [JsonConstructor] - public Manga(string sortName, List authors, string? description, Dictionary altTitles, string[] tags, string? coverUrl, string? coverFileNameInCache, Dictionary? links, int? year, string? originalLanguage, string publicationId, ReleaseStatusByte releaseStatus, string? websiteUrl, string? folderName = null, float? ignoreChaptersBelow = 0) + public Manga(MangaConnector mangaConnector, string sortName, List authors, string? description, Dictionary altTitles, string[] tags, string? coverUrl, string? coverFileNameInCache, Dictionary? links, int? year, string? originalLanguage, string publicationId, ReleaseStatusByte releaseStatus, string? websiteUrl, string? folderName = null, float? ignoreChaptersBelow = 0) { + this.mangaConnector = mangaConnector; this.sortName = sortName; this.authors = authors; this.description = description; @@ -82,7 +82,6 @@ public struct Manga this.authors = authors.Union(newManga.authors).ToList(); this.altTitles = altTitles.UnionBy(newManga.altTitles, kv => kv.Key).ToDictionary(x => x.Key, x => x.Value); this.tags = tags.Union(newManga.tags).ToArray(); - this.status = newManga.status; this.releaseStatus = newManga.releaseStatus; this.year = newManga.year; } @@ -93,7 +92,6 @@ public struct Manga return false; return this.description == compareManga.description && this.year == compareManga.year && - this.status == compareManga.status && this.releaseStatus == compareManga.releaseStatus && this.sortName == compareManga.sortName && this.latestChapterAvailable.Equals(compareManga.latestChapterAvailable) && diff --git a/Tranga/MangaConnectors/Bato.cs b/Tranga/MangaConnectors/Bato.cs index edc6dc9..657af00 100644 --- a/Tranga/MangaConnectors/Bato.cs +++ b/Tranga/MangaConnectors/Bato.cs @@ -114,8 +114,8 @@ public class Bato : MangaConnector case "pending": releaseStatus = Manga.ReleaseStatusByte.Unreleased; break; } - Manga manga = new (sortName, authors, description, altTitles, tags, posterUrl, coverFileNameInCache, new Dictionary(), - year, originalLanguage, publicationId, releaseStatus, websiteUrl: websiteUrl); + Manga manga = new (this, sortName, authors, description, altTitles, tags, posterUrl, coverFileNameInCache, new Dictionary(), + year, originalLanguage, publicationId, releaseStatus, websiteUrl); cachedPublications.Add(manga); return manga; } diff --git a/Tranga/MangaConnectors/MangaDex.cs b/Tranga/MangaConnectors/MangaDex.cs index 550e34f..c764dcd 100644 --- a/Tranga/MangaConnectors/MangaDex.cs +++ b/Tranga/MangaConnectors/MangaDex.cs @@ -126,10 +126,10 @@ public class MangaDex : MangaConnector false => null }; - Manga.ReleaseStatusByte status = Manga.ReleaseStatusByte.Unreleased; + Manga.ReleaseStatusByte releaseStatus = Manga.ReleaseStatusByte.Unreleased; if (attributes.TryGetPropertyValue("status", out JsonNode? statusNode)) { - status = statusNode?.GetValue().ToLower() switch + releaseStatus = statusNode?.GetValue().ToLower() switch { "ongoing" => Manga.ReleaseStatusByte.Continuing, "completed" => Manga.ReleaseStatusByte.Completed, @@ -173,6 +173,7 @@ public class MangaDex : MangaConnector } Manga pub = new( + this, title, authors, description, @@ -184,8 +185,8 @@ public class MangaDex : MangaConnector year, originalLanguage, publicationId, - status, - websiteUrl: $"https://mangadex.org/title/{publicationId}" + releaseStatus, + $"https://mangadex.org/title/{publicationId}" ); cachedPublications.Add(pub); return pub; diff --git a/Tranga/MangaConnectors/MangaKatana.cs b/Tranga/MangaConnectors/MangaKatana.cs index de59030..9ab937a 100644 --- a/Tranga/MangaConnectors/MangaKatana.cs +++ b/Tranga/MangaConnectors/MangaKatana.cs @@ -141,8 +141,8 @@ public class MangaKatana : MangaConnector year = Convert.ToInt32(yearString); } - Manga manga = new (sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, coverFileNameInCache, links, - year, originalLanguage, publicationId, releaseStatus, websiteUrl: websiteUrl); + Manga manga = new (this, sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, coverFileNameInCache, links, + year, originalLanguage, publicationId, releaseStatus, websiteUrl); cachedPublications.Add(manga); return manga; } diff --git a/Tranga/MangaConnectors/MangaLife.cs b/Tranga/MangaConnectors/MangaLife.cs index 3f87953..9245ec2 100644 --- a/Tranga/MangaConnectors/MangaLife.cs +++ b/Tranga/MangaConnectors/MangaLife.cs @@ -121,8 +121,8 @@ public class MangaLife : MangaConnector .Descendants("div").First(); string description = descriptionNode.InnerText; - Manga manga = new(sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, - coverFileNameInCache, links, year, originalLanguage, publicationId, releaseStatus, websiteUrl: websiteUrl); + Manga manga = new(this, sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, + coverFileNameInCache, links, year, originalLanguage, publicationId, releaseStatus, websiteUrl); cachedPublications.Add(manga); return manga; } diff --git a/Tranga/MangaConnectors/Manganato.cs b/Tranga/MangaConnectors/Manganato.cs index cbbf0f0..793c0d0 100644 --- a/Tranga/MangaConnectors/Manganato.cs +++ b/Tranga/MangaConnectors/Manganato.cs @@ -127,8 +127,8 @@ public class Manganato : MangaConnector .First(s => s.HasClass("chapter-time")).InnerText; int year = Convert.ToInt32(yearString.Split(',')[^1]) + 2000; - Manga manga = new (sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, coverFileNameInCache, links, - year, originalLanguage, publicationId, releaseStatus, websiteUrl: websiteUrl); + Manga manga = new (this, sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, coverFileNameInCache, links, + year, originalLanguage, publicationId, releaseStatus, websiteUrl); cachedPublications.Add(manga); return manga; } diff --git a/Tranga/MangaConnectors/Mangasee.cs b/Tranga/MangaConnectors/Mangasee.cs index f99e108..935c866 100644 --- a/Tranga/MangaConnectors/Mangasee.cs +++ b/Tranga/MangaConnectors/Mangasee.cs @@ -176,9 +176,8 @@ public class Mangasee : MangaConnector .Descendants("div").First(); string description = descriptionNode.InnerText; - Manga manga = new(sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, - coverFileNameInCache, links, - year, originalLanguage, publicationId, releaseStatus, websiteUrl: websiteUrl); + Manga manga = new(this, sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, + coverFileNameInCache, links, year, originalLanguage, publicationId, releaseStatus, websiteUrl); cachedPublications.Add(manga); return manga; } diff --git a/Tranga/MangaConnectors/Mangaworld.cs b/Tranga/MangaConnectors/Mangaworld.cs index 0f2e80d..fbacfaa 100644 --- a/Tranga/MangaConnectors/Mangaworld.cs +++ b/Tranga/MangaConnectors/Mangaworld.cs @@ -118,8 +118,8 @@ public class Mangaworld: MangaConnector string yearString = metadata.SelectSingleNode("//span[text()='Anno di uscita: ']/..").SelectNodes("a").First().InnerText; int year = Convert.ToInt32(yearString); - Manga manga = new (sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, coverFileNameInCache, links, - year, originalLanguage, publicationId, releaseStatus, websiteUrl: websiteUrl); + Manga manga = new (this, sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, coverFileNameInCache, links, + year, originalLanguage, publicationId, releaseStatus, websiteUrl); cachedPublications.Add(manga); return manga; } diff --git a/Tranga/Server/Server.cs b/Tranga/Server/Server.cs index b6b42d0..f2d4256 100644 --- a/Tranga/Server/Server.cs +++ b/Tranga/Server/Server.cs @@ -32,7 +32,7 @@ public partial class Server : GlobalBase, IDisposable new ("GET", @"/v2/Jobs/Waiting", GetV2JobsWaiting), new ("GET", @"/v2/Jobs/Monitoring", GetV2JobsMonitoring), new ("Get", @"/v2/Job/Types", GetV2JobTypes), - new ("POST", @"/v2/Job/Create/([a-zA-Z]+)>", PostV2JobsCreateType), + new ("POST", @"/v2/Job/Create/([a-zA-Z]+)", PostV2JobsCreateType), new ("GET", @"/v2/Job/([a-zA-Z\.]+-[-A-Za-z0-9+/]*={0,3}(?:-[0-9]+)?)", GetV2JobJobId), new ("DELETE", @"/v2/Job/([a-zA-Z\.]+-[-A-Za-z0-9+/]*={0,3}(?:-[0-9]+)?)", DeleteV2JobJobId), new ("GET", @"/v2/Job/([a-zA-Z\.]+-[-A-Za-z0-9+/]*={0,3}(?:-[0-9]+)?)/Progress", GetV2JobJobIdProgress), @@ -124,7 +124,7 @@ public partial class Server : GlobalBase, IDisposable .ToDictionary(kv => kv.Key, kv => kv.Value); //The actual variable used for the API ValueTuple responseMessage; //Used to respond to the HttpRequest - if (_apiRequestPaths.Any(p => p.HttpMethod == request.HttpMethod && Regex.IsMatch(path, p.RegexStr))) //Check if Request-Path is valid + if (_apiRequestPaths.Any(p => p.HttpMethod == request.HttpMethod && Regex.Match(path, p.RegexStr).Length == path.Length)) //Check if Request-Path is valid { RequestPath requestPath = _apiRequestPaths.First(p => p.HttpMethod == request.HttpMethod && Regex.Match(path, p.RegexStr).Length == path.Length); diff --git a/Tranga/Server/v2Jobs.cs b/Tranga/Server/v2Jobs.cs index de59001..fda77a0 100644 --- a/Tranga/Server/v2Jobs.cs +++ b/Tranga/Server/v2Jobs.cs @@ -46,42 +46,32 @@ public partial class Server return new ValueTuple(HttpStatusCode.NotFound, $"Manga with ID: '{groups[1].Value}' does not exist."); } - string? connectorStr, mangaId; - MangaConnector? connector; + string? mangaId; Manga? manga; switch (jobType) { case Job.JobType.MonitorManga: - if(!requestParameters.TryGetValue("connector", out connectorStr) || - !_parent.TryGetConnector(connectorStr, out connector) || - connector is null) - return new ValueTuple(HttpStatusCode.NotFound, "Connector Parameter missing, or is not a valid connector."); if(!requestParameters.TryGetValue("internalId", out mangaId) || !_parent.TryGetPublicationById(mangaId, out manga) || manga is null) - return new ValueTuple(HttpStatusCode.NotFound, "InternalId Parameter missing, or is not a valid ID."); + return new ValueTuple(HttpStatusCode.NotFound, "'internalId' Parameter missing, or is not a valid ID."); if(!requestParameters.TryGetValue("interval", out string? intervalStr) || !TimeSpan.TryParse(intervalStr, out TimeSpan interval)) - return new ValueTuple(HttpStatusCode.InternalServerError, "Interval Parameter missing, or is not in correct format."); + return new ValueTuple(HttpStatusCode.InternalServerError, "'interval' Parameter missing, or is not in correct format."); requestParameters.TryGetValue("language", out string? language); - _parent.jobBoss.AddJob(new DownloadNewChapters(this, connector, (Manga)manga, true, interval, language)); - break; + _parent.jobBoss.AddJob(new DownloadNewChapters(this, ((Manga)manga).mangaConnector, (Manga)manga, true, interval, language)); + return new ValueTuple(HttpStatusCode.OK, null); case Job.JobType.UpdateMetaDataJob: - if(!requestParameters.TryGetValue("connector", out connectorStr) || - !_parent.TryGetConnector(connectorStr, out connector) || - connector is null) - return new ValueTuple(HttpStatusCode.NotFound, "Connector Parameter missing, or is not a valid connector."); if(!requestParameters.TryGetValue("internalId", out mangaId) || !_parent.TryGetPublicationById(mangaId, out manga) || manga is null) return new ValueTuple(HttpStatusCode.NotFound, "InternalId Parameter missing, or is not a valid ID."); - _parent.jobBoss.AddJob(new UpdateMetadata(this, connector, (Manga)manga)); - break; + _parent.jobBoss.AddJob(new UpdateMetadata(this, (Manga)manga)); + return new ValueTuple(HttpStatusCode.OK, null); case Job.JobType.DownloadNewChaptersJob: //TODO case Job.JobType.DownloadChapterJob: //TODO default: return new ValueTuple(HttpStatusCode.MethodNotAllowed, $"JobType {Enum.GetName(jobType)} is not supported."); } - return new ValueTuple(HttpStatusCode.NotImplemented, "How'd you get here."); } private ValueTuple GetV2JobJobId(GroupCollection groups, Dictionary requestParameters) diff --git a/docs/API_Calls_v2.md b/docs/API_Calls_v2.md index b9eaa88..f5bc867 100644 --- a/docs/API_Calls_v2.md +++ b/docs/API_Calls_v2.md @@ -239,7 +239,6 @@ Creates a Job. | Parameter | Value | |------------|---------------------------------------------------------------------------------------------------| - | connector | Name of the connector to use | | internalId | Manga ID | | *interval* | Interval at which the Job is re-run in HH:MM:SS format
Only for MonitorManga, UpdateMetadata | | *language* | Translated language
Only for MonitorManga, DownloadNewChapters and DownloadChapter |