Basic fallback parsing code is in place.
This commit is contained in:
parent
5a522b6d5b
commit
95e7ad0f5b
6 changed files with 56 additions and 29 deletions
|
@ -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", ' ')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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('-'))
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue