mirror of
https://github.com/C9Glax/tranga.git
synced 2025-02-23 07:40:13 +01:00
Fix #307 Chapternumbers
ChapterNumbers now can be sub-decimal, like version-numbers (x.y.z.a...)
This commit is contained in:
parent
55c0e2c4e7
commit
7cf7eb85d2
@ -10,19 +10,26 @@ public class Chapter : IComparable<Chapter>
|
|||||||
{
|
{
|
||||||
[MaxLength(64)]
|
[MaxLength(64)]
|
||||||
public string ChapterId { get; init; } = TokenGen.CreateToken(typeof(Chapter), 64);
|
public string ChapterId { get; init; } = TokenGen.CreateToken(typeof(Chapter), 64);
|
||||||
public float? VolumeNumber { get; private set; }
|
public int? VolumeNumber { get; private set; }
|
||||||
public float ChapterNumber { get; private set; }
|
public ChapterNumber ChapterNumber { get; private set; }
|
||||||
public string Url { get; internal set; }
|
public string Url { get; internal set; }
|
||||||
public string? Title { get; private set; }
|
public string? Title { get; private set; }
|
||||||
public string ArchiveFileName { get; private set; }
|
public string ArchiveFileName { get; private set; }
|
||||||
public bool Downloaded { get; internal set; } = false;
|
public bool Downloaded { get; internal set; } = false;
|
||||||
|
|
||||||
public Manga ParentManga { get; init; }
|
public string ParentMangaId { get; internal set; }
|
||||||
|
public Manga? ParentManga { get; init; }
|
||||||
|
|
||||||
public Chapter(Manga parentManga, string url, float chapterNumber,
|
public Chapter(Manga parentManga, string url, ChapterNumber chapterNumber, int? volumeNumber = null, string? title = null)
|
||||||
float? volumeNumber = null, string? title = null)
|
: this(parentManga.MangaId, url, chapterNumber, volumeNumber, title)
|
||||||
{
|
{
|
||||||
this.ParentManga = parentManga;
|
this.ParentManga = parentManga;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chapter(string parentMangaId, string url, ChapterNumber chapterNumber,
|
||||||
|
int? volumeNumber = null, string? title = null)
|
||||||
|
{
|
||||||
|
this.ParentMangaId = parentMangaId;
|
||||||
this.Url = url;
|
this.Url = url;
|
||||||
this.ChapterNumber = chapterNumber;
|
this.ChapterNumber = chapterNumber;
|
||||||
this.VolumeNumber = volumeNumber;
|
this.VolumeNumber = volumeNumber;
|
||||||
@ -30,16 +37,13 @@ public class Chapter : IComparable<Chapter>
|
|||||||
this.ArchiveFileName = BuildArchiveFileName();
|
this.ArchiveFileName = BuildArchiveFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chapter(string url, float chapterNumber, float? volumeNumber = null, string? title = null)
|
public MoveFileOrFolderJob? UpdateChapterNumber(ChapterNumber chapterNumber)
|
||||||
: this(null, url, chapterNumber, volumeNumber, title){}
|
|
||||||
|
|
||||||
public MoveFileOrFolderJob? UpdateChapterNumber(float chapterNumber)
|
|
||||||
{
|
{
|
||||||
this.ChapterNumber = chapterNumber;
|
this.ChapterNumber = chapterNumber;
|
||||||
return UpdateArchiveFileName();
|
return UpdateArchiveFileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MoveFileOrFolderJob? UpdateVolumeNumber(float? volumeNumber)
|
public MoveFileOrFolderJob? UpdateVolumeNumber(int? volumeNumber)
|
||||||
{
|
{
|
||||||
this.VolumeNumber = volumeNumber;
|
this.VolumeNumber = volumeNumber;
|
||||||
return UpdateArchiveFileName();
|
return UpdateArchiveFileName();
|
||||||
|
305
API/Schema/ChapterNumber.cs
Normal file
305
API/Schema/ChapterNumber.cs
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace API.Schema;
|
||||||
|
|
||||||
|
public readonly struct ChapterNumber : INumber<ChapterNumber>
|
||||||
|
{
|
||||||
|
private readonly uint[] _numbers;
|
||||||
|
private readonly bool _naN;
|
||||||
|
|
||||||
|
private ChapterNumber(uint[] numbers, bool naN = false)
|
||||||
|
{
|
||||||
|
this._numbers = numbers;
|
||||||
|
this._naN = naN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChapterNumber(string number)
|
||||||
|
{
|
||||||
|
if (!CanParse(number))
|
||||||
|
{
|
||||||
|
this._numbers = [];
|
||||||
|
this._naN = true;
|
||||||
|
}
|
||||||
|
this._numbers = number.Split('.').Select(uint.Parse).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChapterNumber(float number) : this(number.ToString("F")) {}
|
||||||
|
|
||||||
|
public ChapterNumber(double number) : this((float)number) {}
|
||||||
|
|
||||||
|
public ChapterNumber(uint number)
|
||||||
|
{
|
||||||
|
this._numbers = [number];
|
||||||
|
this._naN = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChapterNumber(int number)
|
||||||
|
{
|
||||||
|
if (int.IsNegative(number))
|
||||||
|
{
|
||||||
|
this._numbers = [];
|
||||||
|
this._naN = true;
|
||||||
|
}
|
||||||
|
this._numbers = [(uint)number];
|
||||||
|
this._naN = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareTo(ChapterNumber other)
|
||||||
|
{
|
||||||
|
byte index = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (this._numbers[index] < other._numbers[index])
|
||||||
|
return -1;
|
||||||
|
else if (this._numbers[index] > other._numbers[index])
|
||||||
|
return 1;
|
||||||
|
}while(index < this._numbers.Length && index < other._numbers.Length);
|
||||||
|
|
||||||
|
if (index >= this._numbers.Length && index >= other._numbers.Length)
|
||||||
|
return 0;
|
||||||
|
else if (index >= this._numbers.Length)
|
||||||
|
return -1;
|
||||||
|
else if (index >= other._numbers.Length)
|
||||||
|
return 1;
|
||||||
|
throw new UnreachableException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly Regex Pattern = new(@"[0-9]+(?:\.[0-9]+)*");
|
||||||
|
public static bool CanParse(string? number) => number is not null && Pattern.Match(number).Length == number.Length && number.Length > 0;
|
||||||
|
|
||||||
|
public bool Equals(ChapterNumber other) => CompareTo(other) == 0;
|
||||||
|
|
||||||
|
public string ToString(string? format, IFormatProvider? formatProvider)
|
||||||
|
{
|
||||||
|
return string.Join('.', _numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object? obj)
|
||||||
|
{
|
||||||
|
return obj is ChapterNumber other && Equals(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(_numbers, _naN);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format, IFormatProvider? provider)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareTo(object? obj)
|
||||||
|
{
|
||||||
|
if(obj is ChapterNumber other)
|
||||||
|
return CompareTo(other);
|
||||||
|
throw new ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChapterNumber Parse(string s, IFormatProvider? provider)
|
||||||
|
{
|
||||||
|
if(!CanParse(s))
|
||||||
|
throw new FormatException($"Invalid ChapterNumber-String: {s}");
|
||||||
|
return new ChapterNumber(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, out ChapterNumber result)
|
||||||
|
{
|
||||||
|
result = new ChapterNumber([], true);;
|
||||||
|
if (!CanParse(s))
|
||||||
|
return false;
|
||||||
|
if (s is null)
|
||||||
|
return false;
|
||||||
|
result = new ChapterNumber(s);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChapterNumber Parse(ReadOnlySpan<char> s, IFormatProvider? provider) => Parse(s.ToString(), provider);
|
||||||
|
|
||||||
|
public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out ChapterNumber result) => TryParse(s.ToString(), provider, out result);
|
||||||
|
|
||||||
|
public static ChapterNumber operator +(ChapterNumber left, ChapterNumber right)
|
||||||
|
{
|
||||||
|
if (IsNaN(left) || IsNaN(right))
|
||||||
|
return new ChapterNumber([], true);
|
||||||
|
int size = left._numbers.Length > right._numbers.Length ? left._numbers.Length : right._numbers.Length;
|
||||||
|
uint[] numbers = new uint[size];
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if(left._numbers.Length < i)
|
||||||
|
numbers[i] = right._numbers[i];
|
||||||
|
else if(right._numbers.Length < i)
|
||||||
|
numbers[i] = left._numbers[i];
|
||||||
|
else
|
||||||
|
numbers[i] = left._numbers[i] + right._numbers[i];
|
||||||
|
}
|
||||||
|
return new ChapterNumber(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool BothNotNaN(ChapterNumber left, ChapterNumber right) => !IsNaN(left) && !IsNaN(right);
|
||||||
|
|
||||||
|
public static ChapterNumber AdditiveIdentity => Zero;
|
||||||
|
|
||||||
|
public static bool operator ==(ChapterNumber left, ChapterNumber right) => BothNotNaN(left, right) && left.Equals(right);
|
||||||
|
|
||||||
|
public static bool operator !=(ChapterNumber left, ChapterNumber right) => !(left == right);
|
||||||
|
|
||||||
|
public static bool operator >(ChapterNumber left, ChapterNumber right) => BothNotNaN(left, right) && left.CompareTo(right) > 0;
|
||||||
|
|
||||||
|
public static bool operator >=(ChapterNumber left, ChapterNumber right) => BothNotNaN(left, right) && left.CompareTo(right) >= 0;
|
||||||
|
|
||||||
|
public static bool operator <(ChapterNumber left, ChapterNumber right) => BothNotNaN(left, right) && left.CompareTo(right) < 0;
|
||||||
|
|
||||||
|
public static bool operator <=(ChapterNumber left, ChapterNumber right) => BothNotNaN(left, right) && left.CompareTo(right) <= 0;
|
||||||
|
|
||||||
|
public static ChapterNumber operator %(ChapterNumber left, ChapterNumber right) => throw new ArithmeticException();
|
||||||
|
|
||||||
|
public static ChapterNumber operator +(ChapterNumber value) => throw new InvalidOperationException();
|
||||||
|
|
||||||
|
public static ChapterNumber operator --(ChapterNumber value)
|
||||||
|
{
|
||||||
|
if (IsNaN(value))
|
||||||
|
return value;
|
||||||
|
uint[] numbers = value._numbers;
|
||||||
|
numbers[0]--;
|
||||||
|
return new ChapterNumber(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChapterNumber operator /(ChapterNumber left, ChapterNumber right) => throw new InvalidOperationException();
|
||||||
|
|
||||||
|
public static ChapterNumber operator ++(ChapterNumber value)
|
||||||
|
{
|
||||||
|
if (IsNaN(value))
|
||||||
|
return value;
|
||||||
|
uint[] numbers = value._numbers;
|
||||||
|
numbers[0]++;
|
||||||
|
return new ChapterNumber(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChapterNumber MultiplicativeIdentity => One;
|
||||||
|
public static ChapterNumber operator *(ChapterNumber left, ChapterNumber right) => throw new InvalidOperationException();
|
||||||
|
|
||||||
|
public static ChapterNumber operator -(ChapterNumber left, ChapterNumber right) => throw new InvalidOperationException();
|
||||||
|
|
||||||
|
public static ChapterNumber operator -(ChapterNumber value) => throw new InvalidOperationException();
|
||||||
|
|
||||||
|
public static ChapterNumber Abs(ChapterNumber value) => value;
|
||||||
|
|
||||||
|
public static bool IsCanonical(ChapterNumber value) => true;
|
||||||
|
|
||||||
|
public static bool IsComplexNumber(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsEvenInteger(ChapterNumber value) => IsInteger(value) && uint.IsEvenInteger(value._numbers[0]);
|
||||||
|
|
||||||
|
public static bool IsFinite(ChapterNumber value) => true;
|
||||||
|
|
||||||
|
public static bool IsImaginaryNumber(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsInfinity(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsInteger(ChapterNumber value) => !IsNaN(value) && value._numbers.Length == 1;
|
||||||
|
|
||||||
|
public static bool IsNaN(ChapterNumber value) => value._naN;
|
||||||
|
|
||||||
|
public static bool IsNegative(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsNegativeInfinity(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsNormal(ChapterNumber value) => true;
|
||||||
|
|
||||||
|
public static bool IsOddInteger(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsPositive(ChapterNumber value) => true;
|
||||||
|
|
||||||
|
public static bool IsPositiveInfinity(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsRealNumber(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsSubnormal(ChapterNumber value) => false;
|
||||||
|
|
||||||
|
public static bool IsZero(ChapterNumber value) => value._numbers.All(n => n == 0);
|
||||||
|
|
||||||
|
public static ChapterNumber MaxMagnitude(ChapterNumber x, ChapterNumber y)
|
||||||
|
{
|
||||||
|
if(IsNaN(x))
|
||||||
|
return new ChapterNumber([], true);
|
||||||
|
if (IsNaN(y))
|
||||||
|
return new ChapterNumber([], true);
|
||||||
|
return x >= y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChapterNumber MaxMagnitudeNumber(ChapterNumber x, ChapterNumber y)
|
||||||
|
{
|
||||||
|
if (IsNaN(x))
|
||||||
|
return y;
|
||||||
|
if (IsNaN(y))
|
||||||
|
return x;
|
||||||
|
return x >= y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChapterNumber MinMagnitude(ChapterNumber x, ChapterNumber y)
|
||||||
|
{
|
||||||
|
if(IsNaN(x))
|
||||||
|
return new ChapterNumber([], true);
|
||||||
|
if (IsNaN(y))
|
||||||
|
return new ChapterNumber([], true);
|
||||||
|
return x <= y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChapterNumber MinMagnitudeNumber(ChapterNumber x, ChapterNumber y)
|
||||||
|
{
|
||||||
|
if (IsNaN(x))
|
||||||
|
return y;
|
||||||
|
if (IsNaN(y))
|
||||||
|
return x;
|
||||||
|
return x <= y ? x : y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChapterNumber Parse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public static ChapterNumber Parse(string s, NumberStyles style, IFormatProvider? provider) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public static bool TryConvertFromChecked<TOther>(TOther value, out ChapterNumber result) where TOther : INumberBase<TOther>
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryConvertFromSaturating<TOther>(TOther value, out ChapterNumber result) where TOther : INumberBase<TOther>
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryConvertFromTruncating<TOther>(TOther value, out ChapterNumber result) where TOther : INumberBase<TOther>
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryConvertToChecked<TOther>(ChapterNumber value, [MaybeNullWhen(false)] out TOther result) where TOther : INumberBase<TOther>
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryConvertToSaturating<TOther>(ChapterNumber value, [MaybeNullWhen(false)] out TOther result) where TOther : INumberBase<TOther>
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryConvertToTruncating<TOther>(ChapterNumber value, [MaybeNullWhen(false)] out TOther result) where TOther : INumberBase<TOther>
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryParse(ReadOnlySpan<char> s, NumberStyles style, IFormatProvider? provider, out ChapterNumber result)
|
||||||
|
=> TryParse(s.ToString(), style, provider, out result);
|
||||||
|
|
||||||
|
public static bool TryParse([NotNullWhen(true)] string? s, NumberStyles style, IFormatProvider? provider, out ChapterNumber result)
|
||||||
|
=> TryParse(s, provider, out result);
|
||||||
|
|
||||||
|
public static ChapterNumber One => new(1);
|
||||||
|
public static int Radix => 10;
|
||||||
|
public static ChapterNumber Zero => new(0);
|
||||||
|
}
|
@ -152,7 +152,9 @@ public class AsuraToon : MangaConnector
|
|||||||
string chapterUrl = chapterInfo.GetAttributeValue("href", "");
|
string chapterUrl = chapterInfo.GetAttributeValue("href", "");
|
||||||
|
|
||||||
Match match = infoRex.Match(chapterInfo.InnerText);
|
Match match = infoRex.Match(chapterInfo.InnerText);
|
||||||
float chapterNumber = float.Parse(match.Groups[1].Value);
|
if(!ChapterNumber.CanParse(match.Groups[1].Value))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(match.Groups[1].Value);
|
||||||
string? chapterName = match.Groups[2].Success && match.Groups[2].Length > 1 ? match.Groups[2].Value : null;
|
string? chapterName = match.Groups[2].Success && match.Groups[2].Length > 1 ? match.Groups[2].Value : null;
|
||||||
string url = $"https://asuracomic.net/series/{chapterUrl}";
|
string url = $"https://asuracomic.net/series/{chapterUrl}";
|
||||||
try
|
try
|
||||||
|
@ -158,8 +158,10 @@ public class Bato : MangaConnector
|
|||||||
|
|
||||||
Match match = numberRex.Match(chapterUrl);
|
Match match = numberRex.Match(chapterUrl);
|
||||||
string id = match.Groups[1].Value;
|
string id = match.Groups[1].Value;
|
||||||
float? volumeNumber = match.Groups[2].Success ? float.Parse(match.Groups[2].Value) : null;
|
int? volumeNumber = match.Groups[2].Success ? int.Parse(match.Groups[2].Value) : null;
|
||||||
float chapterNumber = float.Parse(match.Groups[3].Value);
|
if(ChapterNumber.CanParse(match.Groups[3].Value))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(match.Groups[3].Value);
|
||||||
string url = $"https://bato.to{chapterUrl}?load=2";
|
string url = $"https://bato.to{chapterUrl}?load=2";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -221,13 +221,17 @@ public class MangaDex : MangaConnector
|
|||||||
? attributes["title"]!.GetValue<string>()
|
? attributes["title"]!.GetValue<string>()
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
float? volume = attributes.ContainsKey("volume") && attributes["volume"] is not null
|
int? volume = attributes.ContainsKey("volume") && attributes["volume"] is not null
|
||||||
? float.Parse(attributes["volume"]!.GetValue<string>())
|
? int.Parse(attributes["volume"]!.GetValue<string>())
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
float chapterNum = attributes.ContainsKey("chapter") && attributes["chapter"] is not null
|
string? chapterNumStr = attributes.ContainsKey("chapter") && attributes["chapter"] is not null
|
||||||
? float.Parse(attributes["chapter"]!.GetValue<string>())
|
? attributes["chapter"]!.GetValue<string>()
|
||||||
: 0;
|
: null;
|
||||||
|
|
||||||
|
if(chapterNumStr is null || ChapterNumber.CanParse(chapterNumStr))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(chapterNumStr);
|
||||||
|
|
||||||
|
|
||||||
if (attributes.ContainsKey("pages") && attributes["pages"] is not null &&
|
if (attributes.ContainsKey("pages") && attributes["pages"] is not null &&
|
||||||
@ -238,7 +242,7 @@ public class MangaDex : MangaConnector
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Chapter newChapter = new Chapter(manga, url, chapterNum, volume, title);
|
Chapter newChapter = new Chapter(manga, url, chapterNumber, volume, title);
|
||||||
if(!chapters.Contains(newChapter))
|
if(!chapters.Contains(newChapter))
|
||||||
chapters.Add(newChapter);
|
chapters.Add(newChapter);
|
||||||
}
|
}
|
||||||
|
@ -127,8 +127,10 @@ public class MangaHere : MangaConnector
|
|||||||
{
|
{
|
||||||
Match rexMatch = chapterRex.Match(url);
|
Match rexMatch = chapterRex.Match(url);
|
||||||
|
|
||||||
float? volumeNumber = rexMatch.Groups[1].Value == "TBD" ? null : float.Parse(rexMatch.Groups[1].Value);
|
int? volumeNumber = rexMatch.Groups[1].Value == "TBD" ? null : int.Parse(rexMatch.Groups[1].Value);
|
||||||
float chapterNumber = float.Parse(rexMatch.Groups[2].Value);
|
if(!ChapterNumber.CanParse(rexMatch.Groups[2].Value))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(rexMatch.Groups[2].Value);
|
||||||
string fullUrl = $"https://www.mangahere.cc{url}";
|
string fullUrl = $"https://www.mangahere.cc{url}";
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -184,8 +184,10 @@ public class MangaKatana : MangaConnector
|
|||||||
string url = chapterInfo.Descendants("a").First()
|
string url = chapterInfo.Descendants("a").First()
|
||||||
.GetAttributeValue("href", "");
|
.GetAttributeValue("href", "");
|
||||||
|
|
||||||
float? volumeNumber = volumeRex.IsMatch(url) ? float.Parse(volumeRex.Match(url).Groups[1].Value) : null;
|
int? volumeNumber = volumeRex.IsMatch(url) ? int.Parse(volumeRex.Match(url).Groups[1].Value) : null;
|
||||||
float chapterNumber = float.Parse(chapterNumRex.Match(url).Groups[1].Value);
|
if(!ChapterNumber.CanParse(chapterNumRex.Match(url).Groups[1].Value))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(chapterNumRex.Match(url).Groups[1].Value);
|
||||||
string chapterName = chapterNameRex.Match(fullString).Groups[1].Value;
|
string chapterName = chapterNameRex.Match(fullString).Groups[1].Value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -147,9 +147,13 @@ public class MangaLife : MangaConnector
|
|||||||
{
|
{
|
||||||
Match rexMatch = urlRex.Match(url);
|
Match rexMatch = urlRex.Match(url);
|
||||||
|
|
||||||
float? volumeNumber = rexMatch.Groups[3].Success && rexMatch.Groups[3].Value.Length > 0 ?
|
int? volumeNumber = rexMatch.Groups[3].Success && rexMatch.Groups[3].Value.Length > 0
|
||||||
float.Parse(rexMatch.Groups[3].Value) : null;
|
? int.Parse(rexMatch.Groups[3].Value)
|
||||||
float chapterNumber = float.Parse(rexMatch.Groups[1].Value);
|
: null;
|
||||||
|
|
||||||
|
if(!ChapterNumber.CanParse(rexMatch.Groups[1].Value))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(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,"");
|
||||||
try
|
try
|
||||||
|
@ -178,8 +178,12 @@ public class Manganato : MangaConnector
|
|||||||
string url = chapterInfo.Descendants("a").First(d => d.HasClass("chapter-name"))
|
string url = chapterInfo.Descendants("a").First(d => d.HasClass("chapter-name"))
|
||||||
.GetAttributeValue("href", "");
|
.GetAttributeValue("href", "");
|
||||||
|
|
||||||
float? volumeNumber = volRex.IsMatch(fullString) ? float.Parse(volRex.Match(fullString).Groups[1].Value) : null;
|
int? volumeNumber = volRex.IsMatch(fullString)
|
||||||
float chapterNumber = float.Parse(chapterRex.Match(url).Groups[1].Value);
|
? int.Parse(volRex.Match(fullString).Groups[1].Value)
|
||||||
|
: null;
|
||||||
|
if(!ChapterNumber.CanParse(chapterRex.Match(url).Groups[1].Value))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(chapterRex.Match(url).Groups[1].Value);
|
||||||
string chapterName = nameRex.Match(fullString).Groups[3].Value;
|
string chapterName = nameRex.Match(fullString).Groups[3].Value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -171,8 +171,10 @@ public class Mangasee : MangaConnector
|
|||||||
{
|
{
|
||||||
string url = chapter.Descendants("link").First().Value;
|
string url = chapter.Descendants("link").First().Value;
|
||||||
Match m = chVolRex.Match(url);
|
Match m = chVolRex.Match(url);
|
||||||
float? volumeNumber = m.Groups[2].Success ? float.Parse(m.Groups[2].Value) : null;
|
int? volumeNumber = m.Groups[2].Success ? int.Parse(m.Groups[2].Value) : null;
|
||||||
float chapterNumber = float.Parse(m.Groups[1].Value);
|
if(!ChapterNumber.CanParse(m.Groups[1].Value))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(m.Groups[1].Value);
|
||||||
|
|
||||||
string chapterUrl = Regex.Replace(url, @"-page-[0-9]+(\.html)", ".html");
|
string chapterUrl = Regex.Replace(url, @"-page-[0-9]+(\.html)", ".html");
|
||||||
try
|
try
|
||||||
|
@ -154,17 +154,19 @@ public class Mangaworld : MangaConnector
|
|||||||
foreach (HtmlNode volNode in document.DocumentNode.SelectNodes("//div[contains(concat(' ',normalize-space(@class),' '),'volume-element')]"))
|
foreach (HtmlNode volNode in document.DocumentNode.SelectNodes("//div[contains(concat(' ',normalize-space(@class),' '),'volume-element')]"))
|
||||||
{
|
{
|
||||||
string volumeStr = volumeRex.Match(volNode.SelectNodes("div").First(node => node.HasClass("volume")).SelectSingleNode("p").InnerText).Groups[1].Value;
|
string volumeStr = volumeRex.Match(volNode.SelectNodes("div").First(node => node.HasClass("volume")).SelectSingleNode("p").InnerText).Groups[1].Value;
|
||||||
float volume = float.Parse(volumeStr);
|
int volume = int.Parse(volumeStr);
|
||||||
foreach (HtmlNode chNode in volNode.SelectNodes("div").First(node => node.HasClass("volume-chapters")).SelectNodes("div"))
|
foreach (HtmlNode chNode in volNode.SelectNodes("div").First(node => node.HasClass("volume-chapters")).SelectNodes("div"))
|
||||||
{
|
{
|
||||||
|
|
||||||
string numberStr = chapterRex.Match(chNode.SelectSingleNode("a").SelectSingleNode("span").InnerText).Groups[1].Value;
|
string numberStr = chapterRex.Match(chNode.SelectSingleNode("a").SelectSingleNode("span").InnerText).Groups[1].Value;
|
||||||
float chapter = float.Parse(numberStr);
|
if(!ChapterNumber.CanParse(numberStr))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(numberStr);
|
||||||
string url = chNode.SelectSingleNode("a").GetAttributeValue("href", "");
|
string url = chNode.SelectSingleNode("a").GetAttributeValue("href", "");
|
||||||
string id = idRex.Match(chNode.SelectSingleNode("a").GetAttributeValue("href", "")).Groups[1].Value;
|
string id = idRex.Match(chNode.SelectSingleNode("a").GetAttributeValue("href", "")).Groups[1].Value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ret.Add(new Chapter(manga, url, chapter, volume, null));
|
ret.Add(new Chapter(manga, url, chapterNumber, volume, null));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -177,12 +179,14 @@ public class Mangaworld : MangaConnector
|
|||||||
foreach (HtmlNode chNode in chaptersWrapper.SelectNodes("div").Where(node => node.HasClass("chapter")))
|
foreach (HtmlNode chNode in chaptersWrapper.SelectNodes("div").Where(node => node.HasClass("chapter")))
|
||||||
{
|
{
|
||||||
string numberStr = chapterRex.Match(chNode.SelectSingleNode("a").SelectSingleNode("span").InnerText).Groups[1].Value;
|
string numberStr = chapterRex.Match(chNode.SelectSingleNode("a").SelectSingleNode("span").InnerText).Groups[1].Value;
|
||||||
float chapter = float.Parse(numberStr);
|
if(!ChapterNumber.CanParse(numberStr))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(numberStr);
|
||||||
string url = chNode.SelectSingleNode("a").GetAttributeValue("href", "");
|
string url = chNode.SelectSingleNode("a").GetAttributeValue("href", "");
|
||||||
string id = idRex.Match(chNode.SelectSingleNode("a").GetAttributeValue("href", "")).Groups[1].Value;
|
string id = idRex.Match(chNode.SelectSingleNode("a").GetAttributeValue("href", "")).Groups[1].Value;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ret.Add(new Chapter(manga, url, chapter, null, null));
|
ret.Add(new Chapter(manga, url, chapterNumber, null, null));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -148,7 +148,9 @@ public class ManhuaPlus : MangaConnector
|
|||||||
{
|
{
|
||||||
Match rexMatch = urlRex.Match(url);
|
Match rexMatch = urlRex.Match(url);
|
||||||
|
|
||||||
float chapterNumber = float.Parse(rexMatch.Groups[1].Value);
|
if(!ChapterNumber.CanParse(rexMatch.Groups[1].Value))
|
||||||
|
continue;
|
||||||
|
ChapterNumber chapterNumber = new(rexMatch.Groups[1].Value);
|
||||||
string fullUrl = url;
|
string fullUrl = url;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -182,7 +182,7 @@ public class Weebcentral : MangaConnector
|
|||||||
var url = elem.GetAttributeValue("href", "") ?? "Undefined";
|
var url = elem.GetAttributeValue("href", "") ?? "Undefined";
|
||||||
|
|
||||||
if (!url.StartsWith("https://") && !url.StartsWith("http://"))
|
if (!url.StartsWith("https://") && !url.StartsWith("http://"))
|
||||||
return new Chapter(manga, "undefined", -1, null, null);
|
return new Chapter(manga, "undefined", new ChapterNumber(-1), null, null);
|
||||||
|
|
||||||
var idMatch = idRex.Match(url);
|
var idMatch = idRex.Match(url);
|
||||||
var id = idMatch.Success ? idMatch.Groups[1].Value : null;
|
var id = idMatch.Success ? idMatch.Groups[1].Value : null;
|
||||||
@ -191,10 +191,13 @@ public class Weebcentral : MangaConnector
|
|||||||
"Undefined";
|
"Undefined";
|
||||||
|
|
||||||
var chapterNumberMatch = chapterRex.Match(chapterNode);
|
var chapterNumberMatch = chapterRex.Match(chapterNode);
|
||||||
var chapterNumber = chapterNumberMatch.Success ? float.Parse(chapterNumberMatch.Groups[1].Value) : -1;
|
|
||||||
|
|
||||||
|
if(!chapterNumberMatch.Success || !ChapterNumber.CanParse(chapterNumberMatch.Groups[1].Value))
|
||||||
|
return new Chapter(manga, "undefined", new ChapterNumber(-1), null, null);
|
||||||
|
ChapterNumber chapterNumber = new(chapterNumberMatch.Groups[1].Value);
|
||||||
|
|
||||||
return new Chapter(manga, url, chapterNumber, null, null);
|
return new Chapter(manga, url, chapterNumber, null, null);
|
||||||
}).Where(elem => elem.ChapterNumber < 0 && elem.Url != "undefined").ToList();
|
}).Where(elem => elem.ChapterNumber < ChapterNumber.Zero && elem.Url != "undefined").ToList();
|
||||||
|
|
||||||
ret.Reverse();
|
ret.Reverse();
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user