// ==UserScript== // @name 复制 qBittorrent 种子列表 // @name:en qBittorrent webUI torrent list copy // @namespace localhost // @version 0.2.1 // @description 在webUI的右键菜单中增加批量复制字段的功能,可直接粘贴到excel // @description:en add a contextmenu item to batch copy torrent information in order to pasting to Excel // @author flashlab // @match http://127.0.0.1:8080/ // @icon https://www.qbittorrent.org/favicon.ico // @license MIT // @run-at document-end // @downloadURL https://update.greasyfork.icu/scripts/478932/%E5%A4%8D%E5%88%B6%20qBittorrent%20%E7%A7%8D%E5%AD%90%E5%88%97%E8%A1%A8.user.js // @updateURL https://update.greasyfork.icu/scripts/478932/%E5%A4%8D%E5%88%B6%20qBittorrent%20%E7%A7%8D%E5%AD%90%E5%88%97%E8%A1%A8.meta.js // ==/UserScript== // 完整字段请参考官方api https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-list // 直接在 newItem 结尾增加
  • 标签即可,href 的值为'#<字段名>' // 仅在最新版qBitorrent中测试! (function() { 'use strict'; var newItem = '
  • ' + ' ' + ' Copy 批量复制' + ' ' + ' ' + '
  • '; function getDomainBody(string) { const match = string.match(/:\/\/([^\/]+\.)?([^\/\.]+)\.[^\/\.:]+/i) if (match != null && match.length > 2 && typeof match[2] === 'string' && match[2].length > 0) { return match[2] } else { return '' } } window.addEventListener('load', function () { const newmenu = document.getElementById('torrentsTableMenu'); if (newmenu == null) return; //patch icon if (newmenu.querySelector('img').src.split("/").includes("icons")) { newItem = newItem.replaceAll("images/", "icons/").replace("checked-completed.svg", "checked.svg"); } // append html newmenu.insertAdjacentHTML("beforeend", newItem) new ClipboardJS('#copyall', { text: function() { return copyAllSelected(); } }); // listen to option event const options = document.querySelectorAll("#multicp a:not([role])"); options.forEach(function(op) { op.addEventListener("click", function(e) { e.stopPropagation(); e.target.firstElementChild.checked ^= 1; }); }); const optionT = document.getElementById('copyswitch'); optionT.addEventListener("click", function(e) { e.stopPropagation(); const isChecked = optionT.classList.toggle("checkall") options.forEach(function(op) { op.firstElementChild.checked = isChecked; }); }); // ctrl + v event const tableArea = document.getElementById("transferList_pad"); if (tableArea) window.addEventListener("keydown",function(e) { if (e.repeat) return; if ( e.keyCode == 67 && e.ctrlKey ) { document.getElementById("copyall").click() } }, false); // copy steps function copyAllSelected() { const tablekeys = []; const tablehead = []; options.forEach(function(op) { const key = op.href.split('#')[1]; if (op.firstElementChild.checked && key) { tablekeys.push(key) tablehead.push(op.textContent.trim()) } }); if (tablekeys.length == 0) return alert("至少选择一个字段!") const selectedRows = torrentsTable.selectedRowsIds(); if (selectedRows.length <= 0) return alert("至少选中一行!"); let tablebody = ""; const rows = torrentsTable.getFilteredAndSortedRows(); selectedRows.forEach(function(hash) { const fulldata = rows[hash].full_data; const tablerow = []; tablekeys.forEach(function(k) { switch (k) { //github.com/qbittorrent/qBittorrent/blob/5db2c2c2be422bffca693f7d5620ee74970acd71/src/webui/www/private/scripts/dynamicTable.js#L1230 case "added_on": case "completion_on": tablerow.push(fulldata[k] <0 ? '' : new Date(fulldata[k] * 1000).toLocaleString()); break; //github.com/qbittorrent/qBittorrent/blob/5db2c2c2be422bffca693f7d5620ee74970acd71/src/webui/www/private/scripts/misc.js#L56 case "size": case "total_size": case "uploaded": tablerow.push(unsafeWindow.qBittorrent.Misc.friendlyUnit(fulldata[k])); break; case "tracker": tablerow.push(getDomainBody(fulldata[k])); break; case "progress": tablerow.push(unsafeWindow.qBittorrent.Misc.friendlyPercentage(fulldata[k])); break; default: tablerow.push(fulldata[k]); } }); tablebody += tablerow.join("\t") + "\n"; }); alert("已复制到剪切板,请去excel粘贴") return tablehead.join("\t") + "\n" + tablebody; }; }, false); })();