- manga import
- read from cbz
- save cbz from scrapping
- menu interactions
This commit is contained in:
Jérémy Guillot
2024-06-27 11:28:45 +02:00
parent d52b724df5
commit 115e4336ab
28 changed files with 1239 additions and 302 deletions

View File

@@ -0,0 +1,110 @@
<?php
namespace App\Service;
use App\Entity\Manga;
use App\Repository\ChapterRepository;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use JetBrains\PhpStorm\NoReturn;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\String\Slugger\SluggerInterface;
class MangaImportService
{
private const string CBZ_DIRECTORY = 'public/cbz';
public function __construct(
private readonly string $projectDir,
private readonly EntityManagerInterface $entityManager,
private readonly ChapterRepository $chapterRepository,
private readonly CbzService $cbzService,
private readonly Filesystem $filesystem,
private readonly SluggerInterface $slugger
)
{
}
/**
* @throws Exception
*/
#[NoReturn] public function importVolume(Manga $manga, int $volume, string $tempFilePath, string $originalFileName): void
{
// Extraire les métadonnées du fichier CBZ
$metadata = $this->cbzService->extractMetadata($tempFilePath, $originalFileName);
// Créer le nom de fichier et le chemin pour le stockage permanent
$permanentFileName = $this->createPermanentFileName($manga, $volume, $metadata);
$mangaDirectory = $this->createMangaDirectory($manga);
$permanentFilePath = $this->projectDir . '/' . $mangaDirectory .'/volume_' . sprintf('%02d', $volume) . '/' . $permanentFileName;
// Vérifier si le fichier existe déjà
if ($this->filesystem->exists($permanentFilePath)) {
throw new \RuntimeException("Un fichier pour ce volume/chapitre existe déjà.");
}
// Déplacer le fichier vers l'emplacement permanent
$this->filesystem->mkdir(dirname($permanentFilePath), 0755);
$this->filesystem->rename($tempFilePath, $permanentFilePath, true);
// Mettre à jour ou créer les entités Chapter
if (isset($metadata['chapter'])) {
// Si c'est un chapitre spécifique
$this->updateChapter($manga, $volume, $metadata['chapter'], $permanentFilePath);
} else {
// Si c'est un volume entier, mettre à jour tous les chapitres du volume
$this->updateVolumeChapters($manga, $volume, $permanentFilePath);
}
$this->entityManager->flush();
}
private function createPermanentFileName(Manga $manga, int $volume, array $metadata): string
{
$baseFileName = $this->slugger->slug($manga->getTitle()) . '_vol' . sprintf('%02d', $volume);
if (isset($metadata['chapter'])) {
$baseFileName .= '_ch' . $metadata['chapter'];
}
return $baseFileName . '.cbz';
}
private function createMangaDirectory(Manga $manga): string
{
$mangaYear = $manga->getPublicationYear() ?? 'unknown';
$directoryPath = self::CBZ_DIRECTORY . '/' . ucfirst($manga->getSlug()) . ' (' . $mangaYear . ')';
$this->filesystem->mkdir($directoryPath, 0755);
return $directoryPath;
}
private function updateChapter(Manga $manga, int $volume, float $chapterNumber, string $cbzPath): void
{
$chapter = $this->chapterRepository->findOneBy([
'manga' => $manga,
'volume' => $volume,
'number' => $chapterNumber
]);
if (!$chapter) {
throw new \RuntimeException("Le chapitre $chapterNumber du volume $volume n'existe pas en base de données.");
}
$chapter->setCbzPath($cbzPath);
}
private function updateVolumeChapters(Manga $manga, int $volume, string $cbzPath): void
{
$chapters = $this->chapterRepository->findBy([
'manga' => $manga,
'volume' => $volume
]);
if (empty($chapters)) {
throw new \RuntimeException("Aucun chapitre trouvé pour le volume $volume en base de données.");
}
foreach ($chapters as $chapter) {
$chapter->setCbzPath($cbzPath);
}
}
}