Add accordion and fix minor issues (#742)
* Add docs v0.0.1 * Add icon size warning * Fix sourcenover caution * Fix semver descriptions * Filters fix * Quickfix quickstart * Add icon warning v2 * Fix typos * Add NovelItem * Update plugins host * Update plugins host * Remove unnecesarry .js and .dist * Update plugins host * Add host.ps1 * Fix readme.txt * Fix READNE.txt, again * Remove .js and .dist * Add accordion * Working pagination * readme update with ost * Add linux/windows hosting functions * Add tswatch * Fix fetch function * Change plugin versions * Fix chrome * Fix workflows * Fix search not showing results * remove unnecesarry code * Revert novelupdates changes * Reverted NobleMTL instead of novelupdates, fixing that * Revert nobleMTL to e346c7d0 * WTF NobleMTL?
This commit is contained in:
+125
-40
@@ -1,8 +1,9 @@
|
||||
import { load as loadCheerio } from "cheerio";
|
||||
import { fetchFile } from "@libs/fetch";
|
||||
import { load, load as loadCheerio } from "cheerio";
|
||||
import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { Plugin } from "@typings/plugin";
|
||||
import { defaultCover } from "@libs/defaultCover";
|
||||
import { Filters } from "@libs/filterInputs";
|
||||
import { FilterTypes, Filters } from "@libs/filterInputs";
|
||||
import { NovelItem } from "../../test_web/static/js";
|
||||
// const novelStatus = require('@libs/novelStatus');
|
||||
// const isUrlAbsolute = require('@libs/isAbsoluteUrl');
|
||||
// const parseDate = require('@libs/parseDate');
|
||||
@@ -12,11 +13,11 @@ class Syosetu implements Plugin.PluginBase {
|
||||
name = "Syosetu";
|
||||
icon = "src/jp/syosetu/icon.png";
|
||||
site = "https://yomou.syosetu.com/";
|
||||
filters?: Filters | undefined;
|
||||
version = "1.0.0";
|
||||
version = "1.1.0";
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||
}
|
||||
"User-Agent":
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
||||
};
|
||||
searchUrl = (pagenum?: number, order?: string) => {
|
||||
return `https://yomou.syosetu.com/search.php?order=${order || "hyoka"}${
|
||||
pagenum !== undefined
|
||||
@@ -24,37 +25,62 @@ class Syosetu implements Plugin.PluginBase {
|
||||
: "" // if isn't don't set ?p
|
||||
}`;
|
||||
};
|
||||
async popularNovels(pageNo: number, options: Plugin.PopularNovelsOptions<Filters>): Promise<Plugin.NovelItem[]> {
|
||||
async popularNovels(
|
||||
pageNo: number,
|
||||
{ filters }: Plugin.PopularNovelsOptions<typeof this.filters>
|
||||
): Promise<Plugin.NovelItem[]> {
|
||||
const getNovelsFromPage = async (pagenumber: number) => {
|
||||
// load page
|
||||
let url = this.site;
|
||||
|
||||
const result = await fetch(this.searchUrl(pagenumber), {headers: this.headers});
|
||||
const body = await result.text();
|
||||
// Cheerio it!
|
||||
const cheerioQuery = loadCheerio(body, { decodeEntities: false });
|
||||
let pageNovels: Plugin.NovelItem[] = [];
|
||||
// find class=searchkekka_box
|
||||
cheerioQuery(".searchkekka_box").each(function (i, e) {
|
||||
// get div with link and name
|
||||
const novelDIV = cheerioQuery(this).find(".novel_h");
|
||||
// get link element
|
||||
const novelA = novelDIV.children()[0];
|
||||
// add new novel to array
|
||||
pageNovels.push({
|
||||
name: novelDIV.text(), // get the name
|
||||
url: novelA.attribs.href, // get last part of the link
|
||||
cover: defaultCover,
|
||||
});
|
||||
if (!filters.genre.value) {
|
||||
url += `rank/list/type/${filters.ranking.value}_${filters.modifier.value}/?p=${pagenumber}`;
|
||||
} else {
|
||||
url += `rank/${
|
||||
filters.genre.value.length === 1
|
||||
? "isekailist"
|
||||
: "genrelist"
|
||||
}/type/${filters.ranking.value}_${filters.genre.value}${
|
||||
filters.modifier.value === "total"
|
||||
? ""
|
||||
: `_${filters.modifier.value}`
|
||||
}/?p=${pagenumber}`;
|
||||
}
|
||||
const html = await (await fetchApi(url)).text();
|
||||
|
||||
const loadedCheerio = loadCheerio(html, {
|
||||
decodeEntities: false,
|
||||
});
|
||||
// return all novels from this page
|
||||
return pageNovels;
|
||||
}
|
||||
|
||||
if (
|
||||
parseInt(loadedCheerio(".is-current").html() || "1") !==
|
||||
pagenumber
|
||||
)
|
||||
return [];
|
||||
|
||||
const novels: NovelItem[] = [];
|
||||
loadedCheerio(".c-card").each((_, e) => {
|
||||
const anchor = loadedCheerio(e).find(
|
||||
".p-ranklist-item__title a"
|
||||
);
|
||||
const url = anchor.attr("href");
|
||||
if (!url) return;
|
||||
const name = anchor.text();
|
||||
const novel: NovelItem = {
|
||||
url,
|
||||
name,
|
||||
cover: defaultCover,
|
||||
};
|
||||
novels.push(novel);
|
||||
});
|
||||
return novels;
|
||||
};
|
||||
const novels = await getNovelsFromPage(pageNo);
|
||||
return novels;
|
||||
}
|
||||
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
|
||||
let chapters: Plugin.ChapterItem[] = [];
|
||||
const result = await fetch(novelUrl, {headers: this.headers});
|
||||
const result = await fetch(novelUrl, { headers: this.headers });
|
||||
const body = await result.text();
|
||||
const loadedCheerio = loadCheerio(body, { decodeEntities: false });
|
||||
|
||||
@@ -103,7 +129,7 @@ class Syosetu implements Plugin.PluginBase {
|
||||
|
||||
const nameResult = await fetch(
|
||||
this.searchUrl() + `&word=${novel.name}`,
|
||||
{headers: this.headers}
|
||||
{ headers: this.headers }
|
||||
);
|
||||
const nameBody = await nameResult.text();
|
||||
const summaryQuery = loadCheerio(nameBody, {
|
||||
@@ -129,7 +155,7 @@ class Syosetu implements Plugin.PluginBase {
|
||||
return novel;
|
||||
}
|
||||
async parseChapter(chapterUrl: string): Promise<string> {
|
||||
const result = await fetch(chapterUrl, {headers: this.headers});
|
||||
const result = await fetch(chapterUrl, { headers: this.headers });
|
||||
const body = await result.text();
|
||||
|
||||
// create cheerioQuery
|
||||
@@ -137,20 +163,23 @@ class Syosetu implements Plugin.PluginBase {
|
||||
decodeEntities: false,
|
||||
});
|
||||
|
||||
let chapterText = cheerioQuery("#novel_honbun") // get chapter text
|
||||
.html() || '';
|
||||
let chapterText =
|
||||
cheerioQuery("#novel_honbun") // get chapter text
|
||||
.html() || "";
|
||||
return chapterText;
|
||||
}
|
||||
async searchNovels(searchTerm: string, pageNo: number): Promise<Plugin.NovelItem[]> {
|
||||
async searchNovels(
|
||||
searchTerm: string,
|
||||
pageNo: number
|
||||
): Promise<Plugin.NovelItem[]> {
|
||||
let novels = [];
|
||||
|
||||
// returns list of novels from given page
|
||||
const getNovelsFromPage = async (pagenumber: number) => {
|
||||
// load page
|
||||
const result = await fetch(
|
||||
this.searchUrl(pagenumber) + `&word=${searchTerm}`,
|
||||
{headers: this.headers}
|
||||
);
|
||||
const url = this.searchUrl(pagenumber) + `&word=${searchTerm}`;
|
||||
console.log(url);
|
||||
const result = await fetch(url, { headers: this.headers });
|
||||
const body = await result.text();
|
||||
// Cheerio it!
|
||||
const cheerioQuery = loadCheerio(body, { decodeEntities: false });
|
||||
@@ -171,7 +200,7 @@ class Syosetu implements Plugin.PluginBase {
|
||||
});
|
||||
// return all novels from this page
|
||||
return pageNovels;
|
||||
}
|
||||
};
|
||||
|
||||
// counter of loaded pages
|
||||
// let pagesLoaded = 0;
|
||||
@@ -181,7 +210,7 @@ class Syosetu implements Plugin.PluginBase {
|
||||
// pagesLoaded++;
|
||||
// } while (pagesLoaded < maxPageLoad && isNext); // check if we should load more
|
||||
|
||||
novels = await getNovelsFromPage(1);
|
||||
novels = await getNovelsFromPage(pageNo);
|
||||
|
||||
/** Use
|
||||
* novels.push(...(await getNovelsFromPage(pageNumber)))
|
||||
@@ -194,6 +223,62 @@ class Syosetu implements Plugin.PluginBase {
|
||||
async fetchImage(url: string): Promise<string | undefined> {
|
||||
return fetchFile(url);
|
||||
}
|
||||
filters = {
|
||||
ranking: {
|
||||
type: FilterTypes.Picker,
|
||||
label: "Ranked by",
|
||||
options: [
|
||||
{ label: "日間", value: "daily" },
|
||||
{ label: "週間", value: "weekly" },
|
||||
{ label: "月間", value: "monthly" },
|
||||
{ label: "四半期", value: "quarter" },
|
||||
{ label: "年間", value: "yearly" },
|
||||
{ label: "累計", value: "total" },
|
||||
],
|
||||
value: "total",
|
||||
},
|
||||
genre: {
|
||||
type: FilterTypes.Picker,
|
||||
label: "Ranking Genre",
|
||||
options: [
|
||||
{ label: "総ジャンル", value: "" },
|
||||
{ label: "異世界転生/転移〔恋愛〕〕", value: "1" },
|
||||
{ label: "異世界転生/転移〔ファンタジー〕", value: "2" },
|
||||
{ label: "異世界転生/転移〔文芸・SF・その他〕", value: "o" },
|
||||
{ label: "異世界〔恋愛〕", value: "101" },
|
||||
{ label: "現実世界〔恋愛〕", value: "102" },
|
||||
{ label: "ハイファンタジー〔ファンタジー〕", value: "201" },
|
||||
{ label: "ローファンタジー〔ファンタジー〕", value: "202" },
|
||||
{ label: "純文学〔文芸〕", value: "301" },
|
||||
{ label: "ヒューマンドラマ〔文芸〕", value: "302" },
|
||||
{ label: "歴史〔文芸〕", value: "303" },
|
||||
{ label: "推理〔文芸〕", value: "304" },
|
||||
{ label: "ホラー〔文芸〕", value: "305" },
|
||||
{ label: "アクション〔文芸〕", value: "306" },
|
||||
{ label: "コメディー〔文芸〕", value: "307" },
|
||||
{ label: "VRゲーム〔SF〕", value: "401" },
|
||||
{ label: "宇宙〔SF〕", value: "402" },
|
||||
{ label: "空想科学〔SF〕", value: "403" },
|
||||
{ label: "パニック〔SF〕", value: "404" },
|
||||
{ label: "童話〔その他〕", value: "9901" },
|
||||
{ label: "詩〔その他〕", value: "9902" },
|
||||
{ label: "エッセイ〔その他〕", value: "9903" },
|
||||
{ label: "その他〔その他〕", value: "9999" },
|
||||
],
|
||||
value: "",
|
||||
},
|
||||
modifier: {
|
||||
type: FilterTypes.Picker,
|
||||
label: "Modifier",
|
||||
options: [
|
||||
{ label: "すべて", value: "total" },
|
||||
{ label: "連載中", value: "r" },
|
||||
{ label: "完結済", value: "er" },
|
||||
{ label: "短編", value: "t" },
|
||||
],
|
||||
value: "total",
|
||||
},
|
||||
} satisfies Filters;
|
||||
}
|
||||
|
||||
export default new Syosetu();
|
||||
|
||||
Reference in New Issue
Block a user