import { BasePlugin } from '../core/base-plugin.js';
import { __publicField } from '../core/constants.js';
import { GM_xmlhttpRequest } from 'vite-plugin-monkey/dist/client';
function showCopiedFeedback($btn) {
const originalText = $btn.text();
$btn.addClass("copied").text("已复制");
setTimeout((() => {
$btn.removeClass("copied").text(originalText);
}), 2e3);
}
function fallbackCopy(text, $btn) {
const textarea = document.createElement("textarea");
textarea.value = text;
textarea.style.position = "fixed";
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand("copy");
showCopiedFeedback($btn);
} catch (err) {
console.error("复制失败:", err);
alert("复制失败,请手动复制链接");
}
document.body.removeChild(textarea);
}
class MagnetHubPlugin extends BasePlugin {
constructor() {
super(...arguments);
__publicField(this, "currentEngine", null);
__publicField(this, "searchEngines", [ {
name: "U9A9",
id: "u9a9",
url: "https://u9a9.com/?type=2&search={keyword}",
targetPage: "https://u9a9.com/?type=2&search={keyword}",
parseHtml: this.parseU3C3
}, {
name: "U3C3",
id: "u3c3",
url: "https://u3c3.com/?search2=a8lr16lo&search={keyword}",
targetPage: "https://u3c3.com/?search2=a8lr16lo&search={keyword}",
parseHtml: this.parseU3C3
}, {
name: "Sukebei",
id: "Sukebei",
url: "https://sukebei.nyaa.si/?f=0&c=0_0&q={keyword}",
targetPage: "https://sukebei.nyaa.si/?f=0&c=0_0&q={keyword}",
parseHtml: this.parseSukebei
} ]);
}
getName() {
return "MagnetHubPlugin";
}
async initCss() {
return "\n \n ";
}
createMagnetHub(keyword) {
keyword = keyword.replace("FC2-", "");
const $container = $('
'), $tabs = $(''), key = "jhs_magnetHub_selectedEngine", savedEngineId = localStorage.getItem(key);
let defaultEngineIndex = 0;
const $tabBox = $('');
this.searchEngines.forEach(((engine, index) => {
const $tab = $(`${engine.name}
`);
if (savedEngineId && engine.id === savedEngineId) {
$tab.addClass("active");
this.currentEngine = engine;
defaultEngineIndex = index;
} else if (0 === index && !savedEngineId) {
$tab.addClass("active");
this.currentEngine = engine;
}
$tabBox.append($tab);
}));
$tabs.append($tabBox);
$tabs.append(`原网页`);
$container.append($tabs);
const $resultsContainer = $('');
$container.append($resultsContainer);
$container.on("click", ".magnet-tab", (e => {
const engineId = $(e.target).data("engine");
this.currentEngine = this.searchEngines.find((engine => engine.id === engineId));
$("#targetBox").attr("href", this.currentEngine.targetPage.replace("{keyword}", encodeURIComponent(keyword)));
localStorage.setItem(key, engineId);
$container.find(".magnet-tab").removeClass("active");
$(e.target).addClass("active");
this.searchEngine($resultsContainer, this.currentEngine, keyword);
}));
$container.on("click", ".copy-btn", function () {
const $btn = $(this), magnet = $btn.data("magnet");
navigator.clipboard ? navigator.clipboard.writeText(magnet).then((() => {
showCopiedFeedback($btn);
})).catch((() => {
fallbackCopy(magnet, $btn);
})) : fallbackCopy(magnet, $btn);
});
$container.on("click", ".down-115", (async event => {
event.stopPropagation();
const magnet = $(event.currentTarget).data("magnet");
let loadObj = loading();
try {
await this.getBean("WangPan115TaskPlugin").handleAddTask(magnet);
} catch (e) {
show.error("发生错误:" + e);
console.error(e);
} finally {
loadObj.close();
}
}));
this.searchEngine($resultsContainer, this.currentEngine || this.searchEngines[defaultEngineIndex], keyword);
return $container;
}
searchEngine($container, engine, keyword) {
$container.html(`正在从 ${engine.name} 搜索 "${keyword}"...
`);
const cacheKey = `${engine.name}_${keyword}`;
sessionStorage.getItem(cacheKey);
const url = engine.url.replace("{keyword}", encodeURIComponent(keyword));
engine.parseHtml && GM_xmlhttpRequest({
method: "GET",
url: url,
onload: response => {
try {
const results = engine.parseHtml.call(this, response.responseText, keyword);
results.length > 0 && sessionStorage.setItem(cacheKey, JSON.stringify(results));
this.displayResults($container, results, engine.name);
} catch (e) {
$container.html(`解析 ${engine.name} 结果失败: ${e.message}
`);
}
},
onerror: error => {
$container.html(`从 ${engine.name} 获取数据失败: ${error.statusText}
`);
}
});
engine.parseJson && engine.parseJson.call(this, $container, engine, keyword, cacheKey);
}
displayResults($container, results, engineName) {
$container.empty();
if (0 !== results.length) {
results.forEach((result => {
const $result = $(`\n \n
\n
\n 大小: ${result.size || "未知"}\n 日期: ${result.date || "未知"}\n
\n
\n \n \n
\n
\n `);
$container.append($result);
}));
} else $container.append('没有找到相关结果
');
}
parseBTSOW($container, engine, keyword, cacheKey) {
const _this = this;
GM_xmlhttpRequest({
method: "POST",
url: engine.url,
headers: {
"Content-Type": "application/json"
},
data: `[{"search":"${keyword}"},50,1]`,
onload: response => {
try {
const dataList = JSON.parse(response.responseText).data, results = [];
for (let i = 0; i < dataList.length; i++) {
let item = dataList[i];
results.push({
title: item.name,
magnet: "magnet:?xt=urn:btih:" + item.hash,
size: (item.size / 1073741824).toFixed(2) + " GB",
date: utils.formatDate(new Date(1e3 * item.lastUpdateTime))
});
}
results.length > 0 && sessionStorage.setItem(cacheKey, JSON.stringify(results));
_this.displayResults($container, results, engine.name);
} catch (e) {
$container.html(`解析 ${engine.name} 结果失败: ${e.message}
`);
}
},
onerror: error => {
$container.html(`从 ${engine.name} 获取数据失败: ${error.statusText}
`);
}
});
}
parseU3C3(html, keyword) {
const $dom = utils.htmlTo$dom(html), results = [];
$dom.find(".torrent-list tbody tr").each(((i, el) => {
const $el = $(el);
if ($el.text().includes("置顶")) return;
const title = $el.find("td:nth-child(2) a").attr("title") || $el.find("td:nth-child(2) a").text().trim();
if (!title.toLowerCase().includes(keyword.toLowerCase())) return;
const magnet = $el.find("td:nth-child(3) a[href^='magnet:']").attr("href"), size = $el.find("td:nth-child(4)").text().trim(), date = $el.find("td:nth-child(5)").text().trim();
magnet && results.push({
title: title,
magnet: magnet,
size: size,
date: date
});
}));
return results;
}
parseSukebei(html, keyword) {
const $dom = utils.htmlTo$dom(html), results = [];
$dom.find(".torrent-list tbody tr").each(((i, el) => {
const $el = $(el);
if ($el.text().includes("置顶")) return;
const title = $el.find("td:nth-child(2) a").attr("title") || $el.find("td:nth-child(2) a").text().trim();
if (!title.toLowerCase().includes(keyword.toLowerCase())) return;
const magnet = $el.find("td:nth-child(3) a[href^='magnet:']").attr("href"), size = $el.find("td:nth-child(4)").text().trim(), date = $el.find("td:nth-child(5)").text().trim();
magnet && results.push({
title: title,
magnet: magnet,
size: size,
date: date
});
}));
return results;
}
}
export { MagnetHubPlugin };