Renamed Publication.cs to Manga.cs

Renamed Request-Paths "Tasks" to "Jobs"
This commit is contained in:
glax 2023-08-31 12:16:02 +02:00
parent e663163de8
commit 1fd36c91d6
13 changed files with 133 additions and 133 deletions

View File

@ -10,7 +10,7 @@ namespace Tranga;
public readonly struct Chapter
{
// ReSharper disable once MemberCanBePrivate.Global
public Publication parentPublication { get; }
public Manga parentManga { get; }
public string? name { get; }
public string? volumeNumber { get; }
public string chapterNumber { get; }
@ -20,9 +20,9 @@ public readonly struct Chapter
private static readonly Regex LegalCharacters = new (@"([A-z]*[0-9]* *\.*-*,*\]*\[*'*\'*\)*\(*~*!*)*");
private static readonly Regex IllegalStrings = new(@"Vol(ume)?.?", RegexOptions.IgnoreCase);
public Chapter(Publication parentPublication, string? name, string? volumeNumber, string chapterNumber, string url)
public Chapter(Manga parentManga, string? name, string? volumeNumber, string chapterNumber, string url)
{
this.parentPublication = parentPublication;
this.parentManga = parentManga;
this.name = name;
this.volumeNumber = volumeNumber;
this.chapterNumber = chapterNumber;
@ -38,7 +38,7 @@ public readonly struct Chapter
public override string ToString()
{
return $"Chapter {parentPublication.sortName} {parentPublication.internalId} {chapterNumber} {name}";
return $"Chapter {parentManga.sortName} {parentManga.internalId} {chapterNumber} {name}";
}
/// <summary>
@ -48,9 +48,9 @@ public readonly struct Chapter
internal bool CheckChapterIsDownloaded(string downloadLocation)
{
string newFilePath = GetArchiveFilePath(downloadLocation);
if (!Directory.Exists(Path.Join(downloadLocation, parentPublication.folderName)))
if (!Directory.Exists(Path.Join(downloadLocation, parentManga.folderName)))
return false;
FileInfo[] archives = new DirectoryInfo(Path.Join(downloadLocation, parentPublication.folderName)).GetFiles();
FileInfo[] archives = new DirectoryInfo(Path.Join(downloadLocation, parentManga.folderName)).GetFiles();
Regex chapterInfoRex = new(@"Ch\.[0-9.]+");
Regex chapterRex = new(@"[0-9]+(\.[0-9]+)?");
@ -71,7 +71,7 @@ public readonly struct Chapter
/// <returns>Filepath</returns>
internal string GetArchiveFilePath(string downloadLocation)
{
return Path.Join(downloadLocation, parentPublication.folderName, $"{parentPublication.folderName} - {this.fileName}.cbz");
return Path.Join(downloadLocation, parentManga.folderName, $"{parentManga.folderName} - {this.fileName}.cbz");
}
/// <summary>
@ -82,10 +82,10 @@ public readonly struct Chapter
internal string GetComicInfoXmlString()
{
XElement comicInfo = new XElement("ComicInfo",
new XElement("Tags", string.Join(',', parentPublication.tags)),
new XElement("LanguageISO", parentPublication.originalLanguage),
new XElement("Tags", string.Join(',', parentManga.tags)),
new XElement("LanguageISO", parentManga.originalLanguage),
new XElement("Title", this.name),
new XElement("Writer", string.Join(',', parentPublication.authors)),
new XElement("Writer", string.Join(',', parentManga.authors)),
new XElement("Volume", this.volumeNumber),
new XElement("Number", this.chapterNumber)
);

View File

@ -11,7 +11,7 @@ public abstract class GlobalBase
protected TrangaSettings settings { get; init; }
protected HashSet<NotificationConnector> notificationConnectors { get; init; }
protected HashSet<LibraryConnector> libraryConnectors { get; init; }
protected List<Publication> cachedPublications { get; init; }
protected List<Manga> cachedPublications { get; init; }
protected GlobalBase(GlobalBase clone)
{

View File

@ -14,7 +14,7 @@ public class DownloadChapter : Job
protected override string GetId()
{
return Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Concat(this.GetType().ToString(), chapter.parentPublication.internalId, chapter.chapterNumber)));
return Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Concat(this.GetType().ToString(), chapter.parentManga.internalId, chapter.chapterNumber)));
}
public override string ToString()
@ -28,7 +28,7 @@ public class DownloadChapter : Job
{
mangaConnector.DownloadChapter(chapter, this.progressToken);
UpdateLibraries();
SendNotifications("Chapter downloaded", $"{chapter.parentPublication.sortName} - {chapter.chapterNumber}");
SendNotifications("Chapter downloaded", $"{chapter.parentManga.sortName} - {chapter.chapterNumber}");
});
downloadTask.Start();
return Array.Empty<Job>();

View File

@ -5,26 +5,26 @@ namespace Tranga.Jobs;
public class DownloadNewChapters : Job
{
public Publication publication { get; init; }
public Manga manga { get; init; }
public DownloadNewChapters(GlobalBase clone, MangaConnector connector, Publication publication, bool recurring = false, TimeSpan? recurrence = null) : base (clone, connector, recurring, recurrence)
public DownloadNewChapters(GlobalBase clone, MangaConnector connector, Manga manga, bool recurring = false, TimeSpan? recurrence = null) : base (clone, connector, recurring, recurrence)
{
this.publication = publication;
this.manga = manga;
}
protected override string GetId()
{
return Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Concat(this.GetType().ToString(), publication.internalId)));
return Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Concat(this.GetType().ToString(), manga.internalId)));
}
public override string ToString()
{
return $"DownloadChapter {id} {publication}";
return $"DownloadChapter {id} {manga}";
}
protected override IEnumerable<Job> ExecuteReturnSubTasksInternal()
{
Chapter[] chapters = mangaConnector.GetNewChapters(publication);
Chapter[] chapters = mangaConnector.GetNewChapters(manga);
this.progressToken.increments = chapters.Length;
List<Job> subJobs = new();
foreach (Chapter chapter in chapters)

View File

@ -44,7 +44,7 @@ public class JobBoss : GlobalBase
{
if (jjob is not DownloadChapter job)
return false;
return job.chapter.parentPublication.internalId == internalId &&
return job.chapter.parentManga.internalId == internalId &&
job.chapter.chapterNumber == chapterNumber;
});
else if (internalId is not null)
@ -52,12 +52,12 @@ public class JobBoss : GlobalBase
{
if (jjob is not DownloadNewChapters job)
return false;
return job.publication.internalId == internalId;
return job.manga.internalId == internalId;
});
return ret;
}
public IEnumerable<Job> GetJobsLike(MangaConnector? mangaConnector = null, Publication? publication = null,
public IEnumerable<Job> GetJobsLike(MangaConnector? mangaConnector = null, Manga? publication = null,
Chapter? chapter = null)
{
return GetJobsLike(mangaConnector?.name, publication?.internalId, chapter?.chapterNumber);

View File

@ -9,7 +9,7 @@ namespace Tranga;
/// <summary>
/// Contains information on a Publication (Manga)
/// </summary>
public struct Publication
public struct Manga
{
public string sortName { get; }
public List<string> authors { get; }
@ -36,7 +36,7 @@ public struct Publication
private static readonly Regex LegalCharacters = new (@"[A-Z]*[a-z]*[0-9]* *\.*-*,*'*\'*\)*\(*~*!*");
[JsonConstructor]
public Publication(string sortName, List<string> authors, string? description, Dictionary<string,string> altTitles, string[] tags, string? coverUrl, Dictionary<string,string>? links, int? year, string? originalLanguage, string status, string publicationId, string? folderName = null, float? ignoreChaptersBelow = 0)
public Manga(string sortName, List<string> authors, string? description, Dictionary<string,string> altTitles, string[] tags, string? coverUrl, Dictionary<string,string>? links, int? year, string? originalLanguage, string status, string publicationId, string? folderName = null, float? ignoreChaptersBelow = 0)
{
this.sortName = sortName;
this.authors = authors;

View File

@ -29,40 +29,40 @@ public abstract class MangaConnector : GlobalBase
/// </summary>
/// <param name="publicationTitle">Search-Query</param>
/// <returns>Publications matching the query</returns>
public abstract Publication[] GetPublications(string publicationTitle = "");
public abstract Manga[] GetPublications(string publicationTitle = "");
/// <summary>
/// Returns all Chapters of the publication in the provided language.
/// If the language is empty or null, returns all Chapters in all Languages.
/// </summary>
/// <param name="publication">Publication to get Chapters for</param>
/// <param name="manga">Publication to get Chapters for</param>
/// <param name="language">Language of the Chapters</param>
/// <returns>Array of Chapters matching Publication and Language</returns>
public abstract Chapter[] GetChapters(Publication publication, string language="en");
public abstract Chapter[] GetChapters(Manga manga, string language="en");
/// <summary>
/// Updates the available Chapters of a Publication
/// </summary>
/// <param name="publication">Publication to check</param>
/// <param name="manga">Publication to check</param>
/// <param name="language">Language to receive chapters for</param>
/// <returns>List of Chapters that were previously not in collection</returns>
public Chapter[] GetNewChapters(Publication publication, string language = "en")
public Chapter[] GetNewChapters(Manga manga, string language = "en")
{
Log($"Getting new Chapters for {publication}");
Chapter[] newChapters = this.GetChapters(publication, language);
Log($"Getting new Chapters for {manga}");
Chapter[] newChapters = this.GetChapters(manga, language);
NumberFormatInfo decimalPoint = new (){ NumberDecimalSeparator = "." };
Log($"Checking for duplicates {publication}");
Log($"Checking for duplicates {manga}");
List<Chapter> newChaptersList = newChapters.Where(nChapter =>
float.Parse(nChapter.chapterNumber, decimalPoint) > publication.ignoreChaptersBelow &&
float.Parse(nChapter.chapterNumber, decimalPoint) > manga.ignoreChaptersBelow &&
!nChapter.CheckChapterIsDownloaded(settings.downloadLocation)).ToList();
Log($"{newChaptersList.Count} new chapters. {publication}");
Log($"{newChaptersList.Count} new chapters. {manga}");
return newChaptersList.ToArray();
}
public Chapter[] SelectChapters(Publication publication, string searchTerm, string? language = null)
public Chapter[] SelectChapters(Manga manga, string searchTerm, string? language = null)
{
Chapter[] availableChapters = this.GetChapters(publication, language??"en");
Chapter[] availableChapters = this.GetChapters(manga, language??"en");
Regex volumeRegex = new ("((v(ol)*(olume)*){1} *([0-9]+(-[0-9]+)?){1})", RegexOptions.IgnoreCase);
Regex chapterRegex = new ("((c(h)*(hapter)*){1} *([0-9]+(-[0-9]+)?){1})", RegexOptions.IgnoreCase);
Regex singleResultRegex = new("([0-9]+)", RegexOptions.IgnoreCase);
@ -138,20 +138,20 @@ public abstract class MangaConnector : GlobalBase
/// <summary>
/// Copies the already downloaded cover from cache to downloadLocation
/// </summary>
/// <param name="publication">Publication to retrieve Cover for</param>
public void CopyCoverFromCacheToDownloadLocation(Publication publication)
/// <param name="manga">Publication to retrieve Cover for</param>
public void CopyCoverFromCacheToDownloadLocation(Manga manga)
{
Log($"Copy cover {publication}");
Log($"Copy cover {manga}");
//Check if Publication already has a Folder and cover
string publicationFolder = publication.CreatePublicationFolder(settings.downloadLocation);
string publicationFolder = manga.CreatePublicationFolder(settings.downloadLocation);
DirectoryInfo dirInfo = new (publicationFolder);
if (dirInfo.EnumerateFiles().Any(info => info.Name.Contains("cover", StringComparison.InvariantCultureIgnoreCase)))
{
Log($"Cover exists {publication}");
Log($"Cover exists {manga}");
return;
}
string fileInCache = Path.Join(settings.coverImageCache, publication.coverFileNameInCache);
string fileInCache = Path.Join(settings.coverImageCache, manga.coverFileNameInCache);
string newFilePath = Path.Join(publicationFolder, $"cover.{Path.GetFileName(fileInCache).Split('.')[^1]}" );
Log($"Cloning cover {fileInCache} -> {newFilePath}");
File.Copy(fileInCache, newFilePath, true);

View File

@ -31,13 +31,13 @@ public class MangaDex : MangaConnector
});
}
public override Publication[] GetPublications(string publicationTitle = "")
public override Manga[] GetPublications(string publicationTitle = "")
{
Log($"Searching Publications. Term=\"{publicationTitle}\"");
const int limit = 100; //How many values we want returned at once
int offset = 0; //"Page"
int total = int.MaxValue; //How many total results are there, is updated on first request
HashSet<Publication> publications = new();
HashSet<Manga> publications = new();
int loadedPublicationData = 0;
while (offset < total) //As long as we haven't requested all "Pages"
{
@ -125,7 +125,7 @@ public class MangaDex : MangaConnector
string status = attributes["status"]!.GetValue<string>();
Publication pub = new (
Manga pub = new (
title,
authors,
description,
@ -147,9 +147,9 @@ public class MangaDex : MangaConnector
return publications.ToArray();
}
public override Chapter[] GetChapters(Publication publication, string language="en")
public override Chapter[] GetChapters(Manga manga, string language="en")
{
Log($"Getting chapters {publication}");
Log($"Getting chapters {manga}");
const int limit = 100; //How many values we want returned at once
int offset = 0; //"Page"
int total = int.MaxValue; //How many total results are there, is updated on first request
@ -160,7 +160,7 @@ public class MangaDex : MangaConnector
//Request next "Page"
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(
$"https://api.mangadex.org/manga/{publication.publicationId}/feed?limit={limit}&offset={offset}&translatedLanguage%5B%5D={language}", (byte)RequestType.Feed);
$"https://api.mangadex.org/manga/{manga.publicationId}/feed?limit={limit}&offset={offset}&translatedLanguage%5B%5D={language}", (byte)RequestType.Feed);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
break;
JsonObject? result = JsonSerializer.Deserialize<JsonObject>(requestResult.result);
@ -191,13 +191,13 @@ public class MangaDex : MangaConnector
: "null";
if(chapterNum is not "null")
chapters.Add(new Chapter(publication, title, volume, chapterNum, chapterId));
chapters.Add(new Chapter(manga, title, volume, chapterNum, chapterId));
}
}
//Return Chapters ordered by Chapter-Number
NumberFormatInfo chapterNumberFormatInfo = new() { NumberDecimalSeparator = "." };
Log($"Got {chapters.Count} chapters. {publication}");
Log($"Got {chapters.Count} chapters. {manga}");
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
}
@ -205,8 +205,8 @@ public class MangaDex : MangaConnector
{
if (progressToken?.cancellationRequested ?? false)
return HttpStatusCode.RequestTimeout;
Publication chapterParentPublication = chapter.parentPublication;
Log($"Retrieving chapter-info {chapter} {chapterParentPublication}");
Manga chapterParentManga = chapter.parentManga;
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
//Request URLs for Chapter-Images
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest($"https://api.mangadex.org/at-home/server/{chapter.url}?forcePort443=false'", (byte)RequestType.AtHomeServer);
@ -227,8 +227,8 @@ public class MangaDex : MangaConnector
string comicInfoPath = Path.GetTempFileName();
File.WriteAllText(comicInfoPath, chapter.GetComicInfoXmlString());
if (chapterParentPublication.coverUrl is not null)
chapterParentPublication.coverFileNameInCache = SaveCoverImageToCache(chapterParentPublication.coverUrl, (byte)RequestType.AtHomeServer);
if (chapterParentManga.coverUrl is not null)
chapterParentManga.coverFileNameInCache = SaveCoverImageToCache(chapterParentManga.coverUrl, (byte)RequestType.AtHomeServer);
//Download Chapter-Images
return DownloadChapterImages(imageUrls.ToArray(), chapter.GetArchiveFilePath(settings.downloadLocation), (byte)RequestType.AtHomeServer, comicInfoPath, progressToken:progressToken);
}

View File

@ -19,7 +19,7 @@ public class MangaKatana : MangaConnector
});
}
public override Publication[] GetPublications(string publicationTitle = "")
public override Manga[] GetPublications(string publicationTitle = "")
{
Log($"Searching Publications. Term=\"{publicationTitle}\"");
string sanitizedTitle = string.Join('_', Regex.Matches(publicationTitle, "[A-z]*").Where(m => m.Value.Length > 0)).ToLower();
@ -27,7 +27,7 @@ public class MangaKatana : MangaConnector
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, 1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
return Array.Empty<Publication>();
return Array.Empty<Manga>();
// ReSharper disable once MergeIntoPattern
// If a single result is found, the user will be redirected to the results directly instead of a result page
@ -38,13 +38,13 @@ public class MangaKatana : MangaConnector
return new [] { ParseSinglePublicationFromHtml(requestResult.result, requestResult.redirectedToUrl.Split('/')[^1]) };
}
Publication[] publications = ParsePublicationsFromHtml(requestResult.result);
Manga[] publications = ParsePublicationsFromHtml(requestResult.result);
cachedPublications.AddRange(publications);
Log($"Retrieved {publications.Length} publications. Term=\"{publicationTitle}\"");
return publications;
}
private Publication[] ParsePublicationsFromHtml(Stream html)
private Manga[] ParsePublicationsFromHtml(Stream html)
{
StreamReader reader = new(html);
string htmlString = reader.ReadToEnd();
@ -52,7 +52,7 @@ public class MangaKatana : MangaConnector
document.LoadHtml(htmlString);
IEnumerable<HtmlNode> searchResults = document.DocumentNode.SelectNodes("//*[@id='book_list']/div");
if (searchResults is null || !searchResults.Any())
return Array.Empty<Publication>();
return Array.Empty<Manga>();
List<string> urls = new();
foreach (HtmlNode mangaResult in searchResults)
{
@ -60,13 +60,13 @@ public class MangaKatana : MangaConnector
.First(a => a.Name == "href").Value);
}
HashSet<Publication> ret = new();
HashSet<Manga> ret = new();
foreach (string url in urls)
{
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(url, 1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
return Array.Empty<Publication>();
return Array.Empty<Manga>();
ret.Add(ParseSinglePublicationFromHtml(requestResult.result, url.Split('/')[^1]));
}
@ -74,7 +74,7 @@ public class MangaKatana : MangaConnector
return ret.ToArray();
}
private Publication ParseSinglePublicationFromHtml(Stream html, string publicationId)
private Manga ParseSinglePublicationFromHtml(Stream html, string publicationId)
{
StreamReader reader = new(html);
string htmlString = reader.ReadToEnd();
@ -132,14 +132,14 @@ public class MangaKatana : MangaConnector
year = Convert.ToInt32(yearString);
}
return new Publication(sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, links,
return new Manga(sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, links,
year, originalLanguage, status, publicationId);
}
public override Chapter[] GetChapters(Publication publication, string language="en")
public override Chapter[] GetChapters(Manga manga, string language="en")
{
Log($"Getting chapters {publication}");
string requestUrl = $"https://mangakatana.com/manga/{publication.publicationId}";
Log($"Getting chapters {manga}");
string requestUrl = $"https://mangakatana.com/manga/{manga.publicationId}";
// Leaving this in for verification if the page exists
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, 1);
@ -151,12 +151,12 @@ public class MangaKatana : MangaConnector
{
NumberDecimalSeparator = "."
};
List<Chapter> chapters = ParseChaptersFromHtml(publication, requestUrl);
Log($"Got {chapters.Count} chapters. {publication}");
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestUrl);
Log($"Got {chapters.Count} chapters. {manga}");
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
}
private List<Chapter> ParseChaptersFromHtml(Publication publication, string mangaUrl)
private List<Chapter> ParseChaptersFromHtml(Manga manga, string mangaUrl)
{
// Using HtmlWeb will include the chapters since they are loaded with js
HtmlWeb web = new();
@ -175,7 +175,7 @@ public class MangaKatana : MangaConnector
string chapterName = string.Concat(fullString.Split(':')[1..]);
string url = chapterInfo.Descendants("a").First()
.GetAttributeValue("href", "");
ret.Add(new Chapter(publication, chapterName, volumeNumber, chapterNumber, url));
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));
}
return ret;
@ -185,8 +185,8 @@ public class MangaKatana : MangaConnector
{
if (progressToken?.cancellationRequested ?? false)
return HttpStatusCode.RequestTimeout;
Publication chapterParentPublication = chapter.parentPublication;
Log($"Retrieving chapter-info {chapter} {chapterParentPublication}");
Manga chapterParentManga = chapter.parentManga;
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
string requestUrl = chapter.url;
// Leaving this in to check if the page exists
DownloadClient.RequestResult requestResult =
@ -199,8 +199,8 @@ public class MangaKatana : MangaConnector
string comicInfoPath = Path.GetTempFileName();
File.WriteAllText(comicInfoPath, chapter.GetComicInfoXmlString());
if (chapterParentPublication.coverUrl is not null)
chapterParentPublication.coverFileNameInCache = SaveCoverImageToCache(chapterParentPublication.coverUrl, 1);
if (chapterParentManga.coverUrl is not null)
chapterParentManga.coverFileNameInCache = SaveCoverImageToCache(chapterParentManga.coverUrl, 1);
return DownloadChapterImages(imageUrls, chapter.GetArchiveFilePath(settings.downloadLocation), 1, comicInfoPath, "https://mangakatana.com/", progressToken:progressToken);
}

View File

@ -19,7 +19,7 @@ public class Manganato : MangaConnector
});
}
public override Publication[] GetPublications(string publicationTitle = "")
public override Manga[] GetPublications(string publicationTitle = "")
{
Log($"Searching Publications. Term=\"{publicationTitle}\"");
string sanitizedTitle = string.Join('_', Regex.Matches(publicationTitle, "[A-z]*")).ToLower();
@ -27,15 +27,15 @@ public class Manganato : MangaConnector
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, 1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
return Array.Empty<Publication>();
return Array.Empty<Manga>();
Publication[] publications = ParsePublicationsFromHtml(requestResult.result);
Manga[] publications = ParsePublicationsFromHtml(requestResult.result);
cachedPublications.AddRange(publications);
Log($"Retrieved {publications.Length} publications. Term=\"{publicationTitle}\"");
return publications;
}
private Publication[] ParsePublicationsFromHtml(Stream html)
private Manga[] ParsePublicationsFromHtml(Stream html)
{
StreamReader reader = new (html);
string htmlString = reader.ReadToEnd();
@ -49,13 +49,13 @@ public class Manganato : MangaConnector
.First(a => a.Name == "href").Value);
}
HashSet<Publication> ret = new();
HashSet<Manga> ret = new();
foreach (string url in urls)
{
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(url, 1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
return Array.Empty<Publication>();
return Array.Empty<Manga>();
ret.Add(ParseSinglePublicationFromHtml(requestResult.result, url.Split('/')[^1]));
}
@ -63,7 +63,7 @@ public class Manganato : MangaConnector
return ret.ToArray();
}
private Publication ParseSinglePublicationFromHtml(Stream html, string publicationId)
private Manga ParseSinglePublicationFromHtml(Stream html, string publicationId)
{
StreamReader reader = new (html);
string htmlString = reader.ReadToEnd();
@ -120,14 +120,14 @@ public class Manganato : MangaConnector
.First(s => s.HasClass("chapter-time")).InnerText;
int year = Convert.ToInt32(yearString.Split(',')[^1]) + 2000;
return new Publication(sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, links,
return new Manga(sortName, authors.ToList(), description, altTitles, tags.ToArray(), posterUrl, links,
year, originalLanguage, status, publicationId);
}
public override Chapter[] GetChapters(Publication publication, string language="en")
public override Chapter[] GetChapters(Manga manga, string language="en")
{
Log($"Getting chapters {publication}");
string requestUrl = $"https://chapmanganato.com/{publication.publicationId}";
Log($"Getting chapters {manga}");
string requestUrl = $"https://chapmanganato.com/{manga.publicationId}";
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, 1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
@ -138,12 +138,12 @@ public class Manganato : MangaConnector
{
NumberDecimalSeparator = "."
};
List<Chapter> chapters = ParseChaptersFromHtml(publication, requestResult.result);
Log($"Got {chapters.Count} chapters. {publication}");
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestResult.result);
Log($"Got {chapters.Count} chapters. {manga}");
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
}
private List<Chapter> ParseChaptersFromHtml(Publication publication, Stream html)
private List<Chapter> ParseChaptersFromHtml(Manga manga, Stream html)
{
StreamReader reader = new (html);
string htmlString = reader.ReadToEnd();
@ -162,7 +162,7 @@ public class Manganato : MangaConnector
string chapterName = string.Concat(fullString.Split(':')[1..]);
string url = chapterInfo.Descendants("a").First(d => d.HasClass("chapter-name"))
.GetAttributeValue("href", "");
ret.Add(new Chapter(publication, chapterName, volumeNumber, chapterNumber, url));
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));
}
ret.Reverse();
return ret;
@ -172,8 +172,8 @@ public class Manganato : MangaConnector
{
if (progressToken?.cancellationRequested ?? false)
return HttpStatusCode.RequestTimeout;
Publication chapterParentPublication = chapter.parentPublication;
Log($"Retrieving chapter-info {chapter} {chapterParentPublication}");
Manga chapterParentManga = chapter.parentManga;
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
string requestUrl = chapter.url;
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, 1);
@ -185,8 +185,8 @@ public class Manganato : MangaConnector
string comicInfoPath = Path.GetTempFileName();
File.WriteAllText(comicInfoPath, chapter.GetComicInfoXmlString());
if (chapterParentPublication.coverUrl is not null)
chapterParentPublication.coverFileNameInCache = SaveCoverImageToCache(chapterParentPublication.coverUrl, 1);
if (chapterParentManga.coverUrl is not null)
chapterParentManga.coverFileNameInCache = SaveCoverImageToCache(chapterParentManga.coverUrl, 1);
return DownloadChapterImages(imageUrls, chapter.GetArchiveFilePath(settings.downloadLocation), 1, comicInfoPath, "https://chapmanganato.com/", progressToken:progressToken);
}

View File

@ -69,22 +69,22 @@ public class Mangasee : MangaConnector
});
}
public override Publication[] GetPublications(string publicationTitle = "")
public override Manga[] GetPublications(string publicationTitle = "")
{
Log($"Searching Publications. Term=\"{publicationTitle}\"");
string requestUrl = $"https://mangasee123.com/_search.php";
DownloadClient.RequestResult requestResult =
downloadClient.MakeRequest(requestUrl, 1);
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
return Array.Empty<Publication>();
return Array.Empty<Manga>();
Publication[] publications = ParsePublicationsFromHtml(requestResult.result, publicationTitle);
Manga[] publications = ParsePublicationsFromHtml(requestResult.result, publicationTitle);
cachedPublications.AddRange(publications);
Log($"Retrieved {publications.Length} publications. Term=\"{publicationTitle}\"");
return publications;
}
private Publication[] ParsePublicationsFromHtml(Stream html, string publicationTitle)
private Manga[] ParsePublicationsFromHtml(Stream html, string publicationTitle)
{
string jsonString = new StreamReader(html).ReadToEnd();
List<SearchResultItem> result = JsonConvert.DeserializeObject<List<SearchResultItem>>(jsonString)!;
@ -101,7 +101,7 @@ public class Mangasee : MangaConnector
Log($"Retrieved {queryFiltered.Count} publications.");
HashSet<Publication> ret = new();
HashSet<Manga> ret = new();
List<SearchResultItem> orderedFiltered =
queryFiltered.OrderBy(item => item.Value).ToDictionary(item => item.Key, item => item.Value).Keys.ToList();
@ -120,7 +120,7 @@ public class Mangasee : MangaConnector
}
private Publication ParseSinglePublicationFromHtml(Stream html, string sortName, string publicationId, string[] a)
private Manga ParseSinglePublicationFromHtml(Stream html, string sortName, string publicationId, string[] a)
{
StreamReader reader = new (html);
HtmlDocument document = new ();
@ -170,7 +170,7 @@ public class Mangasee : MangaConnector
foreach(string at in a)
altTitles.Add((i++).ToString(), at);
return new Publication(sortName, authors, description, altTitles, tags.ToArray(), posterUrl, links,
return new Manga(sortName, authors, description, altTitles, tags.ToArray(), posterUrl, links,
year, originalLanguage, status, publicationId);
}
@ -214,10 +214,10 @@ public class Mangasee : MangaConnector
}
}
public override Chapter[] GetChapters(Publication publication, string language="en")
public override Chapter[] GetChapters(Manga manga, string language="en")
{
Log($"Getting chapters {publication}");
XDocument doc = XDocument.Load($"https://mangasee123.com/rss/{publication.publicationId}.xml");
Log($"Getting chapters {manga}");
XDocument doc = XDocument.Load($"https://mangasee123.com/rss/{manga.publicationId}.xml");
XElement[] chapterItems = doc.Descendants("item").ToArray();
List<Chapter> chapters = new();
foreach (XElement chapter in chapterItems)
@ -228,7 +228,7 @@ public class Mangasee : MangaConnector
string url = chapter.Descendants("link").First().Value;
url = url.Replace(Regex.Matches(url,"(-page-[0-9])")[0].ToString(),"");
chapters.Add(new Chapter(publication, "", volumeNumber, chapterNumber, url));
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, url));
}
//Return Chapters ordered by Chapter-Number
@ -236,7 +236,7 @@ public class Mangasee : MangaConnector
{
NumberDecimalSeparator = "."
};
Log($"Got {chapters.Count} chapters. {publication}");
Log($"Got {chapters.Count} chapters. {manga}");
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, chapterNumberFormatInfo)).ToArray();
}
@ -244,7 +244,7 @@ public class Mangasee : MangaConnector
{
if (progressToken?.cancellationRequested ?? false)
return HttpStatusCode.RequestTimeout;
Publication chapterParentPublication = chapter.parentPublication;
Manga chapterParentManga = chapter.parentManga;
while (this._browser is null && !(progressToken?.cancellationRequested??false))
{
Log("Waiting for headless browser to download...");
@ -253,7 +253,7 @@ public class Mangasee : MangaConnector
if (progressToken?.cancellationRequested??false)
return HttpStatusCode.RequestTimeout;
Log($"Retrieving chapter-info {chapter} {chapterParentPublication}");
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
IPage page = _browser!.NewPageAsync().Result;
IResponse response = page.GoToAsync(chapter.url).Result;
if (response.Ok)
@ -270,8 +270,8 @@ public class Mangasee : MangaConnector
string comicInfoPath = Path.GetTempFileName();
File.WriteAllText(comicInfoPath, chapter.GetComicInfoXmlString());
if (chapterParentPublication.coverUrl is not null)
chapterParentPublication.coverFileNameInCache = SaveCoverImageToCache(chapterParentPublication.coverUrl, 1);
if (chapterParentManga.coverUrl is not null)
chapterParentManga.coverFileNameInCache = SaveCoverImageToCache(chapterParentManga.coverUrl, 1);
return DownloadChapterImages(urls.ToArray(), chapter.GetArchiveFilePath(settings.downloadLocation), 1, comicInfoPath, progressToken:progressToken);
}

View File

@ -113,7 +113,7 @@ public class Server : GlobalBase
case "Connectors":
SendResponse(HttpStatusCode.OK, response, _parent.GetConnectors().Select(con => con.name).ToArray());
break;
case "Publications/FromConnector":
case "Manga/FromConnector":
if (!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("title", out string? title) ||
_parent.GetConnector(connectorName) is null)
@ -124,7 +124,7 @@ public class Server : GlobalBase
connector = _parent.GetConnector(connectorName)!;
SendResponse(HttpStatusCode.OK, response, connector.GetPublications(title));
break;
case "Publications/Chapters":
case "Manga/Chapters":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out string? internalId) ||
_parent.GetConnector(connectorName) is null ||
@ -134,10 +134,10 @@ public class Server : GlobalBase
break;
}
connector = _parent.GetConnector(connectorName)!;
Publication publication = (Publication)_parent.GetPublicationById(internalId)!;
SendResponse(HttpStatusCode.OK, response, connector.GetChapters(publication));
Manga manga = (Manga)_parent.GetPublicationById(internalId)!;
SendResponse(HttpStatusCode.OK, response, connector.GetChapters(manga));
break;
case "Tasks":
case "Jobs":
if (!requestVariables.TryGetValue("jobId", out jobId))
{
if(!_parent._jobBoss.jobs.Any(jjob => jjob.id == jobId))
@ -148,7 +148,7 @@ public class Server : GlobalBase
}
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs);
break;
case "Tasks/Progress":
case "Jobs/Progress":
if (!requestVariables.TryGetValue("jobId", out jobId))
{
if(!_parent._jobBoss.jobs.Any(jjob => jjob.id == jobId))
@ -159,10 +159,10 @@ public class Server : GlobalBase
}
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.Select(jjob => jjob.progressToken));
break;
case "Tasks/Running":
case "Jobs/Running":
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.Where(jjob => jjob.progressToken.state is ProgressToken.State.Running));
break;
case "Tasks/Waiting":
case "Jobs/Waiting":
SendResponse(HttpStatusCode.OK, response, _parent._jobBoss.jobs.Where(jjob => jjob.progressToken.state is ProgressToken.State.Standby));
break;
case "Settings":
@ -191,11 +191,11 @@ public class Server : GlobalBase
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query);
string? connectorName, internalId;
MangaConnector connector;
Publication publication;
Manga manga;
string path = Regex.Match(request.Url!.LocalPath, @"[A-z0-9]+(\/[A-z0-9]+)*").Value;
switch (path)
{
case "Tasks/MonitorManga":
case "Jobs/MonitorManga":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out internalId) ||
!requestVariables.TryGetValue("interval", out string? intervalStr) ||
@ -207,11 +207,11 @@ public class Server : GlobalBase
break;
}
connector = _parent.GetConnector(connectorName)!;
publication = (Publication)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.AddJob(new DownloadNewChapters(this, connector, publication, true, interval));
manga = (Manga)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.AddJob(new DownloadNewChapters(this, connector, manga, true, interval));
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Tasks/DownloadNewChapters":
case "Jobs/DownloadNewChapters":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out internalId) ||
_parent.GetConnector(connectorName) is null ||
@ -221,8 +221,8 @@ public class Server : GlobalBase
break;
}
connector = _parent.GetConnector(connectorName)!;
publication = (Publication)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.AddJob(new DownloadNewChapters(this, connector, publication, false));
manga = (Manga)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.AddJob(new DownloadNewChapters(this, connector, manga, false));
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Settings/UpdateDownloadLocation":
@ -325,11 +325,11 @@ public class Server : GlobalBase
Dictionary<string, string> requestVariables = GetRequestVariables(request.Url!.Query);
string? connectorName, internalId;
MangaConnector connector;
Publication publication;
Manga manga;
string path = Regex.Match(request.Url!.LocalPath, @"[A-z0-9]+(\/[A-z0-9]+)*").Value;
switch (path)
{
case "Tasks/DownloadChapter":
case "Jobs/DownloadChapter":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out internalId) ||
!requestVariables.TryGetValue("chapterNumber", out string? chapterNumber) ||
@ -342,7 +342,7 @@ public class Server : GlobalBase
_parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connectorName, internalId, chapterNumber));
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Tasks/MonitorManga":
case "Jobs/MonitorManga":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out internalId) ||
_parent.GetConnector(connectorName) is null ||
@ -352,11 +352,11 @@ public class Server : GlobalBase
break;
}
connector = _parent.GetConnector(connectorName)!;
publication = (Publication)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connector, publication));
manga = (Manga)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connector, manga));
SendResponse(HttpStatusCode.Accepted, response);
break;
case "Tasks/DownloadNewChapters":
case "Jobs/DownloadNewChapters":
if(!requestVariables.TryGetValue("connector", out connectorName) ||
!requestVariables.TryGetValue("internalId", out internalId) ||
_parent.GetConnector(connectorName) is null ||
@ -366,8 +366,8 @@ public class Server : GlobalBase
break;
}
connector = _parent.GetConnector(connectorName)!;
publication = (Publication)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connector, publication));
manga = (Manga)_parent.GetPublicationById(internalId)!;
_parent._jobBoss.RemoveJobs(_parent._jobBoss.GetJobsLike(connector, manga));
SendResponse(HttpStatusCode.Accepted, response);
break;
case "NotificationConnectors":

View File

@ -39,7 +39,7 @@ public partial class Tranga : GlobalBase
return connectors;
}
public Publication? GetPublicationById(string internalId)
public Manga? GetPublicationById(string internalId)
{
if (cachedPublications.Exists(publication => publication.internalId == internalId))
return cachedPublications.First(publication => publication.internalId == internalId);