NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name PTP Home Page - Custom "Latest" Tabs // @namespace http://tampermonkey.net/ // @version 0.4.1 // @description Allow user to customize "latest" movies on PTP homepage // @author yoharnu // @downloadURL https://openuserjs.org/install/yoharnu/PTP_Home_Page_-_Custom_Latest_Tabs.user.js // @updateURL https://openuserjs.org/meta/yoharnu/PTP_Home_Page_-_Custom_Latest_Tabs.meta.js // @icon https://www.google.com/s2/favicons?domain=passthepopcorn.me // @license MIT // @match http*://*.passthepopcorn.me/torrents.php* // @match http*://*.passthepopcorn.me/index.php* // @match http*://*.passthepopcorn.me/user.php?action=edit* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // ==/UserScript== var filters = []; (function () { 'use strict'; filters = GM_getValue('filters'); if (!filters) filters = []; if (window.location.pathname.includes('torrents.php') && !window.location.search.includes('?id=')) { let resultCount = document.querySelector('.search-form__footer'); let addToHomeLink = document.createElement('a'); addToHomeLink.innerHTML = 'Add Current Filters to Home Page'; addToHomeLink.href = '#'; addToHomeLink.onclick = () => addCurrentFilterToHome(); resultCount.insertAdjacentElement('afterend', document.createElement('br')); resultCount.insertAdjacentElement('afterend', addToHomeLink); { let movies; const scripts = document.getElementsByTagName('script'); for (var i = 0; i < scripts.length; i++) { var script = scripts[i].innerHTML; if (script.includes('PageData')) { script = JSON.parse('{' + script.split('PageData = {')[1].split('};')[0] + '}'); movies = script["Movies"]; break; } } let firstFiveMovies = []; if (movies) { for (let i = 0; i < movies.length && i < 5; i++) { firstFiveMovies.push(movies[i]); } } setWithExpiry('customTabs' + window.location.search, firstFiveMovies, 5 * 60 * 1000); } } else if (window.location.pathname.includes('index.php')) { for (let i = 0; i < filters.length; i++) { if (!filters[i].name) { filters.splice(i, 1); GM_setValue('filters', filters); window.location.reload(); } } for (let customTab of filters) { addLink(customTab); addTable(customTab); } InitializeSimpleTabControl(); } else if (window.location.pathname.includes('user.php') && window.location.search.includes('action=edit')) { let defaultSelection = document.querySelector('select[name="Home_LatestUploads"]'); const defaultTabCurrent = GM_getValue('defaultTab'); for (let customTab of filters) { let option = document.createElement('option'); option.innerHTML = customTab.name; option.setAttribute('custom-tab-default', encodeFilterName(customTab.name)); defaultSelection.appendChild(option); if (defaultTabCurrent === encodeFilterName(customTab.name)) defaultSelection.selectedIndex = defaultSelection.options.length - 1; } let submitButton = document.querySelector('input[type="submit"]'); submitButton.onclick = () => { let selection = defaultSelection.options[defaultSelection.selectedIndex].getAttribute('custom-tab-default'); if (!selection) selection = null; GM_setValue('defaultTab', selection); }; } })(); function addLink(item) { const name = item.name; const url = item.searchurl; let linkList = document.querySelector('div#last5t div.panel__heading span.panel__heading__title'); linkList.innerHTML = linkList.innerHTML + ' | '; let a = document.createElement('a'); a.href = url; a.innerHTML = name; a.classList.add('simple-tabs__link'); a.setAttribute('data-tab-target', '#last5custom' + encodeFilterName(item.name) + '_table'); linkList.appendChild(a); } function InitializeSimpleTabControl() { for (let tab of document.querySelectorAll('#last5-tab-control .simple-tabs__link')) { let defaultTabID = GM_getValue('defaultTab'); if (tab.getAttribute('data-tab-target') === '#last5custom' + defaultTabID + '_table') { SwitchToTab(tab); } tab.onclick = function (event) { event.preventDefault(); SwitchToTab(this); }; } } function SwitchToTab(tabBarLinkElement) { for (let tab of document.querySelectorAll('#last5-tab-control .simple-tabs__link')) { tab.classList.remove("simple-tabs__link--active"); } tabBarLinkElement.classList.add("simple-tabs__link--active"); for (let table of document.querySelectorAll('table.last5-movies__table')) { if (!table.classList.contains("hidden")) { table.classList.add("hidden"); } } document.querySelector(tabBarLinkElement.getAttribute("data-tab-target")).classList.remove("hidden"); } function addTable(item) { let tableList = document.querySelector('div#last5'); let table = document.createElement('table'); table.classList.add('last5-movies__table'); table.classList.add('table--no-border'); table.classList.add('hidden'); table.id = 'last5custom' + encodeFilterName(item.name) + '_table'; tableList.appendChild(table); let tbody = document.createElement('tbody'); table.appendChild(tbody); getFirstFive(item.searchurl, (firstFiveData) => { // Add posters { let tr = document.createElement('tr'); for (let movie of firstFiveData) { let td = document.createElement('td'); td.classList.add('text--center'); td.width = '20%'; let a = document.createElement('a'); a.style.backgroundImage = "url('" + movie.Cover + "')"; if (movie.GroupTime) { a.href = 'torrents.php?id=' + movie.GroupId; } else { const latestTorrent = getLatestTorrent(movie); a.href = 'torrents.php?id=' + movie.GroupId + '&torrentid=' + latestTorrent.TorrentId; } a.classList.add('last5-movies__link'); a.classList.add('js-movie-tooltip-triggerer'); a.title = movie.Title + ' [' + movie.Year + ']'; td.appendChild(a); tr.appendChild(td); } tbody.appendChild(tr); } // Add movie titles { let tr = document.createElement('tr'); for (let movie of firstFiveData) { let td = document.createElement('td'); td.classList.add('text--center'); td.width = '20%'; let a = document.createElement('a'); a.classList.add('l_movie'); a.style.fontWeight = 'bold'; a.innerHTML = movie.Title; if (movie.GroupTime) { a.href = 'torrents.php?id=' + movie.GroupId; td.appendChild(a); td.appendChild(document.createElement('br')); td.innerHTML = td.innerHTML + movie.GroupTime; } else { const latestTorrent = getLatestTorrent(movie); a.href = 'torrents.php?id=' + movie.GroupId + '&torrentid=' + latestTorrent.TorrentId; td.appendChild(a); td.appendChild(document.createElement('br')); getUploader(latestTorrent.TorrentId, span => td.innerHTML = td.innerHTML + span); } tr.appendChild(td); } tbody.appendChild(tr); } // Add delete button and "show all" link { let tr = document.createElement('tr'); tr.classList.add("last5-movies__show-all-row"); { let td = document.createElement('td'); td.colSpan = '2'; td.style.textAlign = 'left'; let a = document.createElement('a'); a.href = '#'; a.style.color = 'red'; a.innerHTML = 'Delete Custom Tab'; a.setAttribute('custom-tab-name', item.name); a.classList.add("last5-movies__show-all-link"); a.onclick = function (event) { event.preventDefault(); deleteCustomTab(this.getAttribute('custom-tab-name')); }; td.appendChild(a); tr.appendChild(td); } { let td = document.createElement('td'); td.colSpan = '3'; let a = document.createElement('a'); a.href = item.searchurl; a.classList.add("last5-movies__show-all-link"); a.innerHTML = 'Show All'; td.appendChild(a); tr.appendChild(td); } tbody.appendChild(tr); } }); } function getUploader(torrentID, callback) { let cache = getWithExpiry('customTabs?torrentId=' + torrentID); if (cache) { callback(cache); return; } GM_xmlhttpRequest({ method: 'GET', url: window.location.origin + '/torrents.php?torrentid=' + torrentID, onload: function (xhr) { if (xhr.readyState === 4 && xhr.status === 200) { let newDoc = document.implementation.createHTMLDocument(); newDoc.body.innerHTML = xhr.responseText; let timeSpan = newDoc.querySelector('#torrent_' + torrentID).querySelector('.movie-page__torrent__panel span span.time').outerHTML; let div = newDoc.querySelector('#torrent_' + torrentID + ' .torrent_info_first_block'); let reseedImg = div.querySelector('img'); if (reseedImg) { timeSpan = '<span class="time">' + reseedImg.title.split('Re-seeded ')[1] + '</span>'; reseedImg = reseedImg.outerHTML + ' '; } let usernameArray = div.querySelectorAll('a.username'); let username = ''; for (let u of usernameArray) username = u.outerHTML; let returnHTML = timeSpan + '<br/>'; if (reseedImg) returnHTML = returnHTML + reseedImg; returnHTML = returnHTML + username; setWithExpiry('customTabs?torrentId=' + torrentID, returnHTML, 1 * 60 * 1000); callback(returnHTML); } else if (xhr.readyState === 4) { console.log('Error: ' + xhr.status); } } }); } function getLatestTorrent(movie) { let latestTorrent = null; for (let quality of movie.GroupingQualities) { for (let currTorrent of quality.Torrents) { if (!latestTorrent) { latestTorrent = currTorrent; } else if (currTorrent.TorrentId > latestTorrent.TorrentId) { latestTorrent = currTorrent; } } } return latestTorrent; } function deleteCustomTab(tabName) { if (confirm('Are you sure you want to delete the tab named "' + tabName + '"?')) { for (let i = 0; i < filters.length; i++) { if (filters[i].name === tabName || !filters[i].name) { filters.splice(i, 1); } } GM_setValue('filters', filters); window.location.reload(); } } function setWithExpiry(key, value, ttl) { const now = new Date(); // 'item' is an object which contains the original value // as well as the time when it's supposed to expire const item = { value: value, expiry: now.getTime() + ttl }; localStorage.setItem(key, JSON.stringify(item)); } function getWithExpiry(key) { const itemStr = localStorage.getItem(key); // if the item doesn't exist, return null if (!itemStr) { return null; } const item = JSON.parse(itemStr); const now = new Date(); // compare the expiry time of the item with the current time if (now.getTime() > item.expiry) { // If the item is expired, delete the item from storage // and return null localStorage.removeItem(key); return null; } return item.value; } function getFirstFive(url, callback) { let cache = getWithExpiry('customTabs' + url.split('torrents.php')[1]); if (cache) { console.log(cache); callback(cache); return; } GM_xmlhttpRequest({ method: 'GET', url: window.location.origin + '/' + url, onload: function (xhr) { if (xhr.readyState === 4 && xhr.status === 200) { let newDoc = document.implementation.createHTMLDocument(); newDoc.body.innerHTML = xhr.responseText; let movies; const scripts = newDoc.getElementsByTagName('script'); for (var i = 0; i < scripts.length; i++) { var script = scripts[i].innerHTML; if (script.includes('PageData')) { script = JSON.parse('{' + script.split('PageData = {')[1].split('};')[0] + '}'); movies = script["Movies"]; break; } } let firstFiveMovies = []; if (movies) { for (let i = 0; i < movies.length && i < 5; i++) { firstFiveMovies.push(movies[i]); } } setWithExpiry('customTabs' + url.split('torrents.php')[1], firstFiveMovies, 5 * 60 * 1000); callback(firstFiveMovies); } else if (xhr.readyState === 4) { console.log('Error: ' + xhr.status); } } }); } function addCurrentFilterToHome() { const filterName = prompt("What do you want to name this filter?"); if (validateFilterName(filterName)) { let exists = false; for (let tab of filters) { if (encodeFilterName(tab.name) === encodeFilterName(filterName)) { exists = true; if (confirm('There is already a filter named "' + filterName + '".\nWould you like to replace it with this new filter?')) { tab.name = filterName; tab.searchurl = getSearchURL(document.forms.filter); } else { return; } } } if (!exists) filters.push({ 'name': filterName, 'searchurl': getSearchURL(document.forms.filter) }); GM_setValue('filters', filters); } } function validateFilterName(filterName) { if (!filterName) { alert('You must enter a filter name'); return false; } const letters = /^[0-9a-zA-Z\- '",()[\]]+$/; if (!letters.test(filterName)) { alert('"' + filterName + '" contains invalid characters'); return false; } return true; } function encodeFilterName(filterName) { if (!filterName) { return filterName; } return filterName.toLowerCase().replaceAll(' ', '_').replaceAll('\'', '').replaceAll('"', '').replaceAll('(', '').replaceAll(')', '').replaceAll('[', '').replaceAll(']', '').replaceAll(',', ''); } function getSearchURL(form) { let args = ''; if (form.order_by) { if (form.order_by.value === 'creationtime' || form.order_by.value === 'gptime') { args = args + addToURL('order_by', form.order_by); } } args = args + addToURL('searchstr', form.searchstr); args = args + addToURL('year', form.year); args = args + addToURL('artistname', form.artistname); args = args + addToURL('inallakas', form.inallakas); args = args + addToURL('language', form.language); args = args + addToURL('subtitles', form.subtitles); args = args + addToURL('countrylist', form.countrylist); args = args + addToURL('country_type', form.country_type); args = args + addToURL('taglist', form.taglist); args = args + addToURL('tags_type', form.tags_type); args = args + addToURL('imdbrating', form.imdbrating); args = args + addToURL('imdbvotes', form.imdbvotes); args = args + addToURL('ptprating', form.ptprating); args = args + addToURL('ptpvotes', form.ptpvotes); args = args + addToURL('mcrating', form.mcrating); args = args + addToURL('rtrating', form.rtrating); args = args + addToURL('encoding', form.encoding); args = args + addToURL('format', form.format); args = args + addToURL('media', form.media); args = args + addToURL('resolution', form.resolution); args = args + addToURL('scene', form.scene); args = args + addToURL('freetorrent', form.freetorrent); args = args + addToURL('runtime', form.runtime); args = args + addToURL('remastertitle', form.remastertitle); args = args + addToURL('remasteryear', form.remasteryear); args = args + addToURL('filelist', form.filelist); args = args + addToURL('grouping', form.grouping); args = args + addToURL('filter_cat[1]', form["filter_cat[1]"]); args = args + addToURL('filter_cat[2]', form["filter_cat[2]"]); args = args + addToURL('filter_cat[3]', form["filter_cat[3]"]); args = args + addToURL('filter_cat[4]', form["filter_cat[4]"]); args = args + addToURL('filter_cat[5]', form["filter_cat[5]"]); args = args + addToURL('filter_cat[6]', form["filter_cat[6]"]); if (args[0] === '&') { args = args.substr(1); } args = encodeURI(args); return 'torrents.php?' + args; } function addToURL(name, item) { if (item) { if (item.type === 'checkbox') { if (item.checked) { return '&' + name + '=' + item.value; } else { return ''; } } else if (item.value !== null && item.value !== "" && item.value) { return '&' + name + '=' + item.value; } } return ''; }