feat: ajout de la fonctionnalité de conversion de fichiers de bande dessinée, permettant la conversion de fichiers CBR en CBZ. Intégration d'un service de conversion, d'une API pour gérer les téléchargements, et mise en place de validations pour les fichiers uploadés. Tests unitaires ajoutés pour garantir le bon fonctionnement de cette nouvelle fonctionnalité.

This commit is contained in:
ext.jeremy.guillot@maxicoffee.domains
2025-07-14 16:44:18 +02:00
parent b4bfa48d00
commit 7a05934116
16 changed files with 640 additions and 3 deletions

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Domain\Conversion\Infrastructure\Service;
use App\Domain\Conversion\Domain\Contract\ConversionServiceInterface;
use App\Domain\Conversion\Domain\Exception\ConversionException;
use App\Domain\Conversion\Domain\Model\ConversionRequest;
use App\Domain\Conversion\Domain\Model\ConversionResult;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\Process;
final class ConversionService implements ConversionServiceInterface
{
private readonly string $tempDir;
private readonly Filesystem $filesystem;
public function __construct(string $projectDir)
{
$this->tempDir = $projectDir . '/public/tmp';
$this->filesystem = new Filesystem();
}
public function convert(ConversionRequest $request): ConversionResult
{
try {
$convertedFilePath = $this->convertCbrToCbz($request->getFilePath());
$convertedFileSize = file_exists($convertedFilePath) ? filesize($convertedFilePath) : 0;
return new ConversionResult(
convertedFilePath: $convertedFilePath,
outputFilename: $request->getOutputFilename(),
originalFileSize: $request->getFileSize(),
convertedFileSize: $convertedFileSize
);
} catch (\Exception $e) {
throw ConversionException::conversionFailed($e->getMessage());
}
}
private function convertCbrToCbz(string $cbrPath): string
{
$tempDir = $this->tempDir . '/' . uniqid('cbr_conversion_');
$this->filesystem->mkdir($tempDir);
$extractDir = $tempDir . '/extract';
$this->filesystem->mkdir($extractDir);
// Essayer d'extraire avec unrar-free
$process = new Process(['unrar-free', 'x', $cbrPath, $extractDir]);
$process->run();
// Si unrar échoue, essayer avec 7z
if (!$process->isSuccessful()) {
$process = new Process(['7z', 'x', $cbrPath, "-o$extractDir"]);
$process->run();
if (!$process->isSuccessful()) {
throw new \RuntimeException("Extraction failed: " . $process->getErrorOutput());
}
}
// Créer le CBZ
$cbzFileName = pathinfo($cbrPath, PATHINFO_FILENAME) . '.cbz';
$cbzPath = $this->tempDir . '/' . $cbzFileName;
$zip = new \ZipArchive();
if ($zip->open($cbzPath, \ZipArchive::CREATE) !== true) {
throw new \RuntimeException("Cannot create ZIP file");
}
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($extractDir),
\RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
$relativePath = substr($filePath, strlen($extractDir) + 1);
$zip->addFile($filePath, $relativePath);
}
}
$zip->close();
// Nettoyer le dossier temporaire d'extraction
$this->filesystem->remove($tempDir);
return $cbzPath;
}
}