From 760d280b5083efe9c608e2f4550e5a30bf12728b Mon Sep 17 00:00:00 2001 From: Shigma Date: Wed, 19 Jul 2023 01:40:59 +0800 Subject: [PATCH] feat: support proxy config, close #18 --- package.json | 8 ++++---- src/ascii2d.ts | 15 +++++++-------- src/index.ts | 11 ++++++----- src/iqdb.ts | 4 ++-- src/saucenao.ts | 12 ++++++------ src/utils.ts | 5 +++-- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 340dc1b..b4a47e2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "koishi-plugin-image-search", "description": "Image searching plugin for Koishi", - "version": "4.2.2", + "version": "4.2.3", "main": "lib/index.js", "typings": "lib/index.d.ts", "files": [ @@ -50,8 +50,8 @@ "nhentai-api": "^3.4.3" }, "devDependencies": { - "@types/node": "^18.11.18", - "koishi": "^4.11.4", - "typescript": "^4.9.4" + "@types/node": "^20.4.2", + "koishi": "^4.13.8", + "typescript": "^5.1.6" } } diff --git a/src/ascii2d.ts b/src/ascii2d.ts index 08c932b..9129d93 100644 --- a/src/ascii2d.ts +++ b/src/ascii2d.ts @@ -1,17 +1,17 @@ import { load } from 'cheerio' -import { Session, Logger } from 'koishi' +import { Logger, Quester, Session } from 'koishi' import { Config, getShareText, OutputConfig } from './utils' import FormData from 'form-data' const baseURL = 'https://ascii2d.net' const logger = new Logger('search') -export default async function (url: string, session: Session, config: Config) { +export default async function (http: Quester, url: string, session: Session, config: Config) { try { const tasks: Promise[] = [] const form = new FormData() - form.append('file', await session.app.http.get(url, { responseType: 'stream' })) - const colorHTML = await session.app.http.post(`${baseURL}/search/file`, form, { + form.append('file', await http.get(url, { responseType: 'stream' })) + const colorHTML = await http.post(`${baseURL}/search/file`, form, { headers: { 'User-Agent': 'PostmanRuntime/7.29.0', ...form.getHeaders(), @@ -20,10 +20,10 @@ export default async function (url: string, session: Session, config: Config) { tasks.push(session.send('ascii2d 色合检索\n' + getDetail(colorHTML, config.output))) try { const bovwURL = getTokuchouUrl(colorHTML) - const bovwHTML = await session.app.http.get(bovwURL, { + const bovwHTML = await http.get(bovwURL, { headers: { 'User-Agent': 'PostmanRuntime/7.29.0', - "Content-Type": 'multipart/form-data', + 'Content-Type': 'multipart/form-data', }, }) tasks.push(session.send('ascii2d 特征检索\n' + getDetail(bovwHTML, config.output))) @@ -61,6 +61,5 @@ function getDetail(html: string, config: OutputConfig) { function getTokuchouUrl(html: string) { const $ = load(html, { decodeEntities: false }) - return `${baseURL}/search/bovw/${$($(".hash")[0]).text().trim()}` + return `${baseURL}/search/bovw/${$($('.hash')[0]).text().trim()}` } - diff --git a/src/index.ts b/src/index.ts index 19ec732..11936dc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import { Context, Session, Command, makeArray, segment, Awaitable } from 'koishi' +import { Awaitable, Command, Context, makeArray, Quester, segment, Session } from 'koishi' import ascii2d from './ascii2d' import saucenao from './saucenao' import iqdb from './iqdb' @@ -8,12 +8,13 @@ export { Config } export const name = 'image-search' -async function mixedSearch(url: string, session: Session, config: Config) { - return await saucenao(url, session, config, true) && ascii2d(url, session, config) +async function mixedSearch(http: Quester, url: string, session: Session, config: Config) { + return await saucenao(http, url, session, config, true) && ascii2d(http, url, session, config) } export function apply(ctx: Context, config: Config = {}) { let index = 0 + const http = ctx.http.extend(config) const keys = makeArray(config.saucenaoApiKey) ctx.on('saucenao/get-key', () => { @@ -44,13 +45,13 @@ export function apply(ctx: Context, config: Config = {}) { const pendings = new Set() - type SearchCallback = (url: string, session: Session, config: Config) => Awaitable + type SearchCallback = (http: Quester, url: string, session: Session, config: Config) => Awaitable async function searchUrl(session: Session, url: string, callback: SearchCallback) { const id = session.channelId pendings.add(id) try { - const result = await callback(url, session, config) + const result = await callback(http, url, session, config) if (typeof result === 'string') return result } catch (error) { ctx.logger('search').warn(error) diff --git a/src/iqdb.ts b/src/iqdb.ts index 7d64ce4..84d4d24 100644 --- a/src/iqdb.ts +++ b/src/iqdb.ts @@ -1,5 +1,5 @@ import { searchPic } from 'iqdb-client' -import { segment, Session } from 'koishi' +import { Quester, segment, Session } from 'koishi' async function makeSearch(url: string): Promise { const res = await searchPic(url, { lib: 'www' }) @@ -21,7 +21,7 @@ async function makeSearch(url: string): Promise { } } -export default async function (url: string, session: Session) { +export default async function (http: Quester, url: string, session: Session) { let result = 'iqdb.org 搜图\n' try { result += await makeSearch(url) diff --git a/src/saucenao.ts b/src/saucenao.ts index 7039a54..ff16376 100644 --- a/src/saucenao.ts +++ b/src/saucenao.ts @@ -3,8 +3,8 @@ import nhentai from './nhentai' import danbooru from './danbooru' import konachan from './konachan' -import { Session, Logger, Schema } from 'koishi' -import { getShareText, checkHost, OutputConfig } from './utils' +import { Logger, Quester, Schema, Session } from 'koishi' +import { checkHost, getShareText, OutputConfig } from './utils' import { Config } from '.' declare module 'koishi' { @@ -99,7 +99,7 @@ interface Params { url: string } -async function search(url: string, session: Session, config: saucenao.Config, mixed?: boolean) { +async function search(http: Quester, url: string, session: Session, config: saucenao.Config, mixed?: boolean) { const { app } = session const keys = new Set() for (let i = 0; i < config.maxTrials || 3; ++i) { @@ -110,7 +110,7 @@ async function search(url: string, session: Session, config: saucenao.Config, mi } keys.add(api_key) try { - return await session.app.http.get('https://saucenao.com/search.php', { + return await http.get('https://saucenao.com/search.php', { params: { db: 999, numres: 3, @@ -142,8 +142,8 @@ async function search(url: string, session: Session, config: saucenao.Config, mi await session.send('搜索次数已达单位时间上限,请稍候再试。') } -async function saucenao(url: string, session: Session, config: Config, mixed?: boolean): Promise { - const data = await search(url, session, config, mixed) +async function saucenao(http: Quester, url: string, session: Session, config: Config, mixed?: boolean): Promise { + const data = await search(http, url, session, config, mixed) if (!data) return if (!data.results) { diff --git a/src/utils.ts b/src/utils.ts index 719c8f6..ad9588b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import { Schema, segment } from 'koishi' +import { Quester, Schema, segment } from 'koishi' export function getLink(url: string) { const pidSearch = /pixiv.+illust_id=(\d+)/.exec(url) @@ -33,7 +33,7 @@ export const SearchConfig: Schema = Schema.object({ highSimilarity: Schema.number().description('相似度较高的认定标准 (百分比)。当 SauceNAO 给出的相似度高于这个值时,将不会使用 ascii2d 再次搜索。').default(60), }).description('搜索设置') -export interface Config extends SearchConfig { +export interface Config extends SearchConfig, Quester.Config { output?: OutputConfig } @@ -42,6 +42,7 @@ export const Config: Schema = Schema.intersect([ Schema.object({ output: OutputConfig, }), + Quester.createConfig(), ]) export interface ShareData {