154 lines
6.1 KiB
JavaScript
154 lines
6.1 KiB
JavaScript
|
|
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();
|