From ed74975312c39e7e89940c952b875cbe96143081 Mon Sep 17 00:00:00 2001 From: Glax Date: Fri, 7 Mar 2025 18:13:39 +0100 Subject: [PATCH] Filter and order jobs by type and chapter --- API/Tranga.cs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/API/Tranga.cs b/API/Tranga.cs index 20b786e..aa961b4 100644 --- a/API/Tranga.cs +++ b/API/Tranga.cs @@ -1,5 +1,6 @@ using API.Schema; using API.Schema.Jobs; +using API.Schema.MangaConnectors; using API.Schema.NotificationConnectors; using log4net; using log4net.Config; @@ -85,7 +86,7 @@ public static class Tranga List runJobs = context.Jobs.Where(j => j.state <= JobState.Running && j.Enabled == true).ToList() .Where(j => j.NextExecution < DateTime.UtcNow).ToList(); - foreach (Job job in runJobs) + foreach (Job job in OrderJobs(runJobs, context)) { // If the job is already running, skip it if (RunningJobs.Values.Any(j => j.JobId == job.JobId)) continue; @@ -131,4 +132,65 @@ public static class Tranga Thread.Sleep(2000); } } + + private static IEnumerable OrderJobs(List jobs, PgsqlContext context) + { + Dictionary> jobsByType = new(); + foreach (Job job in jobs) + if(!jobsByType.TryAdd(job.JobType, [job])) + jobsByType[job.JobType].Add(job); + + IEnumerable ret = new List(); + if(jobsByType.ContainsKey(JobType.MoveFileOrFolderJob)) + ret = ret.Concat(jobsByType[JobType.MoveFileOrFolderJob]); + if(jobsByType.ContainsKey(JobType.DownloadMangaCoverJob)) + ret = ret.Concat(jobsByType[JobType.DownloadMangaCoverJob]); + + Dictionary> metadataJobsByConnector = new(); + if (jobsByType.ContainsKey(JobType.DownloadNewChaptersJob)) + { + foreach (DownloadNewChaptersJob job in jobsByType[JobType.DownloadNewChaptersJob]) + { + Manga manga = job.Manga ?? context.Manga.Find(job.MangaId)!; + MangaConnector connector = manga.MangaConnector ?? context.MangaConnectors.Find(manga.MangaConnectorId)!; + if(!metadataJobsByConnector.TryAdd(connector, [job])) + metadataJobsByConnector[connector].Add(job); + } + } + if (jobsByType.ContainsKey(JobType.UpdateMetaDataJob)) + { + foreach (UpdateMetadataJob job in jobsByType[JobType.UpdateMetaDataJob]) + { + Manga manga = job.Manga ?? context.Manga.Find(job.MangaId)!; + MangaConnector connector = manga.MangaConnector ?? context.MangaConnectors.Find(manga.MangaConnectorId)!; + if(!metadataJobsByConnector.TryAdd(connector, [job])) + metadataJobsByConnector[connector].Add(job); + } + } + foreach (List metadataJobs in metadataJobsByConnector.Values) + ret = ret.Append(metadataJobs.MinBy(j => j.NextExecution))!; + + if (jobsByType.ContainsKey(JobType.DownloadSingleChapterJob)) + { + + Dictionary> downloadJobsByConnector = new(); + foreach (DownloadSingleChapterJob job in jobsByType[JobType.DownloadSingleChapterJob]) + { + Chapter chapter = job.Chapter ?? context.Chapters.Find(job.ChapterId)!; + Manga manga = chapter.ParentManga ?? context.Manga.Find(chapter.ParentMangaId)!; + MangaConnector connector = manga.MangaConnector ?? context.MangaConnectors.Find(manga.MangaConnectorId)!; + + if(!downloadJobsByConnector.TryAdd(connector, [job])) + downloadJobsByConnector[connector].Add(job); + } + //From all jobs select those that are supposed to be executed soonest, then select the minimum chapternumber + foreach (List downloadJobs in downloadJobsByConnector.Values) + ret = ret.Append( + downloadJobs.Where(j => j.NextExecution == downloadJobs + .MinBy(mj => mj.NextExecution)!.NextExecution) + .MinBy(j => j.Chapter ?? context.Chapters.Find(j.ChapterId)!))!; + } + + return ret; + } } \ No newline at end of file