Compare commits
No commits in common. "4c1a659f16e64fab2ec695a0f2f24367e10aa6d4" and "963ad375e8b9b036cb8b3337ab7c41dfe8da5499" have entirely different histories.
4c1a659f16
...
963ad375e8
@ -7,12 +7,12 @@ public class DownloadChapter : Job
|
||||
{
|
||||
public Chapter chapter { get; init; }
|
||||
|
||||
public DownloadChapter(GlobalBase clone, MangaConnector connector, Chapter chapter, DateTime lastExecution, string? parentJobId = null) : base(clone, JobType.DownloadChapterJob, connector, lastExecution, parentJobId: parentJobId)
|
||||
public DownloadChapter(GlobalBase clone, MangaConnector connector, Chapter chapter, DateTime lastExecution, string? parentJobId = null) : base(clone, connector, lastExecution, parentJobId: parentJobId)
|
||||
{
|
||||
this.chapter = chapter;
|
||||
}
|
||||
|
||||
public DownloadChapter(GlobalBase clone, MangaConnector connector, Chapter chapter, string? parentJobId = null) : base(clone, JobType.DownloadChapterJob, connector, parentJobId: parentJobId)
|
||||
public DownloadChapter(GlobalBase clone, MangaConnector connector, Chapter chapter, string? parentJobId = null) : base(clone, connector, parentJobId: parentJobId)
|
||||
{
|
||||
this.chapter = chapter;
|
||||
}
|
||||
@ -27,7 +27,7 @@ public class DownloadChapter : Job
|
||||
return $"{id} Chapter: {chapter}";
|
||||
}
|
||||
|
||||
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal(JobBoss jobBoss)
|
||||
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal()
|
||||
{
|
||||
Task downloadTask = new(delegate
|
||||
{
|
||||
|
@ -8,14 +8,14 @@ public class DownloadNewChapters : Job
|
||||
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,
|
||||
bool recurring = false, TimeSpan? recurrence = null, string? parentJobId = null, string translatedLanguage = "en") : base(clone, connector, lastExecution, recurring,
|
||||
recurrence, parentJobId)
|
||||
{
|
||||
this.manga = manga;
|
||||
this.translatedLanguage = translatedLanguage;
|
||||
}
|
||||
|
||||
public DownloadNewChapters(GlobalBase clone, MangaConnector connector, Manga manga, bool recurring = false, TimeSpan? recurrence = null, string? parentJobId = null, string translatedLanguage = "en") : base (clone, JobType.DownloadNewChaptersJob, connector, recurring, recurrence, parentJobId)
|
||||
public DownloadNewChapters(GlobalBase clone, MangaConnector connector, Manga manga, bool recurring = false, TimeSpan? recurrence = null, string? parentJobId = null, string translatedLanguage = "en") : base (clone, connector, recurring, recurrence, parentJobId)
|
||||
{
|
||||
this.manga = manga;
|
||||
this.translatedLanguage = translatedLanguage;
|
||||
@ -31,7 +31,7 @@ public class DownloadNewChapters : Job
|
||||
return $"{id} Manga: {manga}";
|
||||
}
|
||||
|
||||
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal(JobBoss jobBoss)
|
||||
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal()
|
||||
{
|
||||
manga.SaveSeriesInfoJson(settings.downloadLocation);
|
||||
Chapter[] chapters = mangaConnector.GetNewChapters(manga, this.translatedLanguage);
|
||||
@ -43,8 +43,6 @@ 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);
|
||||
jobs.Add(updateMetadataJob);
|
||||
progressToken.Complete();
|
||||
return jobs;
|
||||
}
|
||||
|
@ -13,13 +13,9 @@ public abstract class Job : GlobalBase
|
||||
public string id => GetId();
|
||||
internal IEnumerable<Job>? subJobs { get; private set; }
|
||||
public string? parentJobId { get; init; }
|
||||
public enum JobType : byte { DownloadChapterJob, DownloadNewChaptersJob, UpdateMetaDataJob }
|
||||
|
||||
public JobType jobType;
|
||||
|
||||
internal Job(GlobalBase clone, JobType jobType, MangaConnector connector, bool recurring = false, TimeSpan? recurrenceTime = null, string? parentJobId = null) : base(clone)
|
||||
internal Job(GlobalBase clone, MangaConnector connector, bool recurring = false, TimeSpan? recurrenceTime = null, string? parentJobId = null) : base(clone)
|
||||
{
|
||||
this.jobType = jobType;
|
||||
this.mangaConnector = connector;
|
||||
this.progressToken = new ProgressToken(0);
|
||||
this.recurring = recurring;
|
||||
@ -31,10 +27,9 @@ public abstract class Job : GlobalBase
|
||||
this.parentJobId = parentJobId;
|
||||
}
|
||||
|
||||
internal Job(GlobalBase clone, JobType jobType, MangaConnector connector, DateTime lastExecution, bool recurring = false,
|
||||
internal Job(GlobalBase clone, MangaConnector connector, DateTime lastExecution, bool recurring = false,
|
||||
TimeSpan? recurrenceTime = null, string? parentJobId = null) : base(clone)
|
||||
{
|
||||
this.jobType = jobType;
|
||||
this.mangaConnector = connector;
|
||||
this.progressToken = new ProgressToken(0);
|
||||
this.recurring = recurring;
|
||||
@ -86,13 +81,13 @@ public abstract class Job : GlobalBase
|
||||
subJob.Cancel();
|
||||
}
|
||||
|
||||
public IEnumerable<Job> ExecuteReturnSubTasks(JobBoss jobBoss)
|
||||
public IEnumerable<Job> ExecuteReturnSubTasks()
|
||||
{
|
||||
progressToken.Start();
|
||||
subJobs = ExecuteReturnSubTasksInternal(jobBoss);
|
||||
subJobs = ExecuteReturnSubTasksInternal();
|
||||
lastExecution = DateTime.Now;
|
||||
return subJobs;
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<Job> ExecuteReturnSubTasksInternal(JobBoss jobBoss);
|
||||
protected abstract IEnumerable<Job> ExecuteReturnSubTasksInternal();
|
||||
}
|
@ -253,7 +253,7 @@ public class JobBoss : GlobalBase
|
||||
Log($"Next job in {jobs.MinBy(job => job.nextExecution)?.nextExecution.Subtract(DateTime.Now)} {jobs.MinBy(job => job.nextExecution)?.id}");
|
||||
}else if (queueHead.progressToken.state is ProgressToken.State.Standby)
|
||||
{
|
||||
Job[] subJobs = jobQueue.Peek().ExecuteReturnSubTasks(this).ToArray();
|
||||
Job[] subJobs = jobQueue.Peek().ExecuteReturnSubTasks().ToArray();
|
||||
AddJobs(subJobs);
|
||||
AddJobsToQueue(subJobs);
|
||||
}else if (queueHead.progressToken.state is ProgressToken.State.Running && DateTime.Now.Subtract(queueHead.progressToken.lastUpdate) > TimeSpan.FromMinutes(5))
|
||||
|
@ -23,20 +23,7 @@ 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") && jo["jobType"]!.Value<byte>() == (byte)Job.JobType.UpdateMetaDataJob)
|
||||
{
|
||||
return new UpdateMetadata(this._clone,
|
||||
jo.GetValue("mangaConnector")!.ToObject<MangaConnector>(JsonSerializer.Create(new JsonSerializerSettings()
|
||||
{
|
||||
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
|
||||
if (jo.ContainsKey("manga"))//DownloadNewChapters
|
||||
{
|
||||
return new DownloadNewChapters(this._clone,
|
||||
jo.GetValue("mangaConnector")!.ToObject<MangaConnector>(JsonSerializer.Create(new JsonSerializerSettings()
|
||||
@ -51,7 +38,9 @@ public class JobJsonConverter : JsonConverter
|
||||
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
|
||||
}
|
||||
|
||||
if (jo.ContainsKey("chapter"))//DownloadChapter
|
||||
{
|
||||
return new DownloadChapter(this._clone,
|
||||
jo.GetValue("mangaConnector")!.ToObject<MangaConnector>(JsonSerializer.Create(new JsonSerializerSettings()
|
||||
|
@ -4,11 +4,19 @@ namespace Tranga.Jobs;
|
||||
|
||||
public class UpdateMetadata : Job
|
||||
{
|
||||
public Manga manga { get; set; }
|
||||
private Manga manga { get; set; }
|
||||
private JobBoss jobBoss { get; init; }
|
||||
|
||||
public UpdateMetadata(GlobalBase clone, MangaConnector connector, Manga manga, string? parentJobId = null) : base(clone, JobType.UpdateMetaDataJob, connector, parentJobId: parentJobId)
|
||||
public UpdateMetadata(GlobalBase clone, MangaConnector connector, Manga manga, JobBoss jobBoss, DateTime lastExecution, string? parentJobId = null) : base(clone, connector, lastExecution, parentJobId: parentJobId)
|
||||
{
|
||||
this.manga = manga;
|
||||
this.jobBoss = jobBoss;
|
||||
}
|
||||
|
||||
public UpdateMetadata(GlobalBase clone, MangaConnector connector, Manga manga, JobBoss jobBoss, string? parentJobId = null) : base(clone, connector, parentJobId: parentJobId)
|
||||
{
|
||||
this.manga = manga;
|
||||
this.jobBoss = jobBoss;
|
||||
}
|
||||
|
||||
protected override string GetId()
|
||||
@ -21,35 +29,35 @@ public class UpdateMetadata : Job
|
||||
return $"{id} Manga: {manga}";
|
||||
}
|
||||
|
||||
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal(JobBoss jobBoss)
|
||||
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal()
|
||||
{
|
||||
Manga? possibleUpdatedManga = mangaConnector.GetMangaFromId(manga.publicationId);
|
||||
if(manga.websiteUrl is null)
|
||||
{
|
||||
Log($"Legacy manga {manga}");
|
||||
return Array.Empty<Job>();
|
||||
}
|
||||
if (parentJobId is null)
|
||||
{
|
||||
Log($"Missing parentJob {this}");
|
||||
return Array.Empty<Job>();
|
||||
}
|
||||
Manga? possibleUpdatedManga = mangaConnector.GetMangaFromUrl(manga.websiteUrl);
|
||||
if (possibleUpdatedManga is { } updatedManga)
|
||||
{
|
||||
if(updatedManga.Equals(this.manga))
|
||||
return Array.Empty<Job>();
|
||||
|
||||
cachedPublications.Remove(this.manga);
|
||||
this.manga = updatedManga;
|
||||
cachedPublications.Add(updatedManga);
|
||||
this.manga.SaveSeriesInfoJson(settings.downloadLocation, true);
|
||||
|
||||
if (parentJobId is not null)
|
||||
{
|
||||
|
||||
DownloadNewChapters dncJob = jobBoss.GetJobById(this.parentJobId) as DownloadNewChapters ??
|
||||
throw new Exception("Jobtype has to be DownloadNewChapters");
|
||||
dncJob.manga = updatedManga;
|
||||
}
|
||||
this.progressToken.Complete();
|
||||
DownloadNewChapters dncJob = this.jobBoss.GetJobById(this.parentJobId) as DownloadNewChapters ??
|
||||
throw new Exception("Jobtype has to be DownloadNewChapters");
|
||||
dncJob.manga = updatedManga;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log($"Could not find Manga {manga}");
|
||||
this.progressToken.Cancel();
|
||||
return Array.Empty<Job>();
|
||||
}
|
||||
this.progressToken.Cancel();
|
||||
return Array.Empty<Job>();
|
||||
}
|
||||
}
|
@ -41,33 +41,15 @@ public abstract class LibraryConnector : GlobalBase
|
||||
Method = HttpMethod.Get,
|
||||
RequestUri = new Uri(url)
|
||||
};
|
||||
try
|
||||
{
|
||||
HttpResponseMessage response = client.Send(requestMessage);
|
||||
logger?.WriteLine("LibraryManager.NetClient", $"GET {url} -> {(int)response.StatusCode}: {response.ReasonPhrase}");
|
||||
|
||||
HttpResponseMessage response = client.Send(requestMessage);
|
||||
logger?.WriteLine("LibraryManager.NetClient",
|
||||
$"GET {url} -> {(int)response.StatusCode}: {response.ReasonPhrase}");
|
||||
|
||||
if (response.StatusCode is HttpStatusCode.Unauthorized &&
|
||||
response.RequestMessage!.RequestUri!.AbsoluteUri != url)
|
||||
return MakeRequest(response.RequestMessage!.RequestUri!.AbsoluteUri, authScheme, auth, logger);
|
||||
else if (response.IsSuccessStatusCode)
|
||||
return response.Content.ReadAsStream();
|
||||
else
|
||||
return Stream.Null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
switch (e)
|
||||
{
|
||||
case HttpRequestException:
|
||||
logger?.WriteLine("LibraryManager.NetClient", $"Failed to make Request:\n\r{e}\n\rContinuing.");
|
||||
break;
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
if(response.StatusCode is HttpStatusCode.Unauthorized && response.RequestMessage!.RequestUri!.AbsoluteUri != url)
|
||||
return MakeRequest(response.RequestMessage!.RequestUri!.AbsoluteUri, authScheme, auth, logger);
|
||||
else if (response.IsSuccessStatusCode)
|
||||
return response.Content.ReadAsStream();
|
||||
else
|
||||
return Stream.Null;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool MakePost(string url, string authScheme, string auth, Logger? logger)
|
||||
|
@ -43,6 +43,7 @@ public struct Manga
|
||||
public float ignoreChaptersBelow { get; set; }
|
||||
public float latestChapterDownloaded { get; set; }
|
||||
public float latestChapterAvailable { get; set; }
|
||||
public string? websiteUrl { get; }
|
||||
|
||||
private static readonly Regex LegalCharacters = new (@"[A-Z]*[a-z]*[0-9]* *\.*-*,*'*\'*\)*\(*~*!*");
|
||||
|
||||
@ -70,19 +71,7 @@ public struct Manga
|
||||
this.latestChapterDownloaded = 0;
|
||||
this.latestChapterAvailable = 0;
|
||||
this.releaseStatus = releaseStatus;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not Manga compareManga)
|
||||
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) &&
|
||||
this.tags.Equals(compareManga.tags);
|
||||
this.websiteUrl = websiteUrl;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
@ -36,11 +36,6 @@ public class Bato : MangaConnector
|
||||
return publications;
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromId(string publicationId)
|
||||
{
|
||||
return GetMangaFromUrl($"https://bato.to/title/{publicationId}");
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromUrl(string url)
|
||||
{
|
||||
DownloadClient.RequestResult requestResult =
|
||||
|
@ -38,8 +38,6 @@ public abstract class MangaConnector : GlobalBase
|
||||
|
||||
public abstract Manga? GetMangaFromUrl(string url);
|
||||
|
||||
public abstract Manga? GetMangaFromId(string publicationId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns all Chapters of the publication in the provided language.
|
||||
/// If the language is empty or null, returns all Chapters in all Languages.
|
||||
|
@ -72,10 +72,13 @@ public class MangaDex : MangaConnector
|
||||
return retManga.ToArray();
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromId(string publicationId)
|
||||
public override Manga? GetMangaFromUrl(string url)
|
||||
{
|
||||
Regex idRex = new (@"https:\/\/mangadex.org\/title\/([A-z0-9-]*)\/.*");
|
||||
string id = idRex.Match(url).Groups[1].Value;
|
||||
Log($"Got id {id} from {url}");
|
||||
DownloadClient.RequestResult requestResult =
|
||||
downloadClient.MakeRequest($"https://api.mangadex.org/manga/{publicationId}", (byte)RequestType.Manga);
|
||||
downloadClient.MakeRequest($"https://api.mangadex.org/manga/{id}", (byte)RequestType.Manga);
|
||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||
return null;
|
||||
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result);
|
||||
@ -84,14 +87,6 @@ public class MangaDex : MangaConnector
|
||||
return null;
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromUrl(string url)
|
||||
{
|
||||
Regex idRex = new (@"https:\/\/mangadex.org\/title\/([A-z0-9-]*)\/.*");
|
||||
string id = idRex.Match(url).Groups[1].Value;
|
||||
Log($"Got id {id} from {url}");
|
||||
return GetMangaFromId(id);
|
||||
}
|
||||
|
||||
private Manga? MangaFromJsonObject(JsonObject manga)
|
||||
{
|
||||
if (!manga.ContainsKey("attributes"))
|
||||
|
@ -39,11 +39,6 @@ public class MangaKatana : MangaConnector
|
||||
return publications;
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromId(string publicationId)
|
||||
{
|
||||
return GetMangaFromUrl($"https://mangakatana.com/manga/{publicationId}");
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromUrl(string url)
|
||||
{
|
||||
DownloadClient.RequestResult requestResult =
|
||||
|
@ -32,11 +32,6 @@ public class MangaLife : MangaConnector
|
||||
return publications;
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromId(string publicationId)
|
||||
{
|
||||
return GetMangaFromUrl($"https://manga4life.com/manga/{publicationId}");
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromUrl(string url)
|
||||
{
|
||||
Regex publicationIdRex = new(@"https:\/\/manga4life.com\/manga\/(.*)(\/.*)*");
|
||||
|
@ -54,11 +54,6 @@ public class Manganato : MangaConnector
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromId(string publicationId)
|
||||
{
|
||||
return GetMangaFromUrl($"https://chapmanganato.com/{publicationId}");
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromUrl(string url)
|
||||
{
|
||||
DownloadClient.RequestResult requestResult =
|
||||
|
@ -111,11 +111,6 @@ public class Mangasee : MangaConnector
|
||||
}
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromId(string publicationId)
|
||||
{
|
||||
return GetMangaFromUrl($"https://mangasee123.com/manga/{publicationId}");
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromUrl(string url)
|
||||
{
|
||||
Regex publicationIdRex = new(@"https:\/\/mangasee123.com\/manga\/(.*)(\/.*)*");
|
||||
|
@ -54,11 +54,6 @@ public class Mangaworld: MangaConnector
|
||||
return ret.ToArray();
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromId(string publicationId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override Manga? GetMangaFromUrl(string url)
|
||||
{
|
||||
DownloadClient.RequestResult requestResult =
|
||||
|
@ -304,32 +304,6 @@ public class Server : GlobalBase
|
||||
_parent.jobBoss.AddJob(new DownloadNewChapters(this, connector!, manga, false, translatedLanguage: translatedLanguage??"en"));
|
||||
SendResponse(HttpStatusCode.Accepted, response);
|
||||
break;
|
||||
case "Jobs/UpdateMetadata":
|
||||
if (!requestVariables.TryGetValue("internalId", out internalId))
|
||||
{
|
||||
foreach (DownloadNewChapters dncJob in (_parent.jobBoss.jobs.Where(possibleDncJob =>
|
||||
possibleDncJob is DownloadNewChapters) as IEnumerable<DownloadNewChapters>)!)
|
||||
{
|
||||
_parent.jobBoss.AddJob(new UpdateMetadata(this, dncJob.mangaConnector, dncJob.manga));
|
||||
}
|
||||
SendResponse(HttpStatusCode.Accepted, response);
|
||||
}
|
||||
else
|
||||
{
|
||||
Job[] possibleDncJobs = _parent.jobBoss.GetJobsLike(internalId: internalId).ToArray();
|
||||
switch (possibleDncJobs.Length)
|
||||
{
|
||||
case <1: SendResponse(HttpStatusCode.BadRequest, response, "Could not find matching release"); break;
|
||||
case >1: SendResponse(HttpStatusCode.BadRequest, response, "Multiple releases??"); break;
|
||||
default:
|
||||
DownloadNewChapters dncJob = possibleDncJobs[0] as DownloadNewChapters ??
|
||||
throw new Exception("Has to be DownloadNewChapters Job");
|
||||
_parent.jobBoss.AddJob(new UpdateMetadata(this, dncJob.mangaConnector, dncJob.manga));
|
||||
SendResponse(HttpStatusCode.Accepted, response);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "Jobs/StartNow":
|
||||
if (!requestVariables.TryGetValue("jobId", out jobId) ||
|
||||
!_parent.jobBoss.TryGetJobById(jobId, out job))
|
||||
|
Loading…
Reference in New Issue
Block a user