diff --git a/Tranga/Chapter.cs b/Tranga/Chapter.cs index 006eacc..56687c4 100644 --- a/Tranga/Chapter.cs +++ b/Tranga/Chapter.cs @@ -1,5 +1,5 @@ -using System.Globalization; -using System.Text.RegularExpressions; +using System.Text.RegularExpressions; +using System.Xml.Linq; namespace Tranga; @@ -9,16 +9,18 @@ namespace Tranga; /// public struct Chapter { + public Publication parentPublication { get; } public string? name { get; } public string? volumeNumber { get; } - public string? chapterNumber { get; } + public string chapterNumber { get; } public string url { get; } public string fileName { get; } private static readonly Regex LegalCharacters = new (@"([A-z]*[0-9]* *\.*-*,*\]*\[*'*\'*\)*\(*~*!*)*"); private static readonly Regex IllegalStrings = new(@"Vol(ume)?.?", RegexOptions.IgnoreCase); - public Chapter(string? name, string? volumeNumber, string? chapterNumber, string url) + public Chapter(Publication parentPublication, string? name, string? volumeNumber, string chapterNumber, string url) { + this.parentPublication = parentPublication; this.name = name; this.volumeNumber = volumeNumber; this.chapterNumber = chapterNumber; @@ -26,9 +28,62 @@ public struct Chapter string chapterName = string.Concat(LegalCharacters.Matches(name ?? "")); string volStr = this.volumeNumber is not null ? $"Vol.{this.volumeNumber} " : ""; - string chNumberStr = this.chapterNumber is not null ? $"Ch.{chapterNumber} " : ""; + string chNumberStr = $"Ch.{chapterNumber} "; string chNameStr = chapterName.Length > 0 ? $"- {chapterName}" : ""; chNameStr = IllegalStrings.Replace(chNameStr, ""); this.fileName = $"{volStr}{chNumberStr}{chNameStr}"; } + + + /// + /// Checks if a chapter-archive is already present + /// + /// true if chapter is present + internal bool CheckChapterIsDownloaded(string downloadLocation) + { + string newFilePath = GetArchiveFilePath(downloadLocation); + if (!Directory.Exists(Path.Join(downloadLocation, parentPublication.folderName))) + return false; + FileInfo[] archives = new DirectoryInfo(Path.Join(downloadLocation, parentPublication.folderName)).GetFiles(); + Regex infoRex = new(@"(Vol.[0-9]*)?Ch.[0-9]+"); + Regex chapterInfoRex = new(@"Ch.[0-9]+"); + Regex chapterRex = new(@"[0-9]+"); + + if (File.Exists(newFilePath)) + return true; + + string cn = this.chapterNumber; + if (archives.FirstOrDefault(archive => chapterRex.Match(chapterInfoRex.Match(infoRex.Match(archive.Name).Value).Value).Value == cn) is { } path) + { + File.Move(path.FullName, newFilePath); + return true; + } + return false; + } + /// + /// Creates full file path of chapter-archive + /// + /// Filepath + internal string GetArchiveFilePath(string downloadLocation) + { + return Path.Join(downloadLocation, parentPublication.folderName, $"{parentPublication.folderName} - {this.fileName}.cbz"); + } + + /// + /// Creates a string containing XML of publication and chapter. + /// See ComicInfo.xml + /// + /// XML-string + internal string GetComicInfoXmlString() + { + XElement comicInfo = new XElement("ComicInfo", + new XElement("Tags", string.Join(',', parentPublication.tags)), + new XElement("LanguageISO", parentPublication.originalLanguage), + new XElement("Title", this.name), + new XElement("Writer", string.Join(',', parentPublication.authors)), + new XElement("Volume", this.volumeNumber), + new XElement("Number", this.chapterNumber) + ); + return comicInfo.ToString(); + } } \ No newline at end of file diff --git a/Tranga/Connector.cs b/Tranga/Connector.cs index 88aa426..40302b6 100644 --- a/Tranga/Connector.cs +++ b/Tranga/Connector.cs @@ -158,60 +158,6 @@ public abstract class Connector File.SetUnixFileMode(newFilePath, GroupRead | GroupWrite | OtherRead | OtherWrite | UserRead | UserWrite); } - /// - /// Creates a string containing XML of publication and chapter. - /// See ComicInfo.xml - /// - /// XML-string - internal static string GetComicInfoXmlString(Publication publication, Chapter chapter, Logger? logger) - { - logger?.WriteLine("Connector", $"Creating ComicInfo.Xml for {publication.sortName} {publication.internalId} {chapter.volumeNumber}-{chapter.chapterNumber}"); - XElement comicInfo = new XElement("ComicInfo", - new XElement("Tags", string.Join(',',publication.tags)), - new XElement("LanguageISO", publication.originalLanguage), - new XElement("Title", chapter.name), - new XElement("Writer", string.Join(',', publication.authors)), - new XElement("Volume", chapter.volumeNumber), - new XElement("Number", chapter.chapterNumber) - ); - return comicInfo.ToString(); - } - - /// - /// Checks if a chapter-archive is already present - /// - /// true if chapter is present - public bool CheckChapterIsDownloaded(Publication publication, Chapter chapter) - { - string newFilePath = GetArchiveFilePath(publication, chapter); - if (!Directory.Exists(Path.Join(settings.downloadLocation, publication.folderName))) - return false; - FileInfo[] archives = new DirectoryInfo(Path.Join(settings.downloadLocation, publication.folderName)).GetFiles(); - Regex infoRex = new(@"(Vol.[0-9]*)?Ch.[0-9]+"); - Regex chapterInfoRex = new(@"Ch.[0-9]+"); - Regex chapterRex = new(@"[0-9]+"); - - if (File.Exists(newFilePath)) - return true; - - if (archives.FirstOrDefault(archive => chapterRex.Match(chapterInfoRex.Match(infoRex.Match(archive.Name).Value).Value).Value == chapter.chapterNumber) is { } path) - { - logger?.WriteLine(this.GetType().ToString(), "Move existing Chapter to new name."); - File.Move(path.FullName, newFilePath); - return true; - } - return false; - } - - /// - /// Creates full file path of chapter-archive - /// - /// Filepath - protected string GetArchiveFilePath(Publication publication, Chapter chapter) - { - return Path.Join(settings.downloadLocation, publication.folderName, $"{publication.folderName} - {chapter.fileName}.cbz"); - } - /// /// Downloads Image from URL and saves it to the given path(incl. fileName) /// diff --git a/Tranga/Connectors/MangaDex.cs b/Tranga/Connectors/MangaDex.cs index 1a25430..2087934 100644 --- a/Tranga/Connectors/MangaDex.cs +++ b/Tranga/Connectors/MangaDex.cs @@ -194,7 +194,7 @@ public class MangaDex : Connector ? attributes["chapter"]!.GetValue() : null; - chapters.Add(new Chapter(title, volume, chapterNum, chapterId)); + chapters.Add(new Chapter(publication, title, volume, chapterNum, chapterId)); } } @@ -230,10 +230,10 @@ public class MangaDex : Connector imageUrls.Add($"{baseUrl}/data/{hash}/{image!.GetValue()}"); string comicInfoPath = Path.GetTempFileName(); - File.WriteAllText(comicInfoPath, GetComicInfoXmlString(publication, chapter, logger)); + File.WriteAllText(comicInfoPath, chapter.GetComicInfoXmlString()); //Download Chapter-Images - return DownloadChapterImages(imageUrls.ToArray(), GetArchiveFilePath(publication, chapter), (byte)RequestType.AtHomeServer, parentTask, comicInfoPath, cancellationToken:cancellationToken); + return DownloadChapterImages(imageUrls.ToArray(), chapter.GetArchiveFilePath(settings.downloadLocation), (byte)RequestType.AtHomeServer, parentTask, comicInfoPath, cancellationToken:cancellationToken); } private string? GetCoverUrl(string publicationId, string? posterId) diff --git a/Tranga/Connectors/MangaKatana.cs b/Tranga/Connectors/MangaKatana.cs index 5376828..4b1300b 100644 --- a/Tranga/Connectors/MangaKatana.cs +++ b/Tranga/Connectors/MangaKatana.cs @@ -136,12 +136,12 @@ public class MangaKatana : Connector { NumberDecimalSeparator = "." }; - List chapters = ParseChaptersFromHtml(requestUrl); + List chapters = ParseChaptersFromHtml(publication, requestUrl); logger?.WriteLine(this.GetType().ToString(), $"Done getting Chapters for {publication.internalId}"); return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray(); } - private List ParseChaptersFromHtml(string mangaUrl) + private List ParseChaptersFromHtml(Publication publication, string mangaUrl) { // Using HtmlWeb will include the chapters since they are loaded with js HtmlWeb web = new(); @@ -160,7 +160,7 @@ public class MangaKatana : Connector string chapterName = string.Concat(fullString.Split(':')[1..]); string url = chapterInfo.Descendants("a").First() .GetAttributeValue("href", ""); - ret.Add(new Chapter(chapterName, volumeNumber, chapterNumber, url)); + ret.Add(new Chapter(publication, chapterName, volumeNumber, chapterNumber, url)); } return ret; @@ -181,9 +181,9 @@ public class MangaKatana : Connector string[] imageUrls = ParseImageUrlsFromHtml(requestUrl); string comicInfoPath = Path.GetTempFileName(); - File.WriteAllText(comicInfoPath, GetComicInfoXmlString(publication, chapter, logger)); + File.WriteAllText(comicInfoPath, chapter.GetComicInfoXmlString()); - return DownloadChapterImages(imageUrls, GetArchiveFilePath(publication, chapter), (byte)1, parentTask, comicInfoPath, "https://mangakatana.com/", cancellationToken); + return DownloadChapterImages(imageUrls, chapter.GetArchiveFilePath(settings.downloadLocation), (byte)1, parentTask, comicInfoPath, "https://mangakatana.com/", cancellationToken); } private string[] ParseImageUrlsFromHtml(string mangaUrl) diff --git a/Tranga/Connectors/Manganato.cs b/Tranga/Connectors/Manganato.cs index 98aae52..0b37933 100644 --- a/Tranga/Connectors/Manganato.cs +++ b/Tranga/Connectors/Manganato.cs @@ -139,12 +139,12 @@ public class Manganato : Connector { NumberDecimalSeparator = "." }; - List chapters = ParseChaptersFromHtml(requestResult.result); + List chapters = ParseChaptersFromHtml(publication, requestResult.result); logger?.WriteLine(this.GetType().ToString(), $"Done getting Chapters for {publication.internalId}"); return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray(); } - private List ParseChaptersFromHtml(Stream html) + private List ParseChaptersFromHtml(Publication publication, Stream html) { StreamReader reader = new (html); string htmlString = reader.ReadToEnd(); @@ -163,7 +163,7 @@ public class Manganato : Connector string chapterName = string.Concat(fullString.Split(':')[1..]); string url = chapterInfo.Descendants("a").First(d => d.HasClass("chapter-name")) .GetAttributeValue("href", ""); - ret.Add(new Chapter(chapterName, volumeNumber, chapterNumber, url)); + ret.Add(new Chapter(publication, chapterName, volumeNumber, chapterNumber, url)); } ret.Reverse(); return ret; @@ -183,9 +183,9 @@ public class Manganato : Connector string[] imageUrls = ParseImageUrlsFromHtml(requestResult.result); string comicInfoPath = Path.GetTempFileName(); - File.WriteAllText(comicInfoPath, GetComicInfoXmlString(publication, chapter, logger)); + File.WriteAllText(comicInfoPath, chapter.GetComicInfoXmlString()); - return DownloadChapterImages(imageUrls, GetArchiveFilePath(publication, chapter), (byte)1, parentTask, comicInfoPath, "https://chapmanganato.com/", cancellationToken); + return DownloadChapterImages(imageUrls, chapter.GetArchiveFilePath(settings.downloadLocation), (byte)1, parentTask, comicInfoPath, "https://chapmanganato.com/", cancellationToken); } private string[] ParseImageUrlsFromHtml(Stream html) diff --git a/Tranga/Connectors/Mangasee.cs b/Tranga/Connectors/Mangasee.cs index a583495..56d5b36 100644 --- a/Tranga/Connectors/Mangasee.cs +++ b/Tranga/Connectors/Mangasee.cs @@ -196,7 +196,7 @@ public class Mangasee : Connector string url = chapter.Descendants("link").First().Value; url = url.Replace(Regex.Matches(url,"(-page-[0-9])")[0].ToString(),""); - ret.Add(new Chapter("", volumeNumber, chapterNumber, url)); + ret.Add(new Chapter(publication, "", volumeNumber, chapterNumber, url)); } //Return Chapters ordered by Chapter-Number @@ -235,9 +235,9 @@ public class Mangasee : Connector urls.Add(galleryImage.GetAttributeValue("src", "")); string comicInfoPath = Path.GetTempFileName(); - File.WriteAllText(comicInfoPath, GetComicInfoXmlString(publication, chapter, logger)); + File.WriteAllText(comicInfoPath, chapter.GetComicInfoXmlString()); - return DownloadChapterImages(urls.ToArray(), GetArchiveFilePath(publication, chapter), (byte)1, parentTask, comicInfoPath, cancellationToken:cancellationToken); + return DownloadChapterImages(urls.ToArray(), chapter.GetArchiveFilePath(settings.downloadLocation), (byte)1, parentTask, comicInfoPath, cancellationToken:cancellationToken); } return response.Status; } diff --git a/Tranga/TaskManager.cs b/Tranga/TaskManager.cs index f03f1fd..f9b8344 100644 --- a/Tranga/TaskManager.cs +++ b/Tranga/TaskManager.cs @@ -296,7 +296,7 @@ public class TaskManager chapterCollection.TryAdd(publication, newChaptersList); //To ensure publication is actually in collection Chapter[] newChapters = connector.GetChapters(publication, language); - newChaptersList = newChapters.Where(nChapter => !connector.CheckChapterIsDownloaded(publication, nChapter)).ToList(); + newChaptersList = newChapters.Where(nChapter => !nChapter.CheckChapterIsDownloaded(settings.downloadLocation)).ToList(); return newChaptersList; } @@ -304,7 +304,7 @@ public class TaskManager public List GetExistingChaptersList(Connector connector, Publication publication, string language) { Chapter[] newChapters = connector.GetChapters(publication, language); - return newChapters.Where(nChapter => connector.CheckChapterIsDownloaded(publication, nChapter)).ToList(); + return newChapters.Where(nChapter => nChapter.CheckChapterIsDownloaded(settings.downloadLocation)).ToList(); } ///