Fix: non-english broken plugins (#701)
* fix epiknovel * fix: hasutl * fix: Novelas Ligera * fix: ReinoWuxia * fix: Oasis * fix: json script * fix: Skynovels * fix: Yuuki Tls * fix: Agitoon * fix: Syosetu * fix: IndoWebNovel * fix: Novel Ringan * fix: Sakura Novel * fix: Hako * minor: type checking when PRing
This commit is contained in:
@@ -1,142 +0,0 @@
|
||||
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;
|
||||
@@ -0,0 +1,145 @@
|
||||
import { load as parseHTML } from "cheerio";
|
||||
import { fetchFile } from "@libs/fetch";
|
||||
import { Plugin } from "@typings/plugin";
|
||||
import { Filters } from "@libs/filterInputs";
|
||||
|
||||
class HasulTL implements Plugin.PluginBase {
|
||||
id = "HasuTL";
|
||||
name = "Hasu Translations";
|
||||
icon = "src/es/hasutl/icon.png";
|
||||
site = "https://hasutl.wordpress.com/";
|
||||
filters?: Filters | undefined;
|
||||
version = "1.0.0";
|
||||
baseUrl = this.site
|
||||
async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions<Filters>): Promise<Plugin.NovelItem[]> {
|
||||
let url = this.baseUrl + "light-novels-activas/";
|
||||
|
||||
const result = await fetch(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
|
||||
const url = novelUrl;
|
||||
|
||||
const result = await fetch(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novel: Plugin.SourceNovel = {
|
||||
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: Plugin.ChapterItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
async parseChapter(chapterUrl: string): Promise<string> {
|
||||
const url = chapterUrl;
|
||||
|
||||
const result = await fetch(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let chapterText = loadedCheerio(".post-content").html() || '';
|
||||
|
||||
return chapterText;
|
||||
}
|
||||
async searchNovels(searchTerm: string, pageNo: number): Promise<Plugin.NovelItem[]> {
|
||||
const url = `${this.baseUrl}?s=${searchTerm}&post_type=wp-manga`;
|
||||
|
||||
const result = await fetch(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
async fetchImage(url: string): Promise<string | undefined> {
|
||||
return fetchFile(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new HasulTL();
|
||||
@@ -1,177 +0,0 @@
|
||||
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;
|
||||
@@ -0,0 +1,180 @@
|
||||
import { load as parseHTML } from "cheerio";
|
||||
import { fetchFile } from "@libs/fetch";
|
||||
import { Plugin } from "@typings/plugin";
|
||||
import { Filters } from "@libs/filterInputs";
|
||||
|
||||
class Ligera implements Plugin.PluginBase {
|
||||
id = "ligera.com";
|
||||
name = "Novelas Ligera";
|
||||
icon = "src/es/novelasligera/icon.png";
|
||||
site = "https://novelasligera.com/";
|
||||
filters?: Filters | undefined;
|
||||
version = "1.0.0";
|
||||
baseUrl = this.site;
|
||||
async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions<Filters>): Promise<Plugin.NovelItem[]> {
|
||||
let url = this.baseUrl;
|
||||
|
||||
const result = await fetch(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
|
||||
const url = this.baseUrl + "novela/" + novelUrl;
|
||||
|
||||
// console.log(url);
|
||||
|
||||
const result = await fetch(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novel: Plugin.SourceNovel = { 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: Plugin.ChapterItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
async parseChapter(chapterUrl: string): Promise<string> {
|
||||
const url = chapterUrl;
|
||||
// console.log(url);
|
||||
|
||||
const result = await fetch(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;
|
||||
}
|
||||
async searchNovels(searchTerm: string, pageNo: number): Promise<Plugin.NovelItem[]> {
|
||||
const url = this.baseUrl + "?s=" + searchTerm + "&post_type=wp-manga";
|
||||
// console.log(url);
|
||||
|
||||
const result = await fetch(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
async fetchImage(url: string): Promise<string | undefined> {
|
||||
return fetchFile(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new Ligera();
|
||||
@@ -1,214 +0,0 @@
|
||||
import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { Chapter, Novel, Plugin } from "@typings/plugin";
|
||||
import { load as parseHTML } 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 = parseHTML(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 = parseHTML(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 = parseHTML(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 = parseHTML(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,
|
||||
};
|
||||
@@ -0,0 +1,203 @@
|
||||
import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { Plugin } from "@typings/plugin";
|
||||
import { load as parseHTML } from "cheerio";
|
||||
import { defaultCover } from "@libs/defaultCover";
|
||||
import { Filters } from "@libs/filterInputs";
|
||||
|
||||
class ReinoWuxia implements Plugin.PluginBase {
|
||||
id = "awuxia.com";
|
||||
name = "ReinoWuxia";
|
||||
icon = "src/es/novelawuxia/icon.png";
|
||||
filters?: Filters | undefined;
|
||||
version = "1.0.0";
|
||||
site = "http://www.reinowuxia.com/"
|
||||
baseUrl = this.site;
|
||||
getNovelName(y: string | undefined) {
|
||||
return y?.replace(/-/g, " ").replace(/(?:^|\s)\S/g, (a) => a.toUpperCase());
|
||||
}
|
||||
async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions<Filters>): Promise<Plugin.NovelItem[]> {
|
||||
let url = this.baseUrl + "p/todas-las-novelas.html";
|
||||
|
||||
const result = await fetchApi(url, {
|
||||
method: "GET",
|
||||
});
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
loadedCheerio(".post-body.entry-content")
|
||||
.find("a")
|
||||
.each( (idx, ele) => {
|
||||
let novelName = loadedCheerio(ele)
|
||||
.attr("href")
|
||||
?.split("/")
|
||||
.pop()
|
||||
?.replace(".html", "");
|
||||
novelName = this.getNovelName(novelName);
|
||||
const novelCover = loadedCheerio(ele).find("img").attr("src");
|
||||
|
||||
let novelUrl = loadedCheerio(ele).attr("href");
|
||||
|
||||
if (!novelName || !novelUrl) return;
|
||||
|
||||
const novel = {
|
||||
name: novelName,
|
||||
cover: novelCover,
|
||||
url: novelUrl,
|
||||
};
|
||||
|
||||
novels.push(novel);
|
||||
});
|
||||
|
||||
return novels;
|
||||
}
|
||||
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
|
||||
const url = novelUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novel: Plugin.SourceNovel = { 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) {
|
||||
const text = loadedCheerio(detail).text();
|
||||
|
||||
if (detailName.includes("Autor")) {
|
||||
novel.author = text.replace("Autor:", "");
|
||||
}
|
||||
|
||||
if (detailName.includes("Estatus")) {
|
||||
novel.status = text.replace("Estatus: ", "");
|
||||
}
|
||||
if (detailName.includes("Géneros:")) {
|
||||
novel.genres = text
|
||||
.replace("Géneros: ", "")
|
||||
.replace(/,\s/g, ",");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let novelChapters: Plugin.ChapterItem[] = [];
|
||||
|
||||
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 parseChapter(chapterUrl: string): Promise<string> {
|
||||
const url = chapterUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let chapterText = loadedCheerio(".post-body.entry-content").html() || '';
|
||||
|
||||
return chapterText;
|
||||
}
|
||||
async searchNovels(searchTerm: string, pageNo: number): Promise<Plugin.NovelItem[]> {
|
||||
const url = `${this.baseUrl}search?q=${searchTerm}`;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
loadedCheerio(".date-outer").each((idx, ele) => {
|
||||
let novelName = loadedCheerio(ele)
|
||||
.find("a")
|
||||
.attr("href")
|
||||
?.split("/")
|
||||
.pop()
|
||||
?.replace(/-capitulo(.*?).html/, "");
|
||||
|
||||
const novelUrl = novelName + ".html/";
|
||||
|
||||
novelName = this.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;
|
||||
}
|
||||
async fetchImage(url: string): Promise<string | undefined> {
|
||||
return fetchFile(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new ReinoWuxia();
|
||||
@@ -1,164 +0,0 @@
|
||||
import { fetchFile, fetchApi } from "@libs/fetch";
|
||||
import { Chapter, Novel, Plugin } from "@typings/plugin";
|
||||
import { load as parseHTML } 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 = parseHTML(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 = 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 > 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| /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 = parseHTML(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 = parseHTML(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;
|
||||
};
|
||||
|
||||
export const fetchImage: Plugin.fetchImage = fetchFile;
|
||||
@@ -0,0 +1,171 @@
|
||||
import { fetchFile, fetchApi } from "@libs/fetch";
|
||||
import { Filters } from "@libs/filterInputs";
|
||||
import { Plugin } from "@typings/plugin";
|
||||
import { load as parseHTML } 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;
|
||||
|
||||
class Oasis implements Plugin.PluginBase {
|
||||
id = "oasisTL.wp";
|
||||
name = "Oasis Translations";
|
||||
site = "https://oasistranslations.wordpress.com/";
|
||||
version = "1.0.0";
|
||||
filters?: Filters | undefined;
|
||||
icon = "src/es/oasistranslations/icon.png";
|
||||
async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions<Filters>): Promise<Plugin.NovelItem[]> {
|
||||
let url = baseUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
|
||||
const url = novelUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novel: Plugin.SourceNovel = { 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")) {
|
||||
const details = loadedCheerio(this).html()?.match(/<\/strong>(.|\n)*?<br>/g)?.
|
||||
map((detail) => detail.replace(/<strong>|<\/strong>|<br>|:\s/g, ""));
|
||||
|
||||
novel.genres = "";
|
||||
if (details){
|
||||
novel.author = details[2];
|
||||
novel.genres = details[4].replace(/\s| /g, "");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// let novelSummary = $(this).next().html();
|
||||
novel.summary = "";
|
||||
|
||||
let novelChapters: Plugin.ChapterItem[] = [];
|
||||
|
||||
// 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 parseChapter(chapterUrl: string): Promise<string> {
|
||||
const url = chapterUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
loadedCheerio("div#jp-post-flair").remove();
|
||||
|
||||
let chapterText = loadedCheerio(".entry-content").html() || '';
|
||||
|
||||
return chapterText;
|
||||
}
|
||||
async searchNovels(searchTerm: string, pageNo: number): Promise<Plugin.NovelItem[]> {
|
||||
searchTerm = searchTerm.toLowerCase();
|
||||
|
||||
let url = baseUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
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;
|
||||
}
|
||||
async fetchImage(url: string): Promise<string | undefined> {
|
||||
return fetchFile(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new Oasis();
|
||||
@@ -1,21 +1,22 @@
|
||||
import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { Chapter, Novel, Plugin } from "@typings/plugin";
|
||||
import { Filters } from "@libs/filterInputs";
|
||||
import { 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";
|
||||
class SkyNovels implements Plugin.PluginBase {
|
||||
id = "skynovels.net";
|
||||
name = "SkyNovels";
|
||||
site = "https://www.skynovels.net/";
|
||||
version = "1.0.0";
|
||||
icon = "src/es/skynovels/icon.png";
|
||||
baseUrl = this.site;
|
||||
|
||||
const baseUrl = site;
|
||||
|
||||
export const popularNovels: Plugin.popularNovels = async function (page) {
|
||||
async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions<Filters>): Promise<Plugin.NovelItem[]> {
|
||||
const url = "https://api.skynovels.net/api/novels?&q";
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.json() as response;
|
||||
|
||||
const novels: Novel.Item[] = [];
|
||||
const novels: Plugin.NovelItem[] = [];
|
||||
|
||||
body.novels?.forEach((res) => {
|
||||
const novelName = res.nvl_title;
|
||||
@@ -24,7 +25,7 @@ export const popularNovels: Plugin.popularNovels = async function (page) {
|
||||
res.image +
|
||||
"/novels/false";
|
||||
const novelUrl =
|
||||
baseUrl + "novelas/" + res.id + "/" + res.nvl_name + "/";
|
||||
this.baseUrl + "novelas/" + res.id + "/" + res.nvl_name + "/";
|
||||
|
||||
const novel = { name: novelName, url: novelUrl, cover: novelCover };
|
||||
|
||||
@@ -32,11 +33,9 @@ export const popularNovels: Plugin.popularNovels = async function (page) {
|
||||
});
|
||||
|
||||
return novels;
|
||||
};
|
||||
|
||||
export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
|
||||
async function (novUrl) {
|
||||
const novelId = novUrl.split("/")[4];
|
||||
}
|
||||
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
|
||||
const novelId = novelUrl.split("/")[4];
|
||||
const url =
|
||||
"https://api.skynovels.net/api/novel/" + novelId + "/reading?&q";
|
||||
|
||||
@@ -45,7 +44,7 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
|
||||
|
||||
const item = body?.novel?.[0];
|
||||
|
||||
let novel: Novel.instance = { url: novUrl };
|
||||
let novel: Plugin.SourceNovel = { url: novelUrl };
|
||||
|
||||
novel.name = item?.nvl_title;
|
||||
|
||||
@@ -61,13 +60,13 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
|
||||
novel.summary = item?.nvl_content;
|
||||
novel.status = item?.nvl_status;
|
||||
|
||||
let novelChapters: Chapter.Item[] = [];
|
||||
let novelChapters: Plugin.ChapterItem[] = [];
|
||||
|
||||
item?.volumes?.forEach((volume) => {
|
||||
volume?.chapters?.forEach((chapter) => {
|
||||
const chapterName = chapter.chp_index_title;
|
||||
const releaseDate = new Date(chapter.createdAt).toDateString();
|
||||
const chapterUrl = novUrl + chapter.id + "/" + chapter.chp_name;
|
||||
const chapterUrl = novelUrl + chapter.id + "/" + chapter.chp_name;
|
||||
|
||||
const chap = {
|
||||
name: chapterName,
|
||||
@@ -82,10 +81,9 @@ export const parseNovelAndChapters: Plugin.parseNovelAndChapters =
|
||||
novel.chapters = novelChapters;
|
||||
|
||||
return novel;
|
||||
};
|
||||
|
||||
export const parseChapter: Plugin.parseChapter = async function (chapUrl) {
|
||||
let chapterId: string = chapUrl.split("/")[6];
|
||||
}
|
||||
async parseChapter(chapterUrl: string): Promise<string> {
|
||||
let chapterId: string = chapterUrl.split("/")[6];
|
||||
const url = `https://api.skynovels.net/api/novel-chapter/${chapterId}`;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
@@ -96,9 +94,8 @@ export const parseChapter: Plugin.parseChapter = async function (chapUrl) {
|
||||
let chapterText = item?.chp_content || '404';
|
||||
|
||||
return chapterText;
|
||||
};
|
||||
|
||||
export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
|
||||
}
|
||||
async searchNovels(searchTerm: string, pageNo: number): Promise<Plugin.NovelItem[]> {
|
||||
searchTerm = searchTerm.toLowerCase();
|
||||
const url = "https://api.skynovels.net/api/novels?&q";
|
||||
|
||||
@@ -109,7 +106,7 @@ export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
|
||||
novel.nvl_title.toLowerCase().includes(searchTerm)
|
||||
);
|
||||
|
||||
const novels: Novel.Item[] = [];
|
||||
const novels: Plugin.NovelItem[] = [];
|
||||
|
||||
results?.forEach((res) => {
|
||||
const novelName = res.nvl_title;
|
||||
@@ -118,7 +115,7 @@ export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
|
||||
res.image +
|
||||
"/novels/false";
|
||||
const novelUrl =
|
||||
baseUrl + "novelas/" + res.id + "/" + res.nvl_name + "/";
|
||||
this.baseUrl + "novelas/" + res.id + "/" + res.nvl_name + "/";
|
||||
|
||||
const novel = { name: novelName, url: novelUrl, cover: novelCover };
|
||||
|
||||
@@ -126,9 +123,13 @@ export const searchNovels: Plugin.searchNovels = async function (searchTerm) {
|
||||
});
|
||||
|
||||
return novels;
|
||||
};
|
||||
}
|
||||
async fetchImage(url: string): Promise<string | undefined> {
|
||||
return fetchFile(url);
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchImage: Plugin.fetchImage = fetchFile;
|
||||
export default new SkyNovels();
|
||||
|
||||
interface response {
|
||||
novels?: (NovelsEntity)[] | null;
|
||||
@@ -1,180 +0,0 @@
|
||||
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;
|
||||
@@ -0,0 +1,192 @@
|
||||
import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { Filters } from "@libs/filterInputs";
|
||||
import { 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;
|
||||
|
||||
class Yuuki implements Plugin.PluginBase {
|
||||
id = "yuukitls.com";
|
||||
name = "Yuuki Tls";
|
||||
icon = "src/es/yuukitls/icon.png";
|
||||
site = "https://yuukitls.com/";
|
||||
filters?: Filters | undefined;
|
||||
version = "1.0.0";
|
||||
baseUrl = this.site;
|
||||
|
||||
async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions<Filters>): Promise<Plugin.NovelItem[]> {
|
||||
let url = baseUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
|
||||
const url = novelUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novel: Plugin.SourceNovel = {
|
||||
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: Plugin.ChapterItem[] = [];
|
||||
|
||||
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 parseChapter(chapterUrl: string): Promise<string> {
|
||||
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;
|
||||
}
|
||||
async searchNovels(searchTerm: string, pageNo: number): Promise<Plugin.NovelItem[]> {
|
||||
searchTerm = searchTerm.toLowerCase();
|
||||
|
||||
let url = baseUrl;
|
||||
|
||||
const result = await fetchApi(url);
|
||||
const body = await result.text();
|
||||
|
||||
let loadedCheerio = parseHTML(body);
|
||||
|
||||
let novels: Plugin.NovelItem[] = [];
|
||||
|
||||
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;
|
||||
}
|
||||
fetchImage(url: string): Promise<string | undefined> {
|
||||
return fetchFile(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default new Yuuki();
|
||||
Reference in New Issue
Block a user