🏠 Home 

1337x Magnet Link Fetcher

Adds checkboxes and magnet link extraction functionality to 1337x.to search r###lts


Install this script?
// ==UserScript==
// @name         1337x Magnet Link Fetcher
// @version      1.8
// @description  Adds checkboxes and magnet link extraction functionality to 1337x.to search r###lts
// @author       neokyuubi
// @match        *://1337x.to/search/*
// @match        *://www.1337x.to/search/*
// @namespace    https://github.com/neokyuubi/1337x-Magnet-Link-Fetcher
// @icon         https://1337x.to/favicon.ico
// @grant        GM_xmlhttpRequest
// @run-at       document-end
// ==/UserScript==
(function() {
'use strict';
// Only run on search pages
if (!window.location.href.includes('/search/') && !window.location.href.includes('/category/') && !window.location.href.includes('/popular/') && !window.location.href.includes('/top-100')) {
return;
}
// Variables for shift-click functionality
let lastChecked = null;
let shiftPressed = false;
// Track shift key state
document.addEventListener('keydown', function(e) {
if (e.key === 'Shift') {
shiftPressed = true;
}
});
document.addEventListener('keyup', function(e) {
if (e.key === 'Shift') {
shiftPressed = false;
}
});
// Add CSS for new elements
const style = document.createElement('style');
style.textContent = `
.checkbox-column { width: 30px; text-align: center; }
.magnet-column { width: 100px; text-align: center; }
.action-buttons {
position: fixed;
bottom: 20px;
right: 20px;
display: flex;
flex-direction: column;
gap: 10px;
z-index: 9999;
}
.action-button {
padding: 10px 15px;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
font-weight: bold;
}
.action-button:disabled {
background: #cccccc;
cursor: not-allowed;
}
.magnet-link {
cursor: pointer;
color: #4CAF50;
font-weight: bold;
}
.magnet-link:hover {
text-decoration: underline;
}
.copy-success {
color: green;
transition: opacity 1s;
}
`;
document.head.appendChild(style);
// Find the table containing search r###lts
const table = document.querySelector('.table-list') || document.querySelector('table.table-list');
if (!table) return;
// Add header columns for checkbox and magnet
const headerRow = table.querySelector('thead tr');
const checkboxHeader = document.createElement('th');
checkboxHeader.className = 'checkbox-column';
checkboxHeader.textContent = '';
headerRow.insertBefore(checkboxHeader, headerRow.firstChild);
const magnetHeader = document.createElement('th');
magnetHeader.className = 'magnet-column';
magnetHeader.textContent = 'Magnet';
headerRow.appendChild(magnetHeader);
// Add checkboxes and magnet cells to each row
const rows = table.querySelectorAll('tbody tr');
rows.forEach(row => {
// Add checkbox column
const checkboxCell = document.createElement('td');
checkboxCell.className = 'checkbox-column';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
// Implement shift-click functionality
checkbox.addEventListener('click', function(e) {
if (shiftPressed && lastChecked && lastChecked !== this) {
// Get all checkboxes
const checkboxes = Array.from(document.querySelectorAll('.checkbox-column input[type="checkbox"]'));
// Find indices of current and last checked boxes
const startIndex = checkboxes.indexOf(this);
const endIndex = checkboxes.indexOf(lastChecked);
// Determine range to check (works in both directions)
const start = Math.min(startIndex, endIndex);
const end = Math.max(startIndex, endIndex);
// Check all checkboxes in the range
for (let i = start; i <= end; i++) {
checkboxes[i].checked = this.checked;
}
}
// Update lastChecked reference
lastChecked = this;
});
checkboxCell.appendChild(checkbox);
row.insertBefore(checkboxCell, row.firstChild);
// Add magnet column
const magnetCell = document.createElement('td');
magnetCell.className = 'magnet-column';
magnetCell.dataset.torrentUrl = row.querySelector('a[href^="/torrent/"]').href;
row.appendChild(magnetCell);
});
// Create sticky action buttons
const actionButtons = document.createElement('div');
actionButtons.className = 'action-buttons';
const fetchButton = document.createElement('button');
fetchButton.className = 'action-button';
fetchButton.textContent = 'Fetch Selected Links';
fetchButton.onclick = fetchSelectedMagnetLinks;
const copyAllButton = document.createElement('button');
copyAllButton.className = 'action-button';
copyAllButton.textContent = 'Copy All Links';
copyAllButton.onclick = copyAllMagnetLinks;
copyAllButton.disabled = true;
actionButtons.appendChild(fetchButton);
actionButtons.appendChild(copyAllButton);
document.body.appendChild(actionButtons);
// Function to fetch magnet links for selected torrents
function fetchSelectedMagnetLinks() {
const checkedRows = document.querySelectorAll('.checkbox-column input[type="checkbox"]:checked');
if (checkedRows.length === 0) {
alert('No torrents selected! Please select at least one torrent.');
return;
}
let completedRequests = 0;
let totalRequests = checkedRows.length;
fetchButton.disabled = true;
fetchButton.textContent = `Fetching... (0/${totalRequests})`;
checkedRows.forEach(checkbox => {
const row = checkbox.closest('tr');
const magnetCell = row.querySelector('.magnet-column');
const torrentUrl = magnetCell.dataset.torrentUrl;
// Skip if we already fetched this link
if (magnetCell.innerHTML !== '') {
completedRequests++;
updateFetchButtonStatus(completedRequests, totalRequests);
return;
}
// Fetch the torrent page
GM_xmlhttpRequest({
method: 'GET',
url: torrentUrl,
onload: function(response) {
const parser = new DOMParser();
const doc = parser.parseFromString(response.responseText, 'text/html');
// Extract magnet link
const magnetLink = doc.querySelector('a[href^="magnet:"]');
if (magnetLink) {
const magnetUrl = magnetLink.href;
// Create copy button for the magnet link
const copyLink = document.createElement('span');
copyLink.className = 'magnet-link';
copyLink.textContent = 'Copy';
copyLink.dataset.magnetUrl = magnetUrl;
copyLink.onclick = function() {
navigator.clipboard.writeText(magnetUrl).then(() => {
const originalText = copyLink.textContent;
copyLink.textContent = 'Copied!';
copyLink.classList.add('copy-success');
setTimeout(() => {
copyLink.textContent = originalText;
copyLink.classList.remove('copy-success');
}, 1000);
});
};
magnetCell.innerHTML = '';
magnetCell.appendChild(copyLink);
} else {
magnetCell.textContent = 'Not found';
}
completedRequests++;
updateFetchButtonStatus(completedRequests, totalRequests);
},
onerror: function() {
magnetCell.textContent = 'Error';
completedRequests++;
updateFetchButtonStatus(completedRequests, totalRequests);
}
});
});
}
// Update fetch button status
function updateFetchButtonStatus(completed, total) {
fetchButton.textContent = `Fetching... (${completed}/${total})`;
if (completed === total) {
fetchButton.textContent = 'Fetch Selected Links';
fetchButton.disabled = false;
copyAllButton.disabled = false;
}
}
// Function to copy all magnet links
function copyAllMagnetLinks() {
const magnetLinks = [];
const magnetCells = document.querySelectorAll('.magnet-link');
magnetCells.forEach(link => {
if (link.dataset.magnetUrl) {
magnetLinks.push(link.dataset.magnetUrl);
}
});
if (magnetLinks.length === 0) {
alert('No magnet links found!');
return;
}
navigator.clipboard.writeText(magnetLinks.join('\n')).then(() => {
const originalText = copyAllButton.textContent;
copyAllButton.textContent = 'Copied All Links!';
setTimeout(() => {
copyAllButton.textContent = originalText;
}, 1000);
});
}
})();