// ==UserScript== // @name copyTorrentToRelated // @namespace https://avistaz.to/profile/dryeyes // @description Copy current torrent row to Related Torrents section // @include https://cinemaz.to/torrent/* // @include https://avistaz.to/torrent/* // @version 0.9 // @grant none // @locale English (en) // @downloadURL none // ==/UserScript== 'use strict'; (function(){ function injectFunc(fn) { var scriptElm = document.createElement('script'); scriptElm.setAttribute("type", "application/javascript"); scriptElm.textContent = '(' + fn + ')();'; //scriptElm.async = false; didn't help. document.body.appendChild(scriptElm); // run the script document.body.removeChild(scriptElm); // clean up } function getNoRelatedTorrentsNode () { var noTorrentsFoundNode = document.evaluate('//div[@id="collapseRelatedTorrents"]/div[@class="related-torrents"]/p[normalize-space()="No torrents found!"]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; return noTorrentsFoundNode; } var currentTorrentUrl = window.location.href; var newTR; // the copied element from related torrents query. var nRelated; var atLeast; function onMainTorrentLoaded () { var i; var cleanedUrl = currentTorrentUrl.replace(/(\#.*)$/, ''); console.log("XMLHttpRequest loaded."); var relatedRow = this.response; console.log(relatedRow); var relatedRows = relatedRow.querySelectorAll("div.table-responsive tbody > tr"); console.log("Main page torrent rows:", relatedRows); console.log("Looking for:", cleanedUrl); for (i = 0; i < relatedRows.length; i++) { var row = relatedRows[i]; var anode = row.querySelector("a.torrent-filename"); if (anode!==null) { console.log("Anode:", anode); if (anode.href === cleanedUrl) { newTR = row.cloneNode(true); var tdNode = newTR.querySelector("td:last-of-type"); var inode = relatedRow.createElement("i"); inode.innerHTML = ``; tdNode.appendChild(inode); console.log("ClonedTR:", newTR); break; } } } var lastPageLI = document.querySelector("ul.pagination li:nth-last-of-type(2)"); if (lastPageLI !== null) { var nFullPages = Number(lastPageLI.innerText) - 1; nRelated = (relatedRows.length*nFullPages); atLeast = "+"; } else { nRelated = relatedRows.length; atLeast = ""; } } // Download & copy matching torrent row from related torrents url function copyRelatedRow() { var mainURL = document.querySelector("h3.movie-title > a").href; var pieces = mainURL.split("/"); var site = pieces[2]; var torrentID = pieces[4].split("-")[0]; var relatedURL = `https://${site}/movies/torrents/${torrentID}?quality=all`; var xhr = new XMLHttpRequest(); xhr.onload = onMainTorrentLoaded; xhr.open("GET", relatedURL); xhr.responseType = "document"; xhr.send(); console.log("XMLHttpRequest for "+relatedURL+ " sent."); } var relatedAdded = false; function relatedShown () { if (relatedAdded) return; else relatedAdded = true; console.log("Related shown.", document.readyState); var relatedTorrent = document.querySelector("#collapseRelatedTorrents > div.related-torrents > div > table > tbody > tr"); console.log("Related torrent:", relatedTorrent); var noRelatedTorrentsNode = getNoRelatedTorrentsNode(); if (noRelatedTorrentsNode !== null) console.log("After expanded: No related torrents message found."); if (relatedTorrent !== null) { if (newTR !== undefined) { console.log("NewTR:"); console.log(newTR); relatedTorrent.parentNode.insertBefore(newTR, relatedTorrent); } } else { if (noRelatedTorrentsNode !== null) { var divElm = document.createElement('div'); divElm.innerHTML = ` `; console.log("About to create new related."); var tbody = divElm.querySelector("tbody"); if (newTR !== undefined) { console.log("NewTR:"); console.log(newTR); tbody.appendChild(newTR); } var grandParent = noRelatedTorrentsNode.parentNode.parentNode; grandParent.replaceChild(divElm, noRelatedTorrentsNode.parentNode); } else { console.log("Ooops. No related torrents AND couldn't find the No Related Torrents message?", document.readyState); window.alert("Ooops. No related torrents AND couldn't find the No Related Torrents message?\n\nKeep refreshing page until this alert doesn't appear."); } } var relatedTorrents = document.querySelectorAll("#collapseRelatedTorrents > div.related-torrents > div > table > tbody > tr"); console.log("relatedTorrents:", relatedTorrents); var relatedTorrentsA = document.querySelector('div.panel-heading > strong > a'); if (relatedTorrentsA !== null) { if (nRelated === null) { var nTorrents = relatedTorrents.length > 0 ? relatedTorrents.length : 1; relatedTorrentsA.innerText += " [" + nTorrents + "]"; } else { relatedTorrentsA.innerText += " [" + nRelated + atLeast + "]"; } } } // Expose relatedShown() to injected func. window.relatedShown = relatedShown; // doesn't work with Greasemonkey 4.1 //exportFunction(relatedShown, window, {defineAs: "relatedShown"}); // doesn't work in Greasemonkey 3.17, get exportFunction not defined error :( // Use script injection so can use jQuery to listen to shown.bs.collapse event which // will be automatically triggered when we click the Related Torrents panel during // load event processing. function injectedFunc() { console.log("Injected function running"); var relatedTorrentsDiv = document.querySelector('div#collapseRelatedTorrents'); console.log ("relatedTorrentsDiv:", relatedTorrentsDiv); $(relatedTorrentsDiv).on('shown.bs.collapse', relatedShown); // also works! } function clickRelated() { console.log("Click Related Torrents header."); var relatedTorrentsA = document.querySelector('div.panel-heading > strong > a'); if (relatedTorrentsA !== null) { relatedTorrentsA.click(); } } function onLoadHandler() { console.log("Load event occurred."); if (newTR !== undefined) { clickRelated(); } else { console.log("XMLHttpRequest not done. Wait 2 seconds to click."); setTimeout(clickRelated, 2000); } } console.log("UserScript running"); copyRelatedRow(); injectFunc(injectedFunc); window.addEventListener('load', onLoadHandler, false); })();