NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name PTP To Radarr // @version 0.8.4 // @author DirtyCajunRice // @description Easily add movies to radarr straight from PTP // @homepage https://passthepopcorn.me/forums.php?action=viewthread&threadid=35294 // @icon https://ptpimg.me/19kcyv.png // @updateURL https://openuserjs.org/meta/dirtycajunrice/PTP_To_Radarr.meta.js // @supportURL https://passthepopcorn.me/forums.php?action=viewthread&threadid=35294 // @match https://passthepopcorn.me/* // @require https://openuserjs.org/src/libs/sizzle/GM_config.js // @copyright 2019, dirtycajunrice (https://openuserjs.org//users/dirtycajunrice) // @license MIT // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_openInTab // @grant GM_log // @grant GM_notification // @grant GM_registerMenuCommand // ==/UserScript== // Changelog 0.8.4 - Fixed href bug for covers // Fixed update logic // Changelog 0.8.3 - Major internal code refactor // Found lingering URL sanitization missed // Changelog 0.8.2 - Fixed autoupdate trying to update non-existant buttons // Changelog 0.8.1 - Fixed "Huge view" themeChecker for Raise // Fixed "Huge view" in collections // Added AutoUpdate for "Huge view" // Changelog 0.8.0 - Added "Huge view" // Changelog 0.7.1 - Fixed bug with GM_config iframe document access logic // Fixed bug with themeChecker // Changelog 0.7.0 - Added AutoSync to settings // Update buttons after a sync (manual and auto) // Changelog 0.6.1 - Added Stylesheet checking to fix cover buttons. Confirmed working on all official and supported custom stylesheets + Raise // Changelog 0.6.0 - Added error checking to help debug issues // Added Radarr URL sanitization var current_page_type = ""; (function () { "use strict"; GM_config.init({ "id": "PTPToRadarr", "title": "PTP To Radarr Settings", "css": `#PTPToRadarr {background: #333333;} #PTPToRadarr .field_label {color: #fff;} #PTPToRadarr .config_header {color: #fff; padding-bottom: 10px;} #PTPToRadarr .reset {color: #f00; text-align: center;} #PTPToRadarr .config_var {text-align: center;} #PTPToRadarr_radarr_syncbutton_var {float: left;} #PTPToRadarr .reset_holder {text-align: center;} #PTPToRadarr_radarr_minimumavailability_var {padding-right: 95;} #PTPToRadarr_radarr_apikey_var {padding-left: 49;} #PTPToRadarr_radarr_url_var {padding-left: 69;} #PTPToRadarr .saveclose_buttons {margin: 16px 10px 10px; padding: 2px 12px; background-color: #e7e7e7; color: black; text-decoration: none; border: none; border-radius: 6px;} #PTPToRadarr_field_radarr_syncbutton {background-color: #e7e7e7; color: black; text-decoration: none; border: none; border-radius: 6px; margin-left: 10px; margin-top: 16px; height: 20px;}`, "events": { "open": function(doc) { let style = this.frame.style; style.width = "400px"; style.height = "295px"; style.inset = ""; style.top = "6%"; style.right = "6%"; style.borderRadius = "25px"; doc.getElementById("PTPToRadarr_buttons_holder").prepend(doc.getElementById("PTPToRadarr_radarr_syncbutton_var")); } }, "fields": { "radarr_url": { "label": "Radarr URL", "type": "text", "default": "https://domain.tld/radarr" }, "radarr_apikey": { "label": "Radarr API Key", "type": "text", "default": "" }, "radarr_profileid": { "label": "Radarr Quality Profile ID", "type": "text", "default": "1" }, "radarr_rootfolderpath": { "label": "Radarr Root Folder Path", "type": "text", "default": "/mnt/movies" }, "radarr_minimumavailability": { "label": "Minimum Availability", "type": "select", "options": ["preDB", "announced", "inCinemas", "released"], "default": "released" }, "radarr_searchformovie": { "label": "Search for movie on request", "type": "checkbox", "default": false }, "radarr_sync_interval": { "label": "AutoSync Interval (Minutes)", "type": "select", "options": ["15", "30", "60", "120", "360", "1440", "Never"], "default": "Never" }, "radarr_syncbutton": { "label": "Sync Radarr Movies", "type": "button", "click": get_radarr_movies } } }); new GM_registerMenuCommand("PTP To Radarr Settings",() => GM_config.open()); let url = window.location.href; let radarr_url = GM_config.get("radarr_url").replace(/\/$/, ""); if (document.getElementById("torrent-table")) { current_page_type = "singletorrent"; } else { current_page_type = "multi"; } if (current_page_type) { set_html(false); } let interval = GM_config.get("radarr_sync_interval"); if (interval != "Never") { let millisecondInterval = Number(interval) * 60000; window.setTimeout(() => autoSync(millisecondInterval)); window.setInterval(() => autoSync(millisecondInterval), millisecondInterval); } })(); function themeChecker () { let typeAThemes = ["marcel.css", "ptp-raise"]; typeAThemes.forEach((theme) => { if (document.head.querySelector("[href*=\"" + theme + "\"]")) { return true; } }); return false; } function clickswap (imdbid, titleSlug) { let radarr_url = GM_config.get("radarr_url").replace(/\/$/, ""); let button = document.getElementById("ptptoradarr-" + imdbid) button.firstChild.src = "https://ptpimg.me/19kcyv.png"; button.removeEventListener("click", new_movie_lookup, false); button.addEventListener("click", function () { GM_openInTab(radarr_url.concat("/movies/", titleSlug), "active"); }, false); } function set_html (update) { let theme = themeChecker(); let radarr_url = GM_config.get("radarr_url").replace(/\/$/, ""); let coverView = document.querySelector(".cover-movie-list__container"); let coverViewMovies = Array.from(document.getElementsByClassName("cover-movie-list__movie__rating-and-tags")); let listView = document.querySelector(".js-basic-movie-list"); let listViewMovies = Array.from(document.getElementsByClassName("basic-movie-list__movie__ratings-and-tags")); let hugeView = document.querySelector(".huge-movie-list__movie"); let hugeViewMovies = Array.from(document.getElementsByClassName("huge-movie-list__movie__ratings")); if (update) { let buttons = document.querySelectorAll("[id^=\"ptptoradarr-tt\"]"); if (buttons.length === 0) { return; } buttons.forEach((button) => { window.setTimeout(function () { button.parentNode.removeChild(button); }); }); } if (current_page_type == "singletorrent") { let a = document.querySelector("[href^=\"http://www.imdb.com/title/tt\"]"); let movie = document.querySelector(".panel__body"); if (a) { buttonBuilder(movie, a.href, "single", theme); } } else if (current_page_type == "multi") { if (coverView && !coverView.classList.contains("hidden")) { coverViewMovies.forEach((movie) => { window.setTimeout(() => { let a = movie.querySelector("[href^=\"http://www.imdb.com/title/tt\"]"); if (a) { buttonBuilder(movie, a.href, "medium", theme); } }); }); } else if (listView && !listView.classList.contains("hidden")) { listViewMovies.forEach((movie) => { window.setTimeout(() => { let a = movie.querySelector("[href^=\"http://www.imdb.com/title/tt\"]"); if (a) { buttonBuilder(movie, a.href, "small", theme); } }); }); } else if (hugeView) { hugeViewMovies.forEach((movie) => { window.setTimeout(() => { let a = movie.querySelector("[href^=\"http://www.imdb.com/title/tt\"]"); if (a) { buttonBuilder(movie, a.href, "large", theme); } }); }); } } } function buttonBuilder (movie, href, type, theme) { let radarr_url = GM_config.get("radarr_url").replace(/\/$/, ""); let imdbid = href.substr(26, 9); let exists = check_exists(imdbid); let button = document.createElement("button"); let img = document.createElement("img"); button.id = "ptptoradarr-" + imdbid; button.type = type; Object.assign(button.style, {border: "none", backgroundColor: "transparent"}); Object.assign(img.style, {border: "none", backgroundColor: "transparent"}); Object.assign(img, {height: 32, width: 32}); button.appendChild(img); img.imdbid = imdbid; if (type == "single") { Object.assign(button.style, {position: "absolute", top: "6%", zIndex: 10}); movie.style.position = "relative"; movie.prepend(button); } else if (type == "small") { Object.assign(img, {height: 16, width: 16}); movie.appendChild(button); } else if (type == "medium") { let posterContainer = movie.closest(".cover-movie-list__movie"); posterContainer.prepend(button); Object.assign(button.style, {position: "absolute", top: "3%", zIndex: 10}); if (theme) { posterContainer.style.position = "relative"; } } else if (type == "large") { let posterContainer = movie.closest(".huge-movie-list__movie").firstChild; posterContainer.prepend(button); Object.assign(button.style, {position: "absolute", top: "3%", zIndex: 10}); if (theme) { button.style.left = "3%"; posterContainer.style.position = "relative"; } } if (exists) { img.src = "https://ptpimg.me/19kcyv.png"; button.addEventListener("click", function () { GM_openInTab(radarr_url.concat("/movies/", exists[0].titleSlug), "active"); }, false); } else { img.src = "https://ptpimg.me/0q4vvz.png"; button.addEventListener("click", new_movie_lookup, false); } } function errorNotificationHandler (error, expected, errormsg) { let prestring = "PTPToRadar::"; if (expected) { GM_log(prestring + "Error: " + errormsg + " Actual Error: " + error); GM_notification("Error: " + errormsg); } else { GM_log(prestring + "Unexpected Error: Please report this error in the forum. Actual Error: " + error); GM_notification("Unexpected Error: Please report this error in the forum. Actual Error: " + error); } } function get_radarr_movies() { let radarr_url = GM_config.get("radarr_url").replace(/\/$/, ""); let radarr_apikey = GM_config.get("radarr_apikey"); GM_xmlhttpRequest({ method: "GET", url: radarr_url.concat("/api/movie"), headers: { "X-Api-Key": radarr_apikey, "Accept": "text/json" }, onload: function(response) { let responseJSON = null; if (!response.responseJSON) { try { responseJSON = JSON.parse(response.responseText); if (responseJSON.error == "Unauthorized") { throw "creds"; } GM_setValue("existing_movies", JSON.stringify(responseJSON)); let timestamp = + new Date() GM_setValue("last_sync_timestamp", timestamp) GM_log("PTPToRadarr::Sync: Setting last sync timestamp to " + timestamp) GM_notification("Radarr Sync Complete!", "PTP To Radarr"); set_html(true); } catch (e) { if (e instanceof SyntaxError) { errorNotificationHandler(e, true, "No JSON in response. Please check your Radarr URL.") } else if (e == "creds") { errorNotificationHandler(e, true, "Invalid API Key. Please check your Radarr API Key") } else { errorNotificationHandler(e, false) } } } } }); }; function check_exists (imdbid) { let movieliststr = GM_getValue("existing_movies", "{}"); let movie_list = JSON.parse(movieliststr); let filter = null try { filter = movie_list.filter(movie => movie.imdbId == imdbid); } catch (e) { if (e instanceof TypeError) { return false } else { errorNotificationHandler(e, false) return false } } if (!filter.length) { return false } else { return filter }; } function autoSync (interval) { let currentTimestamp = + new Date(); let lastSyncTimestamp = GM_getValue("last_sync_timestamp", 0); if (currentTimestamp - lastSyncTimestamp >= interval) { let notification = "It has been " + ((currentTimestamp - lastSyncTimestamp) / 60000).toFixed(1) + " minutes since your last sync which exceeds your threshold of " + (interval / 60000) + " minutes. AutoSyncing..."; GM_log(notification); GM_notification(notification); get_radarr_movies(); } } function new_movie_lookup (link) { let imdbid = "" if (link.originalTarget) { imdbid = link.originalTarget.imdbid; } else { imdbid = link.target.imdbid; } let radarr_url = GM_config.get("radarr_url").replace(/\/$/, ""); let radarr_apikey = GM_config.get("radarr_apikey"); let movie = ""; GM_xmlhttpRequest({ method: "GET", url: radarr_url.concat("/api/movie/lookup/imdb?imdbId=", imdbid), headers: { "X-Api-Key": radarr_apikey, "Accept": "text/json" }, onload: function(response) { let responseJSON = null; if (!response.responseJSON) { if (!response.responseText) { GM_notification("No results found"); return; } responseJSON = JSON.parse(response.responseText); add_movie(responseJSON, imdbid); } } }) } function add_movie (movie, imdbid) { let radarr_url = GM_config.get("radarr_url").replace(/\/$/, ""); let radarr_apikey = GM_config.get("radarr_apikey"); movie.ProfileId = GM_config.get("radarr_profileid"); movie.RootFolderPath = GM_config.get("radarr_rootfolderpath"); movie.monitored = true; movie.minimumAvailability = GM_config.get("radarr_minimumavailability");; if (GM_config.get("radarr_searchformovie")) { movie.addOptions = {searchForMovie: true} } GM_xmlhttpRequest({ method: "POST", url: radarr_url.concat("/api/movie"), headers: { "X-Api-Key": radarr_apikey, "Accept": "text/json", "Content-Type": "application/json" }, data: JSON.stringify(movie), onload: function(response) { let responseJSON = null; if (!response.responseJSON) { responseJSON = JSON.parse(response.responseText); try { if (!responseJSON.title && responseJSON.firstChild.errorMessage == "This movie has already been added") throw "exists"; clickswap(imdbid, responseJSON.titleSlug); GM_notification(responseJSON.title + " Sucessfully sent to Radarr", "PTP To Radarr") } catch (e) { if (e == "exists") { errorNotificationHandler(e, true, "Movie already exists in Radarr. Please resync your movies."); } else { errorNotificationHandler(e, false); } } } } }); }