Interlude/Half Volumes (#626)

* Refactored Parser to handle parts

* Fixed a bug where marking multiple entities as unread would actually make them look read on the UI

* Implemented the ability to have float volume numbers

* Removed two unit test cases

* Code smells
This commit is contained in:
Joseph Milazzo 2021-10-03 13:30:31 -07:00 committed by GitHub
parent d4507e3288
commit 6e85fe8c0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 62 deletions

View File

@ -67,6 +67,7 @@ namespace API.Tests.Parser
[InlineData("X-Men v1 #201 (September 2007).cbz", "1")]
[InlineData("Hentai Ouji to Warawanai Neko. - Vol. 06 Ch. 034.5", "6")]
[InlineData("The 100 Girlfriends Who Really, Really, Really, Really, Really Love You - Vol. 03 Ch. 023.5 - Volume 3 Extras.cbz", "3")]
[InlineData("The 100 Girlfriends Who Really, Really, Really, Really, Really Love You - Vol. 03.5 Ch. 023.5 - Volume 3 Extras.cbz", "3.5")]
public void ParseVolumeTest(string filename, string expected)
{
Assert.Equal(expected, API.Parser.Parser.ParseVolume(filename));
@ -291,18 +292,6 @@ namespace API.Tests.Parser
Assert.Equal(expected, API.Parser.Parser.ParseMangaSpecial(inputFile));
}
/*
private static ParserInfo CreateParserInfo(string series, string chapter, string volume, bool isSpecial = false)
{
return new ParserInfo()
{
Chapters = chapter,
Volumes = volume,
IsSpecial = isSpecial,
Series = series,
};
}
*/
[Theory]
[InlineData("/manga/Btooom!/Vol.1/Chapter 1/1.cbz", "Btooom!~1~1")]

View File

@ -437,7 +437,7 @@ namespace API.Controllers
var existingChapterExists = readingList.Items.Select(rli => rli.ChapterId).ToHashSet();
var chaptersForSeries = (await _unitOfWork.ChapterRepository.GetChaptersByIdsAsync(chapterIds))
.OrderBy(c => int.Parse(c.Volume.Name))
.OrderBy(c => float.Parse(c.Volume.Name))
.ThenBy(x => double.Parse(x.Number), _chapterSortComparerForInChapterSorting);
var index = lastOrder + 1;

View File

@ -8,6 +8,9 @@ namespace API.Entities
public class Volume : IEntityDate
{
public int Id { get; set; }
/// <summary>
/// A String representation of the volume number. Allows for floats
/// </summary>
public string Name { get; set; }
public int Number { get; set; }
public IList<Chapter> Chapters { get; set; }

View File

@ -70,19 +70,19 @@ namespace API.Parser
@"(?<Series>.*)(\b|_)(?!\[)v(?<Volume>\d+(-\d+)?)(?!\])",
MatchOptions,
RegexTimeout),
// Kodomo no Jikan vol. 10
// Kodomo no Jikan vol. 10, [dmntsf.net] One Piece - Digital Colored Comics Vol. 20.5-21.5 Ch. 177
new Regex(
@"(?<Series>.*)(\b|_)(vol\.? ?)(?<Volume>\d+(-\d+)?)",
@"(?<Series>.*)(\b|_)(vol\.? ?)(?<Volume>\d+(\.\d)?(-\d+)?(\.\d)?)",
MatchOptions,
RegexTimeout),
// Killing Bites Vol. 0001 Ch. 0001 - Galactica Scanlations (gb)
new Regex(
@"(vol\.? ?)(?<Volume>\d+)",
@"(vol\.? ?)(?<Volume>\d+(\.\d)?)",
MatchOptions,
RegexTimeout),
// Tonikaku Cawaii [Volume 11].cbz
new Regex(
@"(volume )(?<Volume>\d+)",
@"(volume )(?<Volume>\d+(\.\d)?)",
MatchOptions,
RegexTimeout),
// Tower Of God S01 014 (CBT) (digital).cbz
@ -92,7 +92,7 @@ namespace API.Parser
RegexTimeout),
// vol_001-1.cbz for MangaPy default naming convention
new Regex(
@"(vol_)(?<Volume>\d+)",
@"(vol_)(?<Volume>\d+(\.\d)?)",
MatchOptions,
RegexTimeout),
};
@ -480,7 +480,7 @@ namespace API.Parser
RegexTimeout),
// Beelzebub_01_[Noodles].zip, Beelzebub_153b_RHS.zip
new Regex(
@"^((?!v|vo|vol|Volume).)*(\s|_)(?<Chapter>\.?\d+(?:.\d+|-\d+)?)(?<ChapterPart>b)?(\s|_|\[|\()",
@"^((?!v|vo|vol|Volume).)*(\s|_)(?<Chapter>\.?\d+(?:.\d+|-\d+)?)(?<Part>b)?(\s|_|\[|\()",
MatchOptions,
RegexTimeout),
// Yumekui-Merry_DKThias_Chapter21.zip
@ -810,12 +810,8 @@ namespace API.Parser
if (!match.Groups["Volume"].Success || match.Groups["Volume"] == Match.Empty) continue;
var value = match.Groups["Volume"].Value;
if (!value.Contains("-")) return RemoveLeadingZeroes(match.Groups["Volume"].Value);
var tokens = value.Split("-");
var from = RemoveLeadingZeroes(tokens[0]);
var to = RemoveLeadingZeroes(tokens[1]);
return $"{@from}-{to}";
var hasPart = match.Groups["Part"].Success;
return FormatValue(value, hasPart);
}
}
@ -832,18 +828,32 @@ namespace API.Parser
if (!match.Groups["Volume"].Success || match.Groups["Volume"] == Match.Empty) continue;
var value = match.Groups["Volume"].Value;
if (!value.Contains("-")) return RemoveLeadingZeroes(match.Groups["Volume"].Value);
var tokens = value.Split("-");
var from = RemoveLeadingZeroes(tokens[0]);
var to = RemoveLeadingZeroes(tokens[1]);
return $"{@from}-{to}";
var hasPart = match.Groups["Part"].Success;
return FormatValue(value, hasPart);
}
}
return DefaultVolume;
}
private static string FormatValue(string value, bool hasPart)
{
if (!value.Contains("-"))
{
return RemoveLeadingZeroes(hasPart ? AddChapterPart(value) : value);
}
var tokens = value.Split("-");
var from = RemoveLeadingZeroes(tokens[0]);
if (tokens.Length == 2)
{
var to = RemoveLeadingZeroes(hasPart ? AddChapterPart(tokens[1]) : tokens[1]);
return $"{@from}-{to}";
}
return @from;
}
public static string ParseChapter(string filename)
{
foreach (var regex in MangaChapterRegex)
@ -854,24 +864,9 @@ namespace API.Parser
if (!match.Groups["Chapter"].Success || match.Groups["Chapter"] == Match.Empty) continue;
var value = match.Groups["Chapter"].Value;
var hasChapterPart = match.Groups["ChapterPart"].Success;
if (!value.Contains("-"))
{
return RemoveLeadingZeroes(hasChapterPart ? AddChapterPart(value) : value);
}
var tokens = value.Split("-");
var from = RemoveLeadingZeroes(tokens[0]);
if (tokens.Length == 2)
{
var to = RemoveLeadingZeroes(hasChapterPart ? AddChapterPart(tokens[1]) : tokens[1]);
return $"{@from}-{to}";
}
return from;
var hasPart = match.Groups["Part"].Success;
return FormatValue(value, hasPart);
}
}
@ -898,16 +893,8 @@ namespace API.Parser
if (match.Groups["Chapter"].Success && match.Groups["Chapter"] != Match.Empty)
{
var value = match.Groups["Chapter"].Value;
if (value.Contains("-"))
{
var tokens = value.Split("-");
var from = RemoveLeadingZeroes(tokens[0]);
var to = RemoveLeadingZeroes(tokens[1]);
return $"{from}-{to}";
}
return RemoveLeadingZeroes(match.Groups["Chapter"].Value);
var hasPart = match.Groups["Part"].Success;
return FormatValue(value, hasPart);
}
}
@ -1026,7 +1013,7 @@ namespace API.Parser
private static string PerformPadding(string number)
{
var num = Int32.Parse(number);
var num = int.Parse(number);
return num switch
{
< 10 => "00" + num,

View File

@ -245,10 +245,10 @@ export class ActionService implements OnDestroy {
markMultipleAsUnread(seriesId: number, volumes: Array<Volume>, chapters?: Array<Chapter>, callback?: VoidActionCallback) {
this.readerService.markMultipleUnread(seriesId, volumes.map(v => v.id), chapters?.map(c => c.id)).pipe(take(1)).subscribe(() => {
volumes.forEach(volume => {
volume.pagesRead = volume.pages;
volume.chapters?.forEach(c => c.pagesRead = c.pages);
volume.pagesRead = 0;
volume.chapters?.forEach(c => c.pagesRead = 0);
});
chapters?.forEach(c => c.pagesRead = c.pages);
chapters?.forEach(c => c.pagesRead = 0);
this.toastr.success('Marked as Read');
if (callback) {