diff --git a/Tranga/Jobs/JobBoss.cs b/Tranga/Jobs/JobBoss.cs index 004a349..4e924a9 100644 --- a/Tranga/Jobs/JobBoss.cs +++ b/Tranga/Jobs/JobBoss.cs @@ -1,4 +1,5 @@ -using Tranga.MangaConnectors; +using Newtonsoft.Json; +using Tranga.MangaConnectors; namespace Tranga.Jobs; @@ -7,9 +8,12 @@ public class JobBoss : GlobalBase public HashSet jobs { get; init; } private Dictionary> mangaConnectorJobQueue { get; init; } - public JobBoss(GlobalBase clone) : base(clone) + public JobBoss(GlobalBase clone, HashSet connectors) : base(clone) { - this.jobs = new(); + if (File.Exists(settings.jobsFilePath)) + this.jobs = JsonConvert.DeserializeObject>(File.ReadAllText(settings.jobsFilePath), new JobJsonConverter(this, new MangaConnectorJsonConverter(this, connectors)))!; + else + this.jobs = new(); this.mangaConnectorJobQueue = new(); } @@ -23,6 +27,7 @@ public class JobBoss : GlobalBase { Log($"Added {job}"); this.jobs.Add(job); + File.WriteAllText(settings.jobsFilePath, JsonConvert.SerializeObject(this.jobs)); } } diff --git a/Tranga/Jobs/JobJsonConverter.cs b/Tranga/Jobs/JobJsonConverter.cs new file mode 100644 index 0000000..e49cfdd --- /dev/null +++ b/Tranga/Jobs/JobJsonConverter.cs @@ -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(JsonSerializer.Create(new JsonSerializerSettings() + { + Converters = + { + this._mangaConnectorJsonConverter + } + }))!, + jo.GetValue("manga")!.ToObject(), + jo.GetValue("recurring")!.Value(), + jo.GetValue("recurrenceTime")!.ToObject()); + } + + if (jo.ContainsKey("chapter"))//DownloadChapter + { + return new DownloadChapter(this._clone, + jo.GetValue("mangaConnector")!.ToObject(JsonSerializer.Create(new JsonSerializerSettings() + { + Converters = + { + this._mangaConnectorJsonConverter + } + }))!, + jo.GetValue("chapter")!.ToObject()); + } + + throw new Exception(); + } + + public override bool CanWrite => false; + + /// + /// Don't call this + /// + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + throw new Exception("Dont call this"); + } +} \ No newline at end of file diff --git a/Tranga/MangaConnectors/MangaConnectorJsonConverter.cs b/Tranga/MangaConnectors/MangaConnectorJsonConverter.cs new file mode 100644 index 0000000..5b98845 --- /dev/null +++ b/Tranga/MangaConnectors/MangaConnectorJsonConverter.cs @@ -0,0 +1,49 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Tranga.MangaConnectors; + +public class MangaConnectorJsonConverter : JsonConverter +{ + private GlobalBase _clone; + private HashSet connectors; + + internal MangaConnectorJsonConverter(GlobalBase clone, HashSet 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()!) + { + 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; + + /// + /// Don't call this + /// + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + throw new Exception("Dont call this"); + } +} \ No newline at end of file diff --git a/Tranga/Server.cs b/Tranga/Server.cs index f873d3c..e6c999f 100644 --- a/Tranga/Server.cs +++ b/Tranga/Server.cs @@ -157,33 +157,33 @@ public class Server : GlobalBase case "Jobs": 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); 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; } - SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs); + SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs); break; case "Jobs/Progress": 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); 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; } - SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.Select(jjob => jjob.progressToken)); + SendResponse(HttpStatusCode.OK, response, _parent.jobBoss.jobs.Select(jjob => jjob.progressToken)); break; 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; 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; 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; case "Settings": SendResponse(HttpStatusCode.OK, response, settings); @@ -230,7 +230,7 @@ public class Server : GlobalBase } connector = _parent.GetConnector(connectorName)!; 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); break; case "Jobs/DownloadNewChapters": @@ -244,17 +244,17 @@ public class Server : GlobalBase } connector = _parent.GetConnector(connectorName)!; 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); break; case "Jobs/StartNow": 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); break; } - _parent._jobBoss.AddJobToQueue(job!); + _parent.jobBoss.AddJobToQueue(job!); SendResponse(HttpStatusCode.Accepted, response); break; case "Settings/UpdateDownloadLocation": @@ -363,12 +363,12 @@ public class Server : GlobalBase { case "Jobs": 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); break; } - _parent._jobBoss.RemoveJob(job!); + _parent.jobBoss.RemoveJob(job!); SendResponse(HttpStatusCode.Accepted, response); break; case "Jobs/DownloadChapter": @@ -381,7 +381,7 @@ public class Server : GlobalBase SendResponse(HttpStatusCode.BadRequest, response); break; } - _parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connectorName, internalId, chapterNumber)); + _parent.jobBoss.RemoveJobs(_parent.jobBoss.GetJobsLike(connectorName, internalId, chapterNumber)); SendResponse(HttpStatusCode.Accepted, response); break; case "Jobs/MonitorManga": @@ -395,7 +395,7 @@ public class Server : GlobalBase } connector = _parent.GetConnector(connectorName)!; 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); break; case "Jobs/DownloadNewChapters": @@ -409,7 +409,7 @@ public class Server : GlobalBase } connector = _parent.GetConnector(connectorName)!; 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); break; case "NotificationConnectors": diff --git a/Tranga/Tranga.cs b/Tranga/Tranga.cs index b52a60a..3390109 100644 --- a/Tranga/Tranga.cs +++ b/Tranga/Tranga.cs @@ -7,28 +7,28 @@ namespace Tranga; public partial class Tranga : GlobalBase { public bool keepRunning; - public JobBoss _jobBoss; - private Server server; - private HashSet connectors; + public JobBoss jobBoss; + private Server _server; + private HashSet _connectors; public Tranga(Logger? logger, TrangaSettings settings) : base(logger, settings) { keepRunning = true; - _jobBoss = new(this); - connectors = new HashSet() + _connectors = new HashSet() { new Manganato(this), new Mangasee(this), new MangaDex(this), new MangaKatana(this) }; + jobBoss = new(this, this._connectors); StartJobBoss(); - this.server = new Server(this); + this._server = new Server(this); } public MangaConnector? GetConnector(string name) { - foreach(MangaConnector mc in connectors) + foreach(MangaConnector mc in _connectors) if (mc.name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) return mc; return null; @@ -42,7 +42,7 @@ public partial class Tranga : GlobalBase public IEnumerable GetConnectors() { - return connectors; + return _connectors; } public Manga? GetPublicationById(string internalId) @@ -64,7 +64,7 @@ public partial class Tranga : GlobalBase { while (keepRunning) { - _jobBoss.CheckJobs(); + jobBoss.CheckJobs(); Thread.Sleep(1000); } }); diff --git a/Tranga/TrangaSettings.cs b/Tranga/TrangaSettings.cs index 7aacccb..96e8fed 100644 --- a/Tranga/TrangaSettings.cs +++ b/Tranga/TrangaSettings.cs @@ -14,7 +14,7 @@ public class TrangaSettings [JsonIgnore] public string settingsFilePath => Path.Join(workingDirectory, "settings.json"); [JsonIgnore] public string libraryConnectorsFilePath => Path.Join(workingDirectory, "libraryConnectors.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"); public ushort? version { get; set; }