From ff0bacc70edd96cb1efbe170fbeb96f86b653446 Mon Sep 17 00:00:00 2001 From: huankong233 Date: Fri, 8 May 2026 16:17:58 +0800 Subject: [PATCH 1/3] =?UTF-8?q?[*]=20=E4=BF=AE=E5=A4=8D=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E9=94=99=E8=AF=AF=20[*]=20=E4=BF=AE=E5=A4=8D=20AnimeTrace=20?= =?UTF-8?q?=E4=BC=9A=E6=8A=9B=E5=87=BA=20base64=20=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 +++++ README.md | 6 +++--- package.json | 10 ++++------ pnpm-lock.yaml | 30 +++--------------------------- src/libs/AnimeTrace/index.ts | 3 +++ src/libs/TraceMoe/index.ts | 2 +- src/libs/TraceMoe/types.ts | 2 +- src/utils/flaresolverr.ts | 2 +- src/utils/readFileToBlob.ts | 4 ++-- 9 files changed, 23 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 560bcc7..8a7e0f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## 2026 +### 05-07 v1.0.1 + +- [*] 修复类型错误 +- [*] 修复 AnimeTrace 会抛出 base64 错误 + ### 05-07 v1.0.0 - [*] 全新重构 diff --git a/README.md b/README.md index d5d53ca..c0d508f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ | 搜索引擎 | url | path | 特殊选项 | | ------------------------------------ | --- | ---- | ---------------------------------- | -| [Ascii2d](https://ascii2d.net/) | ✔ | ✔ | type, flaresolverr | +| [Ascii2d](https://ascii2d.net/) | ✔ | ✔ | type, flareSolverr | | [Iqdb](https://iqdb.org/) | ✔ | ✔ | service, forcegray | | [SauceNAO](https://saucenao.com) | ✔ | ✔ | hide, dbs | | [TraceMoe](https://trace.moe/) | ✔ | ✔ | curBorders, anilistId, anilistInfo | @@ -73,7 +73,7 @@ const result = await Ascii2d({ const result = await Ascii2d({ url: 'https://example.com/image.jpg', type: 'bovw', // 搜索类型: 'color' 或 'bovw' - flaresolverr: 'https://flaresolverr.example.com' // FlareSolverr API地址 + flareSolverr: 'https://flaresolverr.example.com' // FlareSolverr API地址 }) ``` @@ -171,7 +171,7 @@ docker run -d -p 8191:8191 --name flaresolverr ghcr.io/flaresolverr/flaresolverr ```typescript const result = await Ascii2d({ url: 'https://example.com/image.jpg', - flaresolverr: 'http://localhost:8191' + flareSolverr: 'http://localhost:8191' }) ``` diff --git a/package.json b/package.json index e547b2c..f3ce17d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "image_searcher", "type": "module", - "version": "1.0.0", + "version": "1.0.1", "description": "image searcher of multiple search engines", "author": "huan_kong", "license": "MIT", @@ -22,10 +22,7 @@ "domelementtype": "^3.0.0", "file-type": "^22.0.1", "flaresolverr-client": "^1.2.0", - "ky": "^2.0.2", - "tough-cookie": "^6.0.1", - "typescript": "^6.0.3" - + "ky": "^2.0.2" }, "devDependencies": { "@antfu/eslint-config": "^8.2.0", @@ -34,6 +31,7 @@ "eslint": "^10.2.1", "jiti": "^2.6.1", "tsdown": "^0.21.10", - "tsx": "^4.21.0" + "tsx": "^4.21.0", + "typescript": "^6.0.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0f8ee32..f4579b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,12 +23,6 @@ importers: ky: specifier: ^2.0.2 version: 2.0.2 - tough-cookie: - specifier: ^6.0.1 - version: 6.0.1 - typescript: - specifier: ^6.0.3 - version: 6.0.3 devDependencies: '@antfu/eslint-config': specifier: ^8.2.0 @@ -51,6 +45,9 @@ importers: tsx: specifier: ^4.21.0 version: 4.21.0 + typescript: + specifier: ^6.0.3 + version: 6.0.3 packages: @@ -1802,13 +1799,6 @@ packages: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} - tldts-core@7.0.29: - resolution: {integrity: sha512-W99NuU7b1DcG3uJ3v9k9VztCH3WialNbBkBft5wCs8V8mexu0XQqaZEYb9l9RNNzK8+3EJ9PKWB0/RUtTQ/o+Q==} - - tldts@7.0.29: - resolution: {integrity: sha512-JIXCerhudr/N6OWLwLF1HVsTTUo7ry6qHa5eWZEkiMuxsIiAACL55tGLfqfHfoH7QaMQUW8fngD7u7TxWexYQg==} - hasBin: true - to-valid-identifier@1.0.0: resolution: {integrity: sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==} engines: {node: '>=20'} @@ -1821,10 +1811,6 @@ packages: resolution: {integrity: sha512-A5F0cM6+mDleacLIEUkmfpkBbnHJFV1d2rprHU2MXNk7mlxHq2zGojA+SRvQD1RoMo9gqjZPWEaKG4v1BQ48lw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} - tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -3910,12 +3896,6 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - tldts-core@7.0.29: {} - - tldts@7.0.29: - dependencies: - tldts-core: 7.0.29 - to-valid-identifier@1.0.0: dependencies: '@sindresorhus/base62': 1.0.0 @@ -3931,10 +3911,6 @@ snapshots: dependencies: eslint-visitor-keys: 5.0.1 - tough-cookie@6.0.1: - dependencies: - tldts: 7.0.29 - tree-kill@1.2.2: {} ts-api-utils@2.5.0(typescript@6.0.3): diff --git a/src/libs/AnimeTrace/index.ts b/src/libs/AnimeTrace/index.ts index 65c2633..634fafe 100644 --- a/src/libs/AnimeTrace/index.ts +++ b/src/libs/AnimeTrace/index.ts @@ -14,6 +14,9 @@ export async function AnimeTrace(options: AnimeTraceOptions): Promise { throw new Error('[TraceMoe Error]: please input path or url') } - if (options.curBorders || !('cutBorders' in options)) { + if (options.cutBorders || !('cutBorders' in options)) { searchParams.append('cutBorders', '') } diff --git a/src/libs/TraceMoe/types.ts b/src/libs/TraceMoe/types.ts index de33da3..0926f83 100644 --- a/src/libs/TraceMoe/types.ts +++ b/src/libs/TraceMoe/types.ts @@ -1,7 +1,7 @@ import type { BaseOptions } from '@/utils/BaseOptions.js' export type TraceMoeOptions = BaseOptions<{ - curBorders?: boolean + cutBorders?: boolean anilistId?: number anilistInfo?: boolean }> diff --git a/src/utils/flaresolverr.ts b/src/utils/flaresolverr.ts index 03cc49c..bcbff7b 100644 --- a/src/utils/flaresolverr.ts +++ b/src/utils/flaresolverr.ts @@ -8,6 +8,6 @@ export interface UseFlareSolverrOptions { export async function useFlareSolverr(options: UseFlareSolverrOptions): Promise { const flaresolverr = new FlareSolverrClient(options.api) - const sessionManager = await flaresolverr.createSession({ session: 'image_seacher' }, true) + const sessionManager = await flaresolverr.createSession({ session: 'image_searcher' }, true) return await sessionManager.requestGet({ url: options.url, maxTimeout: 600000 }) } diff --git a/src/utils/readFileToBlob.ts b/src/utils/readFileToBlob.ts index 1932df2..abc190a 100644 --- a/src/utils/readFileToBlob.ts +++ b/src/utils/readFileToBlob.ts @@ -1,9 +1,9 @@ import { readFile } from 'node:fs/promises' import { resolve } from 'node:path' -import { fileTypeFromFile } from 'file-type' +import { fileTypeFromBuffer } from 'file-type' export async function readFileToBlob(path: string): Promise { const buffer = await readFile(resolve(path)) - const fileType = await fileTypeFromFile(path) + const fileType = await fileTypeFromBuffer(buffer) return new Blob([buffer], { type: fileType?.mime ?? 'application/octet-stream' }) } From 5b67c728c876c560d754ed213f6d1d2ff579f221 Mon Sep 17 00:00:00 2001 From: huankong233 Date: Fri, 29 May 2026 12:49:09 +0800 Subject: [PATCH 2/3] =?UTF-8?q?[*]=20=E4=BC=98=E5=8C=96=20Ascii2d=20?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E8=BF=94=E5=9B=9E=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++ package.json | 2 +- src/libs/Ascii2d/index.ts | 79 ++++++++++++++++++++++++++------------- src/libs/Ascii2d/types.ts | 10 ++++- test/index.ts | 27 ++++++------- 5 files changed, 79 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a7e0f0..01545ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## 2026 +### 05-29 v1.0.2 + +- [*] 优化 Ascii2d 搜索返回信息 + ### 05-07 v1.0.1 - [*] 修复类型错误 diff --git a/package.json b/package.json index f3ce17d..7bc5215 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "image_searcher", "type": "module", - "version": "1.0.1", + "version": "1.0.2", "description": "image searcher of multiple search engines", "author": "huan_kong", "license": "MIT", diff --git a/src/libs/Ascii2d/index.ts b/src/libs/Ascii2d/index.ts index 0c2b87b..ed7fb3f 100644 --- a/src/libs/Ascii2d/index.ts +++ b/src/libs/Ascii2d/index.ts @@ -1,4 +1,5 @@ -import type { Ascii2dOptions, Ascii2dRes } from '@/libs/Ascii2d/types.js' +import type { Ascii2dItem, Ascii2dOptions, Ascii2dRes } from '@/libs/Ascii2d/types.js' +import { Buffer } from 'node:buffer' import { basename } from 'node:path' import { load } from 'cheerio' import ky from 'ky' @@ -10,6 +11,8 @@ const BASE_URL = 'https://ascii2d.net' export async function Ascii2d(options: Ascii2dOptions): Promise { let page: string let url: string + let userAgent = '' + let cookie = '' if ('url' in options) { const response = await useFlareSolverr({ @@ -19,6 +22,8 @@ export async function Ascii2d(options: Ascii2dOptions): Promise { page = response.solution.response url = response.solution.url + userAgent = response.solution.userAgent + cookie = response.solution.cookies.map(c => `${c.name}=${c.value}`).join('; ') } else if ('path' in options) { const form = new FormData() @@ -40,34 +45,54 @@ export async function Ascii2d(options: Ascii2dOptions): Promise { page = response.solution.response } + const results: Ascii2dItem[] = [] const $ = load(page) - return $('.item-box') - .toArray() - .map((item) => { - const image = $('.image-box > img', item).first() - const src = image.attr('src') ?? '' + const elements = $('.item-box').toArray() + for (const element of elements) { + const image = $('.image-box > img', element).first() + const src = image.attr('src') ?? '' + const imageUrl = new URL(src, BASE_URL).toString() - const detailBox = $('.detail-box', item) - const [sourceLink, authorLink] = $('a', detailBox).toArray() - - return { - hash: $('.hash', item).text(), - info: $('.info-box > .text-muted', item).text(), - image: new URL(src, BASE_URL).toString(), - source: sourceLink - ? { - link: $(sourceLink).attr('href') ?? '', - text: $(sourceLink).text(), - } - : undefined, - author: authorLink - ? { - link: $(authorLink).attr('href') ?? '', - text: $(authorLink).text(), - } - : undefined, + let base64 = '' + if (options.image2Base64) { + try { + const response = await ky.get(imageUrl, { headers: { cookie, 'User-Agent': userAgent } }) + const buffer = await response.arrayBuffer() + const contentType = response.headers.get('content-type') ?? 'application/octet-stream' + const base64Data = Buffer.from(buffer).toString('base64') + base64 = `data:${contentType};base64,${base64Data}` } + catch {} + } + + const detailBox = $('.detail-box', element) + const [sourceLink, authorLink] = $('a', detailBox).toArray() + + results.push({ + hash: $('.hash', element).text(), + info: $('.info-box > .text-muted', element).text(), + image: imageUrl, + base64, + source: sourceLink + ? { + link: $(sourceLink).attr('href') ?? '', + text: $(sourceLink).text(), + } + : undefined, + author: authorLink + ? { + link: $(authorLink).attr('href') ?? '', + text: $(authorLink).text(), + } + : undefined, }) - .filter(item => item.hash && item.info) - .slice(1) + } + + return { + userAgent, + cookie, + results: results + .filter(item => item.hash && item.info) + .slice(1), + } } diff --git a/src/libs/Ascii2d/types.ts b/src/libs/Ascii2d/types.ts index 30b5d50..8d6d933 100644 --- a/src/libs/Ascii2d/types.ts +++ b/src/libs/Ascii2d/types.ts @@ -3,6 +3,7 @@ import type { BaseOptions } from '@/utils/BaseOptions.js' export type Ascii2dOptions = BaseOptions<{ type: 'color' | 'bovw' flareSolverr: string + image2Base64?: boolean }> export interface Ascii2dSource { @@ -13,9 +14,14 @@ export interface Ascii2dSource { export interface Ascii2dItem { hash: string info: string - image: string | undefined + image: string + base64: string source: Ascii2dSource | undefined author: Ascii2dSource | undefined } -export type Ascii2dRes = Ascii2dItem[] +export interface Ascii2dRes { + userAgent: string + cookie: string + results: Ascii2dItem[] +} diff --git a/test/index.ts b/test/index.ts index 8ef80dd..644c40f 100644 --- a/test/index.ts +++ b/test/index.ts @@ -5,14 +5,15 @@ import { AnimeTrace, Ascii2d, Iqdb, SauceNAO, TinEye, TraceMoe } from '@/index.j const url = 'https://img.huankong.top/i/2024/04/15/661cc5a5b583d.jpg' const path = './test/test.jpg' -// Ascii2d({ -// type: 'bovw', -// url, -// flareSolverr: 'https://flaresolverr.huankong.top', -// }) -// .then((res) => { -// console.dir(res, { depth: null }) -// }) +Ascii2d({ + type: 'color', + url, + flareSolverr: 'http://localhost:8191', + image2Base64: true, +}) + .then((res) => { + console.dir(res, { depth: null }) + }) // SauceNAO({ // path, @@ -38,8 +39,8 @@ const path = './test/test.jpg' // console.dir(res, { depth: null }) // }) -AnimeTrace({ - url, -}).then((res) => { - console.dir(res, { depth: null }) -}) +// AnimeTrace({ +// url, +// }).then((res) => { +// console.dir(res, { depth: null }) +// }) From 2a2a2f65effc7334a8cd24e40033faecf40742a6 Mon Sep 17 00:00:00 2001 From: huankong233 Date: Fri, 29 May 2026 12:50:13 +0800 Subject: [PATCH 3/3] =?UTF-8?q?[*]=20=E4=BF=AE=E6=AD=A3=E4=BB=93=E5=BA=93?= =?UTF-8?q?=E5=9C=B0=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7bc5215..13c8ac8 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,10 @@ "description": "image searcher of multiple search engines", "author": "huan_kong", "license": "MIT", - "repository": "https://github.com/HkTeamX/ImageSearcher", + "repository": { + "type": "git", + "url": "https://github.com/HkTeamX/ImageSearcher.git" + }, "main": "./dist/index.mjs", "types": "./dist/index.d.mts", "files": [