Files
magnet-finder/cli/launch.js
T
blueslmjandClaude Opus 5 0e85433a5d feat: 多站点磁力搜索工具(网页版 + 命令行)
聚合 TPB(apibay) / therarbg / knaben / EZTV 四个站点的 JSON API,
按 infohash 跨站去重,seeders 取各站最大值,0 种子明确标出。

绕过的几个实测问题:
- 站点关键词搜索按整词匹配,"s03" 搜不到(标题里是 S03E07),
  裸季号自动展开成 s03e01..e30 逐集补搜(TPB 实测 0 条 -> 193 条)
- 放宽查询会撞分页天花板,所以三条路互补:knaben 用原查询、
  TPB 用逐集补搜、EZTV 用 IMDb id 列出全剧
- IMDb id 必须从未过滤的结果里推断,只看命中项的话季号一过滤就没了
- therarbg 的 keywords: 必须用 %20 编码,用 + 多词查询返回 0 条

匹配支持智能/完全两种模式,完全匹配按「从标题开头连续对上」判定
(发布名规范是 剧名.SxxExx.质量.小组,剧名永远在开头)。
输入可直接粘发布名,pawn.stars.s24 和 pawn stars s24 等价。

网页版走 SSE 实时推进度,Windows 下双击 .bat 即可启动。
零运行时依赖,48 个测试全部不联网。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 22:42:42 +08:00

74 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
/**
* 双击启动器:起服务 + 自动打开浏览器。
* Windows 上双击「启动搜索.bat」就能用,不用手动敲命令。
*
* node cli/launch.js # 默认端口 5173
* node cli/launch.js 8080 # 指定端口
* node cli/launch.js --no-open # 只起服务,不自动开浏览器(测试用)
*/
'use strict';
const os = require('os');
const child = require('child_process');
const { createServer } = require('./serve.js');
const DEFAULT_PORT = 5173;
const NO_OPEN = process.argv.includes('--no-open');
function readPort() {
const fromEnv = parseInt(process.env.PORT, 10);
if (Number.isFinite(fromEnv) && fromEnv > 0) return fromEnv;
const fromArg = parseInt(process.argv.filter((a) => /^\d+$/.test(a))[0], 10);
return Number.isFinite(fromArg) && fromArg > 0 ? fromArg : DEFAULT_PORT;
}
function openBrowser(url) {
if (NO_OPEN) return;
try {
const p = os.platform();
const cmd =
p === 'win32'
? 'start "" "' + url + '"'
: p === 'darwin'
? 'open "' + url + '"'
: 'xdg-open "' + url + '"';
child.exec(cmd, () => {});
} catch (e) {
console.log('\n打不开浏览器?手动打开: ' + url + '\n');
}
}
const port = readPort();
const url = 'http://127.0.0.1:' + port;
const server = createServer();
function onListenError(e) {
if (e.code === 'EADDRINUSE') {
console.log('端口 ' + port + ' 已被占用 —— 搜索服务可能已经在运行。');
console.log('直接打开: ' + url);
openBrowser(url);
setTimeout(() => process.exit(0), 3000);
} else {
console.error('启动失败: ' + (e.message || e));
process.exit(1);
}
}
// 必须先挂 handler 再 listen,否则 EADDRINUSE 会以未捕获异常的方式崩掉整个进程
server.on('error', onListenError);
server.listen(port, '127.0.0.1', () => {
console.log('');
console.log(' 磁力搜索');
console.log(' ' + url);
console.log(' 关闭这个窗口就停止服务');
console.log('');
openBrowser(url);
});
// 进程被 SIGINT (Ctrl+C) 关闭时也给个提示
process.on('SIGINT', () => {
console.log('\n停止服务');
process.exit(0);
});