Full TS for Plugins (#538)

* remove lang, descrription in plugin script

* remove languages import

* Update README.md

* fix: missing lang

* clean: remove description

* feat(Add Sources) (#15)

* add many sources

* add showToast

* feat(Add Source): (#16)

* add source

* remove descriptions

* Early Novel & Fast Novel (#1)

* some more plugin

* plugin

* try something new

* yes

* try yes

* genres is plural

* fastnovel full fix

* testings

* early check

* earlynovel fixed

* showToast check

* earlynovel done

* fastnovel fixe

* again

* showToasts again

* fix for fastnovel

* done

* for pr

* Update freenovelupdates.js

* MTL Reader and MTL Novel (#2)

* first

* test

* wops

* mtlreaders

* ok

* for PR

* Nitro Scans and Novel Hold (#3)

* start feature

* more feature

* something

* eslint

* yes

* maybe

* wa

* asdasd

* amazing

* change it up

* for pr

* WPmangastream and Novelfull (#4) (#17)

* source generation

* fix json parse error

* update plguins

* delete fetchApi, nobleMTL (.js)

* delete showToast.js

* Typescript Support (#18)

* Initial TS Config

* Initial TS Config

* Fix most errors

* Fix test webserver

* Fix webserver isPlugin not working

* Fix typos

* Add check if plugins have all the fields

* Move exports.protected to the bottom of the plugin

* Change username, reponame and branchname

* Fix no exports error

* Fix type

* Fix typo in tsc_fix

* Remove const from exports to not re-define consts

* Readd const becuause exports may not exist.

* Fix plugins to work in-app

* Fix NobleMTL

* Remove fix_ts.ts

* Change template.ts

* delete cheerio_space

* move api into ./testweb

* remove js dir

* remove js dir (again)

* remove ./js (again)

* init multisrc generator (test)

* remove module.exports in libs

* madara generator

* update template

* rename generator, TS for hako

* fix icon url for madara

* fix icon for madara (again)

* update Readme, nodemon

* export default for all libs

* fix madara novelurl

* update: pluginId, name, filename for madara

* feat: check same id error

* update: precommit, fix: require.default

* Revert "update: precommit, fix: require.default"

This reverts commit c642c5c72241f13eccfe417210c22272c4739ffa.

* Port all plugins to ts (#19)

- fix cheerio
- remove export default
- fix spelling

* update template

* add multisrc noveltl, update generator param, fix web search

* fix undefined id for Snailulitka

* add rulate multisrc, fix max length textarea

* add readwn multisrc

* delete: erolate and rulate are in multisrc

* Change broken extension and show error on commit for those files (#20)

* Change to .broken.ts and show error on commit for those files

* remove novelStatus

* fix: wrong id in github action

* remove mangastream multisrc

* update icon for readwn multisrc

---------

Co-authored-by: K1ngfish3r <trulyihu@gmail.com>
Co-authored-by: Marcin Majewski <skilletssgames@gmail.com>
This commit is contained in:
nyagami
2023-08-17 10:19:45 +07:00
committed by GitHub
parent e444031c25
commit e602df44c8
306 changed files with 58843 additions and 14008 deletions
-139
View File
@@ -1,139 +0,0 @@
const cheerio = require('cheerio');
const fetchApi = require('@libs/fetchApi');
const fetchFile = require('@libs/fetchFile');
const languages = require('@libs/languages');
const baseUrl = 'https://hasutl.wordpress.com/';
async function popularNovels (page) {
let url = baseUrl + 'light-novels-activas/';
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('div.wp-block-columns').each(function () {
const novelName = loadedCheerio(this).find('.wp-block-button').text();
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this)
.find('.wp-block-button > a')
.attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
async function parseNovelAndChapters (novelUrl) {
const url = novelUrl
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel = {};
novel.url = url;
novel.url = novelUrl;
novel.name = loadedCheerio('.post-header').text();
novel.cover = loadedCheerio('.featured-media > img').attr('src');
let novelSummary = loadedCheerio('.post-content').find('p').html();
novel.summary = novelSummary;
let novelChapters = [];
loadedCheerio('.wp-block-media-text__content')
.find('a')
.each(function () {
const chapterName = loadedCheerio(this).text().trim();
const releaseDate = null;
let chapterUrl = loadedCheerio(this).attr('href');
const chapter = { name: chapterName, releaseTime: releaseDate, url: chapterUrl };
novelChapters.push(chapter);
});
novel.chapters = novelChapters;
return novel;
};
async function parseChapter (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let chapterText = loadedCheerio('.post-content').html();
return chapterText;
};
async function searchNovels (searchTerm) {
const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.post-container ').each(function () {
const novelName = loadedCheerio(this).find('.post-header').text();
if (
!novelName.includes('Cap') &&
!novelName.includes('Vol') &&
!novelName.includes('Light Novels')
) {
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('a').attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
return novels;
};
module.exports = {
id: "HasuTL",
name: 'Hasu Translations',
site: baseUrl,
version: '1.0.0',
lang: languages.Spanish,
icon: 'src/es/hasutl/icon.png',
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
fetchImage: fetchFile,
};
+142
View File
@@ -0,0 +1,142 @@
import { load as parseHTML } from "cheerio";
import { fetchApi, fetchFile } from "@libs/fetch";
import { Chapter, Novel, Plugin } from "@typings/plugin";
export const id = "HasuTL";
export const name = "Hasu Translations";
export const site = "https://hasutl.wordpress.com/";
export const version = "1.0.0";
export const icon = "src/es/hasutl/icon.png";
const baseUrl = site;
export const popularNovels: Plugin.popularNovels = async function (page) {
let url = baseUrl + "light-novels-activas/";
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novels: Novel.Item[] = [];
loadedCheerio("div.wp-block-columns").each(function () {
const novelName = loadedCheerio(this).find(".wp-block-button").text();
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this)
.find(".wp-block-button > a")
.attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
async function (novelUrl) {
const url = novelUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novel: Novel.instance = {
url,
};
novel.url = novelUrl;
novel.name = loadedCheerio(".post-header").text();
novel.cover = loadedCheerio(".featured-media > img").attr("src");
let novelSummary = loadedCheerio(".post-content").find("p").html()!;
novel.summary = novelSummary;
let novelChapters: Chapter.Item[] = [];
loadedCheerio(".wp-block-media-text__content")
.find("a")
.each(function () {
const chapterName = loadedCheerio(this).text().trim();
const releaseDate = null;
let chapterUrl = loadedCheerio(this).attr("href");
if (!chapterUrl) return;
const chapter = {
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
};
novelChapters.push(chapter);
});
novel.chapters = novelChapters;
return novel;
};
export const parseChapter: Plugin.parseChapter = async function (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let chapterText = loadedCheerio(".post-content").html();
return chapterText;
};
export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novels: Novel.Item[] = [];
loadedCheerio(".post-container ").each(function () {
const novelName = loadedCheerio(this).find(".post-header").text();
if (
!novelName.includes("Cap") &&
!novelName.includes("Vol") &&
!novelName.includes("Light Novels")
) {
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).find("a").attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
return novels;
};
export const fetchImage: Plugin.fetchImage = fetchFile;
-177
View File
@@ -1,177 +0,0 @@
const cheerio = require('cheerio');
const fetchApi = require('@libs/fetchApi');
const fetchFile = require('@libs/fetchFile');
const languages = require('@libs/languages');
const baseUrl = 'https://novelasligera.com/';
async function popularNovels (page) {
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.elementor-column').each(function () {
const novelName = loadedCheerio(this)
.find('.widget-image-caption.wp-caption-text')
.text();
if (novelName) {
const novelCover = loadedCheerio(this).find('a > img').attr('data-lazy-src');
let novelUrl = loadedCheerio(this).find('a').attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
return novels;
};
async function parseNovelAndChapters ( novelUrl) {
const url = baseUrl + 'novela/' + novelUrl;
// console.log(url);
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel = {};
novel.url = url;
novel.name = loadedCheerio('h1').text();
novel.cover = loadedCheerio('.elementor-widget-container')
.find('img')
.attr('src');
loadedCheerio('.elementor-row')
.find('p')
.each(function () {
if (loadedCheerio(this).text().includes('Autor:')) {
novel.author = loadedCheerio(this).text().replace('Autor:', '').trim();
}
if (loadedCheerio(this).text().includes('Estado:')) {
novel.status = loadedCheerio(this)
.text()
.replace('Estado: ', '')
.trim();
}
if (loadedCheerio(this).text().includes('Género:')) {
loadedCheerio(this).find('span').remove();
novel.genres = loadedCheerio(this).text().replace(/,\s/g, ',');
}
});
novel.artist = null;
novel.summary = loadedCheerio(
'.elementor-text-editor.elementor-clearfix',
).text();
let novelChapters = [];
loadedCheerio('.elementor-accordion-item').remove();
loadedCheerio('.elementor-tab-content')
.find('li')
.each(function () {
const chapterName = loadedCheerio(this).text();
const releaseDate = null;
const chapterUrl = loadedCheerio(this)
.find('a')
.attr('href')
const chapter = { name: chapterName, releaseTime: releaseDate, url: chapterUrl };
novelChapters.push(chapter);
});
novel.chapters = novelChapters;
return novel;
};
async function parseChapter (chapterUrl) {
const url = chapterUrl;
// console.log(url);
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
loadedCheerio('.osny-nightmode.osny-nightmode--left').remove();
loadedCheerio('.code-block.code-block-1').remove();
loadedCheerio('.adsb30').remove();
loadedCheerio('.saboxplugin-wrap').remove();
loadedCheerio('.wp-post-navigation').remove();
let chapterText = loadedCheerio('.entry-content').html();
return chapterText;
};
async function searchNovels (searchTerm) {
const url = baseUrl + '?s=' + searchTerm + '&post_type=wp-manga';
// console.log(url);
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.inside-article').each(function () {
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('a').attr('href');
let novelName;
if (novelUrl) {
novelName = novelUrl.replace(/-/g, ' ').replace(/^./, function (x) {
return x.toUpperCase();
});
}
novelUrl += '/';
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
novels = [{ ...novels[1] }];
return novels;
};
module.exports = {
id: "ligera.com",
name: "Novelas Ligera",
site: baseUrl,
version: '1.0.0',
lang: languages.Spanish,
icon: 'src/es/novelasligera/icon.png',
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
fetchImage: fetchFile,
};
+177
View File
@@ -0,0 +1,177 @@
import { load as parseHTML } from "cheerio";
import { fetchApi, fetchFile } from "@libs/fetch";
import { Chapter, Novel, Plugin } from "@typings/plugin";
export const id = "ligera.com";
export const name = "Novelas Ligera";
export const site = "https://novelasligera.com/";
export const version = "1.0.0";
export const icon = "src/es/novelasligera/icon.png";
const baseUrl = site;
export const popularNovels: Plugin.popularNovels = async function (page) {
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novels: Novel.Item[] = [];
loadedCheerio(".elementor-column").each(function () {
const novelName = loadedCheerio(this)
.find(".widget-image-caption.wp-caption-text")
.text();
if (novelName) {
const novelCover = loadedCheerio(this)
.find("a > img")
.attr("data-lazy-src");
let novelUrl = loadedCheerio(this).find("a").attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
return novels;
};
export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
async function (novelUrl) {
const url = baseUrl + "novela/" + novelUrl;
// console.log(url);
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novel: Novel.instance = { url };
novel.name = loadedCheerio("h1").text();
novel.cover = loadedCheerio(".elementor-widget-container")
.find("img")
.attr("src");
loadedCheerio(".elementor-row")
.find("p")
.each(function () {
if (loadedCheerio(this).text().includes("Autor:")) {
novel.author = loadedCheerio(this)
.text()
.replace("Autor:", "")
.trim();
}
if (loadedCheerio(this).text().includes("Estado:")) {
novel.status = loadedCheerio(this)
.text()
.replace("Estado: ", "")
.trim();
}
if (loadedCheerio(this).text().includes("Género:")) {
loadedCheerio(this).find("span").remove();
novel.genres = loadedCheerio(this)
.text()
.replace(/,\s/g, ",");
}
});
novel.summary = loadedCheerio(
".elementor-text-editor.elementor-clearfix"
).text();
let novelChapters: Chapter.Item[] = [];
loadedCheerio(".elementor-accordion-item").remove();
loadedCheerio(".elementor-tab-content")
.find("li")
.each(function () {
const chapterName = loadedCheerio(this).text();
const releaseDate = null;
const chapterUrl = loadedCheerio(this).find("a").attr("href");
if (!chapterUrl) return;
const chapter = {
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
};
novelChapters.push(chapter);
});
novel.chapters = novelChapters;
return novel;
};
export const parseChapter: Plugin.parseChapter = async function (chapterUrl) {
const url = chapterUrl;
// console.log(url);
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
loadedCheerio(".osny-nightmode.osny-nightmode--left").remove();
loadedCheerio(".code-block.code-block-1").remove();
loadedCheerio(".adsb30").remove();
loadedCheerio(".saboxplugin-wrap").remove();
loadedCheerio(".wp-post-navigation").remove();
let chapterText = loadedCheerio(".entry-content").html();
return chapterText;
};
export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
const url = baseUrl + "?s=" + searchTerm + "&post_type=wp-manga";
// console.log(url);
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novels: Novel.Item[] = [];
loadedCheerio(".inside-article").each(function () {
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).find("a").attr("href");
let novelName;
if (novelUrl) {
novelName = novelUrl.replace(/-/g, " ").replace(/^./, function (x) {
return x.toUpperCase();
});
}
novelUrl += "/";
if (!novelName || !novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
novels = [{ ...novels[1] }];
return novels;
};
export const fetchImage: Plugin.fetchImage = fetchFile;
+214
View File
@@ -0,0 +1,214 @@
import { fetchApi, fetchFile } from "@libs/fetch";
import { Chapter, Novel, Plugin } from "@typings/plugin";
import cheerio from "cheerio";
import { defaultCover } from "@libs/defaultCover";
const pluginId = "awuxia.com";
const baseUrl = "http://www.reinowuxia.com/";
function getNovelName(y: string | undefined) {
return y?.replace(/-/g, " ").replace(/(?:^|\s)\S/g, (a) => a.toUpperCase());
}
export const popularNovels: Plugin.popularNovels = async function (page) {
let url = baseUrl + "p/todas-las-novelas.html";
let headers = {
"User-Agent":
"'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
};
const result = await fetchApi(url, {
method: "GET",
headers: headers,
});
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels: Novel.Item[] = [];
loadedCheerio(".post-body.entry-content")
.find("a")
.each(function () {
let novelName = loadedCheerio(this)
.attr("href")
?.split("/")
.pop()
?.replace(".html", "");
novelName = getNovelName(novelName);
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).attr("href");
if (!novelName || !novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
async function (novelUrl) {
const url = novelUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel: Novel.instance = { url };
novel.name = loadedCheerio("h1.post-title").text().trim();
novel.cover = loadedCheerio("div.separator").find("a").attr("href");
novel.status = "";
loadedCheerio("div > b").each(function () {
const detailName = loadedCheerio(this).text();
let detail = loadedCheerio(this)[0].nextSibling;
if (detailName && detail) {
detail = detail.nodeValue;
if (detailName.includes("Autor")) {
novel.author = detail.replace("Autor:", "");
}
if (detailName.includes("Estatus")) {
novel.status = detail.replace("Estatus: ", "");
}
if (detailName.includes("Géneros:")) {
novel.genres = detail
.replace("Géneros: ", "")
.replace(/,\s/g, ",");
}
}
});
let novelChapters: Chapter.Item[] = [];
loadedCheerio("div").each(function () {
const detailName = loadedCheerio(this).text();
if (detailName.includes("Sinopsis")) {
novel.summary =
loadedCheerio(this).next().text() !== ""
? loadedCheerio(this)
.next()
.text()
.replace("Sinopsis", "")
.trim()
: loadedCheerio(this)
.next()
.next()
.text()
.replace("Sinopsis", "")
.trim();
}
if (detailName.includes("Lista de Capítulos")) {
loadedCheerio(this)
.find("a")
.each(function (res) {
const chapterName = loadedCheerio(this).text();
let chapterUrl = loadedCheerio(this).attr("href");
const releaseDate = null;
if (
chapterName &&
chapterUrl &&
!novelChapters.some(
(chap) => chap.name === chapterName
)
) {
const chapter = {
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
};
novelChapters.push(chapter);
}
});
}
});
novel.chapters = novelChapters;
return novel;
};
export const parseChapter: Plugin.parseChapter = async function (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let chapterText = loadedCheerio(".post-body.entry-content").html();
return chapterText;
};
export const searchNovels: Plugin.searchNovels = async (searchTerm) => {
const url = `${baseUrl}search?q=${searchTerm}`;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels: Novel.Item[] = [];
loadedCheerio(".date-outer").each(function () {
let novelName = loadedCheerio(this)
.find("a")
.attr("href")
?.split("/")
.pop()
?.replace(/-capitulo(.*?).html/, "");
const novelUrl = novelName + ".html/";
novelName = getNovelName(novelName);
const exists = novels.some((novel) => novel.name === novelName);
if (!exists) {
const novelCover = defaultCover;
if (!novelUrl || !novelName) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
return novels;
};
module.exports = {
id: pluginId,
name: "ReinoWuxia",
site: baseUrl,
version: "1.0.0",
icon: "src/es/novelawuxia/icon.png",
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
fetchImage: fetchFile,
};
-205
View File
@@ -1,205 +0,0 @@
const fetchApi = require('@libs/fetchApi');
const languages = require('@libs/languages');
const fetchFile = require('@libs/fetchFile');
const cheerio = require('cheerio');
const pluginId = "awuxia.com"
const baseUrl = 'http://www.reinowuxia.com/';
function getNovelName(y) {
return y.replace(/-/g, ' ').replace(/(?:^|\s)\S/g, a => a.toUpperCase());
}
async function popularNovels (page) {
let url = baseUrl + 'p/todas-las-novelas.html';
let headers ={
'User-Agent':
"'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
};
const result = await fetchApi(url, {
method: 'GET',
headers: headers,
});
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.post-body.entry-content')
.find('a')
.each(function () {
let novelName = loadedCheerio(this)
.attr('href')
.split('/')
.pop()
.replace('.html', '');
novelName = getNovelName(novelName);
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
async function parseNovelAndChapters (novelUrl) {
const url = novelUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel = {};
novel.url = url;
novel.name = loadedCheerio('h1.post-title').text().trim();
novel.cover = loadedCheerio('div.separator').find('a').attr('href');
novel.artist = '';
novel.status = '';
loadedCheerio('div > b').each(function () {
const detailName = loadedCheerio(this).text();
let detail = loadedCheerio(this)[0].nextSibling;
if (detailName && detail) {
detail = detail.nodeValue;
if (detailName.includes('Autor')) {
novel.author = detail.replace('Autor:', '');
}
if (detailName.includes('Estatus')) {
novel.status = detail.replace('Estatus: ', '');
}
if (detailName.includes('Géneros:')) {
novel.genres = detail.replace('Géneros: ', '').replace(/,\s/g, ',');
}
}
});
let novelChapters = [];
loadedCheerio('div').each(function () {
const detailName = loadedCheerio(this).text();
if (detailName.includes('Sinopsis')) {
novel.summary =
loadedCheerio(this).next().text() !== ''
? loadedCheerio(this).next().text().replace('Sinopsis', '').trim()
: loadedCheerio(this)
.next()
.next()
.text()
.replace('Sinopsis', '')
.trim();
}
if (detailName.includes('Lista de Capítulos')) {
loadedCheerio(this)
.find('a')
.each(function (res) {
const chapterName = loadedCheerio(this).text();
let chapterUrl = loadedCheerio(this).attr('href');
const releaseDate = null;
if (
chapterName &&
chapterUrl &&
!novelChapters.some(chap => chap.name === chapterName)
) {
const chapter = {
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
};
novelChapters.push(chapter);
}
});
}
});
novel.chapters = novelChapters;
return novel;
};
async function parseChapter (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let chapterText = loadedCheerio('.post-body.entry-content').html();
return chapterText;
};
const searchNovels = async searchTerm => {
const url = `${baseUrl}search?q=${searchTerm}`;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.date-outer').each(function () {
let novelName = loadedCheerio(this)
.find('a')
.attr('href')
.split('/')
.pop()
.replace(/-capitulo(.*?).html/, '');
const novelUrl = novelName + '.html/';
novelName = getNovelName(novelName);
const exists = novels.some(novel => novel.novelName === novelName);
if (!exists) {
const novelCover = null;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
return novels;
};
module.exports = {
id: pluginId,
name: "ReinoWuxia",
site: baseUrl,
version: '1.0.0',
icon: 'src/es/novelawuxia/icon.png',
lang: languages.Spanish,
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
fetchImage: fetchFile,
};
+162
View File
@@ -0,0 +1,162 @@
import { fetchFile, fetchApi } from "@libs/fetch";
import { Chapter, Novel, Plugin } from "@typings/plugin";
import cheerio from "cheerio";
export const id = "oasisTL.wp";
export const name = "Oasis Translations";
export const site = "https://oasistranslations.wordpress.com/";
export const version = "1.0.0";
export const icon = "src/es/oasistranslations/icon.png";
const baseUrl = site;
export const popularNovels: Plugin.popularNovels = async function (page) {
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels: Novel.Item[] = [];
loadedCheerio(".menu-item-1819")
.find(".sub-menu > li")
.each(function () {
const novelName = loadedCheerio(this).text();
if (!novelName.match(/Activas|Finalizadas|Dropeadas/)) {
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).find("a").attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
return novels;
};
export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
async function (novelUrl) {
const url = novelUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel: Novel.instance = { url };
novel.name = loadedCheerio("h1.entry-title")
.text()
.replace(/[\t\n]/g, "")
.trim();
novel.cover = loadedCheerio('img[loading="lazy"]').attr("src");
loadedCheerio(".entry-content > p").each(function (res) {
if (loadedCheerio(this).text().includes("Autor")) {
let details = loadedCheerio(this).html()!;
details = details.match(/<\/strong>(.|\n)*?<br>/g);
details = details.map((detail) =>
detail.replace(/<strong>|<\/strong>|<br>|:\s/g, "")
);
novel.genres = "";
novel.author = details[2];
novel.genres = details[4].replace(/\s|&nbsp;/g, "");
}
});
// let novelSummary = $(this).next().html();
novel.summary = "";
let novelChapters: Chapter.Item[] = [];
// if ($(".entry-content").find("li").length) {
loadedCheerio(".entry-content")
.find("a")
.each(function () {
let chapterUrl = loadedCheerio(this).attr("href");
if (chapterUrl && chapterUrl.includes(baseUrl)) {
const chapterName = loadedCheerio(this).text();
const releaseDate = null;
const chapter = {
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
};
novelChapters.push(chapter);
}
});
novel.chapters = novelChapters;
return novel;
};
export const parseChapter: Plugin.parseChapter = async function (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
loadedCheerio("div#jp-post-flair").remove();
let chapterText = loadedCheerio(".entry-content").html();
return chapterText;
};
export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
searchTerm = searchTerm.toLowerCase();
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels: Novel.Item[] = [];
loadedCheerio(".menu-item-1819")
.find(".sub-menu > li")
.each(function () {
const novelName = loadedCheerio(this).text();
if (!novelName.match(/Activas|Finalizadas|Dropeadas/)) {
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).find("a").attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
novels = novels.filter((novel) =>
novel.name.toLowerCase().includes(searchTerm)
);
return novels;
};
-167
View File
@@ -1,167 +0,0 @@
const fetchApi = require('@libs/fetchApi');
const languages = require('@libs/languages');
const fetchFile = require('@libs/fetchFile');
const cheerio = require('cheerio');
const pluginId = 'oasisTL.wp';
const sourceName = 'Oasis Translations';
const baseUrl = 'https://oasistranslations.wordpress.com/';
async function popularNovels (page) {
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.menu-item-1819')
.find('.sub-menu > li')
.each(function () {
const novelName = loadedCheerio(this).text();
if (!novelName.match(/Activas|Finalizadas|Dropeadas/)) {
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('a').attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
return novels;
};
async function parseNovelAndChapters (novelUrl) {
const url = novelUrl
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel = {};
novel.url = url;
novel.name = loadedCheerio('h1.entry-title')
.text()
.replace(/[\t\n]/g, '')
.trim();
novel.cover = loadedCheerio('img[loading="lazy"]').attr('src');
loadedCheerio('.entry-content > p').each(function (res) {
if (loadedCheerio(this).text().includes('Autor')) {
let details = loadedCheerio(this).html();
details = details.match(/<\/strong>(.|\n)*?<br>/g);
details = details.map(detail =>
detail.replace(/<strong>|<\/strong>|<br>|:\s/g, ''),
);
novel.genres = '';
novel.author = details[2];
novel.genres = details[4].replace(/\s|&nbsp;/g, '');
novel.artist = details[3];
}
});
// let novelSummary = $(this).next().html();
novel.summary = '';
let novelChapters = [];
// if ($(".entry-content").find("li").length) {
loadedCheerio('.entry-content')
.find('a')
.each(function () {
let chapterUrl = loadedCheerio(this).attr('href');
if (chapterUrl && chapterUrl.includes(baseUrl)) {
const chapterName = loadedCheerio(this).text();
const releaseDate = null;
const chapter = { name: chapterName, releaseTime: releaseDate, url: chapterUrl };
novelChapters.push(chapter);
}
});
novel.chapters = novelChapters;
return novel;
};
async function parseChapter (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
loadedCheerio('div#jp-post-flair').remove();
let chapterText = loadedCheerio('.entry-content').html();
return chapterText;
};
async function searchNovels (searchTerm) {
searchTerm = searchTerm.toLowerCase();
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.menu-item-1819')
.find('.sub-menu > li')
.each(function () {
const novelName = loadedCheerio(this).text();
if (!novelName.match(/Activas|Finalizadas|Dropeadas/)) {
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('a').attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
}
});
novels = novels.filter(novel =>
novel.name.toLowerCase().includes(searchTerm),
);
return novels;
};
module.exports = {
id: pluginId,
name: sourceName,
site: baseUrl,
version: '1.0.0',
icon: 'src/es/oasistranslations/icon.png',
lang: languages.Spanish,
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
fetchImage: fetchFile,
};
+129
View File
@@ -0,0 +1,129 @@
import { fetchApi, fetchFile } from "@libs/fetch";
import { Chapter, Novel, Plugin } from "@typings/plugin";
export const id = "skynovels.net";
export const name = "SkyNovels";
export const site = "https://www.skynovels.net/";
export const version = "1.0.0";
export const icon = "src/es/skynovels/icon.png";
const baseUrl = site;
export const popularNovels: Plugin.popularNovels = async function (page) {
const url = "https://api.skynovels.net/api/novels?&q";
const result = await fetchApi(url);
const body = await result.json();
const novels: Novel.Item[] = [];
body.novels.map((res) => {
const novelName = res.nvl_title;
const novelCover =
"https://api.skynovels.net/api/get-image/" +
res.image +
"/novels/false";
const novelUrl =
baseUrl + "novelas/" + res.id + "/" + res.nvl_name + "/";
const novel = { name: novelName, url: novelUrl, cover: novelCover };
novels.push(novel);
});
return novels;
};
export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
async function (novUrl) {
let novelId = novUrl.substring().split("/")[4];
const url =
"https://api.skynovels.net/api/novel/" + novelId + "/reading?&q";
const result = await fetchApi(url);
const body = await result.json();
const item = body.novel[0];
let novel: Novel.instance = { url: novUrl };
novel.name = item.nvl_title;
novel.cover =
"https://api.skynovels.net/api/get-image/" +
item.image +
"/novels/false";
let genres: string[] = [];
item.genres.map((genre) => genres.push(genre.genre_name));
novel.genres = genres.join(",");
novel.author = item.nvl_writer;
novel.summary = item.nvl_content;
novel.status = item.nvl_status;
let novelChapters: Chapter.Item[] = [];
item.volumes.map((volume) => {
volume.chapters.map((chapter) => {
const chapterName = chapter.chp_index_title;
const releaseDate = new Date(chapter.createdAt).toDateString();
const chapterUrl = novUrl + chapter.id + "/" + chapter.chp_name;
const chap = {
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
};
novelChapters.push(chap);
});
});
novel.chapters = novelChapters;
return novel;
};
export const parseChapter: Plugin.parseChapter = async function (chapUrl) {
let chapterId = chapUrl.split("/")[6];
const url = `https://api.skynovels.net/api/novel-chapter/${chapterId}`;
const result = await fetchApi(url);
const body = await result.json();
const item = body.chapter[0];
let chapterText = item.chp_content;
return chapterText;
};
export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
searchTerm = searchTerm.toLowerCase();
const url = "https://api.skynovels.net/api/novels?&q";
const result = await fetchApi(url);
const body = await result.json();
let results = body.novels.filter((novel) =>
novel.nvl_title.toLowerCase().includes(searchTerm)
);
const novels: Novel.Item[] = [];
results.map((res) => {
const novelName = res.nvl_title;
const novelCover =
"https://api.skynovels.net/api/get-image/" +
res.image +
"/novels/false";
const novelUrl =
baseUrl + "novelas/" + res.id + "/" + res.nvl_name + "/";
const novel = { name: novelName, url: novelUrl, cover: novelCover };
novels.push(novel);
});
return novels;
};
-126
View File
@@ -1,126 +0,0 @@
const fetchApi = require('@libs/fetchApi');
const languages = require('@libs/languages');
const fetchFile = require('@libs/fetchFile');
const baseUrl = 'https://www.skynovels.net/';
async function popularNovels (page) {
const url = 'https://api.skynovels.net/api/novels?&q';
const result = await fetchApi(url);
const body = await result.json();
const novels = [];
body.novels.map(res => {
const novelName = res.nvl_title;
const novelCover =
'https://api.skynovels.net/api/get-image/' + res.image + '/novels/false';
const novelUrl = baseUrl + 'novelas/' + res.id + '/' + res.nvl_name + '/';
const novel = { name: novelName, url: novelUrl, cover: novelCover };
novels.push(novel);
});
return novels ;
};
async function parseNovelAndChapters (novUrl) {
let novelId = novUrl.substring().split('/')[4];
const url = 'https://api.skynovels.net/api/novel/' + novelId + '/reading?&q';
const result = await fetchApi(url);
const body = await result.json();
const item = body.novel[0];
let novel = {};
novel.url = novUrl;
novel.name = item.nvl_title;
novel.cover =
'https://api.skynovels.net/api/get-image/' + item.image + '/novels/false';
let genres = [];
item.genres.map(genre => genres.push(genre.genre_name));
novel.genres = genres.join(',');
novel.author = item.nvl_writer;
novel.summary = item.nvl_content;
novel.status = item.nvl_status;
let novelChapters = [];
item.volumes.map(volume => {
volume.chapters.map(chapter => {
const chapterName = chapter.chp_index_title;
const releaseDate = new Date(chapter.createdAt).toDateString();
const chapterUrl = novUrl + chapter.id + '/' + chapter.chp_name;
const chap = { name: chapterName, releaseTime: releaseDate, url: chapterUrl };
novelChapters.push(chap);
});
});
novel.chapters = novelChapters;
return novel;
};
async function parseChapter (chapUrl) {
let chapterId = chapUrl.split('/')[6];
const url = `https://api.skynovels.net/api/novel-chapter/${chapterId}`;
const result = await fetchApi(url);
const body = await result.json();
const item = body.chapter[0];
let chapterText = item.chp_content;
return chapterText;
};
async function searchNovels (searchTerm) {
searchTerm = searchTerm.toLowerCase();
const url = 'https://api.skynovels.net/api/novels?&q';
const result = await fetchApi(url);
const body = await result.json();
let results = body.novels.filter(novel =>
novel.nvl_title.toLowerCase().includes(searchTerm),
);
const novels = [];
results.map(res => {
const novelName = res.nvl_title;
const novelCover =
'https://api.skynovels.net/api/get-image/' + res.image + '/novels/false';
const novelUrl = baseUrl + 'novelas/' + res.id + '/' + res.nvl_name + '/';
const novel = { name: novelName, url: novelUrl, cover: novelCover };
novels.push(novel);
});
return novels;
};
module.exports = {
id: 'skynovels.net',
name: "SkyNovels",
site: baseUrl,
version: '1.0.0',
icon: 'src/es/skynovels/icon.png',
lang: languages.Spanish,
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
fetchImage: fetchFile,
};
-164
View File
@@ -1,164 +0,0 @@
const fetchApi = require('@libs/fetchApi');
const languages = require('@libs/languages');
const fetchFile = require('@libs/fetchFile');
const cheerio = require('cheerio');
const Status = require('@libs/novelStatus');
const defaultCoverUri =
'https://github.com/LNReader/lnreader-sources/blob/main/icons/src/coverNotAvailable.jpg?raw=true';
const pluginId = "TNL.com";
const sourceName = 'TuNovelaLigera';
const baseUrl = 'https://tunovelaligera.com/';
async function popularNovels (page) {
let url = baseUrl + 'novelas/page/' + page + '/?m_orderby=rating';
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.page-item-detail').each(function () {
const novelName = loadedCheerio(this).find('.h5 > a').text();
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this)
.find('.h5 > a')
.attr('href')
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
async function parseNovelAndChapters (novelUrl) {
const url = novelUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel = {
url,
};
loadedCheerio('.manga-title-badges').remove();
novel.name = loadedCheerio('.post-title > h1').text().trim();
let novelCover = loadedCheerio('.summary_image > a > img');
novel.cover =
novelCover.attr('data-src') || novelCover.attr('src') || defaultCoverUri;
loadedCheerio('.post-content_item').each(function () {
const detailName = loadedCheerio(this)
.find('.summary-heading > h5')
.text()
.trim();
const detail = loadedCheerio(this).find('.summary-content').text().trim();
switch (detailName) {
case 'Generos':
novel.genres = detail.replace(/, /g, ',');
break;
case 'Autores':
novel.author = detail;
break;
case 'Estado':
novel.status =
detail.includes('OnGoing') || detail.includes('Updating')
? Status.Ongoing
: Status.Completed;
break;
}
});
novel.summary = loadedCheerio('div.summary__content > p').text().trim();
let novelChapters = [];
loadedCheerio('.lcp_catlist li').each(function () {
const chapterName = loadedCheerio(this)
.find('a')
.text()
.replace(/[\t\n]/g, '')
.trim();
const releaseDate = loadedCheerio(this).find('span').text().trim();
let chapterUrl = loadedCheerio(this).find('a').attr('href');
novelChapters.push({ name: chapterName, releaseTime: releaseDate, url: chapterUrl });
});
novel.chapters = novelChapters.reverse();
return novel;
};
async function parseChapter (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let chapterText = loadedCheerio('#hola_siguiente').next().text();
return chapterText;
};
async function searchNovels (searchTerm) {
const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.c-tabs-item__content').each(function () {
const novelName = loadedCheerio(this).find('.h4 > a').text();
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('.h4 > a').attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
module.exports = {
id: pluginId,
name: sourceName,
site: baseUrl,
version: '1.0.0',
icon: 'src/es/tunovelaligera/icon.png',
lang: languages.Spanish,
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
fetchImage: fetchFile,
};
+161
View File
@@ -0,0 +1,161 @@
import { fetchApi, fetchFile } from "@libs/fetch";
import { load as parseHTML } from "cheerio";
import { NovelStatus } from "@libs/novelStatus";
import { defaultCover } from "@libs/defaultCover";
import { Chapter, Novel, Plugin } from "@typings/plugin";
export const id = "TNL.com";
export const name = "TuNovelaLigera";
export const site = "https://tunovelaligera.com/";
export const version = "1.0.0";
export const icon = "src/es/tunovelaligera/icon.png";
const baseUrl = site;
export const popularNovels: Plugin.popularNovels = async function (page) {
let url = baseUrl + "novelas/page/" + page + "/?m_orderby=rating";
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novels: Novel.Item[] = [];
loadedCheerio(".page-item-detail").each(function () {
const novelName = loadedCheerio(this).find(".h5 > a").text();
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).find(".h5 > a").attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
async function (novelUrl) {
const url = novelUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novel: Novel.instance = {
url,
};
loadedCheerio(".manga-title-badges").remove();
novel.name = loadedCheerio(".post-title > h1").text().trim();
let novelCover = loadedCheerio(".summary_image > a > img");
novel.cover =
novelCover.attr("data-src") ||
novelCover.attr("src") ||
defaultCover;
loadedCheerio(".post-content_item").each(function () {
const detailName = loadedCheerio(this)
.find(".summary-heading > h5")
.text()
.trim();
const detail = loadedCheerio(this)
.find(".summary-content")
.text()
.trim();
switch (detailName) {
case "Generos":
novel.genres = detail.replace(/, /g, ",");
break;
case "Autores":
novel.author = detail;
break;
case "Estado":
novel.status =
detail.includes("OnGoing") ||
detail.includes("Updating")
? NovelStatus.Ongoing
: NovelStatus.Completed;
break;
}
});
novel.summary = loadedCheerio("div.summary__content > p").text().trim();
let novelChapters: Chapter.Item[] = [];
loadedCheerio(".lcp_catlist li").each(function () {
const chapterName = loadedCheerio(this)
.find("a")
.text()
.replace(/[\t\n]/g, "")
.trim();
const releaseDate = loadedCheerio(this).find("span").text().trim();
let chapterUrl = loadedCheerio(this).find("a").attr("href");
if (!chapterUrl) return;
novelChapters.push({
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
});
});
novel.chapters = novelChapters.reverse();
return novel;
};
export const parseChapter: Plugin.parseChapter = async function (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let chapterText = loadedCheerio("#hola_siguiente").next().text();
return chapterText;
};
export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
const url = `${baseUrl}?s=${searchTerm}&post_type=wp-manga`;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novels: Novel.Item[] = [];
loadedCheerio(".c-tabs-item__content").each(function () {
const novelName = loadedCheerio(this).find(".h4 > a").text();
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).find(".h4 > a").attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
export const fetchImage: Plugin.fetchImage = fetchFile;
-183
View File
@@ -1,183 +0,0 @@
const fetchApi = require('@libs/fetchApi');
const languages = require('@libs/languages');
const fetchFile = require('@libs/fetchFile');
const cheerio = require('cheerio');
const pluginId = "yuukitls.com";
const baseUrl = 'https://yuukitls.com/';
async function popularNovels (page) {
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.quadmenu-navbar-collapse ul li:nth-child(2)')
.find('li')
.each(function () {
const novelName = loadedCheerio(this).text().replace(/[\s\n]+/g,' ');
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('a').attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels ;
};
async function parseNovelAndChapters (novelUrl) {
const url = novelUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novel = {};
novel.url = url;
novel.name = loadedCheerio('h1.entry-title')
.text()
.replace(/[\t\n]/g, '')
.trim();
novel.cover = loadedCheerio('img[loading="lazy"]').attr('src');
loadedCheerio('.entry-content')
.find('div')
.each(function () {
if (loadedCheerio(this).text().includes('Escritor:')) {
novel.author = loadedCheerio(this)
.text()
.replace('Escritor: ', '')
.trim();
}
if (loadedCheerio(this).text().includes('Ilustrador:')) {
novel.artist = loadedCheerio(this)
.text()
.replace('Ilustrador: ', '')
.trim();
}
if (loadedCheerio(this).text().includes('Género:')) {
novel.genres = loadedCheerio(this)
.text()
.replace(/Género: |\s/g, '');
}
if (loadedCheerio(this).text().includes('Sinopsis:')) {
novel.summary = loadedCheerio(this).next().text();
}
});
let novelChapters = [];
if (loadedCheerio('.entry-content').find('li').length) {
loadedCheerio('.entry-content')
.find('li')
.each(function () {
let chapterUrl = loadedCheerio(this).find('a').attr('href');
if (chapterUrl && chapterUrl.includes(baseUrl)) {
const chapterName = loadedCheerio(this).text();
const releaseDate = null;
const chapter = { name: chapterName, releaseTime: releaseDate, url: chapterUrl };
novelChapters.push(chapter);
}
});
} else {
loadedCheerio('.entry-content')
.find('p')
.each(function () {
let chapterUrl = loadedCheerio(this).find('a').attr('href');
if (chapterUrl && chapterUrl.includes(baseUrl)) {
const chapterName = loadedCheerio(this).text();
const releaseDate = null;
const chapter = { name: chapterName, releaseTime: releaseDate, url: chapterUrl };
novelChapters.push(chapter);
}
});
}
novel.chapters = novelChapters;
return novel;
};
async function parseChapter (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let chapterText = loadedCheerio('.entry-content').html();
return chapterText;
};
async function searchNovels (searchTerm) {
searchTerm = searchTerm.toLowerCase();
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = cheerio.load(body);
let novels = [];
loadedCheerio('.menu-item-2869')
.find('.menu-item.menu-item-type-post_type.menu-item-object-post')
.each(function () {
const novelName = loadedCheerio(this).text();
const novelCover = loadedCheerio(this).find('img').attr('src');
let novelUrl = loadedCheerio(this).find('a').attr('href');
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
novels = novels.filter(novel =>
novel.novelName.toLowerCase().includes(searchTerm),
);
return novels;
};
module.exports = {
id: pluginId,
name: "Yuuki Tls",
site: baseUrl,
version: '1.0.0',
icon: 'src/es/yuukitls/icon.png',
lang: languages.Spanish,
popularNovels,
parseNovelAndChapters,
parseChapter,
searchNovels,
fetchImage: fetchFile,
};
+180
View File
@@ -0,0 +1,180 @@
import { fetchApi, fetchFile } from "@libs/fetch";
import { Chapter, Novel, Plugin } from "@typings/plugin";
import { load as parseHTML } from "cheerio";
export const id = "yuukitls.com";
export const name = "Yuuki Tls";
export const site = "https://yuukitls.com/";
export const version = "1.0.0";
export const icon = "src/es/yuukitls/icon.png";
const baseUrl = site;
export const popularNovels: Plugin.popularNovels = async function (page) {
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novels: Novel.Item[] = [];
loadedCheerio(".quadmenu-navbar-collapse ul li:nth-child(2)")
.find("li")
.each(function () {
const novelName = loadedCheerio(this)
.text()
.replace(/[\s\n]+/g, " ");
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).find("a").attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
return novels;
};
export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
async function (novelUrl) {
const url = novelUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novel: Novel.instance = {
url,
};
novel.name = loadedCheerio("h1.entry-title")
.text()
.replace(/[\t\n]/g, "")
.trim();
novel.cover = loadedCheerio('img[loading="lazy"]').attr("src");
loadedCheerio(".entry-content")
.find("div")
.each(function () {
if (loadedCheerio(this).text().includes("Escritor:")) {
novel.author = loadedCheerio(this)
.text()
.replace("Escritor: ", "")
.trim();
}
if (loadedCheerio(this).text().includes("Género:")) {
novel.genres = loadedCheerio(this)
.text()
.replace(/Género: |\s/g, "");
}
if (loadedCheerio(this).text().includes("Sinopsis:")) {
novel.summary = loadedCheerio(this).next().text();
}
});
let novelChapters: Chapter.Item[] = [];
if (loadedCheerio(".entry-content").find("li").length) {
loadedCheerio(".entry-content")
.find("li")
.each(function () {
let chapterUrl = loadedCheerio(this).find("a").attr("href");
if (chapterUrl && chapterUrl.includes(baseUrl)) {
const chapterName = loadedCheerio(this).text();
const releaseDate = null;
const chapter = {
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
};
novelChapters.push(chapter);
}
});
} else {
loadedCheerio(".entry-content")
.find("p")
.each(function () {
let chapterUrl = loadedCheerio(this).find("a").attr("href");
if (chapterUrl && chapterUrl.includes(baseUrl)) {
const chapterName = loadedCheerio(this).text();
const releaseDate = null;
const chapter = {
name: chapterName,
releaseTime: releaseDate,
url: chapterUrl,
};
novelChapters.push(chapter);
}
});
}
novel.chapters = novelChapters;
return novel;
};
export const parseChapter: Plugin.parseChapter = async function (chapterUrl) {
const url = chapterUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let chapterText = loadedCheerio(".entry-content").html();
return chapterText;
};
export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
searchTerm = searchTerm.toLowerCase();
let url = baseUrl;
const result = await fetchApi(url);
const body = await result.text();
let loadedCheerio = parseHTML(body);
let novels: Novel.Item[] = [];
loadedCheerio(".menu-item-2869")
.find(".menu-item.menu-item-type-post_type.menu-item-object-post")
.each(function () {
const novelName = loadedCheerio(this).text();
const novelCover = loadedCheerio(this).find("img").attr("src");
let novelUrl = loadedCheerio(this).find("a").attr("href");
if (!novelUrl) return;
const novel = {
name: novelName,
cover: novelCover,
url: novelUrl,
};
novels.push(novel);
});
novels = novels.filter((novel) =>
novel.name.toLowerCase().includes(searchTerm)
);
return novels;
};
export const fetchImage: Plugin.fetchImage = fetchFile;