Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
@@ -3,6 +3,7 @@ import { FilterTypes, Filters } from "@libs/filterInputs";
|
||||
import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { NovelStatus } from "@libs/novelStatus";
|
||||
import { load as parseHTML } from "cheerio";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
class freedlit implements Plugin.PluginBase {
|
||||
id = "freedlit.space";
|
||||
@@ -75,8 +76,13 @@ class freedlit implements Plugin.PluginBase {
|
||||
const url = loadedCheerio(element).attr("href");
|
||||
if (!name || !url) return;
|
||||
|
||||
const releaseTime = loadedCheerio(element).find('span[class="date"]').text();
|
||||
chapters.push({ name, url, releaseTime, chapterNumber: chapterIndex + 1 });
|
||||
const releaseDate = loadedCheerio(element).find('span[class="date"]').text();
|
||||
chapters.push({
|
||||
name,
|
||||
url,
|
||||
releaseTime: this.parseDate(releaseDate),
|
||||
chapterNumber: chapterIndex + 1
|
||||
});
|
||||
});
|
||||
|
||||
novel.chapters = chapters;
|
||||
@@ -111,6 +117,30 @@ class freedlit implements Plugin.PluginBase {
|
||||
|
||||
return novels;
|
||||
}
|
||||
|
||||
parseDate = (dateString: string | undefined = "") => {
|
||||
const months: { [key: string]: number } = {
|
||||
января: 1,
|
||||
февраля: 2,
|
||||
марта: 3,
|
||||
апреля: 4,
|
||||
мая: 5,
|
||||
июня: 6,
|
||||
июля: 7,
|
||||
августа: 8,
|
||||
сентября: 9,
|
||||
октября: 10,
|
||||
ноября: 11,
|
||||
декабря: 12,
|
||||
};
|
||||
|
||||
const [day, month, year] = dateString.split(" ");
|
||||
if (day && months[month] && year) {
|
||||
return dayjs(year + "-" + months[month] + "-" + day).format("LL");
|
||||
}
|
||||
return dateString || null;
|
||||
};
|
||||
|
||||
fetchImage = fetchFile;
|
||||
|
||||
filters = {
|
||||
|
||||
@@ -68,7 +68,9 @@ class Bookriver implements Plugin.PluginBase {
|
||||
chapters.push({
|
||||
name: chapter.name,
|
||||
url: this.site + "/reader/" + book?.slug + "/" + chapter.chapterId,
|
||||
releaseTime: dayjs(chapter?.firstPublishedAt || chapter.createdAt).format("LLL"),
|
||||
releaseTime: dayjs(
|
||||
chapter.firstPublishedAt || chapter.createdAt || undefined,
|
||||
).format("LLL"),
|
||||
chapterNumber: chapterIndex + 1,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { NovelStatus } from "@libs/novelStatus";
|
||||
import { load as parseHTML } from "cheerio";
|
||||
import { defaultCover } from "@libs/defaultCover";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
class ficbook implements Plugin.PluginBase {
|
||||
id = "ficbook";
|
||||
@@ -99,7 +100,10 @@ class ficbook implements Plugin.PluginBase {
|
||||
|
||||
const releaseTime = loadedCheerio(element).find("div > span").attr("title");
|
||||
chapters.push({
|
||||
name, url: this.site + url, releaseTime, chapterNumber: chapterIndex + 1,
|
||||
name,
|
||||
url: this.site + url,
|
||||
releaseTime,
|
||||
chapterNumber: chapterIndex + 1,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -160,6 +164,30 @@ class ficbook implements Plugin.PluginBase {
|
||||
|
||||
return novels;
|
||||
}
|
||||
|
||||
parseDate = (dateString: string | undefined = "") => {
|
||||
const months: { [key: string]: number } = {
|
||||
января: 1,
|
||||
февраля: 2,
|
||||
марта: 3,
|
||||
апреля: 4,
|
||||
мая: 5,
|
||||
июня: 6,
|
||||
июля: 7,
|
||||
августа: 8,
|
||||
сентября: 9,
|
||||
октября: 10,
|
||||
ноября: 11,
|
||||
декабря: 12,
|
||||
};
|
||||
|
||||
const [day, month, year, , time] = dateString.split(" ");
|
||||
if (day && month && year && months[month] && time) {
|
||||
return dayjs(year + "-" + months[month] + "-" + day + " " + time).format("LLL");
|
||||
}
|
||||
return dateString || null;
|
||||
};
|
||||
|
||||
fetchImage = fetchFile;
|
||||
|
||||
filters = {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { FilterTypes, Filters } from "@libs/filterInputs";
|
||||
import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { NovelStatus } from "@libs/novelStatus";
|
||||
import { load as parseHTML } from "cheerio";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
class Jaomix implements Plugin.PluginBase {
|
||||
id = "jaomix.ru";
|
||||
@@ -98,8 +99,13 @@ class Jaomix implements Plugin.PluginBase {
|
||||
const url = loadedCheerio(element).find("a").attr("href");
|
||||
if (!name || !url) return;
|
||||
|
||||
const releaseTime = loadedCheerio(element).find("time").text();
|
||||
chapters.push({ name, url, releaseTime, chapterNumber: totalChapters - chapterIndex });
|
||||
const releaseDate = loadedCheerio(element).find("time").text();
|
||||
chapters.push({
|
||||
name,
|
||||
url,
|
||||
releaseTime: this.parseDate(releaseDate),
|
||||
chapterNumber: totalChapters - chapterIndex
|
||||
});
|
||||
});
|
||||
|
||||
novel.chapters = chapters.reverse();
|
||||
@@ -146,6 +152,31 @@ class Jaomix implements Plugin.PluginBase {
|
||||
|
||||
return novels;
|
||||
}
|
||||
|
||||
parseDate = (dateString: string | undefined = "") => {
|
||||
const months: { [key: string]: number } = {
|
||||
Янв: 1,
|
||||
Фев: 2,
|
||||
Мар: 3,
|
||||
Апр: 4,
|
||||
Май: 5,
|
||||
Июн: 6,
|
||||
Июл: 7,
|
||||
Авг: 8,
|
||||
Сен: 9,
|
||||
Окт: 10,
|
||||
Ноя: 11,
|
||||
Дек: 12,
|
||||
};
|
||||
|
||||
const [time, day, month, year] = dateString.split(" ");
|
||||
if (time && day && months[month] && year) {
|
||||
return dayjs(year + "-" + months[month] + "-" + day + " " + time).format("LLL");
|
||||
}
|
||||
|
||||
return dateString || null;
|
||||
};
|
||||
|
||||
fetchImage = fetchFile;
|
||||
|
||||
filters = {
|
||||
|
||||
@@ -0,0 +1,415 @@
|
||||
import { Plugin } from "@typings/plugin";
|
||||
import { FilterTypes, Filters } from "@libs/filterInputs";
|
||||
import { fetchApi, fetchFile } from "@libs/fetch";
|
||||
import { NovelStatus } from "@libs/novelStatus";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
class novelOvh implements Plugin.PluginBase {
|
||||
id = "novelovh";
|
||||
name = "НовелОВХ";
|
||||
site = "https://novel.ovh";
|
||||
version = "1.0.0";
|
||||
icon = "src/ru/novelOvh/icon.png";
|
||||
|
||||
async popularNovels(
|
||||
pageNo: number,
|
||||
{ showLatestNovels, filters }: Plugin.PopularNovelsOptions,
|
||||
): Promise<Plugin.NovelItem[]> {
|
||||
let url = this.site + "/novel?page=" + (pageNo - 1);
|
||||
url += "&sort=" +
|
||||
(showLatestNovels ? "updatedAt" : filters?.sort?.value || "averageRating") + ",desc";
|
||||
|
||||
const result = await fetchApi(url + "&_data=routes/reader/book/index");
|
||||
const body = (await result.json()) as { books: BooksEntity[] };
|
||||
|
||||
const novels: Plugin.NovelItem[] = [];
|
||||
body.books.forEach((novel) =>
|
||||
novels.push({
|
||||
name: novel.name.ru,
|
||||
cover: novel.poster,
|
||||
url: this.site + "/novel/" + novel.slug,
|
||||
}),
|
||||
);
|
||||
|
||||
return novels;
|
||||
}
|
||||
|
||||
async parseNovelAndChapters(novelUrl: string): Promise<Plugin.SourceNovel> {
|
||||
const result = await fetchApi(
|
||||
novelUrl + "?_data=routes/reader/book/$slug/index",
|
||||
);
|
||||
const json = (await result.json()) as responseNovel;
|
||||
|
||||
const novel: Plugin.SourceNovel = {
|
||||
url: novelUrl,
|
||||
name: json.book.name.ru,
|
||||
cover: json.book.poster,
|
||||
genres: json.book.labels?.map?.((label) => label.name).join(","),
|
||||
summary: json.book.description,
|
||||
status:
|
||||
json.book.status == "ONGOING"
|
||||
? NovelStatus.Ongoing
|
||||
: NovelStatus.Completed,
|
||||
};
|
||||
|
||||
json.book.relations?.forEach((person) => {
|
||||
switch (person.type) {
|
||||
case "AUTHOR":
|
||||
novel.author = person.publisher.name;
|
||||
case "ARTIST":
|
||||
novel.artist = person.publisher.name;
|
||||
}
|
||||
});
|
||||
|
||||
const chapters: Plugin.ChapterItem[] = [];
|
||||
|
||||
json.chapters.forEach((chapter, chapterIndex) =>
|
||||
chapters.push({
|
||||
name:
|
||||
chapter.title ||
|
||||
"Том " + (chapter.volume || 0) + " " +
|
||||
(chapter.name || "Глава " +
|
||||
(chapter.number || json.chapters.length - chapterIndex)),
|
||||
url: novelUrl + "/" + chapter.id + "/0",
|
||||
releaseTime: dayjs(chapter.createdAt).format("LLL"),
|
||||
chapterNumber: json.chapters.length - chapterIndex,
|
||||
}),
|
||||
);
|
||||
|
||||
novel.chapters = chapters.reverse();
|
||||
return novel;
|
||||
}
|
||||
|
||||
async parseChapter(chapterUrl: string): Promise<string> {
|
||||
const result = await fetchApi(
|
||||
"https://api.novel.ovh/v2/chapters/" + chapterUrl.split("/")[5],
|
||||
);
|
||||
const book = (await result.json()) as responseChapter;
|
||||
const image = Object.fromEntries(
|
||||
book?.pages?.map(({ id, image }) => [id, image]) || [],
|
||||
);
|
||||
|
||||
const chapterText = this.jsonToHtml(book.content.content || [], image);
|
||||
return chapterText;
|
||||
}
|
||||
|
||||
async searchNovels(
|
||||
searchTerm: string,
|
||||
page: number | undefined = 1,
|
||||
): Promise<Plugin.NovelItem[]> {
|
||||
const url = `${this.site}/novel?search=${searchTerm}&page=${page - 1}`;
|
||||
const result = await fetchApi(url + "&_data=routes/reader/book/index");
|
||||
const body = (await result.json()) as { books: BooksEntity[] };
|
||||
|
||||
const novels: Plugin.NovelItem[] = [];
|
||||
body.books.forEach((novel) =>
|
||||
novels.push({
|
||||
name: novel.name.ru,
|
||||
cover: novel.poster,
|
||||
url: this.site + "/novel/" + novel.slug,
|
||||
}),
|
||||
);
|
||||
|
||||
return novels;
|
||||
}
|
||||
|
||||
jsonToHtml = (
|
||||
json: ContentEntity[],
|
||||
image: { [key: string]: string },
|
||||
html: string = "",
|
||||
) => {
|
||||
json.forEach((element) => {
|
||||
switch (element.type) {
|
||||
case "image":
|
||||
if (element.attrs?.pages?.[0]) {
|
||||
html += `<img src="${image[element.attrs.pages[0]]}"/>`;
|
||||
}
|
||||
break;
|
||||
case "hardBreak":
|
||||
html += "<br>";
|
||||
break;
|
||||
case "horizontalRule":
|
||||
case "delimiter":
|
||||
html += '<h2 style="text-align: center">***</h2>';
|
||||
break;
|
||||
case "paragraph":
|
||||
html +=
|
||||
"<p" +
|
||||
(element?.attrs?.textAlign
|
||||
? ` style="text-align: ${element.attrs.textAlign}"`
|
||||
: "") +
|
||||
">" +
|
||||
(element.content ? this.jsonToHtml(element.content, image) : "<br>") +
|
||||
"</p>";
|
||||
break;
|
||||
case "text":
|
||||
html += element.text;
|
||||
break;
|
||||
default:
|
||||
html += JSON.stringify(element, null, "\t"); //maybe I missed something.
|
||||
break;
|
||||
}
|
||||
});
|
||||
return html;
|
||||
};
|
||||
|
||||
fetchImage = fetchFile;
|
||||
|
||||
filters = {
|
||||
sort: {
|
||||
label: "Сортировка",
|
||||
value: "averageRating",
|
||||
options: [
|
||||
{ label: "Кол-во просмотров", value: "viewsCount" },
|
||||
{ label: "Кол-во лайков", value: "likesCount" },
|
||||
{ label: "Кол-во глав", value: "chaptersCount" },
|
||||
{ label: "Кол-во закладок", value: "bookmarksCount" },
|
||||
{ label: "Рейтингу", value: "averageRating" },
|
||||
{ label: "Дате создания", value: "createdAt" },
|
||||
{ label: "Дате обновления", value: "updatedAt" },
|
||||
],
|
||||
type: FilterTypes.Picker,
|
||||
},
|
||||
} satisfies Filters;
|
||||
}
|
||||
|
||||
export default new novelOvh();
|
||||
|
||||
interface BooksEntity {
|
||||
id: string;
|
||||
slug: string;
|
||||
type: string;
|
||||
serviceName: string;
|
||||
poster: string;
|
||||
background?: string | null;
|
||||
featuredCharacter?: null;
|
||||
featuredCharacterBackground?: null;
|
||||
featuredCharacterAnimation?: null;
|
||||
featuredCharacterAnimationWithMask?: null;
|
||||
featuredCharacterAnimationFirstFrame?: null;
|
||||
status: string;
|
||||
contentStatus: string;
|
||||
name: Name;
|
||||
altNames?: AltNamesEntity[] | null;
|
||||
country: string;
|
||||
year: number;
|
||||
formats?: null[] | null;
|
||||
featured: boolean;
|
||||
viewsCount: number;
|
||||
likesCount: number;
|
||||
bookmarksCount: number;
|
||||
ratingVotesCount: number;
|
||||
averageRating: number;
|
||||
chaptersCount: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
interface Name {
|
||||
ru: string;
|
||||
original: string;
|
||||
en: string;
|
||||
}
|
||||
interface AltNamesEntity {
|
||||
language: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface responseNovel {
|
||||
book: Book;
|
||||
branches: BranchesEntity[];
|
||||
chapters: ChaptersEntity[];
|
||||
related?: RelatedEntityOrBook[] | null;
|
||||
associated?: AssociatedEntity[] | null;
|
||||
chapterLikes?: null[] | null;
|
||||
covers?: CoversEntity[] | null;
|
||||
promotionVideos?: null[] | null;
|
||||
folderItems?: null[] | null;
|
||||
contentNotices?: null[] | null;
|
||||
}
|
||||
interface Book {
|
||||
id: string;
|
||||
slug: string;
|
||||
type: string;
|
||||
serviceName: string;
|
||||
poster: string;
|
||||
background?: null;
|
||||
featuredCharacter?: null;
|
||||
featuredCharacterBackground?: null;
|
||||
featuredCharacterAnimation?: null;
|
||||
featuredCharacterAnimationWithMask?: null;
|
||||
featuredCharacterAnimationFirstFrame?: null;
|
||||
contentBlockedCountries?: null[] | null;
|
||||
status: string;
|
||||
contentStatus: string;
|
||||
moderationStatus: string;
|
||||
name: Name;
|
||||
altNames?: null[] | null;
|
||||
externalLinks?: string[] | null;
|
||||
description: string;
|
||||
country: string;
|
||||
year: number;
|
||||
formats?: null[] | null;
|
||||
featured: boolean;
|
||||
viewsCount: number;
|
||||
viewsDayCount: number;
|
||||
viewsWeekCount: number;
|
||||
viewsMonthCount: number;
|
||||
likesCount: number;
|
||||
bookmarksCount: number;
|
||||
ratingVotesCount: number;
|
||||
averageRating: number;
|
||||
chaptersCount: number;
|
||||
labels?: LabelsEntity[] | null;
|
||||
relations?: RelationsEntity[] | null;
|
||||
createdById: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
rating?: null;
|
||||
}
|
||||
interface LabelsEntity {
|
||||
id: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
}
|
||||
interface RelationsEntity {
|
||||
type: string;
|
||||
publisher: Publisher;
|
||||
}
|
||||
interface Publisher {
|
||||
id: string;
|
||||
kind: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
altNames?: (AltNamesEntity | null)[] | null;
|
||||
poster: string;
|
||||
background?: null;
|
||||
trusted: boolean;
|
||||
donationsEnabled: boolean;
|
||||
vkGroupId?: null;
|
||||
vkGroupName?: null;
|
||||
tonAddress?: null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
interface BranchesEntity {
|
||||
id: string;
|
||||
licensed: boolean;
|
||||
editorsChoice: boolean;
|
||||
chaptersCount: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
publishers?: PublishersEntity[] | null;
|
||||
subscription?: null;
|
||||
bookmark?: null;
|
||||
}
|
||||
interface PublishersEntity {
|
||||
id: string;
|
||||
kind: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
altNames?: AltNamesEntity[] | null;
|
||||
poster: string;
|
||||
background?: null;
|
||||
trusted: boolean;
|
||||
donationsEnabled: boolean;
|
||||
vk?: null;
|
||||
tonAddress?: null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
interface ChaptersEntity {
|
||||
id: string;
|
||||
name?: string | null;
|
||||
title?: string | null;
|
||||
number: number;
|
||||
volume: number;
|
||||
likesCount: number;
|
||||
commentsCount: number;
|
||||
donut: boolean;
|
||||
corrupted: boolean;
|
||||
createdById: string;
|
||||
branchId: string;
|
||||
bookId: string;
|
||||
createdAt: string;
|
||||
expiredAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
interface RelatedEntityOrBook {
|
||||
id: string;
|
||||
type: string;
|
||||
slug: string;
|
||||
poster: string;
|
||||
motion?: null;
|
||||
status: string;
|
||||
contentStatus: string;
|
||||
name: Name;
|
||||
country: string;
|
||||
year: number;
|
||||
formats?: null[] | null;
|
||||
viewsCount: number;
|
||||
likesCount: number;
|
||||
bookmarksCount: number;
|
||||
ratingVotesCount: number;
|
||||
averageRating: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
interface AssociatedEntity {
|
||||
id: string;
|
||||
kind: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
book: RelatedEntityOrBook;
|
||||
}
|
||||
interface CoversEntity {
|
||||
id: string;
|
||||
volume: number;
|
||||
image: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
interface responseChapter {
|
||||
id: string;
|
||||
name?: string;
|
||||
title: string;
|
||||
number: number;
|
||||
volume: number;
|
||||
likesCount: number;
|
||||
commentsCount: number;
|
||||
moderationStatus: string;
|
||||
content: Content;
|
||||
pages?: PagesEntity[];
|
||||
donut: boolean;
|
||||
corrupted: boolean;
|
||||
createdById: string;
|
||||
branchId: string;
|
||||
bookId: string;
|
||||
publishers?: PublishersEntity[] | null;
|
||||
createdAt: string;
|
||||
expiredAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
interface Content {
|
||||
type: string;
|
||||
content?: ContentEntity[] | null;
|
||||
}
|
||||
interface ContentEntity {
|
||||
text?: string | null;
|
||||
type: string;
|
||||
attrs?: Attrs | null;
|
||||
content?: Content[] | null;
|
||||
}
|
||||
interface Attrs {
|
||||
textAlign?: string;
|
||||
pages?: [string];
|
||||
}
|
||||
interface PagesEntity {
|
||||
id: string;
|
||||
image: string;
|
||||
index: number;
|
||||
commentsCount: number;
|
||||
height: number;
|
||||
width: number;
|
||||
createdAt: string;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class RNBH implements Plugin.PluginBase {
|
||||
const json = (await result.json()) as { data: responseNovel };
|
||||
|
||||
const novel: Plugin.SourceNovel = {
|
||||
url: json.data.url,
|
||||
url: novelUrl,
|
||||
name: json.data.names?.rus || json.data.names.eng,
|
||||
cover: json.data.posters.medium,
|
||||
summary: json.data.description,
|
||||
|
||||
@@ -156,7 +156,7 @@ class ReN implements Plugin.PluginBase {
|
||||
},
|
||||
order: {
|
||||
label: "Порядок",
|
||||
value: "",
|
||||
value: "-",
|
||||
options: [
|
||||
{ label: "По убыванию", value: "-" },
|
||||
{ label: "По возрастанию", value: "" },
|
||||
|
||||
@@ -66,13 +66,13 @@ class Smakolykytl implements Plugin.PluginBase {
|
||||
"https://api.smakolykytl.site/api/user/projects/" + id + "/books",
|
||||
);
|
||||
const data = (await res.json()) as response;
|
||||
data?.books?.forEach(
|
||||
(volume) =>
|
||||
volume?.chapters?.map((chapter) =>
|
||||
data?.books?.forEach((volume) =>
|
||||
volume?.chapters?.forEach((chapter) =>
|
||||
chapters.push({
|
||||
name: volume.title + " " + chapter.title,
|
||||
releaseTime: dayjs(chapter.modifiedAt).format("LLL"),
|
||||
url: this.site + "read/" + chapter.id,
|
||||
releaseTime: dayjs(chapter.modifiedAt).format("LLL"),
|
||||
chapterNumber: chapters.length + 1,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Filters, FilterTypes } from "@libs/filterInputs";
|
||||
import { Plugin } from "@typings/plugin";
|
||||
import { NovelStatus } from "@libs/novelStatus";
|
||||
import { load as parseHTML } from "cheerio";
|
||||
// import { defaultCover } from "@libs/defaultCover";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export interface IfreedomMetadata {
|
||||
id: string;
|
||||
@@ -105,8 +105,13 @@ class IfreedomPlugin implements Plugin.PluginBase {
|
||||
const name = loadedCheerio(element).find("a").text();
|
||||
const url = loadedCheerio(element).find("a").attr("href");
|
||||
if (!loadedCheerio(element).find("label.buy-ranobe").length && name && url) {
|
||||
const releaseTime = loadedCheerio(element).find("div.li-col2-ranobe").text().trim();
|
||||
chapters.push({ name, url, releaseTime, chapterNumber: totalChapters - chapterIndex });
|
||||
const releaseDate = loadedCheerio(element).find("div.li-col2-ranobe").text().trim();
|
||||
chapters.push({
|
||||
name,
|
||||
url,
|
||||
releaseTime: this.parseDate(releaseDate),
|
||||
chapterNumber: totalChapters - chapterIndex
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -156,5 +161,36 @@ class IfreedomPlugin implements Plugin.PluginBase {
|
||||
return novels;
|
||||
}
|
||||
|
||||
parseDate = (dateString: string | undefined = "") => {
|
||||
const months: { [key: string]: number } = {
|
||||
января: 1,
|
||||
февраля: 2,
|
||||
марта: 3,
|
||||
апреля: 4,
|
||||
мая: 5,
|
||||
июня: 6,
|
||||
июля: 7,
|
||||
августа: 8,
|
||||
сентября: 9,
|
||||
октября: 10,
|
||||
ноября: 11,
|
||||
декабря: 12,
|
||||
};
|
||||
|
||||
if (dateString.includes(".")) {
|
||||
const [day, month, year] = dateString.split(".");
|
||||
if (day && month && year) {
|
||||
return dayjs(year + "-" + month + "-" + day).format("LL");
|
||||
}
|
||||
} else if (dateString.includes(" ")) {
|
||||
const [day, month] = dateString.split(" ");
|
||||
if (day && months[month]) {
|
||||
const year = new Date().getFullYear();
|
||||
return dayjs(year + "-" + months[month] + "-" + day).format("LL");
|
||||
}
|
||||
}
|
||||
return dateString || null;
|
||||
};
|
||||
|
||||
fetchImage = fetchFile;
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ class ReadwnPlugin implements Plugin.PluginBase {
|
||||
return {
|
||||
name,
|
||||
url: this.site + url,
|
||||
releaseTime: releaseTime,
|
||||
releaseTime,
|
||||
chapterNumber: chapterIndex + 1,
|
||||
};
|
||||
})
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Filters, FilterTypes } from "@libs/filterInputs";
|
||||
import { Plugin } from "@typings/plugin";
|
||||
import { NovelStatus } from "@libs/novelStatus";
|
||||
import { load as parseHTML } from "cheerio";
|
||||
// import { defaultCover } from "@libs/defaultCover";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export interface RulateMetadata {
|
||||
id: string;
|
||||
@@ -152,7 +152,7 @@ class RulatePlugin implements Plugin.PluginBase {
|
||||
chapters.push({
|
||||
name: chapterName,
|
||||
url: this.site + chapterUrl,
|
||||
releaseTime: releaseDate,
|
||||
releaseTime: this.parseDate(releaseDate),
|
||||
chapterNumber: chapterIndex + 1,
|
||||
});
|
||||
}
|
||||
@@ -210,6 +210,28 @@ class RulatePlugin implements Plugin.PluginBase {
|
||||
return novels;
|
||||
}
|
||||
|
||||
parseDate = (dateString: string | undefined = "") => {
|
||||
const months: { [key: string]: number } = {
|
||||
"янв.": 1,
|
||||
"февр.": 2,
|
||||
"мар.": 3,
|
||||
"апр.": 4,
|
||||
мая: 5,
|
||||
"июн.": 6,
|
||||
"июл.": 7,
|
||||
"авг.": 8,
|
||||
"сент.": 9,
|
||||
"окт.": 10,
|
||||
"нояб.": 11,
|
||||
"дек.": 12,
|
||||
};
|
||||
const [day, month, year, , time] = dateString.split(" ");
|
||||
if (day && months[month] && year && time) {
|
||||
return dayjs(year + "-" + months[month] + "-" + day + " " + time).format("LLL");
|
||||
}
|
||||
return dateString || null;
|
||||
};
|
||||
|
||||
fetchImage = fetchFile;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user