diff --git a/icons/src/fr/wuxialnscantrad/icon.png b/icons/src/fr/wuxialnscantrad/icon.png new file mode 100644 index 0000000..2148baf Binary files /dev/null and b/icons/src/fr/wuxialnscantrad/icon.png differ diff --git a/plugins/french/wuxialnscantrad.ts b/plugins/french/wuxialnscantrad.ts new file mode 100644 index 0000000..fa1435a --- /dev/null +++ b/plugins/french/wuxialnscantrad.ts @@ -0,0 +1,222 @@ +import { CheerioAPI, load } from 'cheerio'; +import { fetchApi, fetchFile } from '@libs/fetch'; +import { Plugin } from '@typings/plugin'; +import { Filters, FilterTypes } from '@libs/filterInputs'; +import { defaultCover } from '@libs/defaultCover'; +import { NovelStatus } from '@libs/novelStatus'; +import dayjs from 'dayjs'; + +class WuxialnscantradPlugin implements Plugin.PluginBase { + id = 'wuxialnscantrad'; + name = 'WuxiaLnScantrad'; + icon = 'src/fr/wuxialnscantrad/icon.png'; + site = 'https://wuxialnscantrad.wordpress.com'; + version = '1.0.0'; + filters: Filters | undefined = undefined; + + async getCheerio(url: string): Promise { + const r = await fetchApi(url, { + headers: { 'Accept-Encoding': 'deflate' }, + }); + const body = await r.text(); + const $ = load(body); + return $; + } + + async popularNovels( + pageNo: number, + { + showLatestNovels, + filters, + }: Plugin.PopularNovelsOptions, + ): Promise { + if (pageNo > 1) return []; + + const novels: Plugin.NovelItem[] = []; + let novel: Plugin.NovelItem; + let url = this.site; + let $ = await this.getCheerio(url); + $('#menu-item-2210 ul li').each((i, elem) => { + const novelName = $(elem).first().text().trim(); + const novelUrl = $(elem).find('a').attr('href'); + + if (novelUrl && novelName) { + novel = { + name: novelName, + cover: defaultCover, + path: novelUrl.replace(this.site, ''), + }; + novels.push(novel); + } + }); + return novels; + } + + async parseNovel(novelPath: string): Promise { + const novel: Plugin.SourceNovel = { + path: novelPath, + name: 'Sans titre', + }; + + let $ = await this.getCheerio(this.site + novelPath); + + novel.name = $('.entry-title').text().trim(); + novel.cover = + $('.entry-content p strong img').first().attr('src') || + $('.entry-content p img').first().attr('src'); + + const entryContentText = $('.entry-content').text(); + novel.author = this.getAuthor(entryContentText); + novel.genres = this.getGenres(entryContentText); + novel.artist = this.getArtist(entryContentText); + novel.summary = this.getSummary(entryContentText); + novel.status = this.getStatus(entryContentText); + + var pathChapter = $('.entry-content ul').first().children('li'); + let chapters: Plugin.ChapterItem[] = []; + pathChapter.each((i, elem) => { + const chapterName = $(elem).text().trim(); + const chapterUrl = $(elem).find('a').attr('href'); + if (chapterUrl && chapterUrl.includes(this.site) && chapterName) { + const pathchapter = chapterUrl.replace(this.site, ''); + // we do not take the paths already present + if (!chapters.some(chap => chap.path === pathchapter)) { + const releaseDate = dayjs( + chapterUrl?.substring(this.site.length + 1, this.site.length + 11), + ).format('DD MMMM YYYY'); + chapters.push({ + name: chapterName, + path: pathchapter, + releaseTime: releaseDate, + }); + } + } + }); + novel.chapters = chapters; + return novel; + } + + getAuthor(text: string) { + const regex = /Auteur\(s\):\s*(.*)/; + const match = regex.exec(text); + let author = ''; + if (match !== null) { + author = match[1].trim(); + } + return author; + } + + getGenres(text: string) { + const regex = /Genres:\s*(.*)/; + const match = regex.exec(text); + let genre = ''; + if (match !== null) { + genre = match[1].trim(); + } + return genre; + } + + getArtist(text: string) { + const regex = /Artiste\(s\):\s*(.*)Genres/; + const match = regex.exec(text); + let artist = ''; + if (match !== null) { + artist = match[1].trim(); + } + return artist; + } + + getSummary(text: string) { + const regexAuthors = [ + /Synopsis :([\s\S]*)Chapitres disponibles/, + /Sypnopsis([\s\S]*)Sypnopsis officiel/, + /Synopsis([\s\S]*)Chapitres disponibles/, + ]; + + for (const regex of regexAuthors) { + const match = regex.exec(text); + if (match !== null) { + return match[1].trim(); + } + } + return ''; + } + + getStatus(text: string) { + const regex = /Statut:\s*(.*)/; + const match = regex.exec(text); + let status = ''; + if (match !== null) { + status = match[1].trim(); + } + switch (status) { + case 'En cours': + return NovelStatus.Ongoing; + case 'Arrêté': + return NovelStatus.Cancelled; + case 'Terminé': + return NovelStatus.Completed; + default: + return NovelStatus.Ongoing; + } + } + + async parseChapter(chapterPath: string): Promise { + const $ = await this.getCheerio(this.site + chapterPath); + + var contenuHtml = ''; + $('.entry-content') + .contents() + .each(function () { + if ($(this).html()?.includes('