feat: refonte du gestionnaire de chapitres pour intégrer la génération de fichiers CBZ, le téléchargement d'images en lot et la gestion des requêtes de scraping, avec mise à jour des interfaces et des modèles associés
This commit is contained in:
parent
cdee6f77fc
commit
d7088b14c2
@@ -4,13 +4,19 @@ namespace App\Domain\Scraping\Application\CommandHandler;
|
||||
|
||||
use App\Domain\Scraping\Application\Command\ScrapeChapter;
|
||||
use App\Domain\Scraping\Domain\Contract\Repository\ChapterRepositoryInterface;
|
||||
use App\Domain\Scraping\Domain\Contract\Repository\MangaRepositoryInterface;
|
||||
use App\Domain\Scraping\Domain\Contract\Repository\ScrapingJobRepositoryInterface;
|
||||
use App\Domain\Scraping\Domain\Contract\Repository\SourceRepositoryInterface;
|
||||
use App\Domain\Scraping\Domain\Contract\Service\CbzGeneratorInterface;
|
||||
use App\Domain\Scraping\Domain\Contract\Service\ImageDownloaderInterface;
|
||||
use App\Domain\Scraping\Domain\Contract\Service\ScraperInterface;
|
||||
use App\Domain\Scraping\Domain\Event\ChapterScraped;
|
||||
use App\Domain\Scraping\Domain\Event\ChapterScrapingFailed;
|
||||
use App\Domain\Scraping\Domain\Event\ChapterScrapingStarted;
|
||||
use App\Domain\Scraping\Domain\Model\ScrapingJob;
|
||||
use App\Domain\Scraping\Domain\Model\ScrapingStatus;
|
||||
use App\Domain\Scraping\Domain\Model\ValueObject\CbzGenerationRequest;
|
||||
use App\Domain\Scraping\Domain\Model\ValueObject\ScrapingRequest;
|
||||
use App\Domain\Scraping\Domain\Model\ValueObject\TempDirectory;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
|
||||
@@ -18,8 +24,12 @@ readonly class ScrapeChapterHandler
|
||||
{
|
||||
public function __construct(
|
||||
private ScraperInterface $scraper,
|
||||
private ImageDownloaderInterface $imageDownloader,
|
||||
private CbzGeneratorInterface $cbzGenerator,
|
||||
private ScrapingJobRepositoryInterface $scrapingJobRepository,
|
||||
private ChapterRepositoryInterface $chapterRepository,
|
||||
private MangaRepositoryInterface $mangaRepository,
|
||||
private SourceRepositoryInterface $sourceRepository,
|
||||
private MessageBusInterface $eventBus
|
||||
) {
|
||||
}
|
||||
@@ -27,30 +37,71 @@ readonly class ScrapeChapterHandler
|
||||
public function handle(ScrapeChapter $command): void
|
||||
{
|
||||
try {
|
||||
// 1. Création du job
|
||||
$job = new ScrapingJob(
|
||||
Uuid::uuid4(),
|
||||
Uuid::uuid4()->toString(),
|
||||
$command->mangaId,
|
||||
$command->chapterNumber,
|
||||
$command->sourceId
|
||||
);
|
||||
|
||||
$this->scrapingJobRepository->save($job);
|
||||
|
||||
// 2. Préparation des données
|
||||
$manga = $this->mangaRepository->getById($command->mangaId);
|
||||
$chapter = $this->chapterRepository->getByMangaIdAndChapterNumber($command->mangaId, $command->chapterNumber);
|
||||
$source = $this->sourceRepository->getById($command->sourceId);
|
||||
|
||||
$this->eventBus->dispatch(new ChapterScrapingStarted($job->getId()));
|
||||
|
||||
$job = $this->scraper->scrape($job);
|
||||
|
||||
if($job->status === ScrapingStatus::FAILED) {
|
||||
$this->eventBus->dispatch(new ChapterScrapingFailed($command->mangaId, $command->chapterNumber, $job->failureReason));
|
||||
}elseif ($job->status === ScrapingStatus::COMPLETED) {
|
||||
$this->eventBus->dispatch(new ChapterScraped($job->getId()));
|
||||
$chapter = $this->chapterRepository->getByMangaIdAndChapterNumber($command->mangaId, $command->chapterNumber);
|
||||
$chapter->cbzPath = $job->cbzPath->getPath();
|
||||
$this->chapterRepository->save($chapter);
|
||||
}
|
||||
// 3. Scraping des URLs
|
||||
$scrapingRequest = new ScrapingRequest(
|
||||
'html',
|
||||
$source->buildChapterUrl($manga->getSlug(), $command->chapterNumber),
|
||||
$source->getScrappingParameters(),
|
||||
$job->getId()
|
||||
);
|
||||
|
||||
$scrapingResult = $this->scraper->scrape($scrapingRequest);
|
||||
$job->totalPages = $scrapingResult->getTotalPages();
|
||||
$this->scrapingJobRepository->save($job);
|
||||
|
||||
// 4. Téléchargement des images
|
||||
$tempDir = new TempDirectory();
|
||||
$downloadResults = $this->imageDownloader->downloadBatch(
|
||||
$scrapingResult->getImageUrls(),
|
||||
$tempDir,
|
||||
$job->getId()
|
||||
);
|
||||
|
||||
// 5. Génération du CBZ
|
||||
$cbzRequest = new CbzGenerationRequest(
|
||||
$manga->getTitle(),
|
||||
$manga->getPublicationYear(),
|
||||
$chapter->volumeNumber,
|
||||
$command->chapterNumber,
|
||||
$tempDir,
|
||||
array_map(fn($r) => $r->getLocalPath(), $downloadResults)
|
||||
);
|
||||
|
||||
$cbzPath = $this->cbzGenerator->generate($cbzRequest);
|
||||
|
||||
// 6. Mise à jour et sauvegarde
|
||||
$job->complete();
|
||||
$job->cbzPath = $cbzPath;
|
||||
$this->scrapingJobRepository->save($job);
|
||||
|
||||
$chapter->cbzPath = $cbzPath->getPath();
|
||||
$this->chapterRepository->save($chapter);
|
||||
|
||||
$this->eventBus->dispatch(new ChapterScraped($job->getId()));
|
||||
|
||||
// 7. Nettoyage
|
||||
$tempDir->cleanup();
|
||||
} catch (\Exception $e) {
|
||||
if (isset($job)) {
|
||||
$job->fail($e->getMessage());
|
||||
$this->scrapingJobRepository->save($job);
|
||||
}
|
||||
$this->eventBus->dispatch(new ChapterScrapingFailed($command->mangaId, $command->chapterNumber, $e->getMessage()));
|
||||
throw $e;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user