diff --git a/API/Schema/Chapter.cs b/API/Schema/Chapter.cs index 56233be..8de0d8d 100644 --- a/API/Schema/Chapter.cs +++ b/API/Schema/Chapter.cs @@ -8,72 +8,83 @@ namespace API.Schema; [PrimaryKey("ChapterId")] public class Chapter : IComparable { - [MaxLength(64)] - public string ChapterId { get; init; } = TokenGen.CreateToken(typeof(Chapter), 64); + public Chapter(Manga parentManga, string url, string chapterNumber, int? volumeNumber = null, string? title = null) + : this(parentManga.MangaId, url, chapterNumber, volumeNumber, title) + { + ParentManga = parentManga; + ArchiveFileName = BuildArchiveFileName(); + } + + public Chapter(string parentMangaId, string url, string chapterNumber, + int? volumeNumber = null, string? title = null) + { + ParentMangaId = parentMangaId; + Url = url; + ChapterNumber = chapterNumber; + VolumeNumber = volumeNumber; + Title = title; + } + + [MaxLength(64)] public string ChapterId { get; init; } = TokenGen.CreateToken(typeof(Chapter), 64); + public int? VolumeNumber { get; private set; } - [MaxLength(10)] - public string ChapterNumber { get; private set; } + + [MaxLength(10)] public string ChapterNumber { get; private set; } + public string Url { get; internal set; } public string? Title { get; private set; } public string ArchiveFileName { get; private set; } public bool Downloaded { get; internal set; } = false; - + public string ParentMangaId { get; internal set; } public Manga? ParentManga { get; init; } - public Chapter(Manga parentManga, string url, string chapterNumber, int? volumeNumber = null, string? title = null) - : this(parentManga.MangaId, url, chapterNumber, volumeNumber, title) + public int CompareTo(Chapter? other) { - this.ParentManga = parentManga; - this.ArchiveFileName = BuildArchiveFileName(); - } - - public Chapter(string parentMangaId, string url, string chapterNumber, - int? volumeNumber = null, string? title = null) - { - this.ParentMangaId = parentMangaId; - this.Url = url; - this.ChapterNumber = chapterNumber; - this.VolumeNumber = volumeNumber; - this.Title = title; + if (other is not { } otherChapter) + throw new ArgumentException($"{other} can not be compared to {this}"); + return VolumeNumber?.CompareTo(otherChapter.VolumeNumber) switch + { + < 0 => -1, + > 0 => 1, + _ => CompareChapterNumbers(ChapterNumber, otherChapter.ChapterNumber) + }; } public MoveFileOrFolderJob? UpdateChapterNumber(string chapterNumber) { - this.ChapterNumber = chapterNumber; + ChapterNumber = chapterNumber; return UpdateArchiveFileName(); } public MoveFileOrFolderJob? UpdateVolumeNumber(int? volumeNumber) { - this.VolumeNumber = volumeNumber; + VolumeNumber = volumeNumber; return UpdateArchiveFileName(); } public MoveFileOrFolderJob? UpdateTitle(string? title) { - this.Title = title; + Title = title; return UpdateArchiveFileName(); } private string BuildArchiveFileName() { - return $"{this.ParentManga.Name} - Vol.{this.VolumeNumber ?? 0} Ch.{this.ChapterNumber}{(this.Title is null ? "" : $" - {this.Title}")}.cbz"; + return + $"{ParentManga.Name} - Vol.{VolumeNumber ?? 0} Ch.{ChapterNumber}{(Title is null ? "" : $" - {Title}")}.cbz"; } private MoveFileOrFolderJob? UpdateArchiveFileName() { string oldPath = GetArchiveFilePath(); - this.ArchiveFileName = BuildArchiveFileName(); - if (Downloaded) - { - return new MoveFileOrFolderJob(oldPath, GetArchiveFilePath()); - } + ArchiveFileName = BuildArchiveFileName(); + if (Downloaded) return new MoveFileOrFolderJob(oldPath, GetArchiveFilePath()); return null; } - + /// - /// Creates full file path of chapter-archive + /// Creates full file path of chapter-archive /// /// Filepath internal string GetArchiveFilePath() @@ -89,11 +100,11 @@ public class Chapter : IComparable private static int CompareChapterNumbers(string ch1, string ch2) { - var ch1Arr = ch1.Split('.').Select(c => int.Parse(c)).ToArray(); - var ch2Arr = ch2.Split('.').Select(c => int.Parse(c)).ToArray(); + int[] ch1Arr = ch1.Split('.').Select(c => int.Parse(c)).ToArray(); + int[] ch2Arr = ch2.Split('.').Select(c => int.Parse(c)).ToArray(); int i = 0, j = 0; - + while (i < ch1Arr.Length && j < ch2Arr.Length) { if (ch1Arr[i] < ch2Arr[j]) @@ -103,31 +114,19 @@ public class Chapter : IComparable i++; j++; } - + return 0; } - public int CompareTo(Chapter? other) - { - if(other is not { } otherChapter) - throw new ArgumentException($"{other} can not be compared to {this}"); - return this.VolumeNumber?.CompareTo(otherChapter.VolumeNumber) switch - { - <0 => -1, - >0 => 1, - _ => CompareChapterNumbers(this.ChapterNumber, otherChapter.ChapterNumber) - }; - } - internal string GetComicInfoXmlString() { - XElement comicInfo = new XElement("ComicInfo", + XElement comicInfo = new("ComicInfo", new XElement("Tags", string.Join(',', ParentManga.Tags.Select(tag => tag.Tag))), new XElement("LanguageISO", ParentManga.OriginalLanguage), - new XElement("Title", this.Title), + new XElement("Title", Title), new XElement("Writer", string.Join(',', ParentManga.Authors.Select(author => author.AuthorName))), - new XElement("Volume", this.VolumeNumber), - new XElement("Number", this.ChapterNumber) + new XElement("Volume", VolumeNumber), + new XElement("Number", ChapterNumber) ); return comicInfo.ToString(); } diff --git a/API/Tranga.cs b/API/Tranga.cs index 775e311..75e03a5 100644 --- a/API/Tranga.cs +++ b/API/Tranga.cs @@ -1,5 +1,6 @@ using API.Schema; using API.Schema.Jobs; +using API.Schema.NotificationConnectors; using log4net; using log4net.Config; @@ -20,9 +21,9 @@ public static class Tranga private static void NotificationSender(object? pgsqlContext) { if (pgsqlContext is null) return; - var context = (PgsqlContext)pgsqlContext; + PgsqlContext context = (PgsqlContext)pgsqlContext; - var staleNotifications = + IQueryable staleNotifications = context.Notifications.Where(n => n.Urgency < NotificationUrgency.Normal); context.Notifications.RemoveRange(staleNotifications); context.SaveChanges(); @@ -39,14 +40,14 @@ public static class Tranga private static void SendNotifications(PgsqlContext context, NotificationUrgency urgency) { - var notifications = context.Notifications.Where(n => n.Urgency == urgency).ToList(); + List notifications = context.Notifications.Where(n => n.Urgency == urgency).ToList(); if (notifications.Any()) { - var max = notifications.MaxBy(n => n.Date)!.Date; + DateTime max = notifications.MaxBy(n => n.Date)!.Date; if (DateTime.Now.Subtract(max) > TrangaSettings.NotificationUrgencyDelay(urgency)) { - foreach (var notificationConnector in context.NotificationConnectors) - foreach (var notification in notifications) + foreach (NotificationConnector notificationConnector in context.NotificationConnectors) + foreach (Notification notification in notifications) notificationConnector.SendNotification(notification.Title, notification.Message); context.Notifications.RemoveRange(notifications); } @@ -58,15 +59,15 @@ public static class Tranga private static void JobStarter(object? pgsqlContext) { if (pgsqlContext is null) return; - var context = (PgsqlContext)pgsqlContext; + PgsqlContext context = (PgsqlContext)pgsqlContext; - var TRANGA = + string TRANGA = "\n\n _______ \n|_ _|.----..---.-..-----..-----..---.-.\n | | | _|| _ || || _ || _ |\n |___| |__| |___._||__|__||___ ||___._|\n |_____| \n\n"; Log.Info(TRANGA); while (true) { - var completedJobs = context.Jobs.Where(j => j.state == JobState.Completed).ToList(); - foreach (var job in completedJobs) + List completedJobs = context.Jobs.Where(j => j.state == JobState.Completed).ToList(); + foreach (Job job in completedJobs) if (job.RecurrenceMs <= 0) { context.Jobs.Remove(job); @@ -80,7 +81,7 @@ public static class Tranga List runJobs = context.Jobs.Where(j => j.state <= JobState.Running).AsEnumerable() .Where(j => j.NextExecution < DateTime.UtcNow).ToList(); - foreach (var job in runJobs) + foreach (Job job in runJobs) { // If the job is already running, skip it if (RunningJobs.Values.Any(j => j.JobId == job.JobId)) continue;