聚合 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>
74 lines
2.1 KiB
JavaScript
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);
|
|
});
|