NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @namespace https://openuserjs.org/users/SB100
// @name PTP TMDb Mid/End Credit Scene Info
// @description Adds info to the "Movie Info" box on whether the film has a mid/end credit scene
// @updateURL https://openuserjs.org/meta/SB100/PTP_TMDb_MidEnd_Credit_Scene_Info.meta.js
// @version 1.0.1
// @author SB100
// @copyright 2021, SB100 (https://openuserjs.org/users/SB100)
// @license MIT
// @match https://passthepopcorn.me/torrents.php?id=*
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @connect api.themoviedb.org
// ==/UserScript==
// ==OpenUserJS==
// @author SB100
// ==/OpenUserJS==
/* jshint esversion: 6 */
/**
* =============================
* ADVANCED OPTIONS
* =============================
*/
// True = no line added to movie info box when there isn't a particular credit scene
// False = A line with 'No' is added to the movie info box.
const HIDE_WHEN_NO = false;
/**
* =============================
* END ADVANCED OPTIONS
* DO NOT MODIFY BELOW THIS LINE
* =============================
*/
const BASE_TMDB_URL = 'https://api.themoviedb.org/3';
/**
* Gets your TMDb API key. Asks the user for one if it hasn't been set yet
*/
function getTmdbApiKey() {
const key = GM_getValue('tmdb_key', '');
if (!key) {
const input = window.prompt(`Please input your TMDb API key.
If you don't have one, please signup for one at https://themoviedb.org.
Then go to Settings -> API -> API Key (v3 auth)
Disable this userscript until you have one as this prompt will continue to show until one is provided`);
const trimmed = input && input.trim();
if (/[a-f0-9]{32}/.test(trimmed)) {
GM_setValue('tmdb_key', trimmed);
return trimmed;
}
}
return key;
}
/**
* Query the API for some results
*/
function queryApi(path, params = {}) {
let resolver;
let rejecter;
const p = new Promise((resolveFn, rejectFn) => {
resolver = resolveFn;
rejecter = rejectFn;
});
const paramStr = new URLSearchParams(params).toString();
const url = `${BASE_TMDB_URL}${path}${paramStr.length > 0 ? `?${paramStr}` : ''}`
GM_xmlhttpRequest({
method: 'get',
url: url,
timeout: 10000,
onloadstart: () => {},
onload: (result) => {
if (result.status === 401) {
const resp = JSON.parse(result.response);
if (resp.status_code === 7) {
GM_deleteValue('tmdb_key');
alert(`Invalid TMDb API key. It has now been removed.
Please refresh the page and input a valid TMDb API key to continue using this userscript.`);
rejecter(new Error('Invalid TMDb API Key'));
return;
}
}
if (result.status !== 200) {
console.log('[TMDb Movie Mid/End Scene Info]', result);
rejecter(new Error('Not OK'));
return;
}
resolver(JSON.parse(result.response))
},
onerror: (result) => {
rejecter(result)
},
ontimeout: (result) => {
rejecter(result)
}
});
return p;
}
/**
* Find the movies IMDb ID from the page
*/
function findImdbIdFromPage() {
const elem = document.getElementById('imdb-title-link');
const href = elem && elem.href;
return href && href.match(/tt\d+/)[0];
}
/**
* Find the TMBd movie info for the IMDb movie passed in
*/
async function findMovieInfoByIMDb(imdbId, key) {
const movieInfo = await queryApi(`/find/${imdbId}`, {
external_source: 'imdb_id',
api_key: key
});
if (movieInfo && Array.isArray(movieInfo.movie_results) && movieInfo.movie_results.length > 0) {
return movieInfo.movie_results[0];
}
return null;
}
/**
* Gets all tags for a movie using the TMDb API
*/
async function getMovieTagInfo(movieId, key) {
const movieTags = await queryApi(`/movie/${movieId}/keywords`, {
api_key: key
});
if (movieTags && Array.isArray(movieTags.keywords) && movieTags.keywords.length > 0) {
return movieTags.keywords;
}
return null;
}
/**
* Parse the tags and find the ones we're interested in
*/
function doesMovieHaveEndSceneTags(tags) {
let duringTag = false;
let endTag = false;
tags.forEach(tag => {
if (tag.id === 179431) duringTag = true;
if (tag.id === 179430) endTag = true;
});
return {
duringTag,
endTag
}
}
/**
* Add info to the Movie Info box
*/
function addCreditSceneInfoToMovieInfo(during, end) {
const movieInfoBox = document.getElementById('movieinfo');
if (!movieInfoBox) {
return;
}
const panelBody = movieInfoBox.querySelector('.panel__body');
if (!panelBody) {
return;
}
const duringDiv = document.createElement('div');
duringDiv.innerHTML = `<strong>During Credits Scene</strong>: ${during ? 'Yes' : 'No'}`;
const afterDiv = document.createElement('div');
afterDiv.innerHTML = `<strong>After Credits Scene</strong>: ${end ? 'Yes' : 'No'}`;
if (!HIDE_WHEN_NO || during === true) panelBody.appendChild(duringDiv);
if (!HIDE_WHEN_NO || end === true) panelBody.appendChild(afterDiv);
}
/**
* Main script runner
*/
(async function () {
'use strict';
const key = getTmdbApiKey();
if (!key) {
console.log(`[TMDb Movie Mid/End Scene Info] No valid API key found, exiting userscript`);
return;
}
const imdb = findImdbIdFromPage();
if (!imdb) {
console.log(`[TMDb Movie Mid/End Scene Info] Couldn't find IMDb ID`);
return;
}
const movieInfo = await findMovieInfoByIMDb(imdb, key);
if (!movieInfo) {
console.log(`[TMDb Movie Mid/End Scene Info] No movie info found from API`);
return;
}
const movieTags = await getMovieTagInfo(movieInfo.id, key);
if (!movieTags) {
console.log(`[TMDb Movie Mid/End Scene Info] No movie tags found from API`);
return;
}
const {
duringTag,
endTag
} = doesMovieHaveEndSceneTags(movieTags);
addCreditSceneInfoToMovieInfo(duringTag, endTag);
})();