Basic fallback parsing code is in place.

This commit is contained in:
Joseph Milazzo 2024-02-10 16:39:37 -06:00
parent 5a522b6d5b
commit 95e7ad0f5b
6 changed files with 56 additions and 29 deletions

View file

@ -537,18 +537,18 @@ public class SeriesService : ISeriesService
retChapters = Array.Empty<ChapterDto>(); retChapters = Array.Empty<ChapterDto>();
} else } else
{ {
retChapters = chapters retChapters = chapters.Where(ShouldIncludeChapter);
.Where(ShouldIncludeChapter);
} }
var storylineChapters = volumes var storylineChapters = libraryType == LibraryType.Magazine ? []
.Where(v => v.MinNumber == 0) : volumes
.SelectMany(v => v.Chapters.Where(c => !c.IsSpecial)) .Where(v => v.MinNumber == 0)
.OrderBy(c => c.Number.AsFloat(), ChapterSortComparer.Default) .SelectMany(v => v.Chapters.Where(c => !c.IsSpecial))
.ToList(); .OrderBy(c => c.Number.AsFloat(), ChapterSortComparer.Default)
.ToList();
// When there's chapters without a volume number revert to chapter sorting only as opposed to volume then chapter // When there's chapters without a volume number revert to chapter sorting only as opposed to volume then chapter
if (storylineChapters.Any()) { if (storylineChapters.Count > 0) {
retChapters = retChapters.OrderBy(c => c.Number.AsFloat(), ChapterSortComparer.Default); retChapters = retChapters.OrderBy(c => c.Number.AsFloat(), ChapterSortComparer.Default);
} }
@ -615,8 +615,10 @@ public class SeriesService : ISeriesService
{ {
LibraryType.Book => await _localizationService.Translate(userId, "book-num", chapterTitle), LibraryType.Book => await _localizationService.Translate(userId, "book-num", chapterTitle),
LibraryType.LightNovel => await _localizationService.Translate(userId, "book-num", chapterTitle), LibraryType.LightNovel => await _localizationService.Translate(userId, "book-num", chapterTitle),
LibraryType.Magazine => await _localizationService.Translate(userId, "issue-num", hashSpot, chapterTitle),
LibraryType.Comic => await _localizationService.Translate(userId, "issue-num", hashSpot, chapterTitle), LibraryType.Comic => await _localizationService.Translate(userId, "issue-num", hashSpot, chapterTitle),
LibraryType.Manga => await _localizationService.Translate(userId, "chapter-num", chapterTitle), LibraryType.Manga => await _localizationService.Translate(userId, "chapter-num", chapterTitle),
LibraryType.Image => await _localizationService.Translate(userId, "chapter-num", chapterTitle),
_ => await _localizationService.Translate(userId, "chapter-num", ' ') _ => await _localizationService.Translate(userId, "chapter-num", ' ')
}; };
} }

View file

@ -125,13 +125,32 @@ public class DefaultParser : IDefaultParser
{ {
// Try to parse Series from the filename // Try to parse Series from the filename
var libraryPath = _directoryService.FileSystem.DirectoryInfo.New(rootPath).Parent?.FullName ?? rootPath; var libraryPath = _directoryService.FileSystem.DirectoryInfo.New(rootPath).Parent?.FullName ?? rootPath;
ret.Series = Parser.ParseMagazineSeries(filePath); var fileName = _directoryService.FileSystem.Path.GetFileNameWithoutExtension(filePath);
if (string.IsNullOrEmpty(ret.Series)) ret.Series = Parser.ParseMagazineSeries(fileName);
ret.Volumes = Parser.ParseMagazineVolume(fileName);
ret.Chapters = Parser.ParseMagazineChapter(fileName);
if (string.IsNullOrEmpty(ret.Series) || (string.IsNullOrEmpty(ret.Chapters) && string.IsNullOrEmpty(ret.Volumes)))
{ {
// Fallback to the parent folder. We can also likely grab Volume (year) from here // Fallback to the parent folder. We can also likely grab Volume (year) from here
var folders = _directoryService.GetFoldersTillRoot(libraryPath, filePath); var folders = _directoryService.GetFoldersTillRoot(libraryPath, filePath).ToList();
foreach (var folder in folders) // Usually the LAST folder is the Series and everything up to can have Volume
if (string.IsNullOrEmpty(ret.Series))
{ {
ret.Series = Parser.CleanTitle(folders[^1]);
}
foreach (var folder in folders[..^1])
{
if (ret.Volumes == Parser.DefaultVolume)
{
var vol = Parser.ParseYear(folder);
if (vol != folder)
{
ret.Volumes = vol;
}
}
} }
} }

View file

@ -687,6 +687,11 @@ public static partial class Parser
MatchOptions, RegexTimeout), MatchOptions, RegexTimeout),
}; };
private static readonly Regex YearRegex = new Regex(
@"(\b|\s|_)[1-9]{1}\d{3}(\b|\s|_)",
MatchOptions, RegexTimeout
);
#endregion #endregion
@ -858,25 +863,10 @@ public static partial class Parser
} }
// Add mappings for other languages if needed // Add mappings for other languages if needed
// Example: mappings["KoreanMonthName"] = correspondingNumericalValue;
return mappings; return mappings;
} }
static int ConvertMonthToNumber(string month, Dictionary<string, int> monthMappings)
{
// Check if the month exists in the mappings
if (monthMappings.TryGetValue(month, out int numericalValue))
{
return numericalValue;
}
// If the month is not found in mappings, you may handle other cases here,
// such as trying to parse non-English month names or returning a default value.
// For simplicity, we'll return 0 indicating failure.
return 0;
}
public static string ParseMagazineChapter(string filename) public static string ParseMagazineChapter(string filename)
{ {
foreach (var regex in MagazineChapterRegex) foreach (var regex in MagazineChapterRegex)
@ -899,6 +889,12 @@ public static partial class Parser
return DefaultChapter; return DefaultChapter;
} }
public static string ParseYear(string value)
{
if (string.IsNullOrEmpty(value)) return value;
return YearRegex.Match(value).Value;
}
private static string FormatValue(string value, bool hasPart) private static string FormatValue(string value, bool hasPart)
{ {
if (!value.Contains('-')) if (!value.Contains('-'))

View file

@ -5,7 +5,6 @@ export enum LibraryType {
Comic = 1, Comic = 1,
Book = 2, Book = 2,
Images = 3, Images = 3,
Images = 3,
LightNovel = 4, LightNovel = 4,
Magazine = 5 Magazine = 5
} }

View file

@ -338,6 +338,7 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked {
} }
get ShowStorylineTab() { get ShowStorylineTab() {
if (this.libraryType === LibraryType.Magazine) return false;
return (this.libraryType !== LibraryType.Book && this.libraryType !== LibraryType.LightNovel) && (this.volumes.length > 0 || this.chapters.length > 0); return (this.libraryType !== LibraryType.Book && this.libraryType !== LibraryType.LightNovel) && (this.volumes.length > 0 || this.chapters.length > 0);
} }
@ -716,6 +717,16 @@ export class SeriesDetailComponent implements OnInit, AfterContentChecked {
*/ */
updateSelectedTab() { updateSelectedTab() {
// Book libraries only have Volumes or Specials enabled // Book libraries only have Volumes or Specials enabled
if (this.libraryType === LibraryType.Magazine) {
if (this.volumes.length === 0) {
this.activeTabId = TabID.Chapters;
} else {
this.activeTabId = TabID.Volumes;
}
this.cdRef.markForCheck();
return;
}
if (this.libraryType === LibraryType.Book || this.libraryType === LibraryType.LightNovel) { if (this.libraryType === LibraryType.Book || this.libraryType === LibraryType.LightNovel) {
if (this.volumes.length === 0) { if (this.volumes.length === 0) {
this.activeTabId = TabID.Specials; this.activeTabId = TabID.Specials;

View file

@ -63,10 +63,10 @@ export class UtilityService {
*/ */
formatChapterName(libraryType: LibraryType, includeHash: boolean = false, includeSpace: boolean = false) { formatChapterName(libraryType: LibraryType, includeHash: boolean = false, includeSpace: boolean = false) {
switch(libraryType) { switch(libraryType) {
case LibraryType.Magazine: // TODO: Figure out if we need something special
case LibraryType.Book: case LibraryType.Book:
case LibraryType.LightNovel: case LibraryType.LightNovel:
return this.translocoService.translate('common.book-num') + (includeSpace ? ' ' : ''); return this.translocoService.translate('common.book-num') + (includeSpace ? ' ' : '');
case LibraryType.Magazine: // TODO: Figure out if we need something special
case LibraryType.Comic: case LibraryType.Comic:
if (includeHash) { if (includeHash) {
return this.translocoService.translate('common.issue-hash-num'); return this.translocoService.translate('common.issue-hash-num');