Ranobelib: Fix cant parse page (#1683)

* update url

* minor version update

* update types

* unique
This commit is contained in:
K1ngfish3r
2025-05-17 07:46:25 +05:00
committed by GitHub
parent d51ba6e906
commit a1e709ae65
+72 -70
View File
@@ -17,8 +17,8 @@ class RLIB implements Plugin.PluginBase {
id = 'RLIB'; id = 'RLIB';
name = 'RanobeLib'; name = 'RanobeLib';
site = 'https://ranobelib.me'; site = 'https://ranobelib.me';
apiSite = 'https://api.mangalib.me/api/manga/'; apiSite = 'https://api.cdnlibs.org/api/manga/';
version = '2.1.2'; version = '2.2.0';
icon = 'src/ru/ranobelib/icon.png'; icon = 'src/ru/ranobelib/icon.png';
webStorageUtilized = true; webStorageUtilized = true;
@@ -94,9 +94,7 @@ class RLIB implements Plugin.PluginBase {
async parseNovel(novelPath: string): Promise<Plugin.SourceNovel> { async parseNovel(novelPath: string): Promise<Plugin.SourceNovel> {
const { data }: { data: DataClass } = await fetchApi( const { data }: { data: DataClass } = await fetchApi(
this.apiSite + `${this.apiSite}${novelPath}?fields[]=summary&fields[]=genres&fields[]=tags&fields[]=teams&fields[]=authors&fields[]=status_id&fields[]=artists`,
novelPath +
'?fields[]=summary&fields[]=genres&fields[]=tags&fields[]=teams&fields[]=authors&fields[]=status_id&fields[]=artists',
{ headers: this.user?.token }, { headers: this.user?.token },
).then(res => res.json()); ).then(res => res.json());
@@ -104,7 +102,7 @@ class RLIB implements Plugin.PluginBase {
path: novelPath, path: novelPath,
name: data.rus_name || data.name, name: data.rus_name || data.name,
cover: data.cover?.default || defaultCover, cover: data.cover?.default || defaultCover,
summary: data.summary, summary: data.summary?.trim(),
}; };
if (data.status?.id) { if (data.status?.id) {
@@ -126,64 +124,63 @@ class RLIB implements Plugin.PluginBase {
novel.genres = genres.join(', '); novel.genres = genres.join(', ');
} }
const branch_name: Record<number, string> = { 0: 'Главная страница' }; const branch_name: Record<string, string> = data.teams?.reduce(
if (data.teams.length) { (acc, { name, details }) => {
data.teams.forEach( acc[String(details?.branch_id ?? '0')] = name;
({ name, details }) => (branch_name[details?.branch_id || '0'] = name), return acc;
); },
} { '0': 'Главная страница' } as Record<string, string>,
) || { '0': 'Главная страница' };
const chaptersJSON: { data: DataChapter[] } = await fetchApi( const chaptersJSON: { data: DataChapter[] } = await fetchApi(
this.apiSite + novelPath + '/chapters', `${this.apiSite}${novelPath}/chapters`,
{ { headers: this.user?.token },
headers: this.user?.token,
},
).then(res => res.json()); ).then(res => res.json());
if (chaptersJSON.data.length) { if (chaptersJSON.data?.length) {
const chapters: Plugin.ChapterItem[] = []; let chapters: Plugin.ChapterItem[] = chaptersJSON.data.flatMap(chapter =>
chapter.branches.map(({ branch_id, created_at }) => {
chaptersJSON.data.forEach(chapter => const bId = String(branch_id ?? '0');
chapter.branches.forEach(({ branch_id, created_at }) => return {
chapters.push({ name: `Том ${chapter.volume} Глава ${chapter.number}${
name: chapter.name ? ' ' + chapter.name.trim() : ''
'Том ' + }`,
chapter.volume + path: `${novelPath}/${chapter.volume}/${chapter.number}/${bId}`,
' Глава ' + releaseTime: created_at ? dayjs(created_at).format('LLL') : null,
chapter.number +
(chapter.name ? ' ' + chapter.name : ''),
path:
novelPath +
'/' +
chapter.volume +
'/' +
chapter.number +
'/' +
(branch_id || ''),
releaseTime: dayjs(created_at).format('LLL'),
chapterNumber: chapter.index, chapterNumber: chapter.index,
page: branch_name[branch_id || '0'] || 'Неизвестный', page: branch_name[bId] || 'Неизвестный',
}), };
), }),
); );
if (chapters.length && data.teams.length > 1) { if (chapters.length) {
//For whatever reason, the chapters overlap with another page. const uniquePages = new Set(chapters.map(c => c.page));
chapters.sort((chapterA, chapterB) => {
if ( if (uniquePages.size === 1) {
chapterA.page && // If only one unique page value, set page to undefined for all chapters
chapterB.page && // Need more investigation one app side for single page shenanigans
chapterA.page !== chapterB.page chapters = chapters.map(chapter => ({
) { ...chapter,
return chapterA.page.localeCompare(chapterB.page); page: undefined,
} }));
return (chapterA.chapterNumber || 0) - (chapterB.chapterNumber || 0); } else if (data.teams?.length > 1) {
}); // Original sorting logic for multiple pages, for reasons chapters overlap with one another
chapters.sort((chapterA, chapterB) => {
if (
chapterA.page &&
chapterB.page &&
chapterA.page !== chapterB.page
) {
return chapterA.page.localeCompare(chapterB.page);
}
return (
(chapterA.chapterNumber || 0) - (chapterB.chapterNumber || 0)
);
});
}
novel.chapters = chapters;
} }
novel.chapters = chapters;
} }
return novel; return novel;
} }
@@ -205,10 +202,12 @@ class RLIB implements Plugin.PluginBase {
).then(res => res.json()); ).then(res => res.json());
chapterText = chapterText =
result?.data?.content?.type == 'doc' result?.data?.content?.type == 'doc'
? jsonToHtml(result.data.content.content, result.data.attachments) ? jsonToHtml(
result.data.content.content,
result.data.attachments || [],
)
: result?.data?.content; : result?.data?.content;
} }
return chapterText; return chapterText;
} }
@@ -493,7 +492,7 @@ class RLIB implements Plugin.PluginBase {
export default new RLIB(); export default new RLIB();
function jsonToHtml(json: HTML[], images, html = '') { function jsonToHtml(json: HTML[], images: Attachment[], html = '') {
json.forEach(element => { json.forEach(element => {
switch (element.type) { switch (element.type) {
case 'hardBreak': case 'hardBreak':
@@ -504,14 +503,16 @@ function jsonToHtml(json: HTML[], images, html = '') {
break; break;
case 'image': case 'image':
if (element.attrs?.images?.length) { if (element.attrs?.images?.length) {
element.attrs.images.forEach(({ image }) => { element.attrs.images.forEach(
const file = images.find( ({ image }: { image: string | number }) => {
file => file.name == image || file.id == image, const file = images.find(
); (f: Attachment) => f.name == image || f.id == image,
if (file) { );
html += `<img src='${file.url}'>`; if (file) {
} html += `<img src='${file.url}'>`;
}); }
},
);
} else if (element.attrs) { } else if (element.attrs) {
const attrs = Object.entries(element.attrs) const attrs = Object.entries(element.attrs)
.filter(attr => attr?.[1]) .filter(attr => attr?.[1])
@@ -586,9 +587,10 @@ type HTML = {
}; };
type Attrs = { type Attrs = {
src: string; src?: string;
alt: string | null; alt?: string | null;
title: string | null; title?: string | null;
images?: { image: string | number }[];
}; };
type authorization = { type authorization = {
@@ -710,7 +712,7 @@ type Subscription = {
}; };
type Attachment = { type Attachment = {
id?: string; id?: string | null; // Allow null for id
filename: string; filename: string;
name: string; name: string;
extension: string; extension: string;