fix ranobelib (#1342)

* test

* float

* hotfix

* -float
This commit is contained in:
Rider21
2024-11-29 04:59:20 +03:00
committed by GitHub
parent aaed26b01b
commit 99c5fb5d8f
3 changed files with 130 additions and 45 deletions
+30 -12
View File
@@ -28,10 +28,32 @@ class RanobesPlugin implements Plugin.PluginBase {
this.name = metadata.sourceName;
this.icon = 'multisrc/ranobes/ranobes/icon.png';
this.site = metadata.sourceSite;
this.version = '2.0.1';
this.version = '2.0.2';
this.options = metadata.options as RanobesOptions;
}
async safeFecth(url: string, init: any = {}): Promise<string> {
const r = await fetchApi(url, init);
if (!r.ok)
throw new Error(
'Could not reach site (' + r.status + ') try to open in webview.',
);
const data = await r.text();
const title = data.match(/<title>(.*?)<\/title>/)?.[1]?.trim();
if (
title &&
(title == 'Bot Verification' ||
title == 'You are being redirected...' ||
title == 'Un instant...' ||
title == 'Just a moment...' ||
title == 'Redirecting...')
)
throw new Error('Captcha error, please open in webview');
return data;
}
parseNovels(html: string) {
const novels: Plugin.NovelItem[] = [];
let tempNovel = {} as Plugin.NovelItem;
@@ -154,7 +176,7 @@ class RanobesPlugin implements Plugin.PluginBase {
async popularNovels(page: number): Promise<Plugin.NovelItem[]> {
const link = `${this.site}/${this.options.path}/page/${page}/`;
const body = await fetchApi(link).then(r => r.text());
const body = await this.safeFecth(link);
return this.parseNovels(body);
}
@@ -162,8 +184,7 @@ class RanobesPlugin implements Plugin.PluginBase {
novelPath: string,
): Promise<Plugin.SourceNovel & { totalPages: number }> {
const baseUrl = this.site;
const result = await fetchApi(baseUrl + novelPath);
const html = await result.text();
const html = await this.safeFecth(baseUrl + novelPath);
const novel: Plugin.SourceNovel & { totalPages: number } = {
path: novelPath,
name: '',
@@ -330,9 +351,7 @@ class RanobesPlugin implements Plugin.PluginBase {
: '/' + novelPath.split('-').slice(1).join('-').split('.')[0];
const firstUrl =
this.site + '/chapters' + pagePath.replace(this.options.path + '/', '');
const pageBody = await fetchApi(firstUrl + '/page/' + page).then(r =>
r.text(),
);
const pageBody = await this.safeFecth(firstUrl + '/page/' + page);
const baseUrl = this.site;
let isScript = false;
@@ -408,8 +427,7 @@ class RanobesPlugin implements Plugin.PluginBase {
}
async parseChapter(chapterPath: string): Promise<string> {
const result = await fetchApi(this.site + chapterPath);
const html = await result.text();
const html = await this.safeFecth(this.site + chapterPath);
const indexA = html.indexOf('<div class="text" id="arrticle">');
const indexB = html.indexOf('<div class="category grey ellipses">', indexA);
@@ -424,7 +442,7 @@ class RanobesPlugin implements Plugin.PluginBase {
): Promise<Plugin.NovelItem[]> {
let html;
if (this.id === 'ranobes-ru') {
html = await fetchApi(this.site + '/index.php?do=search', {
html = await this.safeFecth(this.site + '/index.php?do=search', {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Referer: this.site + '/',
@@ -436,10 +454,10 @@ class RanobesPlugin implements Plugin.PluginBase {
search_start: page.toString(),
story: searchTerm,
}).toString(),
}).then(res => res.text());
});
} else {
const link = `${this.site}/search/${searchTerm}/page/${page}`;
html = await fetchApi(link).then(r => r.text());
html = await this.safeFecth(link);
}
return this.parseNovels(html);
}
+30 -11
View File
@@ -9,9 +9,31 @@ class Foxteller implements Plugin.PluginBase {
id = 'foxteller';
name = 'Foxteller';
site = 'https://www.foxteller.com';
version = '1.0.1';
version = '1.0.2';
icon = 'src/en/foxteller/icon.png';
async safeFecth(url: string, init: any = {}): Promise<string> {
const r = await fetchApi(url, init);
if (!r.ok)
throw new Error(
'Could not reach site (' + r.status + ') try to open in webview.',
);
const data = await r.text();
const title = data.match(/<title>(.*?)<\/title>/)?.[1]?.trim();
if (
title &&
(title == 'Bot Verification' ||
title == 'You are being redirected...' ||
title == 'Un instant...' ||
title == 'Just a moment...' ||
title == 'Redirecting...')
)
throw new Error('Captcha error, please open in webview');
return data;
}
async popularNovels(
pageNo: number,
{ filters }: Plugin.PopularNovelsOptions<typeof this.filters>,
@@ -19,7 +41,7 @@ class Foxteller implements Plugin.PluginBase {
const url =
this.site + '/library?sort=' + filters?.order?.value || 'popularity';
const body = await fetchApi(url).then(res => res.text());
const body = await this.safeFecth(url);
const novels: Plugin.NovelItem[] = [];
const div = body.match(/<div class="col-md-6">([\s\S]*?)<\/div>/g) || [];
@@ -44,9 +66,7 @@ class Foxteller implements Plugin.PluginBase {
}
async parseNovel(novelPath: string): Promise<Plugin.SourceNovel> {
const body = await fetchApi(this.resolveUrl(novelPath)).then(res =>
res.text(),
);
const body = await this.safeFecth(this.resolveUrl(novelPath));
const novel: Plugin.SourceNovel = {
path: novelPath,
name: '',
@@ -189,10 +209,9 @@ class Foxteller implements Plugin.PluginBase {
}
async parseChapter(chapterPath: string): Promise<string> {
const res = await fetchApi(this.resolveUrl(chapterPath));
const body = await res.text();
const res = await this.safeFecth(this.resolveUrl(chapterPath));
const novelID = chapterPath.split('/')[0];
const chapterID = body.match(/'chapter_id': '([\d]+)'/)?.[1];
const chapterID = res.match(/'chapter_id': '([\d]+)'/)?.[1];
if (!chapterID) throw new Error('No chapter found');
@@ -203,7 +222,7 @@ class Foxteller implements Plugin.PluginBase {
'Accept-Language': 'ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3',
'Content-Type': 'application/json;charset=utf-8',
},
Referer: res.url,
Referer: this.resolveUrl(chapterPath),
body: JSON.stringify({ 'x1': novelID, 'x2': chapterID }),
}).then(res => res.json());
@@ -234,7 +253,7 @@ class Foxteller implements Plugin.PluginBase {
}
async searchNovels(searchTerm: string): Promise<Plugin.NovelItem[]> {
const body = await fetchApi(this.site + '/search', {
const body = await this.safeFecth(this.site + '/search', {
method: 'post',
headers: {
Accept: 'application/json, text/plain, */*',
@@ -243,7 +262,7 @@ class Foxteller implements Plugin.PluginBase {
},
Referer: this.site,
body: JSON.stringify({ query: searchTerm }),
}).then(res => res.text());
});
const novels: Plugin.NovelItem[] = [];
const items = body.match(/<a.*>([\s\S]*?)<\/a>/g) || [];
+70 -22
View File
@@ -18,7 +18,7 @@ class RLIB implements Plugin.PluginBase {
name = 'RanobeLib';
site = 'https://ranobelib.me';
apiSite = 'https://api.mangalib.me/api/manga/';
version = '2.1.0';
version = '2.1.1';
icon = 'src/ru/ranobelib/icon.png';
webStorageUtilized = true;
@@ -126,10 +126,10 @@ class RLIB implements Plugin.PluginBase {
novel.genres = genres.join(', ');
}
const branch_id: Record<number, string> = {};
const branch_name: Record<number, string> = {};
if (data.teams.length) {
data.teams.forEach(
({ name, details }) => (branch_id[details?.branch_id || '0'] = name),
({ name, details }) => (branch_name[details?.branch_id || '0'] = name),
);
}
@@ -144,27 +144,39 @@ class RLIB implements Plugin.PluginBase {
const chapters: Plugin.ChapterItem[] = [];
chaptersJSON.data.forEach(chapter =>
chapters.push({
name:
'Том ' +
chapter.volume +
' Глава ' +
chapter.number +
(chapter.name ? ' ' + chapter.name : ''),
path:
novelPath +
'/' +
chapter.volume +
'/' +
chapter.number +
'/' +
(chapter.branches[0]?.branch_id || ''),
releaseTime: dayjs(chapter.branches[0].created_at).format('LLL'),
chapterNumber: chapter.index,
page: branch_id[chapter.branches[0].branch_id || '0'],
}),
chapter.branches.forEach(({ branch_id, created_at }) =>
chapters.push({
name:
'Том ' +
chapter.volume +
' Глава ' +
chapter.number +
(chapter.name ? ' ' + chapter.name : ''),
path:
novelPath +
'/' +
chapter.volume +
'/' +
chapter.number +
'/' +
(branch_id || ''),
releaseTime: dayjs(created_at).format('LLL'),
chapterNumber: chapter.index,
page: branch_name[branch_id || '0'],
}),
),
);
if (chapters.length && data.teams.length > 1) {
//For whatever reason, the chapters overlap with another page.
chapters.sort((chapterA, chapterB) => {
if (chapterA.page !== chapterB.page) {
return chapterA.page.localeCompare(chapterB.page);
}
return chapterA.chapterNumber - chapterB.chapterNumber;
});
}
novel.chapters = chapters;
}
@@ -509,6 +521,42 @@ function jsonToHtml(json: HTML[], images, html = '') {
(element.content ? jsonToHtml(element.content, images) : '<br>') +
'</p>';
break;
case 'orderedList':
html +=
'<ol>' +
(element.content ? jsonToHtml(element.content, images) : '<br>') +
'</ol>';
break;
case 'listItem':
html +=
'<li>' +
(element.content ? jsonToHtml(element.content, images) : '<br>') +
'</li>';
break;
case 'blockquote':
html +=
'<blockquote>' +
(element.content ? jsonToHtml(element.content, images) : '<br>') +
'</blockquote>';
break;
case 'italic':
html +=
'<i>' +
(element.content ? jsonToHtml(element.content, images) : '<br>') +
'</i>';
break;
case 'bold':
html +=
'<b>' +
(element.content ? jsonToHtml(element.content, images) : '<br>') +
'</b>';
break;
case 'underline':
html +=
'<u>' +
(element.content ? jsonToHtml(element.content, images) : '<br>') +
'</u>';
break;
case 'heading':
html +=
'<h2>' +