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.Abstractions;
using API.Entities.Enums;
using API.Services;
using API.Services.Tasks.Scanner.Parser;
using Microsoft.Extensions.Logging;
using NSubstitute;
using Xunit;
@ -122,4 +124,22 @@ public class BookServiceTests
var comicInfo = _bookService.GetComicInfo(document);
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;
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 == MangaFormat.Epub)
Title = (IsSpecial && info.Format is MangaFormat.Epub or MangaFormat.Pdf)
? info.Title
: Parser.RemoveExtensionIfSupported(Range);

View File

@ -39,9 +39,9 @@ public class ChapterBuilder : IEntityBuilder<Chapter>
return builder.WithNumber(Parser.RemoveExtensionIfSupported(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
: specialTitle)
: specialTitle ?? string.Empty)
.WithIsSpecial(specialTreatment);
}

View File

@ -71,6 +71,11 @@ public class PdfParser(IDirectoryService directoryService) : DefaultParser(direc
// Patch in other information from ComicInfo
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)
{
ret.IsSpecial = true;
@ -79,6 +84,19 @@ public class PdfParser(IDirectoryService directoryService) : DefaultParser(direc
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))
{
ret.Series = Parser.CleanTitle(fileName, type is LibraryType.Comic);

View File

@ -40,7 +40,7 @@ export class TimeAgoPipe implements PipeTransform, OnDestroy {
private translocoService: TranslocoService) {}
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');
}