NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Extratorrent Enhancements // @name:en Extratorrent Enhancements // @name:pt Melhorias pro Extratorrent // @namespace https://github.com/xaxim/ // @version 0.9.1 // @description Make decisions easier when searching torrents // @description:en Make decisions easier when searching torrents // @description:pt Facilita decisões quando procura torrents // @author xaxim // @match *://*.extratorrent.cc/* // @match *://*.etmirror.com/* // @match *://*.etproxy.com/* // @match *://*.extratorrentonline.com/* // @match *://*.extratorrentlive.com/* // @match *://*.extra.to/* // @match *://*.extratorrent.com/* // @grant none // @downloadURL https://github.com/xaxim/extratorrent-userscript/raw/master/Extratorrent%20Enhancements.user.js // ==/UserScript== (function () { 'use strict'; /* eslint-disable no-console */ console.info('Extratorrent Enhancements 0.9.1 loaded at ', new Date()); /* eslint-enable no-console */ const bestResultsStyles = [ { bg: '#1B5E20', color: '#FFF' }, { bg: '#2E7D32', color: '#FFF' }, { bg: '#388E3C', color: '#FFF' }, { bg: '#43A047', color: '#FFF' }, { bg: '#4CAF50', color: '#000' }, { bg: '#66BB6A', color: '#000' }, { bg: '#81C784', color: '#000' }, { bg: '#A5D6A7', color: '#000' }, { bg: '#C8E6C9', color: '#000' }, { bg: '#E8F5E9', color: '#000' }, ]; const body = document.querySelector('body'); let order = 0; let bestResultsPosition = 0; let bestFileSizePosition = 0; let sizes = {}; createActivationButton(); function createActivationButton() { const div = document.createElement('div'); div.style.display = 'flex'; div.style.justifyContent = 'center'; const button = document.createElement('input'); button.type = 'button'; button.value = 'Activate Extratorrent Enhancements'; button.id = 'activateExtratorrentEnhancementsButton'; button.style.backgroundColor = '#4CAF50'; button.style.border = 'none'; button.style.color = 'white'; button.style.padding = '15px 32px'; button.style.textAlign = 'center'; button.style.textDecoration = 'none'; button.style.display = 'inline - block'; button.style.fontSize = '16px'; button.style.margin = '4px 2px'; button.style.cursor = 'pointer'; button.addEventListener('click', activateExtratorrentEnhancements, { once: true }); div.appendChild(button); body.insertBefore(div, body.childNodes[0]); } /* eslint-disable no-console */ function activateExtratorrentEnhancements() { console.info('Extratorrent Enhancements Activated!'); //removes the ad redirecter, which is linked to the document click eventlistener. document.onclick = null; const resultsTableHeader = body.querySelector('thead'); const resultsTable = resultsTableHeader.parentElement; if (resultsTable) { removeUselessPageElements(resultsTable); cleanResults(resultsTable); } else { console.error('No result table was found. Contact developer at github.com/xaxim'); } console.info('Finished Extratorrent Enhancements'); } /* eslint-enable no-console */ function removeUselessPageElements(resultsTable) { Array .from(body.children) .forEach(elem => elem.remove()); document .querySelectorAll('script') .forEach(script => script.remove()); body.appendChild(resultsTable); } function cleanResults(resultsTable) { const resultsWithoutSeeds = Array.from(resultsTable.querySelectorAll('.sn')).map(seedCell => seedCell.parentElement); resultsWithoutSeeds.map(removeWithoutSeeds); const results = Array.from(resultsTable.querySelectorAll('.sy')).map(seedCell => seedCell.parentElement); const subresults = indexTitles(results); const tbody = results[0].parentElement; createExtraHeaders(tbody); Object.getOwnPropertyNames(subresults).map(title => handleSubresults(subresults, title, tbody)); } function removeWithoutSeeds(result) { if (result === null) return null; result.remove(); return null; } function indexTitles(resultados) { const titleIndex = 2; const titles = {}; resultados.forEach(resultado => { const titulo = resultado.children[titleIndex].textContent; const title = titulo.replace(/[^a-zA-Z]/gi, ' ').trim().split(' ')[0]; if (!titles[title]) { titles[title] = { counter: 1, titulos: [titulo], resultados: [resultado] }; } else { titles[title].counter = titles[title].counter + 1; titles[title].titulos = [...titles[title].titulos, titulo]; titles[title].resultados = [...titles[title].resultados, resultado]; } }); return titles; } function createExtraHeaders(tbody) { const thead = tbody.parentElement.children[0]; const theadRow = thead.children[0]; const seedPosition = document.createElement('th'); seedPosition.textContent = 'Seeds Pos'; const fileSizePosition = document.createElement('th'); fileSizePosition.textContent = 'Size Pos'; theadRow.appendChild(seedPosition); theadRow.appendChild(fileSizePosition); } function handleSubresults(subresults, title, tbody) { const seedsIndex = 5; const maxSeeds = Math.max.apply(null, subresults[title].resultados.map(resultLine => resultLine.children[seedsIndex].textContent)); const minSeeds = Math.min.apply(null, subresults[title].resultados.map(resultLine => resultLine.children[seedsIndex].textContent)); const seedsMean = ((maxSeeds + minSeeds) / 2); //console.log(maxSeeds, minSeeds, seedsMean); createSeparatorRow(subresults, title, tbody); subresults[title].resultados .sort(orderBySeeds) .map(createSortPositionColumn) .map(colorResult) .map(result => rearrangeOrderedBySeeds(result, seedsMean)) .sort(orderByFileSize) .map(colorResultFileSize) .map(createSortPositionColumn) .map(removeLowHealth) .sort(orderBySeeds) .map(removeNextDuplicatesWithLessSeeds); return subresults; } function createSeparatorRow(subresults, title, tbody) { const separator = document.createElement('tr'); const separatorTitle = document.createElement('td'); separatorTitle.textContent = `${title} (${subresults[title].resultados.length} raw results)`; separatorTitle.colSpan = 6; separator.style.border = 1; separator.style.borderColor = 'rgb(90,90,90)'; separator.appendChild(separatorTitle); tbody.insertBefore(separator, tbody.childNodes[order]); order = order + 1; resetGlobalVariables(); } function resetGlobalVariables() { bestResultsPosition = 0; bestFileSizePosition = 0; sizes = {}; } function removeLowHealth(result) { if (result === null) return null; const healthThreshold = 8; const healthIndex = 7; const currentResultHealth = result.children[healthIndex].children[0].className.replace('r', ''); if (currentResultHealth < healthThreshold) { result.remove(); return null; } return result; } function orderBySeeds(a, b) { if (a === null || b === null) return 0; const seedsIndex = 5; return b.children[seedsIndex].textContent - a.children[seedsIndex].textContent; } function orderByFileSize(a, b) { if (a === null || b === null) return 0; const tdSizeA = a.children[4]; let [sizeA, unitA] = tdSizeA.innerHTML.split(' '); if (unitA === 'GB') { sizeA = sizeA * 1000; } const tdSizeB = b.children[4]; let [sizeB, unitB] = tdSizeB.innerHTML.split(' '); if (unitB === 'GB') { sizeB = sizeB * 1000; } return sizeB - sizeA; } function rearrangeOrderedBySeeds(result, seedsMean) { if (result === null) return null; const tbody = result.parentElement; tbody.insertBefore(result, tbody.childNodes[order]); order = order + 1; const current = result.textContent; if (current > seedsMean) { result.innerHTML = `<mark>${current}</mark>`; } if (current < (seedsMean * 0.1)) { result.innerHTML = `<span style="color: red">${current}</span>`; } return result; } function createSortPositionColumn(result, index) { if (result === null) return null; const position = document.createElement('td'); position.textContent = index + 1; result.appendChild(position); return result; } function colorResult(result) { if (result === null) return null; const tdTitulo = result.children[2]; const tdSeeds = result.children[5]; const tdLeechs = result.children[6]; result.style.backgroundColor = bestResultsStyles[bestResultsPosition].bg; result.style.color = bestResultsStyles[bestResultsPosition].color; tdSeeds.style.color = bestResultsStyles[bestResultsPosition].color; tdLeechs.style.color = bestResultsStyles[bestResultsPosition].color; tdTitulo.style.color = bestResultsStyles[bestResultsPosition].color; tdTitulo.innerHTML = tdTitulo.textContent; bestResultsPosition = bestResultsPosition < (bestResultsStyles.length - 1) ? bestResultsPosition + 1 : bestResultsStyles.length - 1; return result; } function removeNextDuplicatesWithLessSeeds(result) { if (result === null) return null; const tdTamanho = result.children[4]; let [size, unit] = tdTamanho.innerHTML.split(' '); if (unit === 'GB') { size = size * 1000; } if (!sizes[size]) { sizes[size] = unit; return result; } //console.log('removing duplicate file with less seeds: ', result); result.remove(); return null; } function colorResultFileSize(result) { if (result === null) return null; const tdSize = result.children[4]; tdSize.style.backgroundColor = bestResultsStyles[bestFileSizePosition].bg; tdSize.style.color = bestResultsStyles[bestFileSizePosition].color; bestFileSizePosition = bestFileSizePosition < (bestResultsStyles.length - 1) ? bestFileSizePosition + 1 : bestResultsStyles.length - 1; return result; } })();