- ContentSource handling in message
- ContentSource list, add/update ui
- nextPageSelector and imageSelector can be null
- cleanup
This commit is contained in:
Jérémy Guillot
2024-06-30 20:47:27 +02:00
parent ba30d3102d
commit 3012adfee7
24 changed files with 762 additions and 707 deletions

View File

@@ -10,13 +10,13 @@ use App\Repository\ChapterRepository;
use App\Repository\MangaRepository;
use App\Service\CbzService;
use App\Service\MangadexProvider;
use App\Service\NotificationService;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NonUniqueResultException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
@@ -27,13 +27,14 @@ use Symfony\Component\Routing\Attribute\Route;
class MangaController extends AbstractController
{
public function __construct(
private readonly MangaRepository $mangaRepository,
private readonly ChapterRepository $chapterRepository,
private readonly MessageBusInterface $bus,
private readonly CbzService $cbzService,
private readonly ToolbarFactory $toolbarFactory,
private MangadexProvider $mangadexProvider,
private EntityManagerInterface $entityManager
private readonly MangaRepository $mangaRepository,
private readonly ChapterRepository $chapterRepository,
private readonly MessageBusInterface $bus,
private readonly CbzService $cbzService,
private readonly ToolbarFactory $toolbarFactory,
private readonly MangadexProvider $mangadexProvider,
private readonly EntityManagerInterface $entityManager,
private readonly NotificationService $notificationService
)
{
}
@@ -171,6 +172,14 @@ class MangaController extends AbstractController
$allChapters = array_merge($mangaFeed, $mangaAggregate);
if (empty($allChapters)) {
$this->notificationService->sendUpdate([
'status' => 'error',
'message' => 'No chapters found for this manga.'
]);
return $this->redirectToRoute('app_manga_search', ['query' => $manga->getTitle()]);
}
$mergedChapters = [];
foreach ($allChapters as $chapter) {
$number = $chapter->getNumber();
@@ -187,7 +196,7 @@ class MangaController extends AbstractController
}
}
foreach($mergedChapters as $chapter) {
foreach ($mergedChapters as $chapter) {
$manga->addChapter($chapter);
}

View File

@@ -1,47 +0,0 @@
<?php
namespace App\Controller;
use App\Repository\MangaRepository;
use App\Service\LelScansProviderService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\String\Slugger\AsciiSlugger;
class MenuController extends AbstractController
{
private MangaRepository $mangaRepository;
private LelScansProviderService $mangaProviderService;
public function __construct(MangaRepository $mangaRepository, LelScansProviderService $mangaProviderService)
{
$this->mangaRepository = $mangaRepository;
$this->mangaProviderService = $mangaProviderService;
}
public function menu(): Response
{
$availableManga = $this->mangaProviderService->getMangaList();
foreach($availableManga as $key => $manga) {
$availableManga[$key]['slug'] = $this->titleToSlug($manga['name']);
}
$mangas = $this->mangaRepository->findAll();
return $this->render('menu/menu_old.html.twig', [
'availableManga' => $availableManga,
'mangas' => $mangas,
]);
}
private function slugToTitle(string $slug): string
{
$slugger = new AsciiSlugger();
return $slugger->slug($slug)->replace('-', ' ')->title(true)->toString();
}
private function titleToSlug(string $title): string
{
$slugger = new AsciiSlugger();
return $slugger->slug($title)->lower()->toString();
}
}

View File

@@ -2,12 +2,28 @@
namespace App\Controller;
use App\Entity\ContentSource;
use App\Form\ContentSourceType;
use App\Repository\ContentSourceRepository;
use App\Service\MangaScraperService;
use Doctrine\ORM\EntityManagerInterface;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class SettingsController extends AbstractController
{
public function __construct(
private MangaScraperService $mangaScraperService,
private EntityManagerInterface $entityManager
)
{
}
#[Route('/settings', name: 'app_settings')]
public function index(): Response
{
@@ -32,14 +48,77 @@ class SettingsController extends AbstractController
]);
}
#[Route('/settings/scrappers', name: 'app_settings_scrappers')]
public function scrappers(): Response
#[Route('/settings/scrappers/list', name: 'app_settings_scrappers_list')]
public function list(ContentSourceRepository $repository): Response
{
return $this->render('settings/index.html.twig', [
'controller_name' => 'SettingsController',
$contentSources = $repository->findAll();
return $this->render('settings/scrapper_list.html.twig', [
'contentSources' => $contentSources,
]);
}
#[Route('/settings/scrappers/{id}', name: 'app_settings_scrappers', defaults: ['id' => null])]
public function scrappers(Request $request, ?ContentSource $contentSource): Response
{
$isNew = $contentSource === null;
$contentSource = $contentSource ?? new ContentSource();
$form = $this->createForm(ContentSourceType::class, $contentSource);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->entityManager->persist($contentSource);
$this->entityManager->flush();
$this->addFlash('success', ($isNew ? 'New scrapper configuration saved' : 'Scrapper configuration updated') . ' successfully.');
return $this->redirectToRoute('app_settings_scrappers_list');
}
return $this->render('settings/scrappers.html.twig', [
'form' => $form->createView(),
'isNew' => $isNew,
]);
}
/**
* @throws GuzzleException
*/
#[Route('/settings/scrappers_test', name: 'app_settings_scrappers_test', methods: ['POST'])]
public function scrapperTest(Request $request): JsonResponse
{
$contentSource = new ContentSource();
$form = $this->createForm(ContentSourceType::class, $contentSource);
$form->submit($request->request->all()['content_source']);
if ($form->isValid()) {
$mangaSlug = $request->request->get('mangaSlug');
$chapterNumber = $request->request->get('chapterNumber');
$scrapedData = $this->mangaScraperService->testScrapingHtml($mangaSlug, $chapterNumber, $contentSource);
return new JsonResponse([
'success' => true,
'message' => 'Test successful',
'data' => $scrapedData
]);
} else {
return new JsonResponse([
'success' => false,
'message' => 'Invalid form submission',
'errors' => $this->getFormErrors($form)
]);
}
}
private function getFormErrors($form): array
{
$errors = [];
foreach ($form->getErrors(true) as $error) {
$errors[] = $error->getMessage();
}
return $errors;
}
#[Route('/settings/ui', name: 'app_settings_ui')]
public function ui(): Response
{