Refactor: Using English key (#728)

* fix: use english key instead of native

* fix: ukrainian

* fix: web test with new plugins map
This commit is contained in:
nyagami
2024-01-27 09:26:19 +07:00
committed by GitHub
parent 62fc988019
commit 6ff206eab3
5 changed files with 265 additions and 264 deletions

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

+5 -5
View File
@@ -2,14 +2,14 @@ export const languages = {
Arabic: "العربية", Arabic: "العربية",
Chinese: "中文, 汉语, 漢語", Chinese: "中文, 汉语, 漢語",
English: "English", English: "English",
French: "français, française", French: "Français",
Indonesian: "Bahasa Indonesia", Indonesian: "Bahasa Indonesia",
Japanese: "日本語", Japanese: "日本語",
Korean: "한국어, 조선말", Korean: "조선말, 한국어",
Portuguese: "Português", Portuguese: "Português",
Russian: "русский язык", Russian: "Русский",
Spanish: "español, castellano", Spanish: "Español",
Turkish: "Türkçe", Turkish: "Türkçe",
Ukraine: "Україна", Ukrainian: "Українська",
Vietnamese: "Tiếng Việt", Vietnamese: "Tiếng Việt",
} as const; } as const;
@@ -1,255 +1,256 @@
import { Plugin } from "@typings/plugin"; import { Plugin } from "@typings/plugin";
import { fetchApi, fetchFile } from "@libs/fetch"; import { fetchApi, fetchFile } from "@libs/fetch";
import { NovelStatus } from "@libs/novelStatus"; import { NovelStatus } from "@libs/novelStatus";
import dayjs from "dayjs"; import dayjs from "dayjs";
class Smakolykytl implements Plugin.PluginBase { class Smakolykytl implements Plugin.PluginBase {
id = "smakolykytl"; id = "smakolykytl";
name = "Смаколики"; name = "Смаколики";
site = "https://smakolykytl.site/"; site = "https://smakolykytl.site/";
version = "1.0.0"; version = "1.0.0";
icon = "src/ua/smakolykytl/icon.png"; icon = "src/uk/smakolykytl/icon.png";
async popularNovels(
pageNo: number, async popularNovels(
{ showLatestNovels, filters }: Plugin.PopularNovelsOptions, pageNo: number,
): Promise<Plugin.NovelItem[]> { { showLatestNovels, filters }: Plugin.PopularNovelsOptions,
const url = showLatestNovels ): Promise<Plugin.NovelItem[]> {
? "https://api.smakolykytl.site/api/user/updates" const url = showLatestNovels
: "https://api.smakolykytl.site/api/user/projects"; ? "https://api.smakolykytl.site/api/user/updates"
: "https://api.smakolykytl.site/api/user/projects";
const result = await fetchApi(url);
const json = (await result.json()) as response; const result = await fetchApi(url);
const json = (await result.json()) as response;
const novels: Plugin.NovelItem[] = [];
(json?.projects || json?.updates)?.forEach((novel) => const novels: Plugin.NovelItem[] = [];
novels.push({ (json?.projects || json?.updates)?.forEach((novel) =>
name: novel.title, novels.push({
cover: novel.image.url, name: novel.title,
url: this.site + "titles/" + novel.id, cover: novel.image.url,
}), url: this.site + "titles/" + novel.id,
); }),
);
return novels;
} return novels;
}
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
const id = novelUrl.split("/").pop(); async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
const result = await fetchApi( const id = novelUrl.split("/").pop();
"https://api.smakolykytl.site/api/user/projects/" + id, const result = await fetchApi(
); "https://api.smakolykytl.site/api/user/projects/" + id,
const book = (await result.json()) as response; );
const book = (await result.json()) as response;
const novel: Plugin.SourceNovel = {
url: novelUrl, const novel: Plugin.SourceNovel = {
name: book?.project?.title, url: novelUrl,
cover: book?.project?.image?.url, name: book?.project?.title,
summary: book?.project?.description, cover: book?.project?.image?.url,
author: book?.project?.author, summary: book?.project?.description,
status: book?.project?.status_translate.includes("Триває") author: book?.project?.author,
? NovelStatus.Ongoing status: book?.project?.status_translate.includes("Триває")
: NovelStatus.Completed, ? NovelStatus.Ongoing
}; : NovelStatus.Completed,
const tags = [book?.project?.genres, book?.project?.tags] };
.flat() const tags = [book?.project?.genres, book?.project?.tags]
.map((tags) => tags?.title) .flat()
.filter((tags) => tags); .map((tags) => tags?.title)
.filter((tags) => tags);
if (tags.length) {
novel.genres = tags.join(", "); if (tags.length) {
} novel.genres = tags.join(", ");
}
const chapters: Plugin.ChapterItem[] = [];
const res = await fetchApi( const chapters: Plugin.ChapterItem[] = [];
"https://api.smakolykytl.site/api/user/projects/" + id + "/books", const res = await fetchApi(
); "https://api.smakolykytl.site/api/user/projects/" + id + "/books",
const data = (await res.json()) as response; );
data?.books?.forEach( const data = (await res.json()) as response;
(volume) => data?.books?.forEach(
volume?.chapters?.map((chapter) => (volume) =>
chapters.push({ volume?.chapters?.map((chapter) =>
name: volume.title + " " + chapter.title, chapters.push({
releaseTime: dayjs(chapter.modifiedAt).format("LLL"), name: volume.title + " " + chapter.title,
url: this.site + "read/" + chapter.id, releaseTime: dayjs(chapter.modifiedAt).format("LLL"),
}), url: this.site + "read/" + chapter.id,
), }),
); ),
);
novel.chapters = chapters;
return novel; novel.chapters = chapters;
} return novel;
}
async parseChapter(chapterUrl: string): Promise<string> {
const id = chapterUrl.split("/").pop(); async parseChapter(chapterUrl: string): Promise<string> {
const result = await fetchApi( const id = chapterUrl.split("/").pop();
"https://api.smakolykytl.site/api/user/chapters/" + id, const result = await fetchApi(
); "https://api.smakolykytl.site/api/user/chapters/" + id,
const json = (await result.json()) as response; );
const chapterRaw: HTML[] = JSON.parse(json?.chapter?.content || "[]"); const json = (await result.json()) as response;
const chapterRaw: HTML[] = JSON.parse(json?.chapter?.content || "[]");
const chapterText = jsonToHtml(chapterRaw);
return chapterText; const chapterText = jsonToHtml(chapterRaw);
} return chapterText;
}
async searchNovels(
searchTerm: string, async searchNovels(
//pageNo: number | undefined = 1, searchTerm: string,
): Promise<Plugin.NovelItem[]> { //pageNo: number | undefined = 1,
const result = await fetchApi( ): Promise<Plugin.NovelItem[]> {
"https://api.smakolykytl.site/api/user/projects", const result = await fetchApi(
); "https://api.smakolykytl.site/api/user/projects",
const json = (await result.json()) as response; );
const novels: Plugin.NovelItem[] = []; const json = (await result.json()) as response;
const novels: Plugin.NovelItem[] = [];
json?.projects
?.filter( json?.projects
(novel) => ?.filter(
novel.title.includes(searchTerm) || String(novel.id) === searchTerm, (novel) =>
) novel.title.includes(searchTerm) || String(novel.id) === searchTerm,
?.forEach((novel) => )
novels.push({ ?.forEach((novel) =>
name: novel.title, novels.push({
cover: novel.image.url, name: novel.title,
url: this.site + "titles/" + novel.id, cover: novel.image.url,
}), url: this.site + "titles/" + novel.id,
); }),
return novels; );
} return novels;
}
fetchImage = fetchFile;
} fetchImage = fetchFile;
}
export default new Smakolykytl();
export default new Smakolykytl();
function jsonToHtml(json: HTML[], html: string = "") {
json.forEach((element) => { function jsonToHtml(json: HTML[], html: string = "") {
switch (element.type) { json.forEach((element) => {
case "hardBreak": switch (element.type) {
html += "<br>"; case "hardBreak":
break; html += "<br>";
case "horizontalRule": break;
html += "<hr>"; case "horizontalRule":
break; html += "<hr>";
case "image": break;
if (element.attrs) { case "image":
const attrs = Object.entries(element.attrs) if (element.attrs) {
.filter((attr) => attr?.[1]) const attrs = Object.entries(element.attrs)
.map((attr) => `${attr[0]}="${attr[1]}"`); .filter((attr) => attr?.[1])
html += "<img " + attrs.join("; ") + ">"; .map((attr) => `${attr[0]}="${attr[1]}"`);
} html += "<img " + attrs.join("; ") + ">";
break; }
case "paragraph": break;
html += case "paragraph":
"<p>" + html +=
(element.content ? jsonToHtml(element.content) : "<br>") + "<p>" +
"</p>"; (element.content ? jsonToHtml(element.content) : "<br>") +
break; "</p>";
case "text": break;
html += element.text; case "text":
break; html += element.text;
default: break;
html += JSON.stringify(element, null, "\t"); //maybe I missed something. default:
break; html += JSON.stringify(element, null, "\t"); //maybe I missed something.
} break;
}); }
return html; });
} return html;
}
interface response {
projects?: TopLevelProject[]; interface response {
updates?: Update[]; projects?: TopLevelProject[];
project?: TopLevelProject; updates?: Update[];
books?: BookElement[]; project?: TopLevelProject;
chapter?: TopLevelChapter; books?: BookElement[];
} chapter?: TopLevelChapter;
}
interface BookElement {
id: number; interface BookElement {
rank: number; id: number;
title: string; rank: number;
chapters: PurpleChapter[]; title: string;
} chapters: PurpleChapter[];
}
interface PurpleChapter {
id: number; interface PurpleChapter {
title: string; id: number;
rank: string; title: string;
modifiedAt: Date; rank: string;
} modifiedAt: Date;
}
interface TopLevelChapter {
id: number; interface TopLevelChapter {
title: string; id: number;
rank: string; title: string;
content: string; rank: string;
modifiedAt: Date; content: string;
book: ChapterBook; modifiedAt: Date;
} book: ChapterBook;
}
interface ChapterBook {
id: number; interface ChapterBook {
rank: number; id: number;
title: string; rank: number;
chapters: FluffyChapter[]; title: string;
project: BookProject; chapters: FluffyChapter[];
} project: BookProject;
}
interface FluffyChapter {
id: number; interface FluffyChapter {
rank: string; id: number;
} rank: string;
}
interface BookProject {
id: number; interface BookProject {
} id: number;
}
interface TopLevelProject {
id: number; interface TopLevelProject {
title: string; id: number;
description: string; title: string;
author: string; description: string;
translator: string; author: string;
modifiedAt: Date; translator: string;
alternatives: string; modifiedAt: Date;
release: string; alternatives: string;
nation: string; release: string;
status: string; nation: string;
status_translate: string; status: string;
image: Image; status_translate: string;
tags?: Genre[]; image: Image;
genres?: Genre[]; tags?: Genre[];
} genres?: Genre[];
}
interface Genre {
id: number; interface Genre {
title: string; id: number;
} title: string;
}
interface Image {
id: number; interface Image {
url: string; id: number;
name: string; url: string;
} name: string;
}
interface Update {
id: number; interface Update {
title: string; id: number;
author: string; title: string;
translator: string; author: string;
modifiedAt: Date; translator: string;
image: Image; modifiedAt: Date;
} image: Image;
}
interface HTML {
type: string; interface HTML {
content?: HTML[]; type: string;
attrs?: Attrs; content?: HTML[];
text?: string; attrs?: Attrs;
} text?: string;
}
interface Attrs {
src: string; interface Attrs {
alt: string | null; src: string;
title: string | null; alt: string | null;
} title: string | null;
}
+2 -2
View File
@@ -42,7 +42,7 @@ for (let language in languages) {
const langPath = path.join(root, "plugins", language.toLowerCase()); const langPath = path.join(root, "plugins", language.toLowerCase());
if (!fs.existsSync(langPath)) continue; if (!fs.existsSync(langPath)) continue;
const plugins = fs.readdirSync(langPath); const plugins = fs.readdirSync(langPath);
json[languageNative] = []; json[language] = [];
plugins.forEach((plugin) => { plugins.forEach((plugin) => {
if (plugin.startsWith(".")) return; if (plugin.startsWith(".")) return;
const instance: const instance:
@@ -74,7 +74,7 @@ for (let language in languages) {
pluginSet.add(id); pluginSet.add(id);
} }
json[languageNative].push(info); json[language].push(info);
console.log(name, "✅"); console.log(name, "✅");
}); });
} }
+2 -2
View File
@@ -21,7 +21,7 @@ export const all_plugins = (): PluginList => {
); );
if (!fs.existsSync(langPath)) continue; if (!fs.existsSync(langPath)) continue;
const plugins = fs.readdirSync(langPath); const plugins = fs.readdirSync(langPath);
res[languageNative] = []; res[languageEnglish] = [];
plugins.forEach((plugin) => { plugins.forEach((plugin) => {
if (plugin.startsWith(".")) return; if (plugin.startsWith(".")) return;
const requirePath = `@plugins/${languageEnglish.toLowerCase()}/${ const requirePath = `@plugins/${languageEnglish.toLowerCase()}/${
@@ -37,7 +37,7 @@ export const all_plugins = (): PluginList => {
requirePath, requirePath,
icon, icon,
}; // lang: language with native name }; // lang: language with native name
res[info.lang].push(info); res[languageEnglish].push(info);
}); });
} }
return res; return res;