mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-05-24 00:52:23 -04:00
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:
parent
d4507e3288
commit
6e85fe8c0a
@ -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")]
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user