Files
Mangarr/src/Controller/ImportController.php
ext.jeremy.guillot@maxicoffee.domains c55cd62ec7 fix: phpcs-fixer
2025-02-05 21:32:04 +01:00

221 lines
8.2 KiB
PHP

<?php
namespace App\Controller;
use App\Manager\FileSystemManager;
use App\Repository\ChapterRepository;
use App\Repository\MangaRepository;
use App\Service\CbrToCbzConverter;
use App\Service\CbzService;
use App\Service\MangaImportService;
use App\Service\NotificationService;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\String\Slugger\SluggerInterface;
class ImportController extends AbstractController
{
public function __construct(
private readonly FileSystemManager $fileSystemManager,
private readonly CbzService $cbzService,
private readonly MangaImportService $mangaImportService,
private readonly NotificationService $notificationService,
private readonly MangaRepository $mangaRepository,
private readonly CbrToCbzConverter $cbrToCbzConverter
) {
}
#[Route('/manga/import', name: 'app_manga_import')]
public function index(Request $request, SessionInterface $session): Response
{
if ($request->isMethod('POST')) {
$files = $request->files->get('files');
if ($files) {
$importFiles = [];
foreach ($files as $file) {
if ($file && in_array($file->getClientOriginalExtension(), ['cbz', 'cbr'])) {
$originalFileName = $file->getClientOriginalName();
try {
$tmpPath = $this->fileSystemManager->moveUploadedFile(
$file->getPathname(),
$this->fileSystemManager->getUploadsDirectory(),
$file->getClientOriginalName()
);
$importFiles[] = [
'id' => uniqid(),
'path' => $tmpPath,
'original_name' => $originalFileName,
];
} catch (FileException $e) {
$this->notificationService->sendUpdate([
'status' => 'error',
'message' => 'Une erreur est survenue lors de l\'import du fichier ' . $originalFileName,
]);
}
} else {
$this->notificationService->sendUpdate([
'status' => 'error',
'message' => 'Le fichier ' . $file->getClientOriginalName() . ' doit être au format CBZ ou CBR.',
]);
}
}
if (!empty($importFiles)) {
$session->set('import_files', $importFiles);
return $this->redirectToRoute('import_match');
}
} else {
$this->notificationService->sendUpdate([
'status' => 'error',
'message' => 'Aucun fichier n\'a été sélectionné.',
]);
}
}
return $this->render('import/index.html.twig');
}
/**
* @throws Exception
*/
#[Route('/import/match', name: 'import_match')]
public function match(SessionInterface $session): Response
{
$files = $session->get('import_files', []);
if (empty($files)) {
return $this->redirectToRoute('app_manga_import');
}
$processedFiles = [];
foreach ($files as $fileId => $fileInfo) {
$filePath = $fileInfo['path'];
$originalFileName = $fileInfo['original_name'];
$fileExtension = pathinfo($filePath, PATHINFO_EXTENSION);
if (strtolower($fileExtension) === 'cbr') {
$cbzPath = $this->cbrToCbzConverter->convert($filePath);
$filePath = $cbzPath;
$originalFileName = pathinfo($originalFileName, PATHINFO_FILENAME) . '.cbz';
$files[$fileId]['path'] = $filePath;
$files[$fileId]['original_name'] = $originalFileName;
}
$metadata = $this->cbzService->extractMetadata($filePath, $originalFileName);
$mangas = $this->mangaRepository->findBySlug($metadata['title']);
$mangaOptions = [];
foreach ($mangas as $manga) {
$mangaOptions[] = [
'slug' => $manga->getSlug(),
'title' => $manga->getTitle(),
'author' => $manga->getAuthor(),
'publicationYear' => $manga->getPublicationYear(),
'genres' => $manga->getGenres(),
'description' => $manga->getDescription()
];
}
$processedFiles[] = [
'id' => $fileId,
'originalFileName' => $originalFileName,
'fileSize' => $this->formatBytes(filesize($filePath)),
'metadata' => $metadata,
'mangaOptions' => $mangaOptions
];
}
$session->set('import_files', $files);
return $this->render('import/match.html.twig', [
'files' => $processedFiles
]);
}
private function formatBytes($bytes, $precision = 2)
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= (1 << (10 * $pow));
return round($bytes, $precision) . ' ' . $units[$pow];
}
#[Route('/import/confirm', name: 'import_confirm', methods: ['POST'])]
public function confirm(Request $request, SessionInterface $session): Response
{
$files = $session->get('import_files', []);
$selectedFiles = $request->request->all('selected');
$mangaSlugs = $request->request->all('manga_slug');
$volumes = $request->request->all('volume');
$chapters = $request->request->all('chapter');
$importedFiles = [];
$errors = [];
foreach ($selectedFiles as $fileId) {
if (!isset($files[$fileId])) {
continue;
}
$file = $files[$fileId];
$mangaSlug = $mangaSlugs[$fileId] ?? null;
$volume = $volumes[$fileId] ?? null;
$chapter = $chapters[$fileId] ?? null;
try {
$manga = $this->mangaRepository->findOneBy(['slug' => $mangaSlug]);
if (!$manga) {
throw new \Exception('Manga non trouvé.');
}
if (!is_null($chapter)) {
$chapter = $manga->getChapterByNumber($chapter);
if (!$chapter) {
throw new \Exception('Chapitre non trouvé.');
}
}
$importedFiles[] = $file['original_name'];
$this->mangaImportService->importFile($manga, $volume, $chapter, $file['path']);
} catch (\Exception $e) {
$errors[] = "Erreur lors de l'import de {$file['original_name']} : " . $e->getMessage();
}
}
// Nettoyer les fichiers temporaires non importés
foreach ($files as $file) {
$this->fileSystemManager->deleteFile($file['path']);
}
// Nettoyer la session
$session->remove('import_files');
// Préparer le message de notification
if (!empty($importedFiles)) {
$successMessage = 'Fichiers importés avec succès : ' . implode(', ', $importedFiles);
$this->notificationService->sendUpdate([
'status' => 'success',
'message' => $successMessage
]);
}
if (!empty($errors)) {
$errorMessage = implode("\n", $errors);
$this->notificationService->sendUpdate([
'status' => 'error',
'message' => $errorMessage
]);
}
return $this->redirectToRoute('app_manga');
}
}