const axios = require('axios'); const cheerio = require('cheerio'); const Manga = require('../models/manga'); const Chapter = require('../models/chapter'); const connectors = require('../connectors.json'); class MangaController { constructor() {} async fetchAndStoreMangas(connectorId, localisation) { const connectorsToFetch = connectors.filter((config) => { const matchesConnectorId = !connectorId || config.id === connectorId; const matchesLocalisation = !localisation || config.localisation === localisation; return matchesConnectorId && matchesLocalisation; }); for (const config of connectorsToFetch) { await this.fetchMangas(config); } } async fetchMangas(config) { let page = 1; let shouldContinue = true; while (shouldContinue) { const pageUrl = config.paramSup !== "null" ? `${config.url}${config.paramSup}${page}` : config.url; shouldContinue = config.paramSup !== "null"; try { const response = await axios.get(pageUrl); const $ = cheerio.load(response.data); const titleElements = $(config.titleSelector); const imageElements = $(config.imageMangaSelector); const linkElements = $(config.chapterPage); if (!titleElements.length || !imageElements.length || !linkElements.length) break; const mangasOnPage = []; for (let i = 0; i < titleElements.length; i++) { const title = $(titleElements[i]).text().trim(); const imageUrl = $(imageElements[i]).attr(config.attributManga) || ''; let linkChapter = $(linkElements[i]).attr('href') || ''; if (linkChapter.startsWith('/')) linkChapter = config.baseUrl + linkChapter; if (!title) continue; try { const mangaPageResponse = await axios.get(linkChapter); const $$ = cheerio.load(mangaPageResponse.data); const description = $$(config.description).text().trim() || 'Not available'; const categories = []; const categorieElement = $$(config.categorieElement); const categoriesSelector = config.categorieElement === config.categories ? $$(config.categorieElement) : categorieElement.find(config.categories); categoriesSelector.each((_, elem) => { categories.push($$(elem).text().trim()); }); const rate = $$(config.rate).text().trim() || '0'; const chapters = await this.fetchChapters(linkChapter, config); // Enregistrer le manga dans la base de données const [manga, created] = await Manga.findOrCreate({ where: { title }, defaults: { connectorId: config.id, connectorName: config.name, imageUrl, linkChapter, description, categories, rate, }, }); if (!created) { // Mettre à jour le manga existant await manga.update({ connectorId: config.id, connectorName: config.name, imageUrl, linkChapter, description, categories, rate, }); } // Enregistrer les chapitres for (const chapterData of chapters) { await Chapter.findOrCreate({ where: { chapterLink: chapterData.chapterLink }, defaults: { ...chapterData, mangaId: manga.id, }, }); } } catch (e) { console.error(`Erreur lors du traitement du manga ${title}: ${e.message}`); continue; } } page++; } catch (e) { console.error(`Erreur lors de la récupération de la page ${pageUrl}: ${e.message}`); shouldContinue = false; } } } async fetchChapters(linkChapter, config) { try { const response = await axios.get(linkChapter); const $ = cheerio.load(response.data); const chapterElements = $(config.chapterSelector); const chapters = []; chapterElements.each((_, elem) => { const chapterNum = $(elem).find(config.chapterNumSelector).text().trim() || 'N/A'; let chapterLink = $(elem).find(config.chapterTitleSelector).attr('href') || ''; const chapterTitle = $(elem).find(config.chapterTitleSelector).text().replace(/^\s+|\s+$/g, '') || 'N/A'; const chapterDate = $(elem).find(config.chapterDateSelector).text().trim() || ''; if (chapterLink.startsWith('/')) chapterLink = config.baseUrl + chapterLink; console.log(chapterTitle) chapters.push({ chapterNum, chapterTitle, chapterLink, chapterDate, }); }); return chapters; } catch (e) { console.error(`Erreur lors de la récupération des chapitres: ${e.message}`); return []; } } } module.exports = new MangaController();