PDF Parser Changes (#3681)

This commit is contained in:
Fesaa 2025-03-28 18:43:35 +01:00 committed by GitHub
parent da9f02f963
commit 5738014a88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 42 additions and 5 deletions

View File

@ -1,6 +1,8 @@
using System.IO; using System.IO;
using System.IO.Abstractions; using System.IO.Abstractions;
using API.Entities.Enums;
using API.Services; using API.Services;
using API.Services.Tasks.Scanner.Parser;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NSubstitute; using NSubstitute;
using Xunit; using Xunit;
@ -122,4 +124,22 @@ public class BookServiceTests
var comicInfo = _bookService.GetComicInfo(document); var comicInfo = _bookService.GetComicInfo(document);
Assert.Null(comicInfo); Assert.Null(comicInfo);
} }
[Fact]
public void SeriesFallBackToMetadataTitle()
{
var ds = new DirectoryService(Substitute.For<ILogger<DirectoryService>>(), new FileSystem());
var pdfParser = new PdfParser(ds);
var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/BookService");
var filePath = Path.Join(testDirectory, "Bizet-Variations_Chromatiques_de_concert_Theme_A4.pdf");
var comicInfo = _bookService.GetComicInfo(filePath);
Assert.NotNull(comicInfo);
var parserInfo = pdfParser.Parse(filePath, testDirectory, ds.GetParentDirectoryName(testDirectory), LibraryType.Book, comicInfo);
Assert.NotNull(parserInfo);
Assert.Equal(parserInfo.Title, comicInfo.Title);
Assert.Equal(parserInfo.Series, comicInfo.Title);
}
} }

View File

@ -178,8 +178,7 @@ public class Chapter : IEntityDate, IHasReadTimeEstimate, IHasCoverImage
MinNumber = Parser.DefaultChapterNumber; MinNumber = Parser.DefaultChapterNumber;
MaxNumber = Parser.DefaultChapterNumber; MaxNumber = Parser.DefaultChapterNumber;
} }
// NOTE: This doesn't work well for all because Pdf usually should use into.Title or even filename Title = (IsSpecial && info.Format is MangaFormat.Epub or MangaFormat.Pdf)
Title = (IsSpecial && info.Format == MangaFormat.Epub)
? info.Title ? info.Title
: Parser.RemoveExtensionIfSupported(Range); : Parser.RemoveExtensionIfSupported(Range);

View File

@ -39,9 +39,9 @@ public class ChapterBuilder : IEntityBuilder<Chapter>
return builder.WithNumber(Parser.RemoveExtensionIfSupported(info.Chapters)!) return builder.WithNumber(Parser.RemoveExtensionIfSupported(info.Chapters)!)
.WithRange(specialTreatment ? info.Filename : info.Chapters) .WithRange(specialTreatment ? info.Filename : info.Chapters)
.WithTitle((specialTreatment && info.Format == MangaFormat.Epub) .WithTitle(specialTreatment && info.Format is MangaFormat.Epub or MangaFormat.Pdf
? info.Title ? info.Title
: specialTitle) : specialTitle ?? string.Empty)
.WithIsSpecial(specialTreatment); .WithIsSpecial(specialTreatment);
} }

View File

@ -71,6 +71,11 @@ public class PdfParser(IDirectoryService directoryService) : DefaultParser(direc
// Patch in other information from ComicInfo // Patch in other information from ComicInfo
UpdateFromComicInfo(ret); UpdateFromComicInfo(ret);
if (comicInfo != null && !string.IsNullOrEmpty(comicInfo.Title))
{
ret.Title = comicInfo.Title.Trim();
}
if (ret.Chapters == Parser.DefaultChapter && ret.Volumes == Parser.LooseLeafVolume && type == LibraryType.Book) if (ret.Chapters == Parser.DefaultChapter && ret.Volumes == Parser.LooseLeafVolume && type == LibraryType.Book)
{ {
ret.IsSpecial = true; ret.IsSpecial = true;
@ -79,6 +84,19 @@ public class PdfParser(IDirectoryService directoryService) : DefaultParser(direc
ParseFromFallbackFolders(filePath, rootPath, type, ref ret); ParseFromFallbackFolders(filePath, rootPath, type, ref ret);
} }
if (type == LibraryType.Book && comicInfo != null)
{
// For books, fall back to the Title for Series.
if (!string.IsNullOrEmpty(comicInfo.Series))
{
ret.Series = comicInfo.Series.Trim();
}
else if (!string.IsNullOrEmpty(comicInfo.Title))
{
ret.Series = comicInfo.Title.Trim();
}
}
if (string.IsNullOrEmpty(ret.Series)) if (string.IsNullOrEmpty(ret.Series))
{ {
ret.Series = Parser.CleanTitle(fileName, type is LibraryType.Comic); ret.Series = Parser.CleanTitle(fileName, type is LibraryType.Comic);

View File

@ -40,7 +40,7 @@ export class TimeAgoPipe implements PipeTransform, OnDestroy {
private translocoService: TranslocoService) {} private translocoService: TranslocoService) {}
transform(value: string | Date | null) { transform(value: string | Date | null) {
if (value === '' || value === null || value === undefined || (value instanceof String && value.split('T')[0] === '0001-01-01')) { if (value === '' || value === null || value === undefined || (typeof value === 'string' && value.split('T')[0] === '0001-01-01')) {
return this.translocoService.translate('time-ago-pipe.never'); return this.translocoService.translate('time-ago-pipe.never');
} }