From 2bf7b4721c2a786ff0b670a99edc693ac522f682 Mon Sep 17 00:00:00 2001 From: Justin COLLON <48163201+error7404@users.noreply.github.com> Date: Tue, 30 Apr 2024 11:11:29 +0200 Subject: [PATCH] fix lightnovelbrasil (#918) --- .../lightnovelwp}/lightnovelbrasil/icon.png | Bin plugins/portuguese/.gitkeep | 0 plugins/portuguese/lightnovelbrasil.ts | 401 ------------------ .../filters/lightnovelbrasil.json | 244 +++++++++++ scripts/multisrc/lightnovelwp/sources.json | 9 + 5 files changed, 253 insertions(+), 401 deletions(-) rename icons/{src/pt => multisrc/lightnovelwp}/lightnovelbrasil/icon.png (100%) create mode 100644 plugins/portuguese/.gitkeep delete mode 100644 plugins/portuguese/lightnovelbrasil.ts create mode 100644 scripts/multisrc/lightnovelwp/filters/lightnovelbrasil.json diff --git a/icons/src/pt/lightnovelbrasil/icon.png b/icons/multisrc/lightnovelwp/lightnovelbrasil/icon.png similarity index 100% rename from icons/src/pt/lightnovelbrasil/icon.png rename to icons/multisrc/lightnovelwp/lightnovelbrasil/icon.png diff --git a/plugins/portuguese/.gitkeep b/plugins/portuguese/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/plugins/portuguese/lightnovelbrasil.ts b/plugins/portuguese/lightnovelbrasil.ts deleted file mode 100644 index 64d69a8..0000000 --- a/plugins/portuguese/lightnovelbrasil.ts +++ /dev/null @@ -1,401 +0,0 @@ -import { load as parseHTML } from 'cheerio'; -import { fetchApi, fetchFile } from '@libs/fetch'; -import { FilterTypes, Filters } from '@libs/filterInputs'; -import { Plugin } from '@typings/plugin'; - -class LightNovelBrasil implements Plugin.PluginBase { - id = 'lightnovelbrasil'; - name = 'Light Novel Brasil'; - icon = 'src/pt/lightnovelbrasil/icon.png'; - site = 'https://lightnovelbrasil.com/'; - version = '1.0.0'; - - async popularNovels( - pageNo: number, - { filters }: Plugin.PopularNovelsOptions, - ): Promise { - let link = `${this.site}series/?page=${pageNo}`; - - if (filters.genres.value.length) - link += filters.genres.value.map(i => `&genre[]=${i}`).join(''); - - if (filters.type.value.length) - link += filters.type.value.map(i => `&lang[]=${i}`).join(''); - - link += '&status=' + (filters?.status ? filters.status : ''); - - link += '&order=' + (filters?.order ? filters.order : 'popular'); - - const headers = new Headers(); - const body = await fetchApi(link, { headers }).then(result => - result.text(), - ); - - const loadedCheerio = parseHTML(body); - - const novels: Plugin.NovelItem[] = []; - - loadedCheerio('article.bs').each((idx, ele) => { - const novelName = loadedCheerio(ele).find('.ntitle').text().trim(); - let image = loadedCheerio(ele).find('img'); - const novelCover = image.attr('data-src') || image.attr('src'); - - const novelUrl = loadedCheerio(ele).find('a').attr('href'); - - if (!novelUrl) return; - - const novel = { - name: novelName, - cover: novelCover, - path: novelUrl.replace(this.site, ''), - }; - - novels.push(novel); - }); - - return novels; - } - - async parseNovel(novelPath: string): Promise { - const url = this.site + novelPath; - const headers = new Headers(); - const result = await fetchApi(url, { headers }); - const body = await result.text(); - - let loadedCheerio = parseHTML(body); - - const novel: Plugin.SourceNovel = { - path: novelPath, - name: loadedCheerio('.entry-title').text(), - chapters: [], - }; - - novel.cover = - loadedCheerio('img.wp-post-image').attr('data-src') || - loadedCheerio('img.wp-post-image').attr('src'); - - loadedCheerio('div.spe > span').each(function () { - const detailName = loadedCheerio(this).find('b').text().trim(); - const detail = loadedCheerio(this).find('b').remove().end().text().trim(); - - switch (detailName) { - case 'Autor:': - case 'Author:': - novel.author = detail; - break; - case 'Status:': - novel.status = detail; - break; - } - }); - - novel.genres = loadedCheerio('.genxed').text().trim().replace(/\s/g, ','); - - loadedCheerio('div[itemprop="description"] h3,p.a,strong').remove(); - novel.summary = loadedCheerio('div[itemprop="description"]') - .find('br') - .replaceWith('\n') - .end() - .text(); - - let chapter: Plugin.ChapterItem[] = []; - - loadedCheerio('.eplister') - .find('li') - .each((idx, ele) => { - const chapterName = - loadedCheerio(ele).find('.epl-num').text() + - ' - ' + - loadedCheerio(ele).find('.epl-title').text(); - - const releaseDate = loadedCheerio(ele).find('.epl-date').text().trim(); - - const chapterUrl = loadedCheerio(ele).find('a').attr('href'); - - if (!chapterUrl) return; - - chapter.push({ - name: chapterName, - releaseTime: releaseDate, - path: chapterUrl.replace(this.site, ''), - }); - }); - - novel.chapters = chapter.reverse(); - - return novel; - } - async parseChapter(chapterPath: string): Promise { - const headers = new Headers(); - const result = await fetchApi(this.site + chapterPath, { headers }); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - let chapterText = loadedCheerio('.epcontent').html() || ''; - - return chapterText; - } - - async searchNovels( - searchTerm: string, - pageNo?: number | undefined, - ): Promise { - const url = `${this.site}?s=${searchTerm}`; - const headers = new Headers(); - const result = await fetchApi(url, { headers }); - const body = await result.text(); - - const loadedCheerio = parseHTML(body); - - const novels: Plugin.NovelItem[] = []; - - loadedCheerio('article.bs').each((idx, ele) => { - const novelName = loadedCheerio(ele).find('.ntitle').text().trim(); - const novelCover = loadedCheerio(ele).find('img').attr('src'); - const novelUrl = loadedCheerio(ele).find('a').attr('href'); - if (!novelUrl) return; - - novels.push({ - name: novelName, - path: novelUrl.replace(this.site, ''), - cover: novelCover, - }); - }); - - return novels; - } - async fetchImage(url: string): Promise { - return await fetchFile(url); - } - - filters = { - order: { - label: 'Sort By', - value: '', - options: [ - { label: 'Default', value: '' }, - - { label: 'A-Z', value: 'title' }, - - { label: 'Z-A', value: 'titlereverse' }, - - { label: 'Latest Update', value: 'update' }, - - { label: 'Latest Added', value: 'latest' }, - - { label: 'Popular', value: 'popular' }, - ], - type: FilterTypes.Picker, - }, - status: { - label: 'Status', - value: '', - options: [ - { label: 'All', value: '' }, - - { label: 'Ongoing', value: 'ongoing' }, - - { label: 'Hiatus', value: 'hiatus' }, - - { label: 'Completed', value: 'completed' }, - ], - type: FilterTypes.Picker, - }, - type: { - label: 'Type', - value: [], - options: [ - { label: 'Chinese novel', value: 'chinese-novel' }, - - { label: 'habyeol', value: 'habyeol' }, - - { label: 'korean novel', value: 'korean-novel' }, - - { label: 'Web Novel', value: 'web-novel' }, - - { label: '삼심', value: '%ec%82%bc%ec%8b%ac' }, - - { label: '호곡', value: '%ed%98%b8%ea%b3%a1' }, - ], - type: FilterTypes.CheckboxGroup, - }, - genres: { - value: [], - label: 'Genres', - options: [ - { label: 'A.I', value: 'a.i' }, - - { label: 'Academy', value: 'academy' }, - - { label: 'Action', value: 'action' }, - - { label: 'Adult', value: 'adult' }, - - { label: 'Adventure', value: 'adventure' }, - - { label: 'Alternative History', value: 'alternative-history' }, - - { label: 'Another World', value: 'another-world' }, - - { label: 'Apocalypse', value: 'apocalypse' }, - - { label: 'Bromance', value: 'bromance' }, - - { label: 'Comedy', value: 'comedy' }, - - { label: 'Dark fantasy', value: 'dark-fantasy' }, - - { label: 'Demons', value: 'demons' }, - - { label: 'Drama', value: 'drama' }, - - { label: 'Dystopia', value: 'dystopia' }, - - { label: 'Ecchi', value: 'ecchi' }, - - { label: 'Entertainment', value: 'entertainment' }, - - { label: 'Exhaustion', value: 'exhaustion' }, - - { label: 'Fanfiction', value: 'fanfiction' }, - - { label: 'fantasy', value: 'fantasy' }, - - { label: 'finance', value: 'finance' }, - - { label: 'Full color', value: 'full-color' }, - - { label: 'Game', value: 'game' }, - - { label: 'Gender Bender', value: 'gender-bender' }, - - { label: 'Genius', value: 'genius' }, - - { label: 'Harem', value: 'harem' }, - - { label: 'Hero', value: 'hero' }, - - { label: 'Historical', value: 'historical' }, - - { label: 'Hunter', value: 'hunter' }, - - { label: 'korean novel', value: 'korean-novel' }, - - { label: 'Light Novel', value: 'light-novel' }, - - { - label: 'List Adventure Manga Genres', - value: 'list-adventure-manga-genres', - }, - - { label: 'Long Strip', value: 'long-strip' }, - - { label: 'Love comedy', value: 'love-comedy' }, - - { label: 'magic', value: 'magic' }, - - { label: 'Manhua', value: 'manhua' }, - - { label: 'Martial Arts', value: 'martial-arts' }, - - { label: 'Mature', value: 'mature' }, - - { label: 'Medieval', value: 'medieval' }, - - { label: 'Misunderstanding', value: 'misunderstanding' }, - - { label: 'Modern', value: 'modern' }, - - { label: 'modern fantasy', value: 'modern-fantasy' }, - - { label: 'music', value: 'music' }, - - { label: 'Mystery', value: 'mystery' }, - - { label: 'Necromancy', value: 'necromancy' }, - - { label: 'No Romance', value: 'no-romance' }, - - { label: 'NTL', value: 'ntl' }, - - { label: 'o', value: 'o' }, - - { label: 'Obsession', value: 'obsession' }, - - { label: 'Politics', value: 'politics' }, - - { label: 'Possession', value: 'possession' }, - - { label: 'Programming', value: 'programming' }, - - { label: 'Psychological', value: 'psychological' }, - - { label: 'Pure Love', value: 'pure-love' }, - - { label: 'Redemption', value: 'redemption' }, - - { label: 'Regression', value: 'regression' }, - - { label: 'Regret', value: 'regret' }, - - { label: 'Reincarnation', value: 'reincarnation' }, - - { label: 'Revenge', value: 'revenge' }, - - { label: 'Romance', value: 'romance' }, - - { label: 'Romance Fanrasy', value: 'romance-fanrasy' }, - - { label: 'Salvation', value: 'salvation' }, - - { label: 'School Life', value: 'school-life' }, - - { label: 'Sci-fi', value: 'sci-fi' }, - - { label: 'Science fiction', value: 'science-fiction' }, - - { label: 'Seinen', value: 'seinen' }, - - { label: 'Shounen', value: 'shounen' }, - - { label: 'Slice of Life', value: 'slice-of-life' }, - - { label: 'Soft yandere', value: 'soft-yandere' }, - - { label: 'Sports', value: 'sports' }, - - { label: 'Supernatural', value: 'supernatural' }, - - { label: 'Survival', value: 'survival' }, - - { label: 'system', value: 'system' }, - - { label: 'Time limit', value: 'time-limit' }, - - { label: 'Tragedy', value: 'tragedy' }, - - { label: 'Transmigration', value: 'transmigration' }, - - { label: 'TS', value: 'ts' }, - - { label: 'Tsundere', value: 'tsundere' }, - - { label: 'Unique', value: 'unique' }, - - { label: 'Wholesome', value: 'wholesome' }, - - { label: 'Wuxia', value: 'wuxia' }, - - { label: 'Xuanhuan', value: 'xuanhuan' }, - - { label: 'Yandere', value: 'yandere' }, - - { label: 'Yuri', value: 'yuri' }, - ], - type: FilterTypes.CheckboxGroup, - }, - } satisfies Filters; -} - -export default new LightNovelBrasil(); diff --git a/scripts/multisrc/lightnovelwp/filters/lightnovelbrasil.json b/scripts/multisrc/lightnovelwp/filters/lightnovelbrasil.json new file mode 100644 index 0000000..d063335 --- /dev/null +++ b/scripts/multisrc/lightnovelwp/filters/lightnovelbrasil.json @@ -0,0 +1,244 @@ +{ + "filters": { + "genre[]": { + "type": "Checkbox", + "label": "Genre", + "value": [], + "options": [ + { + "label": "+18", + "value": "18" + }, + { + "label": "Ação", + "value": "acao" + }, + { + "label": "Artes Marciais", + "value": "artes-marciais" + }, + { + "label": "Aventura", + "value": "aventura" + }, + { + "label": "Comédia", + "value": "comedia" + }, + { + "label": "Cultivo", + "value": "cultivo" + }, + { + "label": "Cyberpunk", + "value": "cyberpunk" + }, + { + "label": "Drama", + "value": "drama" + }, + { + "label": "Ecchi", + "value": "ecchi" + }, + { + "label": "Esportes", + "value": "esportes" + }, + { + "label": "Fanfiction", + "value": "fanfiction" + }, + { + "label": "Fantasia", + "value": "fantasia" + }, + { + "label": "Ficção Científica", + "value": "ficcao-cientifica" + }, + { + "label": "Games", + "value": "games" + }, + { + "label": "Harem", + "value": "harem" + }, + { + "label": "Horror", + "value": "horror" + }, + { + "label": "Isekai", + "value": "isekai" + }, + { + "label": "Magia", + "value": "magia" + }, + { + "label": "Mecha", + "value": "mecha" + }, + { + "label": "Militar", + "value": "militar" + }, + { + "label": "Mistério", + "value": "misterio" + }, + { + "label": "Novel Nacional", + "value": "novel-nacional" + }, + { + "label": "Psicológico", + "value": "psicologico" + }, + { + "label": "Romance", + "value": "romance" + }, + { + "label": "Sci-fi", + "value": "sci-fi" + }, + { + "label": "Seinen", + "value": "seinen" + }, + { + "label": "Shoujo", + "value": "shoujo" + }, + { + "label": "Shounen", + "value": "shounen" + }, + { + "label": "Shounen BL", + "value": "shounen-bl" + }, + { + "label": "Slice of Life", + "value": "slice-of-life" + }, + { + "label": "Sobrenatural", + "value": "sobrenatural" + }, + { + "label": "Terror", + "value": "terror" + }, + { + "label": "Tragédia", + "value": "tragedia" + }, + { + "label": "Vida Escolar", + "value": "vida-escolar" + }, + { + "label": "Wuxia", + "value": "wuxia" + }, + { + "label": "Xianxia", + "value": "xianxia" + }, + { + "label": "Xuanhuan", + "value": "xuanhuan" + }, + { + "label": "Yaoi", + "value": "yaoi" + }, + { + "label": "Yuri", + "value": "yuri" + } + ] + }, + "type[]": { + "type": "Checkbox", + "label": "Tipo", + "value": [], + "options": [ + { + "label": "Light Novel", + "value": "light-novel" + }, + { + "label": "Livro", + "value": "livro" + }, + { + "label": "One-Shot", + "value": "one-shot" + }, + { + "label": "Web Novel", + "value": "web-novel" + } + ] + }, + "status": { + "type": "Picker", + "label": "Status", + "value": "", + "options": [ + { + "label": "Tudo", + "value": "" + }, + { + "label": "Ongoing", + "value": "ongoing" + }, + { + "label": "Hiatus", + "value": "hiatus" + }, + { + "label": "Completed", + "value": "completed" + } + ] + }, + "order": { + "type": "Picker", + "label": "Ordenar por", + "value": "", + "options": [ + { + "label": "Padrão", + "value": "" + }, + { + "label": "A-Z", + "value": "title" + }, + { + "label": "Z-A", + "value": "titlereverse" + }, + { + "label": "Últimos Lançamentos", + "value": "update" + }, + { + "label": "Última Adição", + "value": "latest" + }, + { + "label": "Popular", + "value": "popular" + } + ] + } + } +} \ No newline at end of file diff --git a/scripts/multisrc/lightnovelwp/sources.json b/scripts/multisrc/lightnovelwp/sources.json index ecf33a0..efb1bf2 100644 --- a/scripts/multisrc/lightnovelwp/sources.json +++ b/scripts/multisrc/lightnovelwp/sources.json @@ -166,5 +166,14 @@ "reverseChapters": true, "seriesPath": "/novels/" } + }, + { + "id": "lightnovelbrasil", + "sourceSite": "https://lightnovelbrasil.com/", + "sourceName": "Light Novel Brasil", + "options": { + "lang": "Portuguese", + "reverseChapters": true + } } ]