From 9e7f7b4cfc54d44f14f02898e213bc3f2b836409 Mon Sep 17 00:00:00 2001 From: "ext.jeremy.guillot@maxicoffee.domains" Date: Thu, 16 Oct 2025 14:35:58 +0200 Subject: [PATCH] fix: more patterns --- .../Service/FilenameAnalyzer.php | 24 ++++++++ .../Service/FilenameAnalyzerTest.php | 60 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/src/Domain/Manga/Infrastructure/Service/FilenameAnalyzer.php b/src/Domain/Manga/Infrastructure/Service/FilenameAnalyzer.php index f71818a..ae02a4b 100644 --- a/src/Domain/Manga/Infrastructure/Service/FilenameAnalyzer.php +++ b/src/Domain/Manga/Infrastructure/Service/FilenameAnalyzer.php @@ -33,6 +33,18 @@ readonly class FilenameAnalyzer implements FilenameAnalyzerInterface private function extractTitle(string $fileName): string { + // Pattern avec tirets complets : titre-volume-42-chapter-100 ou titre-chapitre-100-volume-42 + $fullDashCombinedPattern = '/^(?P.*?)-(?:volume|chapter|chapitre)-\d+-(?:volume|chapter|chapitre)-\d+/i'; + if (preg_match($fullDashCombinedPattern, $fileName, $matches)) { + return trim($matches['title']); + } + + // Pattern avec tirets complets : titre-volume-42 ou titre-chapter-100 ou titre-chapitre-100 + $fullDashPattern = '/^(?P<title>.*?)-(?:volume|chapter|chapitre)-\d+/i'; + if (preg_match($fullDashPattern, $fileName, $matches)) { + return trim($matches['title']); + } + // Pattern principal : titre suivi de volume/chapitre (inspiré du CbzService) // Supporte: vol, volume, tome, t, ch, chap, chapter, chapitre $titlePattern = '/^(?P<title>.+?)(?:\s*-\s*|\s+)?(?:(?:[Tt]ome|[Vv]ol(?:ume)?\.?|[Cc]h(?:ap(?:itre|ter)?)?|[Tt])\s*\d+)/'; @@ -70,6 +82,12 @@ readonly class FilenameAnalyzer implements FilenameAnalyzerInterface return (int) $matches['volume']; } + // Pattern avec tirets complets pour volume : volume-42 + $fullDashVolumePattern = '/volume-(?P<volume>\d+)/i'; + if (preg_match($fullDashVolumePattern, $fileName, $matches)) { + return (int) $matches['volume']; + } + return null; } @@ -81,6 +99,12 @@ readonly class FilenameAnalyzer implements FilenameAnalyzerInterface return (float) $matches['chapter']; } + // Pattern avec tirets complets pour chapitre : chapter-100 ou chapitre-100 + $fullDashChapterPattern = '/(?:chapter|chapitre)-(?P<chapter>\d+(?:\.\d+)?)/i'; + if (preg_match($fullDashChapterPattern, $fileName, $matches)) { + return (float) $matches['chapter']; + } + // Pattern underscore à la fin : _123.cbz $newFormatPattern = '/_ch(?P<chapter>\d+(?:\.\d+)?)(?:\.\w+)?$/i'; if (preg_match($newFormatPattern, $fileName, $matches)) { diff --git a/tests/Domain/Manga/Infrastructure/Service/FilenameAnalyzerTest.php b/tests/Domain/Manga/Infrastructure/Service/FilenameAnalyzerTest.php index db16e0d..88defbb 100644 --- a/tests/Domain/Manga/Infrastructure/Service/FilenameAnalyzerTest.php +++ b/tests/Domain/Manga/Infrastructure/Service/FilenameAnalyzerTest.php @@ -233,4 +233,64 @@ class FilenameAnalyzerTest extends TestCase "Should not have volume for: {$case['filename']}"); } } + + public function test_it_handles_full_dash_patterns(): void + { + $testCases = [ + [ + 'filename' => 'berserk-volume-42.cbz', + 'expectedTitle' => 'berserk', + 'expectedVolume' => 42.0, + ], + [ + 'filename' => 'berserk-chapter-100.cbz', + 'expectedTitle' => 'berserk', + 'expectedChapter' => 100.0, + ], + [ + 'filename' => 'berserk-chapitre-100.cbz', + 'expectedTitle' => 'berserk', + 'expectedChapter' => 100.0, + ], + [ + 'filename' => 'berserk-volume-42-chapter-100.cbz', + 'expectedTitle' => 'berserk', + 'expectedVolume' => 42.0, + 'expectedChapter' => 100.0, + ], + [ + 'filename' => 'berserk-chapitre-100-volume-42.cbz', + 'expectedTitle' => 'berserk', + 'expectedVolume' => 42.0, + 'expectedChapter' => 100.0, + ], + ]; + + foreach ($testCases as $case) { + $result = $this->analyzer->analyze($case['filename']); + + $this->assertEquals($case['expectedTitle'], $result->getTitle()->getValue(), + "Failed title extraction for: {$case['filename']}"); + + if (isset($case['expectedVolume'])) { + $this->assertTrue($result->hasVolumeNumber(), + "Should have volume for: {$case['filename']}"); + $this->assertEquals($case['expectedVolume'], $result->getVolumeNumber()->getValue(), + "Failed volume extraction for: {$case['filename']}"); + } else { + $this->assertFalse($result->hasVolumeNumber(), + "Should not have volume for: {$case['filename']}"); + } + + if (isset($case['expectedChapter'])) { + $this->assertTrue($result->hasChapterNumber(), + "Should have chapter for: {$case['filename']}"); + $this->assertEquals($case['expectedChapter'], $result->getChapterNumber()->getValue(), + "Failed chapter extraction for: {$case['filename']}"); + } else { + $this->assertFalse($result->hasChapterNumber(), + "Should not have chapter for: {$case['filename']}"); + } + } + } }