mirror of
https://github.com/Jerryplusy/rc-plugin.git
synced 2025-10-14 08:09:19 +00:00
✨ feat: V1.4.0 新增米游社文章解析
1. 新增米游社文章解析,感谢群友mix提供的想法 2. 新增ks的图片解析,感谢群友风をした提供手机端图片的例子 3. 格式化部分代码
This commit is contained in:
parent
57c5d2b453
commit
f62bb7a695
@ -8,12 +8,17 @@ import axios from "axios";
|
|||||||
// 常量
|
// 常量
|
||||||
import { CAT_LIMIT } from "../constants/constant.js";
|
import { CAT_LIMIT } from "../constants/constant.js";
|
||||||
// 书库
|
// 书库
|
||||||
import { getZHelper, getYiBook, getZBook } from "../utils/books.js";
|
import { getYiBook, getZBook, getZHelper } from "../utils/books.js";
|
||||||
// 工具类
|
// 工具类
|
||||||
import _ from "lodash";
|
|
||||||
import TokenBucket from '../utils/token-bucket.js'
|
import TokenBucket from '../utils/token-bucket.js'
|
||||||
|
|
||||||
export class query extends plugin {
|
export class query extends plugin {
|
||||||
|
/**
|
||||||
|
* 令牌桶 拿来限流
|
||||||
|
* @type {TokenBucket}
|
||||||
|
*/
|
||||||
|
static #tokenBucket = new TokenBucket(1, 1, 60);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
name: "R插件查询类",
|
name: "R插件查询类",
|
||||||
@ -59,19 +64,19 @@ export class query extends plugin {
|
|||||||
|
|
||||||
async doctor(e) {
|
async doctor(e) {
|
||||||
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)
|
const res = await fetch(url)
|
||||||
.then(resp => resp.json())
|
.then(resp => resp.json())
|
||||||
.then(resp => resp.list);
|
.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 }`;
|
||||||
|
|
||||||
if (title === keyword) {
|
if (title === keyword) {
|
||||||
const browser = await puppeteer.browserInit();
|
const browser = await puppeteer.browserInit();
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
await page.goto(`https://www.dayi.org.cn/drug/${element.id}`);
|
await page.goto(`https://www.dayi.org.cn/drug/${ element.id }`);
|
||||||
const buff = await page.screenshot({
|
const buff = await page.screenshot({
|
||||||
fullPage: true,
|
fullPage: true,
|
||||||
type: "jpeg",
|
type: "jpeg",
|
||||||
@ -101,8 +106,8 @@ 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 =>
|
fetch(`https://api.thecatapi.com/v1/images/search?limit=${ CAT_LIMIT }`).then(data =>
|
||||||
data.json(),
|
data.json(),
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
@ -139,7 +144,7 @@ export class query extends plugin {
|
|||||||
.filter(result => result.status === "fulfilled") // 只保留已解决的 Promise
|
.filter(result => result.status === "fulfilled") // 只保留已解决的 Promise
|
||||||
.flatMap(result =>
|
.flatMap(result =>
|
||||||
result.value.data.list.map(element => {
|
result.value.data.list.map(element => {
|
||||||
const template = `推荐软件:${element.title}\n地址:${element.url}\n`;
|
const template = `推荐软件:${ element.title }\n地址:${ element.url }\n`;
|
||||||
return {
|
return {
|
||||||
message: { type: "text", text: template },
|
message: { type: "text", text: template },
|
||||||
nickname: e.sender.card || e.user_id,
|
nickname: e.sender.card || e.user_id,
|
||||||
@ -228,14 +233,14 @@ export class query extends plugin {
|
|||||||
// 封装答案
|
// 封装答案
|
||||||
let ans = "";
|
let ans = "";
|
||||||
for (let i = 0; i < result.length; i++) {
|
for (let i = 0; i < result.length; i++) {
|
||||||
ans += `${i + 1}. ${result[i]}\n`;
|
ans += `${ i + 1 }. ${ result[i] }\n`;
|
||||||
}
|
}
|
||||||
e.reply(ans);
|
e.reply(ans);
|
||||||
const imgMatch = uri.match(/[^\/]+/g);
|
const imgMatch = uri.match(/[^\/]+/g);
|
||||||
const imgId = imgMatch[imgMatch.length - 2];
|
const imgId = imgMatch[imgMatch.length - 2];
|
||||||
|
|
||||||
axios
|
axios
|
||||||
.get(`https://h5.cyol.com/special/daxuexi/${imgId}/images/end.jpg`, {
|
.get(`https://h5.cyol.com/special/daxuexi/${ imgId }/images/end.jpg`, {
|
||||||
headers: {
|
headers: {
|
||||||
"User-Agent":
|
"User-Agent":
|
||||||
"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",
|
"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",
|
||||||
@ -353,9 +358,9 @@ export class query extends plugin {
|
|||||||
.sort((a, b) => b.luSort - a.luSort)
|
.sort((a, b) => b.luSort - a.luSort)
|
||||||
.map(item => {
|
.map(item => {
|
||||||
const { pn, pa, zn, lu, pu, pq, aa, hl } = 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
|
const template = `标题:${ pn }\n${ pa }\n期刊:${ zn }\n发布日期距今:${ lu }\n链接1:${ pu }\n链接2:${ pq }\n\n 大致描述:${ hl
|
||||||
.join("\n")
|
.join("\n")
|
||||||
.replace(/<\/?font[^>]*>/g, "")}`;
|
.replace(/<\/?font[^>]*>/g, "") }`;
|
||||||
return {
|
return {
|
||||||
message: [segment.image(aa), template],
|
message: [segment.image(aa), template],
|
||||||
nickname: this.e.sender.card || this.e.user_id,
|
nickname: this.e.sender.card || this.e.user_id,
|
||||||
@ -377,7 +382,7 @@ export class query extends plugin {
|
|||||||
if (query.#tokenBucket.consume(e.user_id, 1)) {
|
if (query.#tokenBucket.consume(e.user_id, 1)) {
|
||||||
await func();
|
await func();
|
||||||
} else {
|
} else {
|
||||||
e.reply(`🙅${e.nickname}你已经被限流,请稍后再试!`, true);
|
e.reply(`🙅${ e.nickname }你已经被限流,请稍后再试!`, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,10 +391,4 @@ export class query extends plugin {
|
|||||||
const titleRex = /<[^>]+>/g;
|
const titleRex = /<[^>]+>/g;
|
||||||
return title.replace(titleRex, "");
|
return title.replace(titleRex, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 令牌桶 拿来限流
|
|
||||||
* @type {TokenBucket}
|
|
||||||
*/
|
|
||||||
static #tokenBucket = new TokenBucket(1, 1, 60);
|
|
||||||
}
|
}
|
||||||
|
137
apps/tools.js
137
apps/tools.js
@ -26,7 +26,7 @@ import {
|
|||||||
TWITTER_BEARER_TOKEN,
|
TWITTER_BEARER_TOKEN,
|
||||||
XHS_NO_WATERMARK_HEADER,
|
XHS_NO_WATERMARK_HEADER,
|
||||||
} from "../constants/constant.js";
|
} from "../constants/constant.js";
|
||||||
import { containsChinese, formatBiliInfo, getIdVideo, secondsToTime } from "../utils/common.js";
|
import { containsChinese, downloadImg, formatBiliInfo, getIdVideo, secondsToTime } from "../utils/common.js";
|
||||||
import config from "../model/index.js";
|
import config from "../model/index.js";
|
||||||
import Translate from "../utils/trans-strategy.js";
|
import Translate from "../utils/trans-strategy.js";
|
||||||
import * as xBogus from "../utils/x-bogus.cjs";
|
import * as xBogus from "../utils/x-bogus.cjs";
|
||||||
@ -38,6 +38,7 @@ import { getWbi } from "../utils/biliWbi.js";
|
|||||||
import {
|
import {
|
||||||
BILI_SUMMARY,
|
BILI_SUMMARY,
|
||||||
DY_INFO,
|
DY_INFO,
|
||||||
|
MIYOUSHE_ARTICLE,
|
||||||
TIKTOK_INFO,
|
TIKTOK_INFO,
|
||||||
TWITTER_TWEET_INFO,
|
TWITTER_TWEET_INFO,
|
||||||
XHS_REQ_LINK,
|
XHS_REQ_LINK,
|
||||||
@ -47,6 +48,7 @@ import {
|
|||||||
import child_process from 'node:child_process'
|
import child_process from 'node:child_process'
|
||||||
import { getAudio, getVideo } from "../utils/y2b.js";
|
import { getAudio, getVideo } from "../utils/y2b.js";
|
||||||
import { processTikTokUrl } from "../utils/tiktok.js";
|
import { processTikTokUrl } from "../utils/tiktok.js";
|
||||||
|
import { getDS } from "../utils/mihoyo.js";
|
||||||
|
|
||||||
export class tools extends plugin {
|
export class tools extends plugin {
|
||||||
/**
|
/**
|
||||||
@ -134,6 +136,10 @@ export class tools extends plugin {
|
|||||||
{
|
{
|
||||||
reg: "(ixigua.com)",
|
reg: "(ixigua.com)",
|
||||||
fnc: "xigua"
|
fnc: "xigua"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
reg: "(miyoushe.com)",
|
||||||
|
fnc: "miyoushe"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -566,7 +572,7 @@ export class tools extends plugin {
|
|||||||
for (let item of resp.includes.media) {
|
for (let item of resp.includes.media) {
|
||||||
if (item.type === "photo") {
|
if (item.type === "photo") {
|
||||||
// 图片
|
// 图片
|
||||||
task.push(this.downloadImg(item.url, downloadPath, "", true));
|
task.push(downloadImg(item.url, downloadPath, "", true));
|
||||||
} else if (item.type === "video") {
|
} else if (item.type === "video") {
|
||||||
// 视频
|
// 视频
|
||||||
await this.downloadVideo(resp.includes.media[0].variants[0].url, true).then(
|
await this.downloadVideo(resp.includes.media[0].variants[0].url, true).then(
|
||||||
@ -686,7 +692,7 @@ export class tools extends plugin {
|
|||||||
} else if (type === "normal") {
|
} else if (type === "normal") {
|
||||||
e.reply(`识别:小红书, ${ title }\n${ desc }`);
|
e.reply(`识别:小红书, ${ title }\n${ desc }`);
|
||||||
noteData.imageList.map(async (item, index) => {
|
noteData.imageList.map(async (item, index) => {
|
||||||
imgPromise.push(this.downloadImg(item.urlDefault, downloadPath, index.toString()));
|
imgPromise.push(downloadImg(item.urlDefault, downloadPath, index.toString()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const paths = await Promise.all(imgPromise);
|
const paths = await Promise.all(imgPromise);
|
||||||
@ -773,7 +779,7 @@ export class tools extends plugin {
|
|||||||
// 判断是否是海外服务器
|
// 判断是否是海外服务器
|
||||||
const isOversea = await this.isOverseasServer();
|
const isOversea = await this.isOverseasServer();
|
||||||
// 简单封装图片下载
|
// 简单封装图片下载
|
||||||
const downloadImg = (url, destination) => {
|
const downloadInsImg = (url, destination) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fetch(url, {
|
fetch(url, {
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
@ -805,7 +811,7 @@ export class tools extends plugin {
|
|||||||
.exec(item)[0]
|
.exec(item)[0]
|
||||||
.replace(/#38/g, "")
|
.replace(/#38/g, "")
|
||||||
.replace(/;/g, "");
|
.replace(/;/g, "");
|
||||||
imgPromise.push(downloadImg(imgUrl, `${ downloadPath }/${ index }.jpg`));
|
imgPromise.push(downloadInsImg(imgUrl, `${ downloadPath }/${ index }.jpg`));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// TODO 视频,会出bug暂时不做
|
// TODO 视频,会出bug暂时不做
|
||||||
@ -924,10 +930,25 @@ export class tools extends plugin {
|
|||||||
},
|
},
|
||||||
timeout: 10000 // 设置超时时间
|
timeout: 10000 // 设置超时时间
|
||||||
}).then(resp => {
|
}).then(resp => {
|
||||||
|
// 图片:https://kph8gvfz.m.chenzhongtech.com/fw/photo/3x45s52s9wchwwm
|
||||||
|
|
||||||
|
if (resp.data.data?.imageUrl) {
|
||||||
|
const imageUrl = resp.data.data.imageUrl;
|
||||||
|
const images = imageUrl.map(item => {
|
||||||
|
return {
|
||||||
|
message: segment.image(item),
|
||||||
|
nickname: this.e.sender.card || this.e.user_id,
|
||||||
|
user_id: this.e.user_id,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
e.reply(Bot.makeForwardMsg(images));
|
||||||
|
} else {
|
||||||
|
// 视频:https://www.kuaishou.com/short-video/3xhjgcmir24m4nm
|
||||||
const url = resp.data.data.url;
|
const url = resp.data.data.url;
|
||||||
this.downloadVideo(url).then(path => {
|
this.downloadVideo(url).then(path => {
|
||||||
e.reply(segment.video(path + "/temp.mp4"));
|
e.reply(segment.video(path + "/temp.mp4"));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1075,6 +1096,60 @@ export class tools extends plugin {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async miyoushe(e) {
|
||||||
|
let msg = /(?:https?:\/\/)?(m|www)\.miyoushe\.com\/[A-Za-z\d._?%&+\-=\/#]*/.exec(e.msg)[0];
|
||||||
|
const id = /\/(\d+)$/.exec(msg)?.[0].replace("\/", "");
|
||||||
|
|
||||||
|
fetch(MIYOUSHE_ARTICLE.replace("{}", id), {
|
||||||
|
headers: {
|
||||||
|
"Accept-Encoding": "gzip, deflate, br",
|
||||||
|
"Accept-Language": "zh-cn",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Host": "api-takumi.mihoyo.com",
|
||||||
|
"x-rpc-app_version": "2.11.0",
|
||||||
|
"x-rpc-client_type": "4",
|
||||||
|
"Referer": "https://bbs.mihoyo.com/",
|
||||||
|
"DS": getDS(),
|
||||||
|
}
|
||||||
|
}).then(async resp => {
|
||||||
|
const respJson = await resp.json();
|
||||||
|
const data = respJson.data.post.post;
|
||||||
|
// 分别获取:封面、主题、内容、图片
|
||||||
|
const { cover, subject, content, images, structured_content } = data;
|
||||||
|
let realContent = "";
|
||||||
|
// safe JSON.parse
|
||||||
|
try {
|
||||||
|
realContent = JSON.parse(content);
|
||||||
|
} catch (e) {
|
||||||
|
realContent = content;
|
||||||
|
}
|
||||||
|
const normalMsg = `识别:米游社,${ subject }\n${ realContent }`;
|
||||||
|
const replyMsg = cover ? [segment.image(cover), normalMsg] : normalMsg;
|
||||||
|
e.reply(replyMsg);
|
||||||
|
// 视频
|
||||||
|
if (structured_content) {
|
||||||
|
const sc = JSON.parse(structured_content);
|
||||||
|
const resolutions = sc?.[1].insert.vod.resolutions;
|
||||||
|
// 暂时选取分辨率较低的video进行解析
|
||||||
|
const videoUrl = resolutions[0].url;
|
||||||
|
this.downloadVideo(videoUrl).then(path => {
|
||||||
|
e.reply(segment.video(path + "/temp.mp4"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 这个判断防止发送重复图片
|
||||||
|
if (images && images.length > 1) {
|
||||||
|
const replyImages = images.map(item => {
|
||||||
|
return {
|
||||||
|
message: segment.image(item),
|
||||||
|
nickname: this.e.sender.card || this.e.user_id,
|
||||||
|
user_id: this.e.user_id,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
e.reply(Bot.makeForwardMsg(replyImages));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 哔哩哔哩下载
|
* 哔哩哔哩下载
|
||||||
* @param title
|
* @param title
|
||||||
@ -1111,58 +1186,6 @@ export class tools extends plugin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 下载一张网络图片(自动以url的最后一个为名字)
|
|
||||||
* @param img
|
|
||||||
* @param dir
|
|
||||||
* @param fileName
|
|
||||||
* @param isProxy
|
|
||||||
* @returns {Promise<unknown>}
|
|
||||||
*/
|
|
||||||
async downloadImg(img, dir, fileName = "", isProxy = false) {
|
|
||||||
if (fileName === "") {
|
|
||||||
fileName = img.split("/").pop();
|
|
||||||
}
|
|
||||||
const filepath = `${ dir }/${ fileName }`;
|
|
||||||
await mkdirIfNotExists(dir)
|
|
||||||
const writer = fs.createWriteStream(filepath);
|
|
||||||
const axiosConfig = {
|
|
||||||
headers: {
|
|
||||||
"User-Agent":
|
|
||||||
"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",
|
|
||||||
},
|
|
||||||
responseType: "stream",
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isProxy) {
|
|
||||||
axiosConfig.httpAgent = tunnel.httpOverHttp({
|
|
||||||
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
|
||||||
});
|
|
||||||
axiosConfig.httpsAgent = tunnel.httpOverHttp({
|
|
||||||
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const res = await axios.get(img, axiosConfig);
|
|
||||||
res.data.pipe(writer);
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
writer.on("finish", () => {
|
|
||||||
writer.close(() => {
|
|
||||||
resolve(filepath);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
writer.on("error", err => {
|
|
||||||
fs.unlink(filepath, () => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
logger.error("图片下载失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* douyin 请求参数
|
* douyin 请求参数
|
||||||
* @param url
|
* @param url
|
||||||
|
@ -56,6 +56,12 @@
|
|||||||
- icon: kuaishou
|
- icon: kuaishou
|
||||||
title: "快手(测试阶段)"
|
title: "快手(测试阶段)"
|
||||||
desc: 快手分享实时下载
|
desc: 快手分享实时下载
|
||||||
|
- icon: xigua
|
||||||
|
title: "西瓜(测试阶段)"
|
||||||
|
desc: 西瓜分享实时下载
|
||||||
|
- icon: miyoushe
|
||||||
|
title: "米游社"
|
||||||
|
desc: 米游社文章分享实时下载
|
||||||
- icon: literature
|
- icon: literature
|
||||||
title: "论文"
|
title: "论文"
|
||||||
desc: SCI论文实时解析
|
desc: SCI论文实时解析
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
- {
|
- {
|
||||||
version: 1.3.5,
|
version: 1.4.0,
|
||||||
data:
|
data:
|
||||||
[
|
[
|
||||||
|
新增<span class="cmd">米游社解析</span>功能,
|
||||||
新增<span class="cmd">🍉解析</span>功能,
|
新增<span class="cmd">🍉解析</span>功能,
|
||||||
新增<span class="cmd">油管解析</span>功能,
|
新增<span class="cmd">油管解析</span>功能,
|
||||||
新增<span class="cmd">小红书无水印下载</span>功能,
|
新增<span class="cmd">小红书无水印下载</span>功能,
|
||||||
|
@ -40,6 +40,13 @@ export const BILI_VIDEO_INFO = "http://api.bilibili.com/x/web-interface/view"
|
|||||||
*/
|
*/
|
||||||
export const BILI_NAV = "https://api.bilibili.com/x/web-interface/nav"
|
export const BILI_NAV = "https://api.bilibili.com/x/web-interface/nav"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 米游社网页端获取文章
|
||||||
|
* https://github.com/UIGF-org/mihoyo-api-collect/blob/main/hoyolab/article/article.md#%E8%8E%B7%E5%8F%96%E5%AE%8C%E6%95%B4%E6%96%87%E7%AB%A0%E4%BF%A1%E6%81%AF
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
export const MIYOUSHE_ARTICLE = "https://bbs-api.miyoushe.com/post/wapi/getPostFull?post_id={}"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 视频请求链接CDN
|
* 视频请求链接CDN
|
||||||
* @type {string}
|
* @type {string}
|
||||||
|
BIN
resources/img/icon/miyoushe.png
Normal file
BIN
resources/img/icon/miyoushe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
BIN
resources/img/icon/xigua.png
Normal file
BIN
resources/img/icon/xigua.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.8 KiB |
@ -14,6 +14,7 @@ export class jFetch {
|
|||||||
const r = await fetch(url);
|
const r = await fetch(url);
|
||||||
return await r.json();
|
return await r.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
async post(url, params) {
|
async post(url, params) {
|
||||||
const r = await fetch(url, { ...params, method: "POST" });
|
const r = await fetch(url, { ...params, method: "POST" });
|
||||||
return await r.json();
|
return await r.json();
|
||||||
@ -64,7 +65,7 @@ export function retry(func, maxRetries = 3, delay = 1000) {
|
|||||||
if (remainingTries === 1) {
|
if (remainingTries === 1) {
|
||||||
reject(error);
|
reject(error);
|
||||||
} else {
|
} else {
|
||||||
console.log(`错误: ${error}. 重试将在 ${delay/1000} 秒...`);
|
console.log(`错误: ${ error }. 重试将在 ${ delay / 1000 } 秒...`);
|
||||||
setTimeout(() => attempt(remainingTries - 1), delay);
|
setTimeout(() => attempt(remainingTries - 1), delay);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -79,7 +80,7 @@ export function retry(func, maxRetries = 3, delay = 1000) {
|
|||||||
* @param filename
|
* @param filename
|
||||||
* @returns {Promise<unknown>}
|
* @returns {Promise<unknown>}
|
||||||
*/
|
*/
|
||||||
export function downloadPDF (url, filename) {
|
export function downloadPDF(url, filename) {
|
||||||
return axios({
|
return axios({
|
||||||
url: url,
|
url: url,
|
||||||
responseType: "stream",
|
responseType: "stream",
|
||||||
@ -111,7 +112,7 @@ export async function getIdVideo(url) {
|
|||||||
return idVideo.length > 19 ? idVideo.substring(0, idVideo.indexOf("?")) : idVideo;
|
return idVideo.length > 19 ? idVideo.substring(0, idVideo.indexOf("?")) : idVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateRandomStr(randomlength = 16){
|
export function generateRandomStr(randomlength = 16) {
|
||||||
const base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789='
|
const base_str = 'ABCDEFGHIGKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789='
|
||||||
let random_str = ''
|
let random_str = ''
|
||||||
for (let i = 0; i < randomlength; i++) {
|
for (let i = 0; i < randomlength; i++) {
|
||||||
@ -163,6 +164,58 @@ export async function downloadMp3(mp3Url, path, redirect = "manual") {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载一张网络图片(自动以url的最后一个为名字)
|
||||||
|
* @param img
|
||||||
|
* @param dir
|
||||||
|
* @param fileName
|
||||||
|
* @param isProxy
|
||||||
|
* @returns {Promise<unknown>}
|
||||||
|
*/
|
||||||
|
export async function downloadImg(img, dir, fileName = "", isProxy = false) {
|
||||||
|
if (fileName === "") {
|
||||||
|
fileName = img.split("/").pop();
|
||||||
|
}
|
||||||
|
const filepath = `${ dir }/${ fileName }`;
|
||||||
|
await mkdirIfNotExists(dir)
|
||||||
|
const writer = fs.createWriteStream(filepath);
|
||||||
|
const axiosConfig = {
|
||||||
|
headers: {
|
||||||
|
"User-Agent":
|
||||||
|
"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",
|
||||||
|
},
|
||||||
|
responseType: "stream",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isProxy) {
|
||||||
|
axiosConfig.httpAgent = tunnel.httpOverHttp({
|
||||||
|
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
||||||
|
});
|
||||||
|
axiosConfig.httpsAgent = tunnel.httpOverHttp({
|
||||||
|
proxy: { host: this.proxyAddr, port: this.proxyPort },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await axios.get(img, axiosConfig);
|
||||||
|
res.data.pipe(writer);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
writer.on("finish", () => {
|
||||||
|
writer.close(() => {
|
||||||
|
resolve(filepath);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
writer.on("error", err => {
|
||||||
|
fs.unlink(filepath, () => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
logger.error("图片下载失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 千位数的数据处理
|
* 千位数的数据处理
|
||||||
* @param data
|
* @param data
|
||||||
@ -178,7 +231,7 @@ const dataProcessing = data => {
|
|||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
export function formatBiliInfo(data) {
|
export function formatBiliInfo(data) {
|
||||||
return Object.keys(data).map(key => `${key}:${dataProcessing(data[key])}`).join(' | ');
|
return Object.keys(data).map(key => `${ key }:${ dataProcessing(data[key]) }`).join(' | ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,7 +250,7 @@ export function secondsToTime(seconds) {
|
|||||||
// return `${pad(minutes, 2)}:${pad(secs, 2)}`;
|
// return `${pad(minutes, 2)}:${pad(secs, 2)}`;
|
||||||
|
|
||||||
// 完整的 HH:MM:SS 格式
|
// 完整的 HH:MM:SS 格式
|
||||||
return `${pad(hours, 2)}:${pad(minutes, 2)}:${pad(secs, 2)}`;
|
return `${ pad(hours, 2) }:${ pad(minutes, 2) }:${ pad(secs, 2) }`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
14
utils/mihoyo.js
Normal file
14
utils/mihoyo.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import md5 from 'md5';
|
||||||
|
|
||||||
|
export const getDS = () => {
|
||||||
|
const salt = "ZSHlXeQUBis52qD1kEgKt5lUYed4b7Bb";
|
||||||
|
const lettersAndNumbers = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||||
|
|
||||||
|
const i = Math.floor(Date.now() / 1000);
|
||||||
|
let r = ""
|
||||||
|
for (let i; i < 6; i++) {
|
||||||
|
r += lettersAndNumbers[Math.floor(Math.random() * lettersAndNumbers.length)]
|
||||||
|
}
|
||||||
|
const c = md5(`salt=${ salt }&t=${ i }&r=${ r }`);
|
||||||
|
return `${ i },${ r },${ c }`;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user