Files
Mangarr/src/MessageHandler/DownloadChapterHandler.php
ext.jeremy.guillot@maxicoffee.domains 7506a7a3c1 style: apply php-cs-fixer formatting (PSR-12)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-09 20:46:59 +01:00

104 lines
4.1 KiB
PHP

<?php
namespace App\MessageHandler;
use App\Entity\ContentSource;
use App\Message\DownloadChapter;
use App\Repository\ChapterRepository;
use App\Repository\ContentSourceRepository;
use App\Service\NotificationService;
use App\Service\Scraper\MangaScraperService;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
#[AsMessageHandler]
readonly class DownloadChapterHandler
{
public function __construct(
private ChapterRepository $chapterRepository,
private MangaScraperService $mangaScraperService,
private NotificationService $notificationService,
private ContentSourceRepository $contentSourceRepository
) {
}
/**
* @throws \Exception
*/
public function __invoke(DownloadChapter $message): void
{
$chapter = $this->chapterRepository->find($message->getChapterId());
if (!$chapter) {
$this->notificationService->sendUpdate(['status' => 'error', 'message' => 'Chapter not found.']);
throw new BadRequestHttpException('Chapter not found');
} elseif (null !== $chapter->getCbzPath()) {
$this->notificationService->sendUpdate(['status' => 'error', 'message' => 'Chapter already scraped.']);
throw new BadRequestHttpException('Chapter already downloaded');
}
$manga = $chapter->getManga();
$preferredSources = $manga->getPreferredSources()->toArray();
$allSources = $this->contentSourceRepository->findAll();
$filteredSources = array_udiff($allSources, $preferredSources, function ($a, $b) {
return $a->getId() - $b->getId();
});
$sources = array_merge($preferredSources, $filteredSources);
if (count($preferredSources) > 0) {
$sources = $preferredSources;
} else {
$sources = $allSources;
}
// $sources[] =
// (new ContentSource())
// ->setBaseUrl('https://api.mangadex.org/')
// ->setImageSelector('img')
// ->setChapterUrlFormat('at-home/server/%s')
// ->setScrapingType('mangadex');
// (new ContentSource())
// ->setBaseUrl('https://lelscans.net')
// ->setImageSelector('#image img')
// ->setChapterUrlFormat('https://lelscans.net/scan-%s/%s')
// ->setNextPageSelector('a[title="Suivant"]')
// ->setScrapingType('html'),
// (new ContentSource())
// ->setBaseUrl('https://darkscans.net/')
// ->setImageSelector('.reading-content img')
// ->setChapterUrlFormat('https://darkscans.net/mangas/%s/chapter-%s/')
// ->setNextPageSelector(null)
// ->setScrapingType('html')
$scrapedSuccessfully = false;
foreach ($sources as $source) {
try {
$this->mangaScraperService->scrapeChapter($chapter, $source);
$scrapedSuccessfully = true;
break;
} catch (\Exception $e) {
$this->notificationService->sendUpdate([
'status' => 'warning',
'message' => 'An error occurred while scraping with source: '.$source->getBaseUrl().'. Trying next source...',
]);
} catch (GuzzleException $e) {
}
}
if (!$scrapedSuccessfully) {
$this->notificationService->sendUpdate([
'status' => 'error',
'message' => 'All sources failed to scrape the chapter '.$chapter->getManga()->getTitle().' '.$chapter->getNumber().'.',
]);
throw new \Exception('All sources failed to scrape the chapter '.$chapter->getManga()->getTitle().' '.$chapter->getNumber().'.');
}
$this->notificationService->sendUpdate(['status' => 'success', 'message' => 'Chapter scraped successfully.']);
}
}