mirror of
https://github.com/C9Glax/tranga.git
synced 2025-01-12 03:17:33 +01:00
Chapter volume and chapternumber as float instead of string.
Possible fix #293
This commit is contained in:
parent
025d43b752
commit
1e6a65c0fd
@ -14,8 +14,8 @@ public readonly struct Chapter : IComparable
|
||||
// ReSharper disable once MemberCanBePrivate.Global
|
||||
public Manga parentManga { get; }
|
||||
public string? name { get; }
|
||||
public string volumeNumber { get; }
|
||||
public string chapterNumber { get; }
|
||||
public float volumeNumber { get; }
|
||||
public float chapterNumber { get; }
|
||||
public string url { get; }
|
||||
// ReSharper disable once MemberCanBePrivate.Global
|
||||
public string fileName { get; }
|
||||
@ -23,13 +23,19 @@ public readonly struct Chapter : IComparable
|
||||
|
||||
private static readonly Regex LegalCharacters = new (@"([A-z]*[0-9]* *\.*-*,*\]*\[*'*\'*\)*\(*~*!*)*");
|
||||
private static readonly Regex IllegalStrings = new(@"(Vol(ume)?|Ch(apter)?)\.?", RegexOptions.IgnoreCase);
|
||||
private static readonly Regex Digits = new(@"[0-9\.]*");
|
||||
|
||||
public Chapter(Manga parentManga, string? name, string? volumeNumber, string chapterNumber, string url, string? id = null)
|
||||
: this(parentManga, name, float.Parse(volumeNumber??"0", GlobalBase.numberFormatDecimalPoint),
|
||||
float.Parse(chapterNumber, GlobalBase.numberFormatDecimalPoint), url, id)
|
||||
{
|
||||
}
|
||||
|
||||
public Chapter(Manga parentManga, string? name, float? volumeNumber, float chapterNumber, string url, string? id = null)
|
||||
{
|
||||
this.parentManga = parentManga;
|
||||
this.name = name;
|
||||
this.volumeNumber = volumeNumber is not null ? string.Concat(Digits.Matches(volumeNumber).Select(x => x.Value)) : "0";
|
||||
this.chapterNumber = string.Concat(Digits.Matches(chapterNumber).Select(x => x.Value));
|
||||
this.volumeNumber = volumeNumber??0;
|
||||
this.chapterNumber = chapterNumber;
|
||||
this.url = url;
|
||||
this.id = id;
|
||||
|
||||
@ -60,26 +66,12 @@ public readonly struct Chapter : IComparable
|
||||
{
|
||||
if(obj is not Chapter otherChapter)
|
||||
throw new ArgumentException($"{obj} can not be compared to {this}");
|
||||
|
||||
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))
|
||||
return volumeNumber.CompareTo(otherChapter.volumeNumber) switch
|
||||
{
|
||||
return volumeNumberFloat.CompareTo(otherVolumeNumberFloat) switch
|
||||
{
|
||||
<0 => -1,
|
||||
>0 => 1,
|
||||
_ => chapterNumberFloat.CompareTo(otherChapterNumberFloat)
|
||||
};
|
||||
}
|
||||
else throw new FormatException($"Value could not be parsed.\n" +
|
||||
$"\tVolumeNumber: '{volumeNumber}' ChapterNumber: '{chapterNumber}'\n" +
|
||||
$"\tOther-VolumeNumber: '{otherChapter.volumeNumber}' Other-ChapterNumber: '{otherChapter.chapterNumber}'\n" +
|
||||
$"\t{this}\n" +
|
||||
$"\t{otherChapter}");
|
||||
<0 => -1,
|
||||
>0 => 1,
|
||||
_ => chapterNumber.CompareTo(otherChapter.chapterNumber)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -111,9 +103,10 @@ public readonly struct Chapter : IComparable
|
||||
{
|
||||
Match m = volChRex.Match(archive.Name);
|
||||
if (m.Groups[1].Success)
|
||||
return m.Groups[1].Value == t.volumeNumber && m.Groups[2].Value == t.chapterNumber;
|
||||
return m.Groups[1].Value == t.volumeNumber.ToString(GlobalBase.numberFormatDecimalPoint) &&
|
||||
m.Groups[2].Value == t.chapterNumber.ToString(GlobalBase.numberFormatDecimalPoint);
|
||||
else
|
||||
return m.Groups[2].Value == t.chapterNumber;
|
||||
return m.Groups[2].Value == t.chapterNumber.ToString(GlobalBase.numberFormatDecimalPoint);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ public class JobBoss : GlobalBase
|
||||
RemoveJob(job);
|
||||
}
|
||||
|
||||
public IEnumerable<Job> GetJobsLike(string? connectorName = null, string? internalId = null, string? chapterNumber = null)
|
||||
public IEnumerable<Job> GetJobsLike(string? connectorName = null, string? internalId = null, float? chapterNumber = null)
|
||||
{
|
||||
IEnumerable<Job> ret = this.jobs;
|
||||
if (connectorName is not null)
|
||||
@ -82,7 +82,7 @@ public class JobBoss : GlobalBase
|
||||
if (jjob is not DownloadChapter job)
|
||||
return false;
|
||||
return job.chapter.parentManga.internalId == internalId &&
|
||||
job.chapter.chapterNumber == chapterNumber;
|
||||
job.chapter.chapterNumber.Equals(chapterNumber);
|
||||
});
|
||||
else if (internalId is not null)
|
||||
ret = ret.Where(jjob =>
|
||||
|
@ -155,7 +155,14 @@ public class AsuraToon : MangaConnector
|
||||
string chapterNumber = match.Groups[1].Value;
|
||||
string? chapterName = match.Groups[2].Success && match.Groups[2].Length > 1 ? match.Groups[2].Value : null;
|
||||
string url = $"https://asuracomic.net/series/{chapterUrl}";
|
||||
ret.Add(new Chapter(manga, chapterName, null, chapterNumber, url));
|
||||
try
|
||||
{
|
||||
ret.Add(new Chapter(manga, chapterName, null, chapterNumber, url));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNumber}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -163,7 +163,14 @@ public class Bato : MangaConnector
|
||||
string chapterNumber = match.Groups[3].Value;
|
||||
string chapterName = chapterNumber;
|
||||
string url = $"https://bato.to{chapterUrl}?load=2";
|
||||
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));
|
||||
try
|
||||
{
|
||||
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNumber}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -60,8 +60,7 @@ public abstract class MangaConnector : GlobalBase
|
||||
return Array.Empty<Chapter>();
|
||||
|
||||
Log($"Checking for duplicates {manga}");
|
||||
List<Chapter> newChaptersList = allChapters.Where(nChapter => float.TryParse(nChapter.chapterNumber, numberFormatDecimalPoint, out float chapterNumber)
|
||||
&& chapterNumber > manga.ignoreChaptersBelow
|
||||
List<Chapter> newChaptersList = allChapters.Where(nChapter => nChapter.chapterNumber > manga.ignoreChaptersBelow
|
||||
&& !nChapter.CheckChapterIsDownloaded()).ToList();
|
||||
Log($"{newChaptersList.Count} new chapters. {manga}");
|
||||
try
|
||||
@ -79,79 +78,6 @@ public abstract class MangaConnector : GlobalBase
|
||||
|
||||
return newChaptersList.ToArray();
|
||||
}
|
||||
|
||||
public Chapter[] SelectChapters(Manga manga, string searchTerm, string? language = null)
|
||||
{
|
||||
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);
|
||||
Regex rangeResultRegex = new("([0-9]+(-[0-9]+))", RegexOptions.IgnoreCase);
|
||||
Regex allRegex = new("a(ll)?", RegexOptions.IgnoreCase);
|
||||
if (volumeRegex.IsMatch(searchTerm) && chapterRegex.IsMatch(searchTerm))
|
||||
{
|
||||
string volume = singleResultRegex.Match(volumeRegex.Match(searchTerm).Value).Value;
|
||||
string chapter = singleResultRegex.Match(chapterRegex.Match(searchTerm).Value).Value;
|
||||
return availableChapters.Where(aCh => aCh.volumeNumber is not null &&
|
||||
aCh.volumeNumber.Equals(volume, StringComparison.InvariantCultureIgnoreCase) &&
|
||||
aCh.chapterNumber.Equals(chapter, StringComparison.InvariantCultureIgnoreCase))
|
||||
.ToArray();
|
||||
}
|
||||
else if (volumeRegex.IsMatch(searchTerm))
|
||||
{
|
||||
string volume = volumeRegex.Match(searchTerm).Value;
|
||||
if (rangeResultRegex.IsMatch(volume))
|
||||
{
|
||||
string range = rangeResultRegex.Match(volume).Value;
|
||||
int start = Convert.ToInt32(range.Split('-')[0]);
|
||||
int end = Convert.ToInt32(range.Split('-')[1]);
|
||||
return availableChapters.Where(aCh => aCh.volumeNumber is not null &&
|
||||
Convert.ToInt32(aCh.volumeNumber) >= start &&
|
||||
Convert.ToInt32(aCh.volumeNumber) <= end).ToArray();
|
||||
}
|
||||
else if (singleResultRegex.IsMatch(volume))
|
||||
{
|
||||
string volumeNumber = singleResultRegex.Match(volume).Value;
|
||||
return availableChapters.Where(aCh =>
|
||||
aCh.volumeNumber is not null &&
|
||||
aCh.volumeNumber.Equals(volumeNumber, StringComparison.InvariantCultureIgnoreCase)).ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
else if (chapterRegex.IsMatch(searchTerm))
|
||||
{
|
||||
string chapter = chapterRegex.Match(searchTerm).Value;
|
||||
if (rangeResultRegex.IsMatch(chapter))
|
||||
{
|
||||
string range = rangeResultRegex.Match(chapter).Value;
|
||||
int start = Convert.ToInt32(range.Split('-')[0]);
|
||||
int end = Convert.ToInt32(range.Split('-')[1]);
|
||||
return availableChapters.Where(aCh => Convert.ToInt32(aCh.chapterNumber) >= start &&
|
||||
Convert.ToInt32(aCh.chapterNumber) <= end).ToArray();
|
||||
}
|
||||
else if (singleResultRegex.IsMatch(chapter))
|
||||
{
|
||||
string chapterNumber = singleResultRegex.Match(chapter).Value;
|
||||
return availableChapters.Where(aCh =>
|
||||
aCh.chapterNumber.Equals(chapterNumber, StringComparison.InvariantCultureIgnoreCase)).ToArray();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rangeResultRegex.IsMatch(searchTerm))
|
||||
{
|
||||
int start = Convert.ToInt32(searchTerm.Split('-')[0]);
|
||||
int end = Convert.ToInt32(searchTerm.Split('-')[1]);
|
||||
return availableChapters[start..(end + 1)];
|
||||
}
|
||||
else if(singleResultRegex.IsMatch(searchTerm))
|
||||
return new [] { availableChapters[Convert.ToInt32(searchTerm)] };
|
||||
else if (allRegex.IsMatch(searchTerm))
|
||||
return availableChapters;
|
||||
}
|
||||
|
||||
return Array.Empty<Chapter>();
|
||||
}
|
||||
|
||||
public abstract HttpStatusCode DownloadChapter(Chapter chapter, ProgressToken? progressToken = null);
|
||||
|
||||
|
@ -246,8 +246,17 @@ public class MangaDex : MangaConnector
|
||||
continue;
|
||||
}
|
||||
|
||||
if(chapterNum is not "null" && !chapters.Any(chp => chp.volumeNumber.Equals(volume) && chp.chapterNumber.Equals(chapterNum)))
|
||||
try
|
||||
{
|
||||
if(!chapters.Any(chp =>
|
||||
chp.volumeNumber.Equals(float.Parse(volume??"0", numberFormatDecimalPoint)) &&
|
||||
chp.chapterNumber.Equals(float.Parse(chapterNum, numberFormatDecimalPoint))))
|
||||
chapters.Add(new Chapter(manga, title, volume, chapterNum, chapterId, chapterId));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNum}: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,15 @@ public class MangaHere : MangaConnector
|
||||
string volumeNumber = rexMatch.Groups[1].Value == "TBD" ? "0" : rexMatch.Groups[1].Value;
|
||||
string chapterNumber = rexMatch.Groups[2].Value;
|
||||
string fullUrl = $"https://www.mangahere.cc{url}";
|
||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, fullUrl));
|
||||
|
||||
try
|
||||
{
|
||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, fullUrl));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNumber}: {e.Message}");
|
||||
}
|
||||
}
|
||||
//Return Chapters ordered by Chapter-Number
|
||||
Log($"Got {chapters.Count} chapters. {manga}");
|
||||
|
@ -186,7 +186,14 @@ public class MangaKatana : MangaConnector
|
||||
string? volumeNumber = volumeRex.IsMatch(url) ? volumeRex.Match(url).Groups[1].Value : null;
|
||||
string chapterNumber = chapterNumRex.Match(url).Groups[1].Value;
|
||||
string chapterName = chapterNameRex.Match(fullString).Groups[1].Value;
|
||||
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));
|
||||
try
|
||||
{
|
||||
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNumber}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -152,7 +152,14 @@ public class MangaLife : MangaConnector
|
||||
string chapterNumber = rexMatch.Groups[1].Value;
|
||||
string fullUrl = $"https://manga4life.com{url}";
|
||||
fullUrl = fullUrl.Replace(Regex.Match(url,"(-page-[0-9])").Value,"");
|
||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, fullUrl));
|
||||
try
|
||||
{
|
||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, fullUrl));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNumber}: {e.Message}");
|
||||
}
|
||||
}
|
||||
//Return Chapters ordered by Chapter-Number
|
||||
Log($"Got {chapters.Count} chapters. {manga}");
|
||||
|
@ -181,7 +181,14 @@ public class Manganato : MangaConnector
|
||||
string? volumeNumber = volRex.IsMatch(fullString) ? volRex.Match(fullString).Groups[1].Value : null;
|
||||
string chapterNumber = chapterRex.Match(url).Groups[1].Value;
|
||||
string chapterName = nameRex.Match(fullString).Groups[3].Value;
|
||||
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));
|
||||
try
|
||||
{
|
||||
ret.Add(new Chapter(manga, chapterName, volumeNumber, chapterNumber, url));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNumber}: {e.Message}");
|
||||
}
|
||||
}
|
||||
ret.Reverse();
|
||||
return ret;
|
||||
|
@ -176,7 +176,14 @@ public class Mangasee : MangaConnector
|
||||
string chapterNumber = m.Groups[1].Value;
|
||||
|
||||
string chapterUrl = Regex.Replace(url, @"-page-[0-9]+(\.html)", ".html");
|
||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, chapterUrl));
|
||||
try
|
||||
{
|
||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, chapterUrl));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNumber}: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
//Return Chapters ordered by Chapter-Number
|
||||
|
@ -163,7 +163,14 @@ public class Mangaworld: MangaConnector
|
||||
string number = chapterRex.Match(chNode.SelectSingleNode("a").SelectSingleNode("span").InnerText).Groups[1].Value;
|
||||
string url = chNode.SelectSingleNode("a").GetAttributeValue("href", "");
|
||||
string id = idRex.Match(chNode.SelectSingleNode("a").GetAttributeValue("href", "")).Groups[1].Value;
|
||||
ret.Add(new Chapter(manga, null, volume, number, url, id));
|
||||
try
|
||||
{
|
||||
ret.Add(new Chapter(manga, null, volume, number, url, id));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {number}: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -174,7 +181,14 @@ public class Mangaworld: MangaConnector
|
||||
string number = chapterRex.Match(chNode.SelectSingleNode("a").SelectSingleNode("span").InnerText).Groups[1].Value;
|
||||
string url = chNode.SelectSingleNode("a").GetAttributeValue("href", "");
|
||||
string id = idRex.Match(chNode.SelectSingleNode("a").GetAttributeValue("href", "")).Groups[1].Value;
|
||||
ret.Add(new Chapter(manga, null, null, number, url, id));
|
||||
try
|
||||
{
|
||||
ret.Add(new Chapter(manga, null, null, number, url, id));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {number}: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,14 @@ public class ManhuaPlus : MangaConnector
|
||||
string volumeNumber = "1";
|
||||
string chapterNumber = rexMatch.Groups[1].Value;
|
||||
string fullUrl = url;
|
||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, fullUrl));
|
||||
try
|
||||
{
|
||||
chapters.Add(new Chapter(manga, "", volumeNumber, chapterNumber, fullUrl));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"Failed to load chapter {chapterNumber}: {e.Message}");
|
||||
}
|
||||
}
|
||||
//Return Chapters ordered by Chapter-Number
|
||||
Log($"Got {chapters.Count} chapters. {manga}");
|
||||
|
Loading…
x
Reference in New Issue
Block a user