2
0

No longer require connector name to create job

This commit is contained in:
Glax 2024-04-22 04:21:30 +02:00
parent 64482931a3
commit 03e90eccd3
14 changed files with 62 additions and 86 deletions

View File

@ -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;

View File

@ -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>() == (byte)Job.JobType.UpdateMetaDataJob)
return Enum.Parse<Job.JobType>(jo["jobType"]!.Value<byte>().ToString()) switch
{
return new UpdateMetadata(this._clone,
Job.JobType.UpdateMetaDataJob => new UpdateMetadata(_clone,
jo.GetValue("manga")!.ToObject<Manga>(JsonSerializer.Create(new JsonSerializerSettings()
{
Converters = { this._mangaConnectorJsonConverter }
})),
jo.GetValue("parentJobId")!.Value<string?>()),
Job.JobType.DownloadChapterJob => new DownloadChapter(this._clone,
jo.GetValue("mangaConnector")!.ToObject<MangaConnector>(JsonSerializer.Create(new JsonSerializerSettings()
{
Converters =
{
this._mangaConnectorJsonConverter
}
Converters = { this._mangaConnectorJsonConverter }
}))!,
jo.GetValue("manga")!.ToObject<Manga>(),
jo.GetValue("parentJobId")!.Value<string?>());
}else if ((jo.ContainsKey("jobType") && jo["jobType"]!.Value<byte>() == (byte)Job.JobType.DownloadNewChaptersJob) || jo.ContainsKey("translatedLanguage"))//TODO change to jobType
{
DateTime lastExecution = jo.GetValue("lastExecution") is {} le
? le.ToObject<DateTime>()
: DateTime.UnixEpoch; //TODO do null checks on all variables
return new DownloadNewChapters(this._clone,
jo.GetValue("mangaConnector")!.ToObject<MangaConnector>(JsonSerializer.Create(new JsonSerializerSettings()
jo.GetValue("chapter")!.ToObject<Chapter>(JsonSerializer.Create(new JsonSerializerSettings()
{
Converters =
{
this._mangaConnectorJsonConverter
}
}))!,
jo.GetValue("manga")!.ToObject<Manga>(),
lastExecution,
Converters = { this._mangaConnectorJsonConverter }
})),
DateTime.UnixEpoch,
jo.GetValue("parentJobId")!.Value<string?>()),
Job.JobType.DownloadNewChaptersJob => new DownloadNewChapters(this._clone,
jo.GetValue("manga")!.ToObject<Manga>(JsonSerializer.Create(new JsonSerializerSettings()
{
Converters = { this._mangaConnectorJsonConverter }
})),
jo.GetValue("lastExecution") is {} le
? le.ToObject<DateTime>()
: DateTime.UnixEpoch,
jo.GetValue("recurring")!.Value<bool>(),
jo.GetValue("recurrenceTime")!.ToObject<TimeSpan?>(),
jo.GetValue("parentJobId")!.Value<string?>());
}else if ((jo.ContainsKey("jobType") && jo["jobType"]!.Value<byte>() == (byte)Job.JobType.DownloadChapterJob) || jo.ContainsKey("chapter"))//TODO change to jobType
{
return new DownloadChapter(this._clone,
jo.GetValue("mangaConnector")!.ToObject<MangaConnector>(JsonSerializer.Create(new JsonSerializerSettings()
{
Converters =
{
this._mangaConnectorJsonConverter
}
}))!,
jo.GetValue("chapter")!.ToObject<Chapter>(),
DateTime.UnixEpoch,
jo.GetValue("parentJobId")!.Value<string?>());
}
throw new Exception();
jo.GetValue("parentJobId")!.Value<string?>()),
_ => throw new Exception()
};
}
public override bool CanWrite => false;

View File

@ -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;
}

View File

@ -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<string> authors, string? description, Dictionary<string,string> altTitles, string[] tags, string? coverUrl, string? coverFileNameInCache, Dictionary<string,string>? links, int? year, string? originalLanguage, string publicationId, ReleaseStatusByte releaseStatus, string? websiteUrl, string? folderName = null, float? ignoreChaptersBelow = 0)
public Manga(MangaConnector mangaConnector, string sortName, List<string> authors, string? description, Dictionary<string,string> altTitles, string[] tags, string? coverUrl, string? coverFileNameInCache, Dictionary<string,string>? 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) &&

View File

@ -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<string, string>(),
year, originalLanguage, publicationId, releaseStatus, websiteUrl: websiteUrl);
Manga manga = new (this, sortName, authors, description, altTitles, tags, posterUrl, coverFileNameInCache, new Dictionary<string, string>(),
year, originalLanguage, publicationId, releaseStatus, websiteUrl);
cachedPublications.Add(manga);
return manga;
}

View File

@ -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<string>().ToLower() switch
releaseStatus = statusNode?.GetValue<string>().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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<HttpStatusCode, object?> 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);

View File

@ -46,42 +46,32 @@ public partial class Server
return new ValueTuple<HttpStatusCode, object?>(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, object?>(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, object?>(HttpStatusCode.NotFound, "InternalId Parameter missing, or is not a valid ID.");
return new ValueTuple<HttpStatusCode, object?>(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, object?>(HttpStatusCode.InternalServerError, "Interval Parameter missing, or is not in correct format.");
return new ValueTuple<HttpStatusCode, object?>(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, object?>(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, object?>(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, object?>(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, object?>(HttpStatusCode.OK, null);
case Job.JobType.DownloadNewChaptersJob: //TODO
case Job.JobType.DownloadChapterJob: //TODO
default: return new ValueTuple<HttpStatusCode, object?>(HttpStatusCode.MethodNotAllowed, $"JobType {Enum.GetName(jobType)} is not supported.");
}
return new ValueTuple<HttpStatusCode, object?>(HttpStatusCode.NotImplemented, "How'd you get here.");
}
private ValueTuple<HttpStatusCode, object?> GetV2JobJobId(GroupCollection groups, Dictionary<string, string> requestParameters)

View File

@ -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<br />Only for MonitorManga, UpdateMetadata |
| *language* | Translated language<br />Only for MonitorManga, DownloadNewChapters and DownloadChapter |