mirror of
https://github.com/venera-app/venera-configs.git
synced 2025-09-27 16:37:23 +00:00
Compare commits
9 Commits
b6448c2055
...
main
Author | SHA1 | Date | |
---|---|---|---|
![]() |
603fefe9be | ||
![]() |
cd941b92ef | ||
62fbe9294b | |||
91823846a0 | |||
ef87d90e89 | |||
![]() |
a991dac6d6 | ||
![]() |
c9fdc8367a | ||
![]() |
aafc7078ba | ||
![]() |
edebc0c430 |
@@ -1,4 +1,19 @@
|
|||||||
/** @type {import('./_venera_.js')} */
|
/** @type {import('./_venera_.js')} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} PageJumpTarget
|
||||||
|
* @Property {string} page - The page name (search, category)
|
||||||
|
* @Property {Object} attributes - The attributes of the page
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* {
|
||||||
|
* page: "search",
|
||||||
|
* attributes: {
|
||||||
|
* keyword: "example",
|
||||||
|
* },
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
class NewComicSource extends ComicSource {
|
class NewComicSource extends ComicSource {
|
||||||
// Note: The fields which are marked as [Optional] should be removed if not used
|
// Note: The fields which are marked as [Optional] should be removed if not used
|
||||||
|
|
||||||
@@ -256,20 +271,42 @@ class NewComicSource extends ComicSource {
|
|||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
},
|
},
|
||||||
// provide options for category comic loading
|
// [Optional] provide options for category comic loading
|
||||||
optionList: [
|
optionList: [
|
||||||
{
|
{
|
||||||
|
// [Optional] The label will not be displayed if it is empty.
|
||||||
|
label: "",
|
||||||
// For a single option, use `-` to separate the value and text, left for value, right for text
|
// For a single option, use `-` to separate the value and text, left for value, right for text
|
||||||
options: [
|
options: [
|
||||||
"newToOld-New to Old",
|
"newToOld-New to Old",
|
||||||
"oldToNew-Old to New"
|
"oldToNew-Old to New"
|
||||||
],
|
],
|
||||||
// [Optional] {string[]} - show this option only when the value not in the list
|
// [Optional] {string[]} - show this option only when the category not in the list
|
||||||
notShowWhen: null,
|
notShowWhen: null,
|
||||||
// [Optional] {string[]} - show this option only when the value in the list
|
// [Optional] {string[]} - show this option only when the category in the list
|
||||||
showWhen: null
|
showWhen: null
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
/**
|
||||||
|
* [Optional] load options dynamically. If `optionList` is provided, this will be ignored.
|
||||||
|
* @since 1.5.0
|
||||||
|
* @param category {string}
|
||||||
|
* @param param {string?}
|
||||||
|
* @return {Promise<{options: string[], label?: string}[]>} - return a list of option group, each group contains a list of options
|
||||||
|
*/
|
||||||
|
optionLoader: async (category, param) => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
// [Optional] The label will not be displayed if it is empty.
|
||||||
|
label: "",
|
||||||
|
// For a single option, use `-` to separate the value and text, left for value, right for text
|
||||||
|
options: [
|
||||||
|
"newToOld-New to Old",
|
||||||
|
"oldToNew-Old to New"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
ranking: {
|
ranking: {
|
||||||
// For a single option, use `-` to separate the value and text, left for value, right for text
|
// For a single option, use `-` to separate the value and text, left for value, right for text
|
||||||
options: [
|
options: [
|
||||||
|
71
_venera_.js
71
_venera_.js
@@ -4,6 +4,18 @@ Venera JavaScript Library
|
|||||||
This library provides a set of APIs for interacting with the Venera app.
|
This library provides a set of APIs for interacting with the Venera app.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function sendMessage
|
||||||
|
* @global
|
||||||
|
* @param {Object} message
|
||||||
|
* @returns {any}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a timeout to execute a callback function after a specified delay.
|
||||||
|
* @param callback {Function}
|
||||||
|
* @param delay {number} - delay in milliseconds
|
||||||
|
*/
|
||||||
function setTimeout(callback, delay) {
|
function setTimeout(callback, delay) {
|
||||||
sendMessage({
|
sendMessage({
|
||||||
method: 'delay',
|
method: 'delay',
|
||||||
@@ -42,8 +54,6 @@ let Convert = {
|
|||||||
/**
|
/**
|
||||||
* @param str {string}
|
* @param str {string}
|
||||||
* @returns {ArrayBuffer}
|
* @returns {ArrayBuffer}
|
||||||
*
|
|
||||||
* @since 1.4.3
|
|
||||||
*/
|
*/
|
||||||
encodeGbk: (str) => {
|
encodeGbk: (str) => {
|
||||||
return sendMessage({
|
return sendMessage({
|
||||||
@@ -57,8 +67,6 @@ let Convert = {
|
|||||||
/**
|
/**
|
||||||
* @param value {ArrayBuffer}
|
* @param value {ArrayBuffer}
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*
|
|
||||||
* @since 1.4.3
|
|
||||||
*/
|
*/
|
||||||
decodeGbk: (value) => {
|
decodeGbk: (value) => {
|
||||||
return sendMessage({
|
return sendMessage({
|
||||||
@@ -1042,20 +1050,6 @@ function ImageLoadingConfig({url, method, data, headers, onResponse, modifyImage
|
|||||||
this.onLoadFailed = onLoadFailed;
|
this.onLoadFailed = onLoadFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} PageJumpTarget
|
|
||||||
* @Property {string} page - The page name (search, category)
|
|
||||||
* @Property {Object} attributes - The attributes of the page
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* {
|
|
||||||
* page: "search",
|
|
||||||
* attributes: {
|
|
||||||
* keyword: "example",
|
|
||||||
* },
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ComicSource {
|
class ComicSource {
|
||||||
name = ""
|
name = ""
|
||||||
|
|
||||||
@@ -1404,3 +1398,44 @@ let APP = {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set clipboard text
|
||||||
|
* @param text {string}
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*
|
||||||
|
* @since 1.3.4
|
||||||
|
*/
|
||||||
|
function setClipboard(text) {
|
||||||
|
return sendMessage({
|
||||||
|
method: 'setClipboard',
|
||||||
|
text: text
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get clipboard text
|
||||||
|
* @returns {Promise<string>}
|
||||||
|
*
|
||||||
|
* @since 1.3.4
|
||||||
|
*/
|
||||||
|
function getClipboard() {
|
||||||
|
return sendMessage({
|
||||||
|
method: 'getClipboard'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a function with arguments. The function will be executed in the engine pool which is not in the main thread.
|
||||||
|
* @param func {string} - A js code string which can be evaluated to a function. The function will receive the args as its only argument.
|
||||||
|
* @param args {any[]} - The arguments to pass to the function.
|
||||||
|
* @returns {Promise<any>} - The result of the function.
|
||||||
|
* @since 1.5.0
|
||||||
|
*/
|
||||||
|
function compute(func, ...args) {
|
||||||
|
return sendMessage({
|
||||||
|
method: 'compute',
|
||||||
|
function: func,
|
||||||
|
args: args
|
||||||
|
})
|
||||||
|
}
|
||||||
|
128
hitomi.js
128
hitomi.js
@@ -995,7 +995,7 @@ class Hitomi extends ComicSource {
|
|||||||
// unique id of the source
|
// unique id of the source
|
||||||
key = "hitomi";
|
key = "hitomi";
|
||||||
|
|
||||||
version = "1.1.1";
|
version = "1.1.2";
|
||||||
|
|
||||||
minAppVersion = "1.4.6";
|
minAppVersion = "1.4.6";
|
||||||
|
|
||||||
@@ -1004,7 +1004,7 @@ class Hitomi extends ComicSource {
|
|||||||
|
|
||||||
galleryCache = [];
|
galleryCache = [];
|
||||||
categoryResultCache = undefined;
|
categoryResultCache = undefined;
|
||||||
searchResultCache = undefined;
|
searchResultCaches = new Map();
|
||||||
|
|
||||||
_mapGalleryBlockInfoToComic(n) {
|
_mapGalleryBlockInfoToComic(n) {
|
||||||
return new Comic({
|
return new Comic({
|
||||||
@@ -1088,95 +1088,24 @@ class Hitomi extends ComicSource {
|
|||||||
title: "hitomi.la",
|
title: "hitomi.la",
|
||||||
parts: [
|
parts: [
|
||||||
{
|
{
|
||||||
name: "Language",
|
name: "语言",
|
||||||
type: "fixed",
|
type: "fixed",
|
||||||
categories: [
|
categories: ["汉语", "英语"],
|
||||||
{
|
itemType: "category",
|
||||||
label: "Chinese",
|
categoryParams: ["language:chinese", "language:english"],
|
||||||
target: {
|
|
||||||
page: "category",
|
|
||||||
attributes: {
|
|
||||||
category: "language",
|
|
||||||
param: "chinese",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "English",
|
|
||||||
target: {
|
|
||||||
page: "category",
|
|
||||||
attributes: {
|
|
||||||
category: "language",
|
|
||||||
param: "english",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "类别",
|
name: "类别",
|
||||||
type: "fixed",
|
type: "fixed",
|
||||||
categories: [
|
categories: ["同人志", "漫画", "画师CG", "游戏CG", "图集", "动画"],
|
||||||
{
|
itemType: "category",
|
||||||
label: "doujinshi",
|
categoryParams: [
|
||||||
target: {
|
"type:doujinshi",
|
||||||
page: "category",
|
"type:manga",
|
||||||
attributes: {
|
"type:artistcg",
|
||||||
category: "type",
|
"type:gamecg",
|
||||||
param: "doujinshi",
|
"type:imageset",
|
||||||
},
|
"type:anime",
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "manga",
|
|
||||||
target: {
|
|
||||||
page: "category",
|
|
||||||
attributes: {
|
|
||||||
category: "type",
|
|
||||||
param: "manga",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "artistcg",
|
|
||||||
target: {
|
|
||||||
page: "category",
|
|
||||||
attributes: {
|
|
||||||
category: "type",
|
|
||||||
param: "artistcg",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "gamecg",
|
|
||||||
target: {
|
|
||||||
page: "category",
|
|
||||||
attributes: {
|
|
||||||
category: "type",
|
|
||||||
param: "gamecg",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "imageset",
|
|
||||||
target: {
|
|
||||||
page: "category",
|
|
||||||
attributes: {
|
|
||||||
category: "type",
|
|
||||||
param: "imageset",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "anime",
|
|
||||||
target: {
|
|
||||||
page: "category",
|
|
||||||
attributes: {
|
|
||||||
category: "type",
|
|
||||||
param: "anime",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -1195,9 +1124,11 @@ class Hitomi extends ComicSource {
|
|||||||
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
||||||
*/
|
*/
|
||||||
load: async (category, param, options, page) => {
|
load: async (category, param, options, page) => {
|
||||||
|
const term = param;
|
||||||
|
if (!term.includes(":"))
|
||||||
|
throw new Error("不合法的标签,请使用namespace:tag的格式");
|
||||||
if (page === 1) {
|
if (page === 1) {
|
||||||
const option = parseInt(options[0]);
|
const option = parseInt(options[0]);
|
||||||
const term = category + ":" + param;
|
|
||||||
const searchOptions = {
|
const searchOptions = {
|
||||||
term,
|
term,
|
||||||
orderby: "date",
|
orderby: "date",
|
||||||
@@ -1351,6 +1282,7 @@ class Hitomi extends ComicSource {
|
|||||||
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
||||||
*/
|
*/
|
||||||
load: async (keyword, options, page) => {
|
load: async (keyword, options, page) => {
|
||||||
|
const cacheKey = (keyword || "") + "|" + options.join(",");
|
||||||
if (page === 1) {
|
if (page === 1) {
|
||||||
const option = parseInt(options[0]);
|
const option = parseInt(options[0]);
|
||||||
const term = keyword;
|
const term = keyword;
|
||||||
@@ -1392,11 +1324,11 @@ class Hitomi extends ComicSource {
|
|||||||
const comics = (await get_galleryblocks(result.gids)).map((n) =>
|
const comics = (await get_galleryblocks(result.gids)).map((n) =>
|
||||||
this._mapGalleryBlockInfoToComic(n)
|
this._mapGalleryBlockInfoToComic(n)
|
||||||
);
|
);
|
||||||
this.searchResultCache = {
|
this.searchResultCaches.set(cacheKey, {
|
||||||
type: "single",
|
type: "single",
|
||||||
state: result.state,
|
state: result.state,
|
||||||
count: result.count,
|
count: result.count,
|
||||||
};
|
});
|
||||||
return {
|
return {
|
||||||
comics,
|
comics,
|
||||||
maxPage: Math.ceil(result.count / 25),
|
maxPage: Math.ceil(result.count / 25),
|
||||||
@@ -1407,20 +1339,21 @@ class Hitomi extends ComicSource {
|
|||||||
result.gids.slice(25 * page - 25, 25 * page)
|
result.gids.slice(25 * page - 25, 25 * page)
|
||||||
)
|
)
|
||||||
).map((n) => this._mapGalleryBlockInfoToComic(n));
|
).map((n) => this._mapGalleryBlockInfoToComic(n));
|
||||||
this.searchResultCache = {
|
this.searchResultCaches.set(cacheKey, {
|
||||||
type: "all",
|
type: "all",
|
||||||
gids: result.gids,
|
gids: result.gids,
|
||||||
count: result.count,
|
count: result.count,
|
||||||
};
|
});
|
||||||
return {
|
return {
|
||||||
comics,
|
comics,
|
||||||
maxPage: Math.ceil(result.count / 25),
|
maxPage: Math.ceil(result.count / 25),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.searchResultCache.type === "single") {
|
const searchResultCache = this.searchResultCaches.get(cacheKey);
|
||||||
|
if (searchResultCache.type === "single") {
|
||||||
const result = await getSingleTagSearchPage({
|
const result = await getSingleTagSearchPage({
|
||||||
state: this.searchResultCache.state,
|
state: searchResultCache.state,
|
||||||
page: page - 1,
|
page: page - 1,
|
||||||
});
|
});
|
||||||
const comics = (await get_galleryblocks(result.galleryids)).map((n) =>
|
const comics = (await get_galleryblocks(result.galleryids)).map((n) =>
|
||||||
@@ -1428,17 +1361,17 @@ class Hitomi extends ComicSource {
|
|||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
comics,
|
comics,
|
||||||
maxPage: Math.ceil(this.searchResultCache.count / 25),
|
maxPage: Math.ceil(searchResultCache.count / 25),
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const comics = (
|
const comics = (
|
||||||
await get_galleryblocks(
|
await get_galleryblocks(
|
||||||
this.searchResultCache.gids.slice(25 * page - 25, 25 * page)
|
searchResultCache.gids.slice(25 * page - 25, 25 * page)
|
||||||
)
|
)
|
||||||
).map((n) => this._mapGalleryBlockInfoToComic(n));
|
).map((n) => this._mapGalleryBlockInfoToComic(n));
|
||||||
return {
|
return {
|
||||||
comics,
|
comics,
|
||||||
maxPage: Math.ceil(this.searchResultCache.count / 25),
|
maxPage: Math.ceil(searchResultCache.count / 25),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1526,7 +1459,8 @@ class Hitomi extends ComicSource {
|
|||||||
if ("type" in data && data.type) tags.set("type", [data.type]);
|
if ("type" in data && data.type) tags.set("type", [data.type]);
|
||||||
if (data.groups.length) tags.set("groups", data.groups);
|
if (data.groups.length) tags.set("groups", data.groups);
|
||||||
if (data.artists.length) tags.set("artists", data.artists);
|
if (data.artists.length) tags.set("artists", data.artists);
|
||||||
if ("language" in data && data.language) tags.set("language", [data.language]);
|
if ("language" in data && data.language)
|
||||||
|
tags.set("language", [data.language]);
|
||||||
if (data.series.length) tags.set("series", data.series);
|
if (data.series.length) tags.set("series", data.series);
|
||||||
if (data.characters.length) tags.set("characters", data.characters);
|
if (data.characters.length) tags.set("characters", data.characters);
|
||||||
if (data.females.length) tags.set("females", data.females);
|
if (data.females.length) tags.set("females", data.females);
|
||||||
|
130
ikmmh.js
130
ikmmh.js
@@ -1,13 +1,47 @@
|
|||||||
|
/** @type {import('./_venera_.js')} */
|
||||||
|
|
||||||
|
function getValidatorCookie(htmlString) {
|
||||||
|
// 正则表达式匹配 document.cookie 设置语句
|
||||||
|
const cookieRegex = /document\.cookie\s*=\s*"([^"]+)"/;
|
||||||
|
const match = htmlString.match(cookieRegex);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
return null; // 没有找到 cookie 设置语句
|
||||||
|
}
|
||||||
|
|
||||||
|
const cookieSetting = match[1];
|
||||||
|
const cookies = cookieSetting.split(';');
|
||||||
|
if (cookies.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const nameValuePart = cookies[0].trim();
|
||||||
|
const equalsIndex = nameValuePart.indexOf('=');
|
||||||
|
|
||||||
|
const name = nameValuePart.substring(0, equalsIndex);
|
||||||
|
const value = nameValuePart.substring(equalsIndex + 1);
|
||||||
|
|
||||||
|
return new Cookie({ name, value, domain: "www.ikmmh.com" })
|
||||||
|
}
|
||||||
|
|
||||||
|
function needPassValidator(htmlString) {
|
||||||
|
var cookie = getValidatorCookie(htmlString)
|
||||||
|
if (cookie != null) {
|
||||||
|
Network.setCookies(Ikm.baseUrl, [cookie])
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
class Ikm extends ComicSource {
|
class Ikm extends ComicSource {
|
||||||
// 基础配置
|
// 基础配置
|
||||||
name = "爱看漫";
|
name = "爱看漫";
|
||||||
key = "ikmmh";
|
key = "ikmmh";
|
||||||
version = "1.0.4";
|
version = "1.0.5";
|
||||||
minAppVersion = "1.0.0";
|
minAppVersion = "1.0.0";
|
||||||
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/ikmmh.js";
|
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/ikmmh.js";
|
||||||
// 常量定义
|
// 常量定义
|
||||||
static baseUrl = "https://ymcdnyfqdapp.ikmmh.com";
|
static baseUrl = "https://www.ikmmh.com";
|
||||||
static Mobile_UA = "Mozilla/5.0 (Linux; Android) Mobile";
|
static Mobile_UA = "Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.5 Mobile/15E148 Safari/604.1 Edg/140.0.0.0";
|
||||||
static webHeaders = {
|
static webHeaders = {
|
||||||
"User-Agent": Ikm.Mobile_UA,
|
"User-Agent": Ikm.Mobile_UA,
|
||||||
"Accept":
|
"Accept":
|
||||||
@@ -38,14 +72,26 @@ class Ikm extends ComicSource {
|
|||||||
);
|
);
|
||||||
if (res.status !== 200)
|
if (res.status !== 200)
|
||||||
throw new Error(`登录失败,状态码:${res.status}`);
|
throw new Error(`登录失败,状态码:${res.status}`);
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.post(
|
||||||
|
`${Ikm.baseUrl}/api/user/userarr/login`,
|
||||||
|
Ikm.jsonHead,
|
||||||
|
`user=${account}&pass=${pwd}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let data = JSON.parse(res.body);
|
let data = JSON.parse(res.body);
|
||||||
if (data.code !== 0) throw new Error(data.msg || "登录异常");
|
if (data.code !== 0)
|
||||||
|
throw new Error(data.msg || "登录异常");
|
||||||
|
|
||||||
return "ok";
|
return "ok";
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error(`登录失败:${err.message}`);
|
throw new Error(`登录失败:${err.message}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logout: () => Network.deleteCookies("ymcdnyfqdapp.ikmmh.com"),
|
logout: () => Network.deleteCookies("www.ikmmh.com"),
|
||||||
registerWebsite: `${Ikm.baseUrl}/user/register/`,
|
registerWebsite: `${Ikm.baseUrl}/user/register/`,
|
||||||
};
|
};
|
||||||
// 探索页面
|
// 探索页面
|
||||||
@@ -58,6 +104,12 @@ class Ikm extends ComicSource {
|
|||||||
let res = await Network.get(`${Ikm.baseUrl}/`, Ikm.webHeaders);
|
let res = await Network.get(`${Ikm.baseUrl}/`, Ikm.webHeaders);
|
||||||
if (res.status !== 200)
|
if (res.status !== 200)
|
||||||
throw new Error(`加载探索页面失败,状态码:${res.status}`);
|
throw new Error(`加载探索页面失败,状态码:${res.status}`);
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.get(`${Ikm.baseUrl}/`, Ikm.webHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
let document = new HtmlDocument(res.body);
|
let document = new HtmlDocument(res.body);
|
||||||
let parseComic = (e) => {
|
let parseComic = (e) => {
|
||||||
let title = e.querySelector("div.title").text.split("~")[0];
|
let title = e.querySelector("div.title").text.split("~")[0];
|
||||||
@@ -176,6 +228,15 @@ class Ikm extends ComicSource {
|
|||||||
);
|
);
|
||||||
if (res.status !== 200)
|
if (res.status !== 200)
|
||||||
throw new Error(`分类请求失败,状态码:${res.status}`);
|
throw new Error(`分类请求失败,状态码:${res.status}`);
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.get(
|
||||||
|
`${Ikm.baseUrl}/update/${param}.html`,
|
||||||
|
Ikm.webHeaders
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let document = new HtmlDocument(res.body);
|
let document = new HtmlDocument(res.body);
|
||||||
let comics = document.querySelectorAll("li.comic-item").map((e) => ({
|
let comics = document.querySelectorAll("li.comic-item").map((e) => ({
|
||||||
title: e.querySelector("p.title").text.split("~")[0],
|
title: e.querySelector("p.title").text.split("~")[0],
|
||||||
@@ -195,6 +256,17 @@ class Ikm extends ComicSource {
|
|||||||
options[0]
|
options[0]
|
||||||
}&page=${page}`
|
}&page=${page}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.post(
|
||||||
|
`${Ikm.baseUrl}/api/comic/index/lists`,
|
||||||
|
Ikm.jsonHead,
|
||||||
|
`area=${options[1]}&tags=${encodeURIComponent(category)}&full=${options[0]
|
||||||
|
}&page=${page}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let resData = JSON.parse(res.body);
|
let resData = JSON.parse(res.body);
|
||||||
return {
|
return {
|
||||||
comics: resData.data.map((e) => ({
|
comics: resData.data.map((e) => ({
|
||||||
@@ -260,6 +332,15 @@ class Ikm extends ComicSource {
|
|||||||
`${Ikm.baseUrl}/search?searchkey=${encodeURIComponent(keyword)}`,
|
`${Ikm.baseUrl}/search?searchkey=${encodeURIComponent(keyword)}`,
|
||||||
Ikm.webHeaders
|
Ikm.webHeaders
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.get(
|
||||||
|
`${Ikm.baseUrl}/search?searchkey=${encodeURIComponent(keyword)}`,
|
||||||
|
Ikm.webHeaders
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let document = new HtmlDocument(res.body);
|
let document = new HtmlDocument(res.body);
|
||||||
return {
|
return {
|
||||||
comics: document.querySelectorAll("li.comic-item").map((e) => ({
|
comics: document.querySelectorAll("li.comic-item").map((e) => ({
|
||||||
@@ -286,6 +367,12 @@ class Ikm extends ComicSource {
|
|||||||
if (isAdding) {
|
if (isAdding) {
|
||||||
// 获取漫画信息
|
// 获取漫画信息
|
||||||
let infoRes = await Network.get(comicId, Ikm.webHeaders);
|
let infoRes = await Network.get(comicId, Ikm.webHeaders);
|
||||||
|
|
||||||
|
if (needPassValidator(infoRes.body)) {
|
||||||
|
// rePost
|
||||||
|
infoRes = await Network.get(comicId, Ikm.webHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
let name = new HtmlDocument(infoRes.body).querySelector(
|
let name = new HtmlDocument(infoRes.body).querySelector(
|
||||||
"meta[property='og:title']"
|
"meta[property='og:title']"
|
||||||
).attributes["content"];
|
).attributes["content"];
|
||||||
@@ -305,6 +392,16 @@ class Ikm extends ComicSource {
|
|||||||
Ikm.jsonHead,
|
Ikm.jsonHead,
|
||||||
`articleid=${id}`
|
`articleid=${id}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.post(
|
||||||
|
`${Ikm.baseUrl}/api/user/bookcase/del`,
|
||||||
|
Ikm.jsonHead,
|
||||||
|
`articleid=${id}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let data = JSON.parse(res.body);
|
let data = JSON.parse(res.body);
|
||||||
if (data.code !== "0") throw new Error(data.msg || "取消收藏失败");
|
if (data.code !== "0") throw new Error(data.msg || "取消收藏失败");
|
||||||
return "ok";
|
return "ok";
|
||||||
@@ -322,6 +419,15 @@ class Ikm extends ComicSource {
|
|||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
throw "加载收藏失败:" + res.status;
|
throw "加载收藏失败:" + res.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.get(
|
||||||
|
`${Ikm.baseUrl}/user/bookcase`,
|
||||||
|
Ikm.webHeaders
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let document = new HtmlDocument(res.body);
|
let document = new HtmlDocument(res.body);
|
||||||
return {
|
return {
|
||||||
comics: document.querySelectorAll("div.bookrack-item").map((e) => ({
|
comics: document.querySelectorAll("div.bookrack-item").map((e) => ({
|
||||||
@@ -347,6 +453,12 @@ class Ikm extends ComicSource {
|
|||||||
console.error("加载收藏页失败:", error);
|
console.error("加载收藏页失败:", error);
|
||||||
}
|
}
|
||||||
let res = await Network.get(id, Ikm.webHeaders);
|
let res = await Network.get(id, Ikm.webHeaders);
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.get(id, Ikm.webHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
let document = new HtmlDocument(res.body);
|
let document = new HtmlDocument(res.body);
|
||||||
let comicId = id.match(/\d+/)[0];
|
let comicId = id.match(/\d+/)[0];
|
||||||
// 获取章节数据
|
// 获取章节数据
|
||||||
@@ -410,13 +522,19 @@ class Ikm extends ComicSource {
|
|||||||
cover: e.querySelector("div.thumb_img").attributes["data-src"],
|
cover: e.querySelector("div.thumb_img").attributes["data-src"],
|
||||||
id: `${Ikm.baseUrl}${e.querySelector("a").attributes["href"]}`,
|
id: `${Ikm.baseUrl}${e.querySelector("a").attributes["href"]}`,
|
||||||
})),
|
})),
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
onThumbnailLoad: Ikm.thumbConfig,
|
onThumbnailLoad: Ikm.thumbConfig,
|
||||||
loadEp: async (comicId, epId) => {
|
loadEp: async (comicId, epId) => {
|
||||||
try {
|
try {
|
||||||
let res = await Network.get(epId, Ikm.webHeaders);
|
let res = await Network.get(epId, Ikm.webHeaders);
|
||||||
|
|
||||||
|
if (needPassValidator(res.body)) {
|
||||||
|
// rePost
|
||||||
|
res = await Network.get(epId, Ikm.webHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
let document = new HtmlDocument(res.body);
|
let document = new HtmlDocument(res.body);
|
||||||
return {
|
return {
|
||||||
images: document
|
images: document
|
||||||
|
@@ -46,7 +46,7 @@
|
|||||||
"name": "禁漫天堂",
|
"name": "禁漫天堂",
|
||||||
"fileName": "jm.js",
|
"fileName": "jm.js",
|
||||||
"key": "jm",
|
"key": "jm",
|
||||||
"version": "1.2.1",
|
"version": "1.3.0",
|
||||||
"description": "禁漫天堂漫畫源, 不能使用時請嘗試切換分流"
|
"description": "禁漫天堂漫畫源, 不能使用時請嘗試切換分流"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
"name": "爱看漫",
|
"name": "爱看漫",
|
||||||
"fileName": "ikmmh.js",
|
"fileName": "ikmmh.js",
|
||||||
"key": "ikmmh",
|
"key": "ikmmh",
|
||||||
"version": "1.0.4"
|
"version": "1.0.5"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "少年ジャンプ+",
|
"name": "少年ジャンプ+",
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
"name": "hitomi.la",
|
"name": "hitomi.la",
|
||||||
"fileName": "hitomi.js",
|
"fileName": "hitomi.js",
|
||||||
"key": "hitomi",
|
"key": "hitomi",
|
||||||
"version": "1.1.1"
|
"version": "1.1.2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "comick",
|
"name": "comick",
|
||||||
@@ -114,6 +114,6 @@
|
|||||||
"name": "Lanraragi",
|
"name": "Lanraragi",
|
||||||
"fileName": "lanraragi.js",
|
"fileName": "lanraragi.js",
|
||||||
"key": "lanraragi",
|
"key": "lanraragi",
|
||||||
"version": "1.0.0"
|
"version": "1.1.0"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
129
jm.js
129
jm.js
@@ -7,22 +7,22 @@ class JM extends ComicSource {
|
|||||||
// unique id of the source
|
// unique id of the source
|
||||||
key = "jm"
|
key = "jm"
|
||||||
|
|
||||||
version = "1.2.1"
|
version = "1.3.0"
|
||||||
|
|
||||||
minAppVersion = "1.2.5"
|
minAppVersion = "1.5.0"
|
||||||
|
|
||||||
static jmVersion = "2.0.1"
|
static jmVersion = "2.0.6"
|
||||||
|
|
||||||
static jmPkgName = "com.example.app"
|
static jmPkgName = "com.example.app"
|
||||||
|
|
||||||
// update url
|
// update url
|
||||||
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/jm.js"
|
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/jm.js"
|
||||||
|
|
||||||
static apiDomains = [
|
static fallbackServers = [
|
||||||
"www.cdnaspa.vip",
|
"www.cdntwice.org",
|
||||||
"www.cdnaspa.club",
|
"www.cdnsha.org",
|
||||||
"www.cdnplaystation6.vip",
|
"www.cdnaspa.cc",
|
||||||
"www.cdnplaystation6.cc"
|
"www.cdnntr.cc",
|
||||||
];
|
];
|
||||||
|
|
||||||
static imageUrl = "https://cdn-msp.jmapinodeudzn.net"
|
static imageUrl = "https://cdn-msp.jmapinodeudzn.net"
|
||||||
@@ -121,11 +121,11 @@ class JM extends ComicSource {
|
|||||||
* @param showConfirmDialog {boolean}
|
* @param showConfirmDialog {boolean}
|
||||||
*/
|
*/
|
||||||
async refreshApiDomains(showConfirmDialog) {
|
async refreshApiDomains(showConfirmDialog) {
|
||||||
let url = "https://jmapp03-1308024008.cos.ap-jakarta.myqcloud.com/server-2024.txt"
|
let url = "https://rup4a04-c02.tos-cn-hongkong.bytepluses.com/newsvr-2025.txt"
|
||||||
let domainSecret = "diosfjckwpqpdfjkvnqQjsik"
|
let domainSecret = "diosfjckwpqpdfjkvnqQjsik"
|
||||||
let title = ""
|
let title = ""
|
||||||
let message = ""
|
let message = ""
|
||||||
let jm3_Server = []
|
let servers = []
|
||||||
let domains = []
|
let domains = []
|
||||||
let res = await fetch(
|
let res = await fetch(
|
||||||
url,
|
url,
|
||||||
@@ -134,20 +134,20 @@ class JM extends ComicSource {
|
|||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
let data = this.convertData(await res.text(), domainSecret)
|
let data = this.convertData(await res.text(), domainSecret)
|
||||||
let json = JSON.parse(data)
|
let json = JSON.parse(data)
|
||||||
if (json["jm3_Server"]) {
|
if (json["Server"]) {
|
||||||
title = "Update Success"
|
title = "Update Success"
|
||||||
message = "\n"
|
message = "\n"
|
||||||
jm3_Server = json["jm3_Server"]
|
servers = json["Server"].slice(0, 4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jm3_Server.length === 0) {
|
if (servers.length === 0) {
|
||||||
title = "Update Failed"
|
title = "Update Failed"
|
||||||
message = `Using built-in domains:\n\n`
|
message = `Using built-in domains:\n\n`
|
||||||
domains = JM.apiDomains
|
servers = JM.fallbackServers
|
||||||
}
|
}
|
||||||
for (let [domain, index] of jm3_Server) {
|
for (let i = 0; i < servers.length; i++) {
|
||||||
message = message + `${index}: ${domain}\n`
|
message = message + `線路${i + 1}: ${servers[i]}\n\n`
|
||||||
domains.push(domain)
|
domains.push(servers[i])
|
||||||
}
|
}
|
||||||
if (showConfirmDialog) {
|
if (showConfirmDialog) {
|
||||||
UI.showDialog(
|
UI.showDialog(
|
||||||
@@ -370,6 +370,12 @@ class JM extends ComicSource {
|
|||||||
/// title of the category page, used to identify the page, it should be unique
|
/// title of the category page, used to identify the page, it should be unique
|
||||||
title: "禁漫天堂",
|
title: "禁漫天堂",
|
||||||
parts: [
|
parts: [
|
||||||
|
{
|
||||||
|
name: "每週必看",
|
||||||
|
type: "fixed",
|
||||||
|
categories: ["每週必看"],
|
||||||
|
itemType: "category",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "成人A漫",
|
name: "成人A漫",
|
||||||
type: "fixed",
|
type: "fixed",
|
||||||
@@ -480,33 +486,74 @@ class JM extends ComicSource {
|
|||||||
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
* @returns {Promise<{comics: Comic[], maxPage: number}>}
|
||||||
*/
|
*/
|
||||||
load: async (category, param, options, page) => {
|
load: async (category, param, options, page) => {
|
||||||
param ??= category
|
if (category !== "每週必看") {
|
||||||
param = encodeURIComponent(param)
|
param ??= category
|
||||||
let res = await this.get(`${this.baseUrl}/categories/filter?o=${options[0]}&c=${param}&page=${page}`)
|
param = encodeURIComponent(param)
|
||||||
let data = JSON.parse(res)
|
let res = await this.get(`${this.baseUrl}/categories/filter?o=${options[0]}&c=${param}&page=${page}`)
|
||||||
let total = data.total
|
let data = JSON.parse(res)
|
||||||
let maxPage = Math.ceil(total / 80)
|
let total = data.total
|
||||||
let comics = data.content.map((e) => this.parseComic(e))
|
let maxPage = Math.ceil(total / 80)
|
||||||
return {
|
let comics = data.content.map((e) => this.parseComic(e))
|
||||||
comics: comics,
|
return {
|
||||||
maxPage: maxPage
|
comics: comics,
|
||||||
|
maxPage: maxPage
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let res = await this.get(`${this.baseUrl}/week/filter?id=${options[0]}&page=1&type=${options[1]}&page=0`)
|
||||||
|
let data = JSON.parse(res)
|
||||||
|
let comics = data.list.map((e) => this.parseComic(e))
|
||||||
|
return {
|
||||||
|
comics: comics,
|
||||||
|
maxPage: 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// provide options for category comic loading
|
/**
|
||||||
optionList: [
|
* [Optional] load options dynamically. If `optionList` is provided, this will be ignored.
|
||||||
{
|
* @param category {string}
|
||||||
// For a single option, use `-` to separate the value and text, left for value, right for text
|
* @param param {string?}
|
||||||
options: [
|
* @return {Promise<{options: string[], label?: string}[]>} - return a list of option group, each group contains a list of options
|
||||||
"mr-最新",
|
*/
|
||||||
"mv-總排行",
|
optionLoader: async (category, param) => {
|
||||||
"mv_m-月排行",
|
if (category !== "每週必看") {
|
||||||
"mv_w-周排行",
|
return [
|
||||||
"mv_t-日排行",
|
{
|
||||||
"mp-最多圖片",
|
label: "排序",
|
||||||
"tf-最多喜歡",
|
// For a single option, use `-` to separate the value and text, left for value, right for text
|
||||||
],
|
options: [
|
||||||
|
"mr-最新",
|
||||||
|
"mv-總排行",
|
||||||
|
"mv_m-月排行",
|
||||||
|
"mv_w-周排行",
|
||||||
|
"mv_t-日排行",
|
||||||
|
"mp-最多圖片",
|
||||||
|
"tf-最多喜歡",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
let res = await this.get(`${this.baseUrl}/week`)
|
||||||
|
let data = JSON.parse(res)
|
||||||
|
let options = []
|
||||||
|
for (let e of data["categories"]) {
|
||||||
|
options.push(`${e["id"]}-${e["time"]}`)
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: "時間",
|
||||||
|
options: options,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "類型",
|
||||||
|
options: [
|
||||||
|
"manga-日漫",
|
||||||
|
"hanman-韓漫",
|
||||||
|
"another-其他",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
},
|
||||||
ranking: {
|
ranking: {
|
||||||
// For a single option, use `-` to separate the value and text, left for value, right for text
|
// For a single option, use `-` to separate the value and text, left for value, right for text
|
||||||
options: [
|
options: [
|
||||||
|
45
lanraragi.js
45
lanraragi.js
@@ -2,23 +2,34 @@
|
|||||||
class Lanraragi extends ComicSource {
|
class Lanraragi extends ComicSource {
|
||||||
name = "Lanraragi"
|
name = "Lanraragi"
|
||||||
key = "lanraragi"
|
key = "lanraragi"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
minAppVersion = "1.4.0"
|
minAppVersion = "1.4.0"
|
||||||
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/lanraragi.js"
|
url = "https://git.nyne.dev/nyne/venera-configs/raw/branch/main/lanraragi.js"
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
api: { title: "API", type: "input", default: "http://lrr.tvc-16.science" }
|
api: { title: "API", type: "input", default: "http://lrr.tvc-16.science" },
|
||||||
|
apiKey: { title: "APIKEY", type: "input", default: "" }
|
||||||
}
|
}
|
||||||
get baseUrl() {
|
|
||||||
|
|
||||||
|
get baseUrl() {
|
||||||
const api = this.loadSetting('api') || this.settings.api.default
|
const api = this.loadSetting('api') || this.settings.api.default
|
||||||
|
|
||||||
return api.replace(/\/$/, '')
|
return api.replace(/\/$/, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get headers() {
|
||||||
|
let apiKey = this.loadSetting('apiKey')
|
||||||
|
if (apiKey) apiKey = "Bearer " + Convert.encodeBase64(Convert.encodeUtf8(apiKey))
|
||||||
|
|
||||||
|
return {
|
||||||
|
"Authorization": `${apiKey}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
try {
|
try {
|
||||||
const url = `${this.baseUrl}/api/categories`
|
const url = `${this.baseUrl}/api/categories`
|
||||||
const res = await Network.get(url)
|
const res = await Network.get(url, this.headers)
|
||||||
if (res.status !== 200) { this.saveData('categories', []); return }
|
if (res.status !== 200) { this.saveData('categories', []); return }
|
||||||
let data = []
|
let data = []
|
||||||
try { data = JSON.parse(res.body) } catch (_) { data = [] }
|
try { data = JSON.parse(res.body) } catch (_) { data = [] }
|
||||||
@@ -39,7 +50,7 @@ class Lanraragi extends ComicSource {
|
|||||||
explore = [
|
explore = [
|
||||||
{ title: "Lanraragi", type: "multiPageComicList", load: async (page = 1) => {
|
{ title: "Lanraragi", type: "multiPageComicList", load: async (page = 1) => {
|
||||||
const url = `${this.baseUrl}/api/archives`
|
const url = `${this.baseUrl}/api/archives`
|
||||||
const res = await Network.get(url)
|
const res = await Network.get(url, this.headers)
|
||||||
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
||||||
const data = JSON.parse(res.body)
|
const data = JSON.parse(res.body)
|
||||||
const list = data.slice((page-1)*50, page*50)
|
const list = data.slice((page-1)*50, page*50)
|
||||||
@@ -114,7 +125,7 @@ class Lanraragi extends ComicSource {
|
|||||||
add('search[regex]', 'false')
|
add('search[regex]', 'false')
|
||||||
|
|
||||||
const url = `${base}/search?${qp.join('&')}`
|
const url = `${base}/search?${qp.join('&')}`
|
||||||
const res = await Network.get(url)
|
const res = await Network.get(url, this.headers)
|
||||||
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
||||||
const data = JSON.parse(res.body)
|
const data = JSON.parse(res.body)
|
||||||
const list = Array.isArray(data.data) ? data.data : []
|
const list = Array.isArray(data.data) ? data.data : []
|
||||||
@@ -169,7 +180,7 @@ class Lanraragi extends ComicSource {
|
|||||||
add('groupby_tanks', groupby)
|
add('groupby_tanks', groupby)
|
||||||
|
|
||||||
const url = `${base}/api/search?${qp.join('&')}`
|
const url = `${base}/api/search?${qp.join('&')}`
|
||||||
const res = await Network.get(url)
|
const res = await Network.get(url, this.headers)
|
||||||
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
||||||
const data = JSON.parse(res.body)
|
const data = JSON.parse(res.body)
|
||||||
const all = Array.isArray(data.data) ? data.data : []
|
const all = Array.isArray(data.data) ? data.data : []
|
||||||
@@ -225,7 +236,7 @@ class Lanraragi extends ComicSource {
|
|||||||
comic = {
|
comic = {
|
||||||
loadInfo: async (id) => {
|
loadInfo: async (id) => {
|
||||||
const url = `${this.baseUrl}/api/archives/${id}/metadata`
|
const url = `${this.baseUrl}/api/archives/${id}/metadata`
|
||||||
const res = await Network.get(url)
|
const res = await Network.get(url, this.headers)
|
||||||
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
||||||
const data = JSON.parse(res.body)
|
const data = JSON.parse(res.body)
|
||||||
const cover = `${this.baseUrl}/api/archives/${id}/thumbnail`
|
const cover = `${this.baseUrl}/api/archives/${id}/thumbnail`
|
||||||
@@ -237,7 +248,7 @@ class Lanraragi extends ComicSource {
|
|||||||
},
|
},
|
||||||
loadThumbnails: async (id, next) => {
|
loadThumbnails: async (id, next) => {
|
||||||
const metaUrl = `${this.baseUrl}/api/archives/${id}/metadata`
|
const metaUrl = `${this.baseUrl}/api/archives/${id}/metadata`
|
||||||
const res = await Network.get(metaUrl)
|
const res = await Network.get(metaUrl, this.headers)
|
||||||
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
||||||
const data = JSON.parse(res.body)
|
const data = JSON.parse(res.body)
|
||||||
const pagecount = data.pagecount || 1
|
const pagecount = data.pagecount || 1
|
||||||
@@ -249,7 +260,7 @@ class Lanraragi extends ComicSource {
|
|||||||
loadEp: async (comicId, epId) => {
|
loadEp: async (comicId, epId) => {
|
||||||
const base = (this.baseUrl || '').replace(/\/$/, '')
|
const base = (this.baseUrl || '').replace(/\/$/, '')
|
||||||
const url = `${base}/api/archives/${comicId}/files?force=false`
|
const url = `${base}/api/archives/${comicId}/files?force=false`
|
||||||
const res = await Network.get(url)
|
const res = await Network.get(url, this.headers)
|
||||||
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
if (res.status !== 200) throw `Invalid status code: ${res.status}`
|
||||||
const data = JSON.parse(res.body)
|
const data = JSON.parse(res.body)
|
||||||
const images = (data.pages || []).map(p => {
|
const images = (data.pages || []).map(p => {
|
||||||
@@ -260,8 +271,16 @@ class Lanraragi extends ComicSource {
|
|||||||
}).filter(Boolean)
|
}).filter(Boolean)
|
||||||
return { images }
|
return { images }
|
||||||
},
|
},
|
||||||
// onImageLoad: (url, comicId, epId) => ({}),
|
onImageLoad: (url, comicId, epId) => {
|
||||||
// onThumbnailLoad: (url) => ({}),
|
return {
|
||||||
|
headers: this.headers
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onThumbnailLoad: (url) => {
|
||||||
|
return {
|
||||||
|
headers: this.headers
|
||||||
|
}
|
||||||
|
},
|
||||||
// likeComic: async (id, isLike) => {},
|
// likeComic: async (id, isLike) => {},
|
||||||
// loadComments: async (comicId, subId, page, replyTo) => {},
|
// loadComments: async (comicId, subId, page, replyTo) => {},
|
||||||
// sendComment: async (comicId, subId, content, replyTo) => {},
|
// sendComment: async (comicId, subId, content, replyTo) => {},
|
||||||
@@ -272,4 +291,4 @@ class Lanraragi extends ComicSource {
|
|||||||
// link: { domains: ['example.com'], linkToId: (url) => null },
|
// link: { domains: ['example.com'], linkToId: (url) => null },
|
||||||
enableTagsTranslate: false,
|
enableTagsTranslate: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user