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
${result.title}
\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 };