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']); } }