205 lines
7.5 KiB
PHP
205 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace App\Controller;
|
|
|
|
use App\Entity\ContentSource;
|
|
use App\Form\AppSettingsType;
|
|
use App\Form\ContentSourceType;
|
|
use App\Manager\AppSettingsManager;
|
|
use App\Manager\Toolbar\Factory\ToolbarFactory;
|
|
use App\Repository\ContentSourceRepository;
|
|
|
|
use App\Service\NotificationService;
|
|
use App\Service\Scraper\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,
|
|
private NotificationService $notificationService,
|
|
private ContentSourceRepository $contentSourceRepository
|
|
) {
|
|
|
|
}
|
|
|
|
#[Route('/settings', name: 'app_settings')]
|
|
public function index(): Response
|
|
{
|
|
return $this->render('settings/index.html.twig', [
|
|
'controller_name' => 'SettingsController',
|
|
]);
|
|
}
|
|
|
|
#[Route('/settings/general', name: 'app_settings_general')]
|
|
public function general(): Response
|
|
{
|
|
return $this->render('settings/index.html.twig', [
|
|
'controller_name' => 'SettingsController',
|
|
]);
|
|
}
|
|
|
|
#[Route('/settings/folders', name: 'app_settings_folders')]
|
|
public function folders(Request $request, AppSettingsManager $settingsManager): Response
|
|
{
|
|
$currentSettings = $settingsManager->getSettings();
|
|
|
|
$form = $this->createForm(AppSettingsType::class, $currentSettings);
|
|
$form->handleRequest($request);
|
|
|
|
if ($form->isSubmitted() && $form->isValid()) {
|
|
$newSettings = $form->getData();
|
|
$settingsManager->updateSettings($newSettings);
|
|
|
|
$this->notificationService->sendUpdate(['status' => 'success', 'message' => 'Settings updated successfully.']);
|
|
return $this->json(['success' => true]);
|
|
}
|
|
|
|
return $this->render('settings/folders.html.twig', [
|
|
'form' => $form->createView(),
|
|
]);
|
|
}
|
|
|
|
#[Route('/settings/scrappers/list', name: 'app_settings_scrappers_list')]
|
|
public function list(ContentSourceRepository $repository, ToolbarFactory $toolbarFactory): Response
|
|
{
|
|
$contentSources = $repository->findAll();
|
|
|
|
return $this->render('settings/scrapper_list.html.twig', [
|
|
'contentSources' => $contentSources,
|
|
'toolbar' => $toolbarFactory->createToolbar('scraper_list')->getGroups(),
|
|
]);
|
|
}
|
|
|
|
#[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->notificationService->sendUpdate(['status' => 'success', 'message' => ($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');
|
|
|
|
try {
|
|
$scrapedData = $this->mangaScraperService->testScraping($mangaSlug, $chapterNumber, $contentSource);
|
|
} catch (\Exception $e) {
|
|
$this->notificationService->sendUpdate(['status' => 'error', 'message' => $e->getMessage()]);
|
|
return new JsonResponse([
|
|
'success' => false,
|
|
'message' => $e->getMessage(),
|
|
]);
|
|
}
|
|
|
|
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
|
|
{
|
|
return $this->render('settings/index.html.twig', [
|
|
'controller_name' => 'SettingsController',
|
|
]);
|
|
}
|
|
|
|
#[Route('/settings/export_scrappers', name: 'app_settings_scrappers_export', methods: ['GET'])]
|
|
public function exportScrappers(): JsonResponse
|
|
{
|
|
$contentSources = $this->contentSourceRepository->findAll();
|
|
$data = [];
|
|
|
|
foreach ($contentSources as $source) {
|
|
$data[] = [
|
|
'baseUrl' => $source->getBaseUrl(),
|
|
'imageSelector' => $source->getImageSelector(),
|
|
'nextPageSelector' => $source->getNextPageSelector(),
|
|
'chapterUrlFormat' => $source->getChapterUrlFormat(),
|
|
'scrapingType' => $source->getScrapingType(),
|
|
'chapterSelector' => $source->getChapterSelector(), //TODO à renommer en chapterListSelector
|
|
];
|
|
}
|
|
|
|
return new JsonResponse($data);
|
|
}
|
|
|
|
#[Route('/settings/import_scrappers', name: 'app_settings_scrappers_import', methods: ['POST'])]
|
|
public function importScrappers(Request $request): JsonResponse
|
|
{
|
|
$content = $request->getContent();
|
|
$data = json_decode($content, true);
|
|
|
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
$this->notificationService->sendUpdate(['status' => 'error', 'message' => 'Invalid JSON data']);
|
|
return new JsonResponse(['error' => 'Invalid JSON data'], 400);
|
|
}
|
|
|
|
foreach ($data as $sourceData) {
|
|
$contentSource = new ContentSource();
|
|
$contentSource->setBaseUrl($sourceData['baseUrl']);
|
|
$contentSource->setImageSelector($sourceData['imageSelector']);
|
|
$contentSource->setNextPageSelector($sourceData['nextPageSelector']);
|
|
$contentSource->setChapterUrlFormat($sourceData['chapterUrlFormat']);
|
|
$contentSource->setScrapingType($sourceData['scrapingType']);
|
|
|
|
$this->entityManager->persist($contentSource);
|
|
}
|
|
|
|
$this->entityManager->flush();
|
|
|
|
return new JsonResponse(['message' => 'Content sources imported successfully']);
|
|
}
|
|
}
|