Compare commits
3 Commits
903bb5af5e
...
05573f65f9
Author | SHA1 | Date | |
---|---|---|---|
05573f65f9 | |||
d986c808e3 | |||
5df63b00c2 |
@ -7,7 +7,7 @@ namespace Tranga;
|
|||||||
/// Has to be Part of a publication
|
/// Has to be Part of a publication
|
||||||
/// Includes the Chapter-Name, -VolumeNumber, -ChapterNumber, the location of the chapter on the internet and the saveName of the local file.
|
/// Includes the Chapter-Name, -VolumeNumber, -ChapterNumber, the location of the chapter on the internet and the saveName of the local file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly struct Chapter
|
public readonly struct Chapter : IComparable
|
||||||
{
|
{
|
||||||
// ReSharper disable once MemberCanBePrivate.Global
|
// ReSharper disable once MemberCanBePrivate.Global
|
||||||
public Manga parentManga { get; }
|
public Manga parentManga { get; }
|
||||||
@ -41,6 +41,33 @@ public readonly struct Chapter
|
|||||||
return $"Chapter {parentManga.sortName} {parentManga.internalId} {chapterNumber} {name}";
|
return $"Chapter {parentManga.sortName} {parentManga.internalId} {chapterNumber} {name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int CompareTo(object? obj)
|
||||||
|
{
|
||||||
|
if (obj is Chapter otherChapter)
|
||||||
|
{
|
||||||
|
if (float.TryParse(volumeNumber, GlobalBase.numberFormatDecimalPoint, out float volumeNumberFloat) &&
|
||||||
|
float.TryParse(chapterNumber, GlobalBase.numberFormatDecimalPoint, out float chapterNumberFloat) &&
|
||||||
|
float.TryParse(otherChapter.volumeNumber, GlobalBase.numberFormatDecimalPoint,
|
||||||
|
out float otherVolumeNumberFloat) &&
|
||||||
|
float.TryParse(otherChapter.chapterNumber, GlobalBase.numberFormatDecimalPoint,
|
||||||
|
out float otherChapterNumberFloat))
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (volumeNumberFloat.CompareTo(otherVolumeNumberFloat))
|
||||||
|
{
|
||||||
|
case < 0:
|
||||||
|
return -1;
|
||||||
|
case > 0:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return chapterNumberFloat.CompareTo(otherChapterNumberFloat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else throw new FormatException($"Value could not be parsed");
|
||||||
|
}
|
||||||
|
throw new ArgumentException($"{obj} can not be compared to {this}");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a chapter-archive is already present
|
/// Checks if a chapter-archive is already present
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -20,7 +20,7 @@ public class Bato : MangaConnector
|
|||||||
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
||||||
string sanitizedTitle = string.Join(' ', Regex.Matches(publicationTitle, "[A-z]*").Where(m => m.Value.Length > 0)).ToLower();
|
string sanitizedTitle = string.Join(' ', Regex.Matches(publicationTitle, "[A-z]*").Where(m => m.Value.Length > 0)).ToLower();
|
||||||
string requestUrl = $"https://bato.to/v3x-search?word={sanitizedTitle}&lang=en";
|
string requestUrl = $"https://bato.to/v3x-search?word={sanitizedTitle}&lang=en";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Manga>();
|
return Array.Empty<Manga>();
|
||||||
@ -43,7 +43,7 @@ public class Bato : MangaConnector
|
|||||||
|
|
||||||
public override Manga? GetMangaFromUrl(string url)
|
public override Manga? GetMangaFromUrl(string url)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(url, 1);
|
downloadClient.MakeRequest(url, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return null;
|
return null;
|
||||||
@ -128,7 +128,7 @@ public class Bato : MangaConnector
|
|||||||
Log($"Getting chapters {manga}");
|
Log($"Getting chapters {manga}");
|
||||||
string requestUrl = $"https://bato.to/title/{manga.publicationId}";
|
string requestUrl = $"https://bato.to/title/{manga.publicationId}";
|
||||||
// Leaving this in for verification if the page exists
|
// Leaving this in for verification if the page exists
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
@ -136,12 +136,12 @@ public class Bato : MangaConnector
|
|||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestUrl);
|
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestUrl);
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.Order().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Chapter> ParseChaptersFromHtml(Manga manga, string mangaUrl)
|
private List<Chapter> ParseChaptersFromHtml(Manga manga, string mangaUrl)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult result = downloadClient.MakeRequest(mangaUrl, 1);
|
RequestResult result = downloadClient.MakeRequest(mangaUrl, 1);
|
||||||
if ((int)result.statusCode < 200 || (int)result.statusCode >= 300 || result.htmlDocument is null)
|
if ((int)result.statusCode < 200 || (int)result.statusCode >= 300 || result.htmlDocument is null)
|
||||||
{
|
{
|
||||||
Log("Failed to load site");
|
Log("Failed to load site");
|
||||||
@ -183,7 +183,7 @@ public class Bato : MangaConnector
|
|||||||
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
||||||
string requestUrl = chapter.url;
|
string requestUrl = chapter.url;
|
||||||
// Leaving this in to check if the page exists
|
// Leaving this in to check if the page exists
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
{
|
{
|
||||||
@ -201,7 +201,7 @@ public class Bato : MangaConnector
|
|||||||
|
|
||||||
private string[] ParseImageUrlsFromHtml(string mangaUrl)
|
private string[] ParseImageUrlsFromHtml(string mangaUrl)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(mangaUrl, 1);
|
downloadClient.MakeRequest(mangaUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ internal class ChromiumDownloadClient : DownloadClient
|
|||||||
this.browser = DownloadBrowser().Result;
|
this.browser = DownloadBrowser().Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override RequestResult MakeRequestInternal(string url, string? referrer = null)
|
protected override RequestResult MakeRequestInternal(string url, string? referrer = null, string? clickButton = null)
|
||||||
{
|
{
|
||||||
IPage page = this.browser.NewPageAsync().Result;
|
IPage page = this.browser.NewPageAsync().Result;
|
||||||
page.DefaultTimeout = 10000;
|
page.DefaultTimeout = 10000;
|
||||||
@ -72,6 +72,8 @@ internal class ChromiumDownloadClient : DownloadClient
|
|||||||
{
|
{
|
||||||
if (content.Contains("text/html"))
|
if (content.Contains("text/html"))
|
||||||
{
|
{
|
||||||
|
if(clickButton is not null)
|
||||||
|
page.ClickAsync(clickButton).Wait();
|
||||||
string htmlString = page.GetContentAsync().Result;
|
string htmlString = page.GetContentAsync().Result;
|
||||||
stream = new MemoryStream(Encoding.Default.GetBytes(htmlString));
|
stream = new MemoryStream(Encoding.Default.GetBytes(htmlString));
|
||||||
document = new ();
|
document = new ();
|
||||||
|
@ -16,7 +16,7 @@ internal abstract class DownloadClient : GlobalBase
|
|||||||
_rateLimit.Add(limit.Key, TimeSpan.FromMinutes(1).Divide(limit.Value));
|
_rateLimit.Add(limit.Key, TimeSpan.FromMinutes(1).Divide(limit.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestResult MakeRequest(string url, byte requestType, string? referrer = null)
|
public RequestResult MakeRequest(string url, byte requestType, string? referrer = null, string? clickButton = null)
|
||||||
{
|
{
|
||||||
if (_rateLimit.TryGetValue(requestType, out TimeSpan value))
|
if (_rateLimit.TryGetValue(requestType, out TimeSpan value))
|
||||||
_lastExecutedRateLimit.TryAdd(requestType, DateTime.Now.Subtract(value));
|
_lastExecutedRateLimit.TryAdd(requestType, DateTime.Now.Subtract(value));
|
||||||
@ -35,35 +35,11 @@ internal abstract class DownloadClient : GlobalBase
|
|||||||
Thread.Sleep(rateLimitTimeout);
|
Thread.Sleep(rateLimitTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestResult result = MakeRequestInternal(url, referrer);
|
RequestResult result = MakeRequestInternal(url, referrer, clickButton);
|
||||||
_lastExecutedRateLimit[requestType] = DateTime.Now;
|
_lastExecutedRateLimit[requestType] = DateTime.Now;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract RequestResult MakeRequestInternal(string url, string? referrer = null);
|
protected abstract RequestResult MakeRequestInternal(string url, string? referrer = null, string? clickButton = null);
|
||||||
public abstract void Close();
|
public abstract void Close();
|
||||||
|
|
||||||
public struct RequestResult
|
|
||||||
{
|
|
||||||
public HttpStatusCode statusCode { get; }
|
|
||||||
public Stream result { get; }
|
|
||||||
public bool hasBeenRedirected { get; }
|
|
||||||
public string? redirectedToUrl { get; }
|
|
||||||
public HtmlDocument? htmlDocument { get; }
|
|
||||||
|
|
||||||
public RequestResult(HttpStatusCode statusCode, HtmlDocument? htmlDocument, Stream result)
|
|
||||||
{
|
|
||||||
this.statusCode = statusCode;
|
|
||||||
this.htmlDocument = htmlDocument;
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RequestResult(HttpStatusCode statusCode, HtmlDocument? htmlDocument, Stream result, bool hasBeenRedirected, string redirectedTo)
|
|
||||||
: this(statusCode, htmlDocument, result)
|
|
||||||
{
|
|
||||||
this.hasBeenRedirected = hasBeenRedirected;
|
|
||||||
redirectedToUrl = redirectedTo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -24,8 +24,10 @@ internal class HttpDownloadClient : DownloadClient
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override RequestResult MakeRequestInternal(string url, string? referrer = null)
|
protected override RequestResult MakeRequestInternal(string url, string? referrer = null, string? clickButton = null)
|
||||||
{
|
{
|
||||||
|
if(clickButton is not null)
|
||||||
|
Log("Can not click button on static site.");
|
||||||
HttpResponseMessage? response = null;
|
HttpResponseMessage? response = null;
|
||||||
while (response is null)
|
while (response is null)
|
||||||
{
|
{
|
||||||
|
@ -70,7 +70,7 @@ public abstract class MangaConnector : GlobalBase
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Chapter latestChapterAvailable =
|
Chapter latestChapterAvailable =
|
||||||
allChapters.MaxBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint));
|
allChapters.Max();
|
||||||
manga.latestChapterAvailable =
|
manga.latestChapterAvailable =
|
||||||
Convert.ToSingle(latestChapterAvailable.chapterNumber, numberFormatDecimalPoint);
|
Convert.ToSingle(latestChapterAvailable.chapterNumber, numberFormatDecimalPoint);
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ public abstract class MangaConnector : GlobalBase
|
|||||||
/// <param name="referrer">referrer used in html request header</param>
|
/// <param name="referrer">referrer used in html request header</param>
|
||||||
private HttpStatusCode DownloadImage(string imageUrl, string fullPath, byte requestType, string? referrer = null)
|
private HttpStatusCode DownloadImage(string imageUrl, string fullPath, byte requestType, string? referrer = null)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult requestResult = downloadClient.MakeRequest(imageUrl, requestType, referrer);
|
RequestResult requestResult = downloadClient.MakeRequest(imageUrl, requestType, referrer);
|
||||||
|
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return requestResult.statusCode;
|
return requestResult.statusCode;
|
||||||
@ -283,7 +283,7 @@ public abstract class MangaConnector : GlobalBase
|
|||||||
if (File.Exists(saveImagePath))
|
if (File.Exists(saveImagePath))
|
||||||
return filename;
|
return filename;
|
||||||
|
|
||||||
DownloadClient.RequestResult coverResult = downloadClient.MakeRequest(url, requestType);
|
RequestResult coverResult = downloadClient.MakeRequest(url, requestType);
|
||||||
using MemoryStream ms = new();
|
using MemoryStream ms = new();
|
||||||
coverResult.result.CopyTo(ms);
|
coverResult.result.CopyTo(ms);
|
||||||
File.WriteAllBytes(saveImagePath, ms.ToArray());
|
File.WriteAllBytes(saveImagePath, ms.ToArray());
|
||||||
|
@ -39,7 +39,7 @@ public class MangaDex : MangaConnector
|
|||||||
while (offset < total) //As long as we haven't requested all "Pages"
|
while (offset < total) //As long as we haven't requested all "Pages"
|
||||||
{
|
{
|
||||||
//Request next Page
|
//Request next Page
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(
|
downloadClient.MakeRequest(
|
||||||
$"https://api.mangadex.org/manga?limit={limit}&title={publicationTitle}&offset={offset}", (byte)RequestType.Manga);
|
$"https://api.mangadex.org/manga?limit={limit}&title={publicationTitle}&offset={offset}", (byte)RequestType.Manga);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
@ -74,7 +74,7 @@ public class MangaDex : MangaConnector
|
|||||||
|
|
||||||
public override Manga? GetMangaFromId(string publicationId)
|
public override Manga? GetMangaFromId(string publicationId)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest($"https://api.mangadex.org/manga/{publicationId}", (byte)RequestType.Manga);
|
downloadClient.MakeRequest($"https://api.mangadex.org/manga/{publicationId}", (byte)RequestType.Manga);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return null;
|
return null;
|
||||||
@ -214,7 +214,7 @@ public class MangaDex : MangaConnector
|
|||||||
while (offset < total)
|
while (offset < total)
|
||||||
{
|
{
|
||||||
//Request next "Page"
|
//Request next "Page"
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(
|
downloadClient.MakeRequest(
|
||||||
$"https://api.mangadex.org/manga/{manga.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)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
@ -253,7 +253,7 @@ public class MangaDex : MangaConnector
|
|||||||
|
|
||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.Order().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null)
|
public override HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null)
|
||||||
@ -267,7 +267,7 @@ public class MangaDex : MangaConnector
|
|||||||
Manga chapterParentManga = chapter.parentManga;
|
Manga chapterParentManga = chapter.parentManga;
|
||||||
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
||||||
//Request URLs for Chapter-Images
|
//Request URLs for Chapter-Images
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest($"https://api.mangadex.org/at-home/server/{chapter.url}?forcePort443=false'", (byte)RequestType.AtHomeServer);
|
downloadClient.MakeRequest($"https://api.mangadex.org/at-home/server/{chapter.url}?forcePort443=false'", (byte)RequestType.AtHomeServer);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
{
|
{
|
||||||
@ -306,7 +306,7 @@ public class MangaDex : MangaConnector
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Request information where to download Cover
|
//Request information where to download Cover
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest($"https://api.mangadex.org/cover/{posterId}", (byte)RequestType.CoverUrl);
|
downloadClient.MakeRequest($"https://api.mangadex.org/cover/{posterId}", (byte)RequestType.CoverUrl);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return null;
|
return null;
|
||||||
@ -327,7 +327,7 @@ public class MangaDex : MangaConnector
|
|||||||
List<string> ret = new();
|
List<string> ret = new();
|
||||||
foreach (string authorId in authorIds)
|
foreach (string authorId in authorIds)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest($"https://api.mangadex.org/author/{authorId}", (byte)RequestType.Author);
|
downloadClient.MakeRequest($"https://api.mangadex.org/author/{authorId}", (byte)RequestType.Author);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -20,7 +20,7 @@ public class MangaKatana : MangaConnector
|
|||||||
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
||||||
string sanitizedTitle = string.Join('_', Regex.Matches(publicationTitle, "[A-z]*").Where(m => m.Value.Length > 0)).ToLower();
|
string sanitizedTitle = string.Join('_', Regex.Matches(publicationTitle, "[A-z]*").Where(m => m.Value.Length > 0)).ToLower();
|
||||||
string requestUrl = $"https://mangakatana.com/?search={sanitizedTitle}&search_by=book_name";
|
string requestUrl = $"https://mangakatana.com/?search={sanitizedTitle}&search_by=book_name";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Manga>();
|
return Array.Empty<Manga>();
|
||||||
@ -46,7 +46,7 @@ public class MangaKatana : MangaConnector
|
|||||||
|
|
||||||
public override Manga? GetMangaFromUrl(string url)
|
public override Manga? GetMangaFromUrl(string url)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(url, 1);
|
downloadClient.MakeRequest(url, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return null;
|
return null;
|
||||||
@ -157,7 +157,7 @@ public class MangaKatana : MangaConnector
|
|||||||
Log($"Getting chapters {manga}");
|
Log($"Getting chapters {manga}");
|
||||||
string requestUrl = $"https://mangakatana.com/manga/{manga.publicationId}";
|
string requestUrl = $"https://mangakatana.com/manga/{manga.publicationId}";
|
||||||
// Leaving this in for verification if the page exists
|
// Leaving this in for verification if the page exists
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
@ -165,7 +165,7 @@ public class MangaKatana : MangaConnector
|
|||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestUrl);
|
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestUrl);
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.Order().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Chapter> ParseChaptersFromHtml(Manga manga, string mangaUrl)
|
private List<Chapter> ParseChaptersFromHtml(Manga manga, string mangaUrl)
|
||||||
@ -209,7 +209,7 @@ public class MangaKatana : MangaConnector
|
|||||||
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
||||||
string requestUrl = chapter.url;
|
string requestUrl = chapter.url;
|
||||||
// Leaving this in to check if the page exists
|
// Leaving this in to check if the page exists
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ public class MangaLife : MangaConnector
|
|||||||
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
||||||
string sanitizedTitle = WebUtility.UrlEncode(publicationTitle);
|
string sanitizedTitle = WebUtility.UrlEncode(publicationTitle);
|
||||||
string requestUrl = $"https://manga4life.com/search/?name={sanitizedTitle}";
|
string requestUrl = $"https://manga4life.com/search/?name={sanitizedTitle}";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Manga>();
|
return Array.Empty<Manga>();
|
||||||
@ -42,7 +42,7 @@ public class MangaLife : MangaConnector
|
|||||||
Regex publicationIdRex = new(@"https:\/\/manga4life.com\/manga\/(.*)(\/.*)*");
|
Regex publicationIdRex = new(@"https:\/\/manga4life.com\/manga\/(.*)(\/.*)*");
|
||||||
string publicationId = publicationIdRex.Match(url).Groups[1].Value;
|
string publicationId = publicationIdRex.Match(url).Groups[1].Value;
|
||||||
|
|
||||||
DownloadClient.RequestResult requestResult = this.downloadClient.MakeRequest(url, 1);
|
RequestResult requestResult = this.downloadClient.MakeRequest(url, 1);
|
||||||
if(requestResult.htmlDocument is not null)
|
if(requestResult.htmlDocument is not null)
|
||||||
return ParseSinglePublicationFromHtml(requestResult.htmlDocument, publicationId);
|
return ParseSinglePublicationFromHtml(requestResult.htmlDocument, publicationId);
|
||||||
return null;
|
return null;
|
||||||
@ -133,7 +133,7 @@ public class MangaLife : MangaConnector
|
|||||||
public override Chapter[] GetChapters(Manga manga, string language="en")
|
public override Chapter[] GetChapters(Manga manga, string language="en")
|
||||||
{
|
{
|
||||||
Log($"Getting chapters {manga}");
|
Log($"Getting chapters {manga}");
|
||||||
DownloadClient.RequestResult result = downloadClient.MakeRequest($"https://manga4life.com/manga/{manga.publicationId}", 1);
|
RequestResult result = downloadClient.MakeRequest($"https://manga4life.com/manga/{manga.publicationId}", 1, clickButton:"[class*='ShowAllChapters']");
|
||||||
if ((int)result.statusCode < 200 || (int)result.statusCode >= 300 || result.htmlDocument is null)
|
if ((int)result.statusCode < 200 || (int)result.statusCode >= 300 || result.htmlDocument is null)
|
||||||
{
|
{
|
||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
@ -150,16 +150,16 @@ public class MangaLife : MangaConnector
|
|||||||
Match rexMatch = urlRex.Match(url);
|
Match rexMatch = urlRex.Match(url);
|
||||||
|
|
||||||
string volumeNumber = "1";
|
string volumeNumber = "1";
|
||||||
if (rexMatch.Groups.Count == 4)
|
if (rexMatch.Groups[3].Value.Length > 1)
|
||||||
volumeNumber = rexMatch.Groups[3].ToString();
|
volumeNumber = rexMatch.Groups[3].Value;
|
||||||
string chapterNumber = rexMatch.Groups[1].ToString();
|
string chapterNumber = rexMatch.Groups[1].Value;
|
||||||
string fullUrl = $"https://manga4life.com{url}";
|
string fullUrl = $"https://manga4life.com{url}";
|
||||||
fullUrl = fullUrl.Replace(Regex.Match(url,"(-page-[0-9])").Value,"");
|
fullUrl = fullUrl.Replace(Regex.Match(url,"(-page-[0-9])").Value,"");
|
||||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, fullUrl));
|
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, fullUrl));
|
||||||
}
|
}
|
||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.Order().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null)
|
public override HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null)
|
||||||
@ -179,7 +179,7 @@ public class MangaLife : MangaConnector
|
|||||||
|
|
||||||
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
||||||
|
|
||||||
DownloadClient.RequestResult requestResult = this.downloadClient.MakeRequest(chapter.url, 1);
|
RequestResult requestResult = this.downloadClient.MakeRequest(chapter.url, 1);
|
||||||
if (requestResult.htmlDocument is null)
|
if (requestResult.htmlDocument is null)
|
||||||
{
|
{
|
||||||
progressToken?.Cancel();
|
progressToken?.Cancel();
|
||||||
|
@ -20,7 +20,7 @@ public class Manganato : MangaConnector
|
|||||||
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
||||||
string sanitizedTitle = string.Join('_', Regex.Matches(publicationTitle, "[A-z]*").Where(str => str.Length > 0)).ToLower();
|
string sanitizedTitle = string.Join('_', Regex.Matches(publicationTitle, "[A-z]*").Where(str => str.Length > 0)).ToLower();
|
||||||
string requestUrl = $"https://manganato.com/search/story/{sanitizedTitle}";
|
string requestUrl = $"https://manganato.com/search/story/{sanitizedTitle}";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Manga>();
|
return Array.Empty<Manga>();
|
||||||
@ -61,7 +61,7 @@ public class Manganato : MangaConnector
|
|||||||
|
|
||||||
public override Manga? GetMangaFromUrl(string url)
|
public override Manga? GetMangaFromUrl(string url)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(url, 1);
|
downloadClient.MakeRequest(url, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return null;
|
return null;
|
||||||
@ -142,7 +142,7 @@ public class Manganato : MangaConnector
|
|||||||
{
|
{
|
||||||
Log($"Getting chapters {manga}");
|
Log($"Getting chapters {manga}");
|
||||||
string requestUrl = $"https://chapmanganato.com/{manga.publicationId}";
|
string requestUrl = $"https://chapmanganato.com/{manga.publicationId}";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
@ -152,12 +152,7 @@ public class Manganato : MangaConnector
|
|||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestResult.htmlDocument);
|
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestResult.htmlDocument);
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter =>
|
return chapters.Order().ToArray();
|
||||||
{
|
|
||||||
if (float.TryParse(chapter.chapterNumber, numberFormatDecimalPoint, out float chapterNumber))
|
|
||||||
return chapterNumber;
|
|
||||||
else return 0;
|
|
||||||
}).ToArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Chapter> ParseChaptersFromHtml(Manga manga, HtmlDocument document)
|
private List<Chapter> ParseChaptersFromHtml(Manga manga, HtmlDocument document)
|
||||||
@ -196,7 +191,7 @@ public class Manganato : MangaConnector
|
|||||||
Manga chapterParentManga = chapter.parentManga;
|
Manga chapterParentManga = chapter.parentManga;
|
||||||
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
||||||
string requestUrl = chapter.url;
|
string requestUrl = chapter.url;
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ public class Mangasee : MangaConnector
|
|||||||
{
|
{
|
||||||
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
||||||
string requestUrl = "https://mangasee123.com/_search.php";
|
string requestUrl = "https://mangasee123.com/_search.php";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
{
|
{
|
||||||
@ -121,7 +121,7 @@ public class Mangasee : MangaConnector
|
|||||||
Regex publicationIdRex = new(@"https:\/\/mangasee123.com\/manga\/(.*)(\/.*)*");
|
Regex publicationIdRex = new(@"https:\/\/mangasee123.com\/manga\/(.*)(\/.*)*");
|
||||||
string publicationId = publicationIdRex.Match(url).Groups[1].Value;
|
string publicationId = publicationIdRex.Match(url).Groups[1].Value;
|
||||||
|
|
||||||
DownloadClient.RequestResult requestResult = this.downloadClient.MakeRequest(url, 1);
|
RequestResult requestResult = this.downloadClient.MakeRequest(url, 1);
|
||||||
if(requestResult.htmlDocument is not null)
|
if(requestResult.htmlDocument is not null)
|
||||||
return ParseSinglePublicationFromHtml(requestResult.htmlDocument, publicationId);
|
return ParseSinglePublicationFromHtml(requestResult.htmlDocument, publicationId);
|
||||||
return null;
|
return null;
|
||||||
@ -206,7 +206,7 @@ public class Mangasee : MangaConnector
|
|||||||
|
|
||||||
//Return Chapters ordered by Chapter-Number
|
//Return Chapters ordered by Chapter-Number
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.Order().ToArray();
|
||||||
}
|
}
|
||||||
catch (HttpRequestException e)
|
catch (HttpRequestException e)
|
||||||
{
|
{
|
||||||
@ -232,7 +232,7 @@ public class Mangasee : MangaConnector
|
|||||||
|
|
||||||
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
||||||
|
|
||||||
DownloadClient.RequestResult requestResult = this.downloadClient.MakeRequest(chapter.url, 1);
|
RequestResult requestResult = this.downloadClient.MakeRequest(chapter.url, 1);
|
||||||
if (requestResult.htmlDocument is null)
|
if (requestResult.htmlDocument is null)
|
||||||
{
|
{
|
||||||
progressToken?.Cancel();
|
progressToken?.Cancel();
|
||||||
|
@ -20,7 +20,7 @@ public class Mangaworld: MangaConnector
|
|||||||
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
Log($"Searching Publications. Term=\"{publicationTitle}\"");
|
||||||
string sanitizedTitle = string.Join(' ', Regex.Matches(publicationTitle, "[A-z]*").Where(str => str.Length > 0)).ToLower();
|
string sanitizedTitle = string.Join(' ', Regex.Matches(publicationTitle, "[A-z]*").Where(str => str.Length > 0)).ToLower();
|
||||||
string requestUrl = $"https://www.mangaworld.bz/archive?keyword={sanitizedTitle}";
|
string requestUrl = $"https://www.mangaworld.bz/archive?keyword={sanitizedTitle}";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Manga>();
|
return Array.Empty<Manga>();
|
||||||
@ -61,7 +61,7 @@ public class Mangaworld: MangaConnector
|
|||||||
|
|
||||||
public override Manga? GetMangaFromUrl(string url)
|
public override Manga? GetMangaFromUrl(string url)
|
||||||
{
|
{
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(url, 1);
|
downloadClient.MakeRequest(url, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return null;
|
return null;
|
||||||
@ -131,7 +131,7 @@ public class Mangaworld: MangaConnector
|
|||||||
{
|
{
|
||||||
Log($"Getting chapters {manga}");
|
Log($"Getting chapters {manga}");
|
||||||
string requestUrl = $"https://www.mangaworld.bz/manga/{manga.publicationId}";
|
string requestUrl = $"https://www.mangaworld.bz/manga/{manga.publicationId}";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
@ -141,7 +141,7 @@ public class Mangaworld: MangaConnector
|
|||||||
return Array.Empty<Chapter>();
|
return Array.Empty<Chapter>();
|
||||||
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestResult.htmlDocument);
|
List<Chapter> chapters = ParseChaptersFromHtml(manga, requestResult.htmlDocument);
|
||||||
Log($"Got {chapters.Count} chapters. {manga}");
|
Log($"Got {chapters.Count} chapters. {manga}");
|
||||||
return chapters.OrderBy(chapter => Convert.ToSingle(chapter.chapterNumber, numberFormatDecimalPoint)).ToArray();
|
return chapters.Order().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Chapter> ParseChaptersFromHtml(Manga manga, HtmlDocument document)
|
private List<Chapter> ParseChaptersFromHtml(Manga manga, HtmlDocument document)
|
||||||
@ -190,7 +190,7 @@ public class Mangaworld: MangaConnector
|
|||||||
Manga chapterParentManga = chapter.parentManga;
|
Manga chapterParentManga = chapter.parentManga;
|
||||||
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
Log($"Retrieving chapter-info {chapter} {chapterParentManga}");
|
||||||
string requestUrl = $"{chapter.url}?style=list";
|
string requestUrl = $"{chapter.url}?style=list";
|
||||||
DownloadClient.RequestResult requestResult =
|
RequestResult requestResult =
|
||||||
downloadClient.MakeRequest(requestUrl, 1);
|
downloadClient.MakeRequest(requestUrl, 1);
|
||||||
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
if ((int)requestResult.statusCode < 200 || (int)requestResult.statusCode >= 300)
|
||||||
{
|
{
|
||||||
|
27
Tranga/MangaConnectors/RequestResult.cs
Normal file
27
Tranga/MangaConnectors/RequestResult.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System.Net;
|
||||||
|
using HtmlAgilityPack;
|
||||||
|
|
||||||
|
namespace Tranga.MangaConnectors;
|
||||||
|
|
||||||
|
public struct RequestResult
|
||||||
|
{
|
||||||
|
public HttpStatusCode statusCode { get; }
|
||||||
|
public Stream result { get; }
|
||||||
|
public bool hasBeenRedirected { get; }
|
||||||
|
public string? redirectedToUrl { get; }
|
||||||
|
public HtmlDocument? htmlDocument { get; }
|
||||||
|
|
||||||
|
public RequestResult(HttpStatusCode statusCode, HtmlDocument? htmlDocument, Stream result)
|
||||||
|
{
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
this.htmlDocument = htmlDocument;
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestResult(HttpStatusCode statusCode, HtmlDocument? htmlDocument, Stream result, bool hasBeenRedirected, string redirectedTo)
|
||||||
|
: this(statusCode, htmlDocument, result)
|
||||||
|
{
|
||||||
|
this.hasBeenRedirected = hasBeenRedirected;
|
||||||
|
redirectedToUrl = redirectedTo;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user