🐞 fix: 过滤书源 & add: 增加更多的书本信息实现聚合搜索

This commit is contained in:
RrOrange 2023-04-08 00:50:08 +08:00
parent 06edf46768
commit d7a2eddc02
2 changed files with 230 additions and 55 deletions

View File

@ -8,7 +8,7 @@ import fs from "node:fs";
// 常量 // 常量
import { CAT_LIMIT } from "../utils/constant.js"; import { CAT_LIMIT } from "../utils/constant.js";
// 书库 // 书库
import { getYiBook, getZBook } from "../utils/books.js"; import { getZHelper, getBookDetail, getYiBook, getZBook } from "../utils/books.js";
export class query extends plugin { export class query extends plugin {
constructor() { constructor() {
@ -53,7 +53,7 @@ export class query extends plugin {
{ {
reg: "^#竹白(.*)", reg: "^#竹白(.*)",
fnc: "zhubaiSearch", fnc: "zhubaiSearch",
} },
], ],
}); });
} }
@ -62,7 +62,9 @@ export class query extends plugin {
const keyword = e.msg.replace("#医药查询", "").trim(); const keyword = e.msg.replace("#医药查询", "").trim();
const url = `https://api2.dayi.org.cn/api/search2?keyword=${keyword}&pageNo=1&pageSize=10`; const url = `https://api2.dayi.org.cn/api/search2?keyword=${keyword}&pageNo=1&pageSize=10`;
try { try {
const res = await fetch(url).then(resp => resp.json()).then(resp => resp.list); const res = await fetch(url)
.then(resp => resp.json())
.then(resp => resp.list);
const promises = res.map(async element => { const promises = res.map(async element => {
const title = this.removeTag(element.title); const title = this.removeTag(element.title);
const template = `${title}\n标签:${element.secondTitle}\n介绍:${element.introduction}`; const template = `${title}\n标签:${element.secondTitle}\n介绍:${element.introduction}`;
@ -84,14 +86,14 @@ export class query extends plugin {
return { return {
message: { message: {
type: "text", type: "text",
text: template text: template,
}, },
nickname: Bot.nickname, nickname: Bot.nickname,
user_id: Bot.user_id user_id: Bot.user_id,
}; };
}); });
const msg = await Promise.all(promises); const msg = await Promise.all(promises);
e.reply(await Bot.makeForwardMsg(msg)) e.reply(await Bot.makeForwardMsg(msg));
} catch (err) { } catch (err) {
logger.error(err); logger.error(err);
} }
@ -101,7 +103,9 @@ export class query extends plugin {
async cat(e) { async cat(e) {
const [shibes, cats] = await Promise.allSettled([ const [shibes, cats] = await Promise.allSettled([
fetch(`https://shibe.online/api/cats?count=${CAT_LIMIT}`).then(data => data.json()), fetch(`https://shibe.online/api/cats?count=${CAT_LIMIT}`).then(data => data.json()),
fetch(`https://api.thecatapi.com/v1/images/search?limit=${CAT_LIMIT}`).then(data => data.json()), fetch(`https://api.thecatapi.com/v1/images/search?limit=${CAT_LIMIT}`).then(data =>
data.json(),
),
]); ]);
const shibeUrls = shibes.status === "fulfilled" ? shibes.value : []; const shibeUrls = shibes.status === "fulfilled" ? shibes.value : [];
@ -123,25 +127,27 @@ export class query extends plugin {
// 接口 // 接口
const urls = [ const urls = [
"https://www.ghxi.com/ghapi?type=query&n=pc", "https://www.ghxi.com/ghapi?type=query&n=pc",
"https://www.ghxi.com/ghapi?type=query&n=and" "https://www.ghxi.com/ghapi?type=query&n=and",
]; ];
// 一起请求 // 一起请求
const promises = urls.map(url => const promises = urls.map(url =>
fetch(url) fetch(url)
.then(resp => resp.json()) .then(resp => resp.json())
.catch(err => logger.error(err)) .catch(err => logger.error(err)),
); );
const results = await Promise.allSettled(promises); const results = await Promise.allSettled(promises);
const msg = results const msg = results
.filter(result => result.status === 'fulfilled') // 只保留已解决的 Promise .filter(result => result.status === "fulfilled") // 只保留已解决的 Promise
.flatMap(result => result.value.data.list.map(element => { .flatMap(result =>
const template = `推荐软件:${element.title}\n地址:${element.url}\n`; result.value.data.list.map(element => {
return { const template = `推荐软件:${element.title}\n地址:${element.url}\n`;
message: { type: "text", text: template }, return {
nickname: e.sender.card || e.user_id, message: { type: "text", text: template },
user_id: e.user_id nickname: e.sender.card || e.user_id,
}; user_id: e.user_id,
})); };
}),
);
// 异步操作 // 异步操作
e.reply(await Bot.makeForwardMsg(msg)); e.reply(await Bot.makeForwardMsg(msg));
@ -156,7 +162,9 @@ export class query extends plugin {
.then(resp => resp.imgurl); .then(resp => resp.imgurl);
const results = await Promise.allSettled([p1, p2]); const results = await Promise.allSettled([p1, p2]);
const images = results.filter(result => result.status === "fulfilled").map(result => result.value); const images = results
.filter(result => result.status === "fulfilled")
.map(result => result.value);
for (const img of images) { for (const img of images) {
e.reply(segment.image(img)); e.reply(segment.image(img));
@ -265,22 +273,22 @@ export class query extends plugin {
} }
async cospro(e) { async cospro(e) {
let [res1, res2] = (await Promise.allSettled([ let [res1, res2] = (
fetch("https://imgapi.cn/cos2.php?return=jsonpro").then(resp => resp.json()), await Promise.allSettled([
fetch("https://imgapi.cn/cos.php?return=jsonpro").then(resp => resp.json()) fetch("https://imgapi.cn/cos2.php?return=jsonpro").then(resp => resp.json()),
])) fetch("https://imgapi.cn/cos.php?return=jsonpro").then(resp => resp.json()),
.filter(result => result.status === "fulfilled").map(result => result.value); ])
let req = [ )
...res1.imgurls, .filter(result => result.status === "fulfilled")
...res2.imgurls .map(result => result.value);
]; let req = [...res1.imgurls, ...res2.imgurls];
e.reply("哪天克火掉一定是在这个群里面..."); e.reply("哪天克火掉一定是在这个群里面...");
let images = req.map(item => ({ let images = req.map(item => ({
message: segment.image(encodeURI(item)), message: segment.image(encodeURI(item)),
nickname: this.e.sender.card || this.e.user_id, nickname: this.e.sender.card || this.e.user_id,
user_id: this.e.user_id, user_id: this.e.user_id,
})); }));
e.reply(await Bot.makeForwardMsg(images)) e.reply(await Bot.makeForwardMsg(images));
return true; return true;
} }
@ -292,7 +300,7 @@ export class query extends plugin {
return true; return true;
} }
const replyMessage = async (msg) => { const replyMessage = async msg => {
if (msg && msg.length > 0) { if (msg && msg.length > 0) {
await e.reply(await Bot.makeForwardMsg(msg)); await e.reply(await Bot.makeForwardMsg(msg));
} }
@ -300,13 +308,71 @@ export class query extends plugin {
// 集成易书、zBook // 集成易书、zBook
const bookList = await Promise.allSettled([getYiBook(e, keyword), getZBook(e, keyword)]); const bookList = await Promise.allSettled([getYiBook(e, keyword), getZBook(e, keyword)]);
bookList.filter(one => one.status === "fulfilled") bookList
.filter(one => one.status === "fulfilled")
.map(item => { .map(item => {
replyMessage(item.value) replyMessage(item.value);
}) });
const zHelper = await getZHelper(e, keyword);
if (zHelper && zHelper.length > 0) {
await replyMessage(zHelper);
const replyText =
"请选择一个你想要的ID、来源例如\n" +
"11918807 superlib\n" +
"只回复11918807 默认zlibrary\n" +
"书源若不对应则回复无效链接,数字字母之间空格";
await e.reply(replyText);
this.setContext("searchBookContext");
}
return true; return true;
} }
// 通过id搜书
async searchBookById(e) {
let keyword = e.msg.replace(/#bookid/, "").trim();
if (_.isEmpty(keyword)) {
e.reply(`请输入书名,例如:#搜书 12`);
return true;
}
let id, source;
if (keyword.includes(" ")) {
[id, source] = keyword.split(" ");
} else {
id = /\d+/.exec(keyword)[0];
source = "";
}
const res = await getBookDetail(e, id, source);
await this.reply(await Bot.makeForwardMsg(res));
}
/**
* @link searchBook 的上下文
* @returns {Promise<void>}
*/
async searchBookContext() {
// 当前消息
const curMsg = this.e;
// 上一个消息
// const preMsg = this.getContext();
if (!curMsg.msg) {
this.e.reply("请回复id和来源");
return;
}
// 获取id和来源
let id, source;
if (curMsg.msg.includes(" ")) {
[id, source] = curMsg.msg.split(" ");
} else {
id = /\d+/.exec(curMsg.msg)[0];
source = "";
}
const res = await getBookDetail(curMsg, id, source);
await this.reply(await Bot.makeForwardMsg(res));
this.finish("searchBookContext");
}
// 竹白百科 // 竹白百科
async zhubaiSearch(e) { async zhubaiSearch(e) {
const keyword = e.msg.replace("#竹白", "").trim(); const keyword = e.msg.replace("#竹白", "").trim();
@ -314,27 +380,35 @@ export class query extends plugin {
e.reply("请输入想了解的内容,例如:#竹白 javascript"); e.reply("请输入想了解的内容,例如:#竹白 javascript");
return true; return true;
} }
await axios.post("https://open.zhubai.wiki/a/zb/s/ep/", { await axios
"content": 1, .post(
"keyword": keyword "https://open.zhubai.wiki/a/zb/s/ep/",
}, { {
headers: { content: 1,
"User-Agent": keyword: keyword,
"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36", },
} {
}).then(async resp => { headers: {
const res = resp.data.data; "User-Agent":
const content = await res.map(item => { "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Mobile Safari/537.36",
const {pn, pa, zn, lu, pu, pq, aa, hl } = item; },
const template = `标题:${pn}\n${pa}\n期刊:${zn}\n发布日期距今:${lu}\n链接1${pu}\n链接2${pq}\n\n 大致描述:${hl.join("\n").replace(/<\/?font[^>]*>/g, '')}` },
return { )
message: [segment.image(aa), template], .then(async resp => {
nickname: this.e.sender.card || this.e.user_id, const res = resp.data.data;
user_id: this.e.user_id, const content = await res.map(item => {
} const { pn, pa, zn, lu, pu, pq, aa, hl } = item;
}) const template = `标题:${pn}\n${pa}\n期刊:${zn}\n发布日期距今:${lu}\n链接1${pu}\n链接2${pq}\n\n 大致描述:${hl
e.reply(await Bot.makeForwardMsg(content)); .join("\n")
}) .replace(/<\/?font[^>]*>/g, "")}`;
return {
message: [segment.image(aa), template],
nickname: this.e.sender.card || this.e.user_id,
user_id: this.e.user_id,
};
});
e.reply(await Bot.makeForwardMsg(content));
});
return true; return true;
} }

View File

@ -127,4 +127,105 @@ async function getZBook(e, keyword) {
}); });
} }
export { getYiBook, getZBook }; /**
* 获取ZHelper的数据
* @param keyword
* @returns {Promise<AxiosResponse<any>>}
*/
async function getZHelper(e, keyword) {
const sendTemplate = {
nickname: e.sender.card || e.user_id,
user_id: e.user_id,
};
return axios
.post("https://api.ylibrary.org/api/search/", {
headers: {
"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1660.14",
referer: "https://search.zhelper.net/",
},
keyword: keyword,
page: 1,
sensitive: false,
})
.then(async resp => {
return resp.data.data.map(item => {
const { title, author, publisher, isbn, extension, filesize, year, id, source } =
item;
// 数据组合
return {
message: {
type: "text",
text:
`${id}: <${title}>\n` +
`作者:${author}\n` +
`书籍类型:${extension}\n` +
`出版年月:${year}\n` +
`来源:${source}\n` +
`ISBN${isbn || "暂无"}\n` +
`出版社:${publisher}\n` +
`文件大小:${(Number(filesize) / 1024 / 1024).toFixed(2)}MB`,
},
...sendTemplate,
};
});
});
}
/**
* 获取书籍下载方式
* @param e
* @param id
* @param source
* @returns {Promise<AxiosResponse<any>>}
*/
async function getBookDetail(e, id, source) {
return axios
.post("https://api.ylibrary.org/api/detail/", {
headers: {
"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1660.14",
referer: "https://search.zhelper.net/",
},
id: id,
source: source || "zlibrary",
})
.then(async resp => {
const {
author,
extension,
filesize,
id,
in_libgen,
ipfs_cid,
md5,
publisher,
source,
title,
year,
} = resp.data;
const Libgen = `https://libgendown.1kbtool.com/${md5}`;
const ipfs = `https://ipfs-checker.1kbtool.com/${ipfs_cid}?filename=${encodeURIComponent(
title,
)}_${source}-search.${extension}`;
const reqUrl = `${md5}#${filesize}#${encodeURIComponent(title)}_${encodeURIComponent(
author,
)}_${id}_${source}-search.${extension}`;
const cleverPass = `https://rapidupload.1kbtool.com/${reqUrl}`;
const cleverPass2 = `https://rulite.1kbtool.com/${reqUrl}`;
return [
`Libgen${Libgen}`,
`ipfs${ipfs}`,
`秒传:${cleverPass}`,
`秒传Lite${cleverPass2}`,
].map(item => {
return {
message: { type: "text", text: item },
nickname: e.sender.card || e.user_id,
user_id: e.user_id,
};
});
});
}
export { getYiBook, getZBook, getBookDetail, getZHelper };