mirror of
https://github.com/C9Glax/tranga.git
synced 2025-07-06 19:04:18 +02:00
Added Jobs and ProgressToken
This commit is contained in:
23
Tranga/Jobs/DownloadChapter.cs
Normal file
23
Tranga/Jobs/DownloadChapter.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Tranga.MangaConnectors;
|
||||
|
||||
namespace Tranga.Jobs;
|
||||
|
||||
public class DownloadChapter : Job
|
||||
{
|
||||
public Chapter chapter { get; init; }
|
||||
|
||||
public DownloadChapter(MangaConnector connector, Chapter chapter) : base(connector)
|
||||
{
|
||||
this.chapter = chapter;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal()
|
||||
{
|
||||
Task downloadTask = new(delegate
|
||||
{
|
||||
mangaConnector.DownloadChapter(chapter, this.progressToken);
|
||||
});
|
||||
downloadTask.Start();
|
||||
return Array.Empty<Job>();
|
||||
}
|
||||
}
|
27
Tranga/Jobs/DownloadNewChapters.cs
Normal file
27
Tranga/Jobs/DownloadNewChapters.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using Tranga.MangaConnectors;
|
||||
|
||||
namespace Tranga.Jobs;
|
||||
|
||||
public class DownloadNewChapters : Job
|
||||
{
|
||||
public Publication publication { get; init; }
|
||||
|
||||
public DownloadNewChapters(MangaConnector connector, Publication publication, bool recurring = false) : base (connector, recurring)
|
||||
{
|
||||
this.publication = publication;
|
||||
}
|
||||
|
||||
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal()
|
||||
{
|
||||
Chapter[] chapters = mangaConnector.GetNewChapters(publication);
|
||||
this.progressToken.increments = chapters.Length;
|
||||
List<Job> subJobs = new();
|
||||
foreach (Chapter chapter in chapters)
|
||||
{
|
||||
DownloadChapter downloadChapterJob = new(this.mangaConnector, chapter);
|
||||
subJobs.Add(downloadChapterJob);
|
||||
}
|
||||
progressToken.Complete();
|
||||
return subJobs;
|
||||
}
|
||||
}
|
73
Tranga/Jobs/Job.cs
Normal file
73
Tranga/Jobs/Job.cs
Normal file
@ -0,0 +1,73 @@
|
||||
using Tranga.MangaConnectors;
|
||||
|
||||
namespace Tranga.Jobs;
|
||||
|
||||
public abstract class Job
|
||||
{
|
||||
public MangaConnector mangaConnector { get; init; }
|
||||
public ProgressToken progressToken { get; private set; }
|
||||
public bool recurring { get; init; }
|
||||
public TimeSpan? recurrenceTime { get; set; }
|
||||
public DateTime? lastExecution { get; private set; }
|
||||
public DateTime nextExecution => NextExecution();
|
||||
|
||||
public Job(MangaConnector connector, bool recurring = false, TimeSpan? recurrenceTime = null)
|
||||
{
|
||||
this.mangaConnector = connector;
|
||||
this.progressToken = new ProgressToken(0);
|
||||
this.recurring = recurring;
|
||||
if (recurring && recurrenceTime is null)
|
||||
throw new ArgumentException("If recurrence is set to true, a recurrence time has to be provided.");
|
||||
this.recurrenceTime = recurrenceTime;
|
||||
}
|
||||
|
||||
public Job(MangaConnector connector, ProgressToken progressToken, bool recurring = false, TimeSpan? recurrenceTime = null)
|
||||
{
|
||||
this.mangaConnector = connector;
|
||||
this.progressToken = progressToken;
|
||||
this.recurring = recurring;
|
||||
if (recurring && recurrenceTime is null)
|
||||
throw new ArgumentException("If recurrence is set to true, a recurrence time has to be provided.");
|
||||
this.recurrenceTime = recurrenceTime;
|
||||
}
|
||||
|
||||
public Job(MangaConnector connector, int taskIncrements, bool recurring = false, TimeSpan? recurrenceTime = null)
|
||||
{
|
||||
this.mangaConnector = connector;
|
||||
this.progressToken = new ProgressToken(taskIncrements);
|
||||
this.recurring = recurring;
|
||||
if (recurring && recurrenceTime is null)
|
||||
throw new ArgumentException("If recurrence is set to true, a recurrence time has to be provided.");
|
||||
this.recurrenceTime = recurrenceTime;
|
||||
}
|
||||
|
||||
private DateTime NextExecution()
|
||||
{
|
||||
if(recurring && recurrenceTime.HasValue && lastExecution.HasValue)
|
||||
return lastExecution.Value.Add(recurrenceTime.Value);
|
||||
if(recurring && recurrenceTime.HasValue && !lastExecution.HasValue)
|
||||
return DateTime.Now;
|
||||
return DateTime.MaxValue;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
this.progressToken = new ProgressToken(this.progressToken.increments);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
this.progressToken.cancellationRequested = true;
|
||||
this.progressToken.Complete();
|
||||
}
|
||||
|
||||
public IEnumerable<Job> ExecuteReturnSubTasks()
|
||||
{
|
||||
progressToken.Start();
|
||||
IEnumerable<Job> ret = ExecuteReturnSubTasksInternal();
|
||||
lastExecution = DateTime.Now;
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected abstract IEnumerable<Job> ExecuteReturnSubTasksInternal();
|
||||
}
|
70
Tranga/Jobs/JobBoss.cs
Normal file
70
Tranga/Jobs/JobBoss.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using Tranga.MangaConnectors;
|
||||
|
||||
namespace Tranga.Jobs;
|
||||
|
||||
public class JobBoss : GlobalBase
|
||||
{
|
||||
private HashSet<Job> jobs { get; init; }
|
||||
private Dictionary<MangaConnector, Queue<Job>> mangaConnectorJobQueue { get; init; }
|
||||
|
||||
public JobBoss(GlobalBase clone) : base(clone)
|
||||
{
|
||||
this.jobs = new();
|
||||
this.mangaConnectorJobQueue = new();
|
||||
}
|
||||
|
||||
public void MonitorJobs()
|
||||
{
|
||||
foreach (Job job in jobs.Where(job => job.nextExecution < DateTime.Now && !QueueContainsJob(job)).OrderBy(job => job.nextExecution))
|
||||
AddJobToQueue(job);
|
||||
CheckJobQueue();
|
||||
}
|
||||
|
||||
public void AddJob(Job job)
|
||||
{
|
||||
this.jobs.Add(job);
|
||||
}
|
||||
|
||||
public void RemoveJob(Job job)
|
||||
{
|
||||
job.Cancel();
|
||||
this.jobs.Remove(job);
|
||||
}
|
||||
|
||||
private bool QueueContainsJob(Job job)
|
||||
{
|
||||
mangaConnectorJobQueue.TryAdd(job.mangaConnector, new Queue<Job>());
|
||||
return mangaConnectorJobQueue[job.mangaConnector].Contains(job);
|
||||
}
|
||||
|
||||
private void AddJobToQueue(Job job)
|
||||
{
|
||||
Log($"Adding Job to Queue. {job}");
|
||||
mangaConnectorJobQueue.TryAdd(job.mangaConnector, new Queue<Job>());
|
||||
Queue<Job> connectorJobQueue = mangaConnectorJobQueue[job.mangaConnector];
|
||||
if(!connectorJobQueue.Contains(job))
|
||||
connectorJobQueue.Enqueue(job);
|
||||
}
|
||||
|
||||
public void AddJobsToQueue(IEnumerable<Job> jobs)
|
||||
{
|
||||
foreach(Job job in jobs)
|
||||
AddJobToQueue(job);
|
||||
}
|
||||
|
||||
private void CheckJobQueue()
|
||||
{
|
||||
foreach (Queue<Job> jobQueue in mangaConnectorJobQueue.Values)
|
||||
{
|
||||
Job queueHead = jobQueue.Peek();
|
||||
if (queueHead.progressToken.state == ProgressToken.State.Complete)
|
||||
{
|
||||
if(queueHead.recurring)
|
||||
queueHead.Reset();
|
||||
jobQueue.Dequeue();
|
||||
AddJobsToQueue(jobQueue.Peek().ExecuteReturnSubTasks());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
Tranga/Jobs/ProgressToken.cs
Normal file
44
Tranga/Jobs/ProgressToken.cs
Normal file
@ -0,0 +1,44 @@
|
||||
namespace Tranga.Jobs;
|
||||
|
||||
public class ProgressToken
|
||||
{
|
||||
public bool cancellationRequested { get; set; }
|
||||
public int increments { get; set; }
|
||||
public int incrementsCompleted { get; set; }
|
||||
public float progress => GetProgress();
|
||||
|
||||
public enum State { Running, Complete, Standby }
|
||||
public State state { get; private set; }
|
||||
|
||||
public ProgressToken(int increments)
|
||||
{
|
||||
this.cancellationRequested = false;
|
||||
this.increments = increments;
|
||||
this.incrementsCompleted = 0;
|
||||
this.state = State.Standby;
|
||||
}
|
||||
|
||||
private float GetProgress()
|
||||
{
|
||||
if(increments > 0 && incrementsCompleted > 0)
|
||||
return (float)incrementsCompleted / (float)increments;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void Increment()
|
||||
{
|
||||
this.incrementsCompleted++;
|
||||
if (incrementsCompleted > increments)
|
||||
state = State.Complete;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
state = State.Running;
|
||||
}
|
||||
|
||||
public void Complete()
|
||||
{
|
||||
state = State.Complete;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user