// ==UserScript==
// @name TorrentBD-Torrent Downloader
// @namespace Violentmonkey Scripts
// @match https://www.torrentbd.net/*
// @match https://www.torrentbd.com/*
// @match https://www.torrentbd.org/*
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAABaCAYAAAA4qEECAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAkASURBVHhe7dxrcFTlGQfw//Oec/aSGzGsgHZ00QIbLpXlUsfLsFAqWNAWxxl7sbYsCFKkDu10ZJyp0+kXe4GhdCilpSKstlXH2qGCExnscFmmpRdGlgFJFpWQikBTVi6RZDd7zvP0QxIa35JkL9ndl7i/DzD8n5O9/LN7zuHs2QOUlZWVlZWVlZWVlWWL1EAndy5cbR14fhWmPfS0L3khUX353Gk2LDdV3zg6YKc6PE4yycwS6Y42gBnCcsN0VwBguKtrhbTTZy68/85pV0WNqB51s7z84dnTqbY2554nN9rPPTxKqvdXSCUvun7W4hoyjJFsO6NIiKBkOZKAsdJOu4TpCjjpFBmW63pmrmbHYRAghOlmMMDcdSM9f9OVP0BCgKUES5kEEQnDlNJOfwAiaViui3aqo9l0ey/aqY4m01PRwo59wnR7/216K8/F/rS683+PcHAUrehpDz1dnWq7cJOdSn6apTMBzOPAPBYEP4A6MKpABICL+bC6MQCSAH8I4DRAzcx8jIRoNF2eZjLNd257YFnri8smdf9Gs1ewZzRx7vKR0nGmSDsdJKK7mXk8mD8FwKMuq68rv/RWEJ0A8HcS4i1hmAfd1bXHD237qa3+RF8Grejb5q+8wUl33i6d9N0s5Z0s5TgAI9TlhogOgBsB+qdhud4C0T7DW3HiyI51aXXBHjkXfcfDPxIXzzZPAXAfO84MZjkZwPXqcp8QklmuOb7/hafUQY+si57w+cf80nEeYuksADAVgKEu80kkTGt94+5nV6p5j4yLnnTvihF2qmMVS7kYwHXq/JONQYaxoGnPlu3qpIdQg6upn7V4sp1s/xtL+b1yyVdBotXyVv1FjXsbsOiJc5ZPYSnfYOZb1FlZF9Pt2XKkYX1CzXsbsGgn3fkzADeo+RAiiUQHiN4jIY4J02oUptVIJJqI6JK6sIpIPOcbM/n7aq7qdx39mXlPTE23f3SQmftd7hqTIiFiJMQBIvEPMsx3TZf7nDCtVk91XariupEkLBOXzjRTx6XzI5zOlJ+lDLJjB0BUL+20AAlBgpoN0/X622/+apt6B1fTb4ET5z6+xE62P6vm16jjIPq15fa+cXTXxiZ1WGj9rjpYSreaXWuY+T/M/ISrqmZ6fN/WdaUoGQMVbVjWya7jD9esQ0Q04/j+5zccaVjfpg6Lqd+iWcpDBFxU87wxdx9HKBxmGZWOPTMejcTVWSkM+HIdP3vpXmmnZ6p5lloAxEB0yDCtU53tbcdMt7cGoCBLZx6AfG//44haLW/lXUd3bnhPHZXKgEVPunfFV9LJ9pevHPPNBBHAHAdzg+F27xKmdeDozl/2+c4IzFi4HEQb1TxXpqdi8du7Nm5V81IasGgAqJ/16CaWzmNq/n+IEgRqEJb1suWt2nN4x9oOdZG+jJ+9ZJ607e+oedaItsf3bV2gxqXW7zq6hyFcjxsu90YQXf74hEDCuChMc7cwrWWGZU1o2rflm8f+vKkhm5IBwHR71xJR3hss0+XZrGY6yOgV3WPinOU3M/MsduxaELWTEI2uypqW2GtrTqnL5qJ+1qNvsnTuUfOMEcU9NXVTD+9Y266OSi2rogtt/Oylq6WdflLNMyUM84XGPZsXqrkOMlp1FAtL+S81ywrRfjXShVZFkxB5fIhAEIapze6cSq+i1SAr3MZSnlRTXWhVNOfxv0USBlyVNWqsDb2KljK3s4eYIUxTVNSNyO9NUUBaFW26PWPVLCNEkLb9PkunVR3pQquinc5On5plhkFC1JBhVKoTXWhVNMB1apIRBohomLTtctEDuePrzxjMfJOaZ6Rr1SHbE2dz35oWmDZFp9ovVYFRpeaZY3CO29Ji0KbodPtHdQDnfK4eA5BOxuccFp02RRMJL+fzeAr/oU1ecn9ig4xZjgbgUvOhQpuinXSnmdWnOAoigIw8DpUUmDZFs+OoUbaIhL4f2WtTtLCsSWqWFaKUYbkG/bsng0WbolnKajXLHIOEka4YPkrb3Q6dis5jJ5ggHfuU3ZksH+sYCEsn9y1hF+nx1OZ7GwWjTdEgkddxCgLIU1OrxtrQpmhhmhPVLHMMYbnk1K89og60oU3RyOscbIJ07Kaf3E7lVceA8tkWdm1MtTuXozd9is7j9QwAhuXS57lchTYPjmV+73pmblQznWhTdL6knb6gZjoZGkUTwfLmtXdYcEOjaGZmx9bizP6+DI2iASltO6mGOhkSRZMwOj21w8tFFxpLpzV56fwHaq6TIVE0CUGuyuo898QLa2gUTeLsrXfdp3ztQy8lKToQCo8LhMLT1DxX0rHPbntqthMIhbW9AkPRiw6EwtsBPA3guwC+GgiF/xQIhav6+Vd9vDEJQ3/0x1Dbb7CZY+1G5jfhGJVh7NNe8zI8Y9LfY9zb7VGDZ1PZ4FtDvez1c4NZN6rJNIAXAXgByBZDEA5HPrMKVlk7OoAABjVHJwBgBYFp6i2I2PeBGWF9jd6Hv9O6zV7LXWZ8ZDHadQDf5O6S0FcwZ8oQm0WNCD9+0Jd8N14N6LjPEJ+qWE5O1DzKzK61oJ4ANQD8LYEJOdRMZGQbZj5uTwAbRfNOqjXRW8oNaIaM7mq3hU9aE5E5xjg4G7V1F23aBsL5CAYFxfDvD4tC6n8k8Xqh78M2YpSdUWg6Av/LXKYhqV1u0WjTxpRyOD/9mKPRorhCBGqp1YcB3vhRVUWb3gfg6AyPbqOe8AiEqHfBGUFO3DxA4KnwQBEPOQJaahQxrE8RBz7ZQr9jPX1KAIYT/cxpGchSv1XyIYhw2uTy66YhpSB0JGSRKZJxbz6jWIULdvKS7cVYYhzKFnqQMOJYKv2VTEuuxBqzAfOt2VWWuDDjPaG5Wol8uWTqQJeWNvmQW5Z9FtWCwxCaFNJpF7GlCW+1z/RzSLKuWIaQ4ZRwMxOqTUXmLvl64xVJIkMg7vP3X31FFl1OhJOHJ8m9NYOD4zNapBQHOTJF0Xz5YgJhbfg47sAyCOCxCF3+JhV6E2LQEM21+kXO+MfCMwDxMpB9T8TJz5dECmU6iGFZxOGnxZFYrEhJpMW5+KdcbJ/6QlC7CwZu+aHGi6zE7YgFB9T8x6gGQzD88YpSDIvJAzUUkYUJoTJZNB+HdqhXJJ/LXo91HGzZOvlQEPR8L+KhCE7cEJ8v8q5LHX6NLdqYJMOYBFi6cCfCzTFi2v8QJo5CCUYPl5SbD6j8QECjzqmDRFu0iF5xBJI0B7l20YggzHYVJQ6m7XZN0xH4z7vX/s5lhI6Ef0wIkz4AQk9BUtN5uD3rJd/Qo00AiwI2Nc2s82WuS/P4jI3kOpN3P8Q6WnQk7aZKwJ2LXAHtqF7FJX8+/sxKKy7g8u7F+GKpqaRLfgCAQTdKVZWVlZWVlVUy+C+CYV5W5k2yyQAAAABJRU5ErkJggg==
// @version 2.0
// @run-at document-end
// @author TheMyth
// @grant GM_registerMenuCommand
// @license MIT
// @description Automatically downloads torrents within your size and count limits (perfect for 2x seedbonus). Configure min/max size, download limit, and total size. Click "Download Start" on the search page and keep the tab open.
// ==/UserScript==
// Default configuration
const defaultConfig = {
max: [200,"mb"],
min: [100, "mb"],
downloadLimit: 200,
sumDownloadSize: null,
};
// Function to get current user config
function getUserConfig() {
const savedConfig = localStorage.getItem("torrentBDConfig");
if (savedConfig) {
try {
return JSON.parse(savedConfig);
} catch (e) {
console.error("Failed to parse saved config:", e);
return defaultConfig;
}
}
return defaultConfig;
}
// Function to process config into working format
function processConfig(userConfig) {
const t_c = {};
function converter(x) {
if (["kib", "kb"].includes(String(x[1]).toLowerCase())) {
return parseFloat(x[0]);
} else if (["mib", "mb"].includes(String(x[1]).toLowerCase())) {
return parseFloat(x[0]) * 1024;
} else if (["gib", "gb"].includes(String(x[1]).toLowerCase())) {
return parseFloat(x[0]) * 1024 * 1024;
} else if (["tib", "tb"].includes(String(x[1]).toLowerCase())) {
return parseFloat(x[0]) * 1024 * 1024 * 1024;
} else {
return null;
}
}
if (userConfig.max) {
t_c.max = converter(userConfig.max);
} else {
t_c.max = null;
}
if (userConfig.min) {
t_c.min = converter(userConfig.min);
} else {
t_c.min = null;
}
if (userConfig.sumDownloadSize) {
t_c.sumDownloadSize = converter(userConfig.sumDownloadSize);
} else {
t_c.sumDownloadSize = null;
}
t_c.downloadLimit = userConfig.downloadLimit;
return t_c;
}
// Initialize config
let Config = processConfig(getUserConfig());
let sumDownlodSize = 0.0;
let DownloadedTorrents = 0;
console.log(`User Config:`, Config);
console.log("Last History:",getLocal());
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
function setLocal(object) {
localStorage.setItem("endof", JSON.stringify(object));
alert(`Download Done!\nTotalDownloads:${object.DownloadedTorrents}\nLatTorrentName:${object.lastTorrentName}\nTotalFileSize:${object.sumDownlodSize}`)
}
function getLocal() {
if (localStorage.getItem("endof")) {
return JSON.parse(localStorage.getItem("endof"));
} else {
return null;
}
}
/**
*
* @param {HTMLElement} element
*/
function getTheFileSize(element) {
let el_TextContent = element
.querySelector('div[title="File Size"')
.textContent.split(" ");
if (el_TextContent[2].toLowerCase() == "kib") {
return parseFloat(el_TextContent[1]);
} else if (el_TextContent[2].toLowerCase() == "mib") {
return parseFloat(el_TextContent[1]) * 1024;
} else if (el_TextContent[2].toLowerCase() == "gib") {
return parseFloat(el_TextContent[1]) * 1024 * 1024;
} else if (el_TextContent[2].toLowerCase() == "tib") {
return parseFloat(el_TextContent[1]) * 1024 * 1024 * 1024;
}
}
async function getTorrentData() {
// Get fresh config at the start of download
const currentUserConfig = getUserConfig();
Config = processConfig(currentUserConfig);
console.log('Using current config:', Config);
while (true) {
/**
*
* @param {HTMLElement} element
* @param {Float} fileSize
*/
async function downloadHelper(element, fileSize) {
let title = element.querySelector("td:nth-child(2) a");
let dwnLink = element.querySelector("td:nth-child(3) a");
sumDownlodSize += fileSize;
DownloadedTorrents += 1;
dwnLink.click();
console.log(`${DownloadedTorrents}:${title.textContent}`);
}
let tableBody = document.querySelector(
"#kuddus-results-container > table > tbody"
);
let lastTorrentName = "";
for (let index = 0; index < tableBody.children.length; index++) {
const element = tableBody.children[index];
let fileSize = getTheFileSize(element);
if (Config.max && Config.min) {
if (fileSize >= Config.min && fileSize <= Config.max) {
downloadHelper(element, fileSize);
await sleep(2000);
}
} else if (Config.max && fileSize <= Config.max) {
downloadHelper(element, fileSize);
await sleep(2000);
} else if (Config.min && fileSize >= Config.min) {
downloadHelper(element, fileSize);
await sleep(2000);
}
if (Config.downloadLimit && Config.downloadLimit == DownloadedTorrents) {
lastTorrentName =
element.querySelector("td:nth-child(2) a").textContent;
break;
} else if (
Config.sumDownloadSize &&
sumDownlodSize >= Config.sumDownloadSize
) {
lastTorrentName =
element.querySelector("td:nth-child(2) a").textContent;
break;
} else if (
!Config.sumDownloadSize &&
!Config.downloadLimit &&
DownloadedTorrents == 100
) {
lastTorrentName =
element.querySelector("td:nth-child(2) a").textContent;
break;
}
}
console.log(sumDownlodSize);
console.log(DownloadedTorrents);
let next = document.querySelector('li[title="Next page"]');
if (Config.downloadLimit && Config.downloadLimit == DownloadedTorrents) {
setLocal({
sumDownlodSize: sumDownlodSize,
DownloadedTorrents: DownloadedTorrents,
page: parseInt(next.getAttribute("data-paginate-to")) - 1,
lastTorrentName: lastTorrentName,
});
return
} else if (
Config.sumDownloadSize &&
sumDownlodSize >= Config.sumDownloadSize
) {
setLocal({
sumDownlodSize: sumDownlodSize,
DownloadedTorrents: DownloadedTorrents,
page: parseInt(next.getAttribute("data-paginate-to")) - 1,
lastTorrentName: lastTorrentName,
});
return
} else if (
!Config.sumDownloadSize &&
!Config.downloadLimit &&
DownloadedTorrents == 100
) {
setLocal({
sumDownlodSize: sumDownlodSize,
DownloadedTorrents: DownloadedTorrents,
page: parseInt(next.getAttribute("data-paginate-to")) - 1,
lastTorrentName: lastTorrentName,
});
return
}
if (!next) {
return
} else {
next.click();
await sleep(2000);
}
}
}
async function dwnBtnFunc() {
let resultContainer = document.querySelector("#kuddus-results-container");
if (resultContainer.childNodes.length == 0) {
alert("No Torrent Found on th page");
} else if (resultContainer.childNodes.length > 0) {
sumDownlodSize = 0.0;
DownloadedTorrents = 0;
getTorrentData();
}
}
// Create configuration UI
function createConfigUI(panel) {
const configPanel = document.createElement("div");
configPanel.id = "torrentbd-config-panel";
configPanel.style = "position: absolute; background: white; padding: 10px; border-radius: 5px; box-shadow: 0 0 10px rgba(0,0,0,0.2); z-index: 9999; display: none; color: black; font-size: 12px; width: 300px; top: 5%;left:30%;";
// Get current user config for the UI
const currentUserConfig = getUserConfig();
configPanel.innerHTML = `
<h3 style="margin: 0 0 5px 0; font-size: 14px;">TorrentBD Settings</h3>
<div style="display: grid; grid-template-columns: auto 60px 50px 55px; gap: 5px; align-items: center;">
<label title="Maximum size of a single torrent file">Max Size:</label>
<input type="number" id="config-max-value" value="${currentUserConfig.max ? currentUserConfig.max[0] : ''}" style="width: 100%;" />
<select id="config-max-unit" style="width: 100%;">
${['kb', 'mb', 'gb', 'tb'].map(unit => `<option value="${unit}" ${currentUserConfig.max && currentUserConfig.max[1].toLowerCase() === unit ? 'selected' : ''}>${unit}</option>`).join('')}
</select>
<div>
<input type="checkbox" id="config-max-enabled" ${currentUserConfig.max ? 'checked' : ''} />
<label for="config-max-enabled"></label>
</div>
<label title="Minimum size of a single torrent file">Min Size:</label>
<input type="number" id="config-min-value" value="${currentUserConfig.min ? currentUserConfig.min[0] : ''}" style="width: 100%;" />
<select id="config-min-unit" style="width: 100%;">
${['kb', 'mb', 'gb', 'tb'].map(unit => `<option value="${unit}" ${currentUserConfig.min && currentUserConfig.min[1].toLowerCase() === unit ? 'selected' : ''}>${unit}</option>`).join('')}
</select>
<div>
<input type="checkbox" id="config-min-enabled" ${currentUserConfig.min ? 'checked' : ''} />
<label for="config-min-enabled"></label>
</div>
<label title="Number of torrents to download">Download Limit:</label>
<input type="number" id="config-limit-value" value="${currentUserConfig.downloadLimit || ''}" style="width: 100%;" />
<span></span>
<div>
<input type="checkbox" id="config-limit-enabled" ${currentUserConfig.downloadLimit ? 'checked' : ''} />
<label for="config-limit-enabled"></label>
</div>
<label title="Total size of all downloaded torrents">Sum Size:</label>
<input type="number" id="config-sum-value" value="${currentUserConfig.sumDownloadSize ? currentUserConfig.sumDownloadSize[0] : ''}" style="width: 100%;" />
<select id="config-sum-unit" style="width: 100%;">
${['kb', 'mb', 'gb', 'tb'].map(unit => `<option value="${unit}" ${currentUserConfig.sumDownloadSize && currentUserConfig.sumDownloadSize[1].toLowerCase() === unit ? 'selected' : ''}>${unit}</option>`).join('')}
</select>
<div>
<input type="checkbox" id="config-sum-enabled" ${currentUserConfig.sumDownloadSize ? 'checked' : ''} />
<label for="config-sum-enabled"></label>
</div>
</div>
<div style="display: flex; justify-content: space-between; margin-top: 10px;">
<button id="config-save" style="padding: 3px 8px;">Save</button>
<button id="config-cancel" style="padding: 3px 8px;">Cancel</button>
</div>
<div style="font-size: 10px; margin-top: 5px;">
<strong>Tips:</strong> Hover over labels for descriptions
</div>
`;
panel.appendChild(configPanel);
// Add event listeners
document.getElementById("config-save").addEventListener("click", saveConfig);
document.getElementById("config-cancel").addEventListener("click", hideConfigPanel);
// Helper functions
function saveConfig() {
const config = {};
if (document.getElementById("config-max-enabled").checked) {
config.max = [
parseFloat(document.getElementById("config-max-value").value),
document.getElementById("config-max-unit").value
];
} else {
config.max = null;
}
if (document.getElementById("config-min-enabled").checked) {
config.min = [
parseFloat(document.getElementById("config-min-value").value),
document.getElementById("config-min-unit").value
];
} else {
config.min = null;
}
if (document.getElementById("config-limit-enabled").checked) {
config.downloadLimit = parseInt(document.getElementById("config-limit-value").value, 10);
} else {
config.downloadLimit = null;
}
if (document.getElementById("config-sum-enabled").checked) {
config.sumDownloadSize = [
parseFloat(document.getElementById("config-sum-value").value),
document.getElementById("config-sum-unit").value
];
} else {
config.sumDownloadSize = null;
}
localStorage.setItem("torrentBDConfig", JSON.stringify(config));
// Update the current Config object immediately
Config = processConfig(config);
console.log('Config updated:', Config);
alert("Settings saved successfully! You can now use DownloadStart with the new configuration.");
hideConfigPanel();
}
function hideConfigPanel() {
const panel = document.getElementById("torrentbd-config-panel");
if (panel) {
panel.style.display = "none";
}
}
}
function showConfigPanel() {
const panel = document.getElementById("torrentbd-config-panel");
if (panel) {
panel.style.display = "block";
} else {
console.error("Config panel not found. Make sure createConfigUI was called.");
}
}
// Register menu command for configuration
GM_registerMenuCommand('TorrentBD Downloader Settings', showConfigPanel);
let panel = document.querySelector("#kuddus-wrapper");
const dwnBtn = document.createElement("button");
dwnBtn.textContent = "DownloadStart";
dwnBtn.setAttribute("align", "center");
dwnBtn.setAttribute("title", "DownloadStart");
dwnBtn.style =
"position: fixed; top: -6px; left: 70px; border-radius: 4px; margin: 6px 8px; padding: 6px 14px; border: none; opacity: 0.5;";
dwnBtn.addEventListener("click", dwnBtnFunc);
if (panel.children.length > 0) {
// Check if panel has children to avoid errors
panel.insertBefore(dwnBtn, panel.children[panel.children.length - 1]);
} else {
panel.appendChild(dwnBtn); // If panel has no children, just append it
}
let panel2=document.querySelector(".kuddus")
// Initialize configuration UI
createConfigUI(panel2);