2
0

Added import and export for Jobs

Renamed tasksFilePath -> jobsFilePath and changed to jobs.json
This commit is contained in:
glax 2023-09-01 23:37:50 +02:00
parent eaab7c5235
commit 28e05e549d
6 changed files with 151 additions and 31 deletions

View File

@ -1,4 +1,5 @@
using Tranga.MangaConnectors; using Newtonsoft.Json;
using Tranga.MangaConnectors;
namespace Tranga.Jobs; namespace Tranga.Jobs;
@ -7,9 +8,12 @@ public class JobBoss : GlobalBase
public HashSet<Job> jobs { get; init; } public HashSet<Job> jobs { get; init; }
private Dictionary<MangaConnector, Queue<Job>> mangaConnectorJobQueue { get; init; } private Dictionary<MangaConnector, Queue<Job>> mangaConnectorJobQueue { get; init; }
public JobBoss(GlobalBase clone) : base(clone) public JobBoss(GlobalBase clone, HashSet<MangaConnector> connectors) : base(clone)
{ {
this.jobs = new(); if (File.Exists(settings.jobsFilePath))
this.jobs = JsonConvert.DeserializeObject<HashSet<Job>>(File.ReadAllText(settings.jobsFilePath), new JobJsonConverter(this, new MangaConnectorJsonConverter(this, connectors)))!;
else
this.jobs = new();
this.mangaConnectorJobQueue = new(); this.mangaConnectorJobQueue = new();
} }
@ -23,6 +27,7 @@ public class JobBoss : GlobalBase
{ {
Log($"Added {job}"); Log($"Added {job}");
this.jobs.Add(job); this.jobs.Add(job);
File.WriteAllText(settings.jobsFilePath, JsonConvert.SerializeObject(this.jobs));
} }
} }

View File

@ -0,0 +1,66 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Tranga.MangaConnectors;
namespace Tranga.Jobs;
public class JobJsonConverter : JsonConverter
{
private GlobalBase _clone;
private MangaConnectorJsonConverter _mangaConnectorJsonConverter;
internal JobJsonConverter(GlobalBase clone, MangaConnectorJsonConverter mangaConnectorJsonConverter)
{
this._clone = clone;
this._mangaConnectorJsonConverter = mangaConnectorJsonConverter;
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Job));
}
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
if (jo.ContainsKey("manga"))//DownloadNewChapters
{
return new DownloadNewChapters(this._clone,
jo.GetValue("mangaConnector")!.ToObject<MangaConnector>(JsonSerializer.Create(new JsonSerializerSettings()
{
Converters =
{
this._mangaConnectorJsonConverter
}
}))!,
jo.GetValue("manga")!.ToObject<Manga>(),
jo.GetValue("recurring")!.Value<bool>(),
jo.GetValue("recurrenceTime")!.ToObject<TimeSpan?>());
}
if (jo.ContainsKey("chapter"))//DownloadChapter
{
return new DownloadChapter(this._clone,
jo.GetValue("mangaConnector")!.ToObject<MangaConnector>(JsonSerializer.Create(new JsonSerializerSettings()
{
Converters =
{
this._mangaConnectorJsonConverter
}
}))!,
jo.GetValue("chapter")!.ToObject<Chapter>());
}
throw new Exception();
}
public override bool CanWrite => false;
/// <summary>
/// Don't call this
/// </summary>
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new Exception("Dont call this");
}
}

View File

@ -0,0 +1,49 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Tranga.MangaConnectors;
public class MangaConnectorJsonConverter : JsonConverter
{
private GlobalBase _clone;
private HashSet<MangaConnector> connectors;
internal MangaConnectorJsonConverter(GlobalBase clone, HashSet<MangaConnector> connectors)
{
this._clone = clone;
this.connectors = connectors;
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(MangaConnector));
}
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
switch (jo.GetValue("name")!.Value<string>()!)
{
case "MangaDex":
return this.connectors.First(c => c is MangaDex);
case "Manganato":
return this.connectors.First(c => c is Manganato);
case "MangaKatana":
return this.connectors.First(c => c is MangaKatana);
case "Mangasee":
return this.connectors.First(c => c is Mangasee);
}
throw new Exception();
}
public override bool CanWrite => false;
/// <summary>
/// Don't call this
/// </summary>
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new Exception("Dont call this");
}
}

View File

@ -157,33 +157,33 @@ public class Server : GlobalBase
case "Jobs": case "Jobs":
if (!requestVariables.TryGetValue("jobId", out jobId)) if (!requestVariables.TryGetValue("jobId", out jobId))
{ {
if(!_parent._jobBoss.jobs.Any(jjob => jjob.id == jobId)) if(!_parent.jobBoss.jobs.Any(jjob => jjob.id == jobId))
SendResponse(HttpStatusCode.BadRequest, response); SendResponse(HttpStatusCode.BadRequest, response);
else else
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.First(jjob => jjob.id == jobId)); SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs.First(jjob => jjob.id == jobId));
break; break;
} }
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs); SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs);
break; break;
case "Jobs/Progress": case "Jobs/Progress":
if (!requestVariables.TryGetValue("jobId", out jobId)) if (!requestVariables.TryGetValue("jobId", out jobId))
{ {
if(!_parent._jobBoss.jobs.Any(jjob => jjob.id == jobId)) if(!_parent.jobBoss.jobs.Any(jjob => jjob.id == jobId))
SendResponse(HttpStatusCode.BadRequest, response); SendResponse(HttpStatusCode.BadRequest, response);
else else
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.First(jjob => jjob.id == jobId).progressToken); SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs.First(jjob => jjob.id == jobId).progressToken);
break; break;
} }
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.Select(jjob => jjob.progressToken)); SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs.Select(jjob => jjob.progressToken));
break; break;
case "Jobs/Running": case "Jobs/Running":
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.Where(jjob => jjob.progressToken.state is ProgressToken.State.Running)); SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs.Where(jjob => jjob.progressToken.state is ProgressToken.State.Running));
break; break;
case "Jobs/Waiting": case "Jobs/Waiting":
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.Where(jjob => jjob.progressToken.state is ProgressToken.State.Standby)); SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs.Where(jjob => jjob.progressToken.state is ProgressToken.State.Standby));
break; break;
case "Jobs/MonitorJobs": case "Jobs/MonitorJobs":
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.Where(jjob => jjob is DownloadNewChapters)); SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs.Where(jjob => jjob is DownloadNewChapters));
break; break;
case "Settings": case "Settings":
SendResponse(HttpStatusCode.OK, response, settings); SendResponse(HttpStatusCode.OK, response, settings);
@ -230,7 +230,7 @@ public class Server : GlobalBase
} }
connector = _parent.GetConnector(connectorName)!; connector = _parent.GetConnector(connectorName)!;
manga = (Manga)_parent.GetPublicationById(internalId)!; manga = (Manga)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.AddJob(new DownloadNewChapters(this, connector, manga, true, interval)); _parent.jobBoss.AddJob(new DownloadNewChapters(this, connector, manga, true, interval));
SendResponse(HttpStatusCode.Accepted, response); SendResponse(HttpStatusCode.Accepted, response);
break; break;
case "Jobs/DownloadNewChapters": case "Jobs/DownloadNewChapters":
@ -244,17 +244,17 @@ public class Server : GlobalBase
} }
connector = _parent.GetConnector(connectorName)!; connector = _parent.GetConnector(connectorName)!;
manga = (Manga)_parent.GetPublicationById(internalId)!; manga = (Manga)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.AddJob(new DownloadNewChapters(this, connector, manga, false)); _parent.jobBoss.AddJob(new DownloadNewChapters(this, connector, manga, false));
SendResponse(HttpStatusCode.Accepted, response); SendResponse(HttpStatusCode.Accepted, response);
break; break;
case "Jobs/StartNow": case "Jobs/StartNow":
if (!requestVariables.TryGetValue("jobId", out string? jobId) || if (!requestVariables.TryGetValue("jobId", out string? jobId) ||
!_parent._jobBoss.TryGetJobById(jobId, out Job? job)) !_parent.jobBoss.TryGetJobById(jobId, out Job? job))
{ {
SendResponse(HttpStatusCode.BadRequest, response); SendResponse(HttpStatusCode.BadRequest, response);
break; break;
} }
_parent._jobBoss.AddJobToQueue(job!); _parent.jobBoss.AddJobToQueue(job!);
SendResponse(HttpStatusCode.Accepted, response); SendResponse(HttpStatusCode.Accepted, response);
break; break;
case "Settings/UpdateDownloadLocation": case "Settings/UpdateDownloadLocation":
@ -363,12 +363,12 @@ public class Server : GlobalBase
{ {
case "Jobs": case "Jobs":
if (!requestVariables.TryGetValue("jobID", out string? jobId) || if (!requestVariables.TryGetValue("jobID", out string? jobId) ||
!_parent._jobBoss.TryGetJobById(jobId, out Job? job)) !_parent.jobBoss.TryGetJobById(jobId, out Job? job))
{ {
SendResponse(HttpStatusCode.BadRequest, response); SendResponse(HttpStatusCode.BadRequest, response);
break; break;
} }
_parent._jobBoss.RemoveJob(job!); _parent.jobBoss.RemoveJob(job!);
SendResponse(HttpStatusCode.Accepted, response); SendResponse(HttpStatusCode.Accepted, response);
break; break;
case "Jobs/DownloadChapter": case "Jobs/DownloadChapter":
@ -381,7 +381,7 @@ public class Server : GlobalBase
SendResponse(HttpStatusCode.BadRequest, response); SendResponse(HttpStatusCode.BadRequest, response);
break; break;
} }
_parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connectorName, internalId, chapterNumber)); _parent.jobBoss.RemoveJobs(_parent.jobBoss.GetJobsLike(connectorName, internalId, chapterNumber));
SendResponse(HttpStatusCode.Accepted, response); SendResponse(HttpStatusCode.Accepted, response);
break; break;
case "Jobs/MonitorManga": case "Jobs/MonitorManga":
@ -395,7 +395,7 @@ public class Server : GlobalBase
} }
connector = _parent.GetConnector(connectorName)!; connector = _parent.GetConnector(connectorName)!;
manga = (Manga)_parent.GetPublicationById(internalId)!; manga = (Manga)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connector, manga)); _parent.jobBoss.RemoveJobs(_parent.jobBoss.GetJobsLike(connector, manga));
SendResponse(HttpStatusCode.Accepted, response); SendResponse(HttpStatusCode.Accepted, response);
break; break;
case "Jobs/DownloadNewChapters": case "Jobs/DownloadNewChapters":
@ -409,7 +409,7 @@ public class Server : GlobalBase
} }
connector = _parent.GetConnector(connectorName)!; connector = _parent.GetConnector(connectorName)!;
manga = (Manga)_parent.GetPublicationById(internalId)!; manga = (Manga)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connector, manga)); _parent.jobBoss.RemoveJobs(_parent.jobBoss.GetJobsLike(connector, manga));
SendResponse(HttpStatusCode.Accepted, response); SendResponse(HttpStatusCode.Accepted, response);
break; break;
case "NotificationConnectors": case "NotificationConnectors":

View File

@ -7,28 +7,28 @@ namespace Tranga;
public partial class Tranga : GlobalBase public partial class Tranga : GlobalBase
{ {
public bool keepRunning; public bool keepRunning;
public JobBoss _jobBoss; public JobBoss jobBoss;
private Server server; private Server _server;
private HashSet<MangaConnector> connectors; private HashSet<MangaConnector> _connectors;
public Tranga(Logger? logger, TrangaSettings settings) : base(logger, settings) public Tranga(Logger? logger, TrangaSettings settings) : base(logger, settings)
{ {
keepRunning = true; keepRunning = true;
_jobBoss = new(this); _connectors = new HashSet<MangaConnector>()
connectors = new HashSet<MangaConnector>()
{ {
new Manganato(this), new Manganato(this),
new Mangasee(this), new Mangasee(this),
new MangaDex(this), new MangaDex(this),
new MangaKatana(this) new MangaKatana(this)
}; };
jobBoss = new(this, this._connectors);
StartJobBoss(); StartJobBoss();
this.server = new Server(this); this._server = new Server(this);
} }
public MangaConnector? GetConnector(string name) public MangaConnector? GetConnector(string name)
{ {
foreach(MangaConnector mc in connectors) foreach(MangaConnector mc in _connectors)
if (mc.name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) if (mc.name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
return mc; return mc;
return null; return null;
@ -42,7 +42,7 @@ public partial class Tranga : GlobalBase
public IEnumerable<MangaConnector> GetConnectors() public IEnumerable<MangaConnector> GetConnectors()
{ {
return connectors; return _connectors;
} }
public Manga? GetPublicationById(string internalId) public Manga? GetPublicationById(string internalId)
@ -64,7 +64,7 @@ public partial class Tranga : GlobalBase
{ {
while (keepRunning) while (keepRunning)
{ {
_jobBoss.CheckJobs(); jobBoss.CheckJobs();
Thread.Sleep(1000); Thread.Sleep(1000);
} }
}); });

View File

@ -14,7 +14,7 @@ public class TrangaSettings
[JsonIgnore] public string settingsFilePath => Path.Join(workingDirectory, "settings.json"); [JsonIgnore] public string settingsFilePath => Path.Join(workingDirectory, "settings.json");
[JsonIgnore] public string libraryConnectorsFilePath => Path.Join(workingDirectory, "libraryConnectors.json"); [JsonIgnore] public string libraryConnectorsFilePath => Path.Join(workingDirectory, "libraryConnectors.json");
[JsonIgnore] public string notificationConnectorsFilePath => Path.Join(workingDirectory, "notificationConnectors.json"); [JsonIgnore] public string notificationConnectorsFilePath => Path.Join(workingDirectory, "notificationConnectors.json");
[JsonIgnore] public string tasksFilePath => Path.Join(workingDirectory, "tasks.json"); [JsonIgnore] public string jobsFilePath => Path.Join(workingDirectory, "jobs.json");
[JsonIgnore] public string coverImageCache => Path.Join(workingDirectory, "imageCache"); [JsonIgnore] public string coverImageCache => Path.Join(workingDirectory, "imageCache");
public ushort? version { get; set; } public ushort? version { get; set; }