Greasy Fork

TMDB with IMDB, RottenTomatoes, Metacritic & MyAnimeList score

It adds IMDB, RottenTomatoes, Metacritic, MyAnimeList & Awards/Nominations to TMDB

目前为 2022-11-24 提交的版本。查看 最新版本

作者
passthesh3ll
评分
0 0 0
版本
2.8.5
创建于
2021-08-29
更新于
2022-11-24
大小
39.9 KB
许可证
暂无
适用于

TMDB with IMDB, RottenTomatoes, Metacritic, MyAnimeList & Awards/Nominations

It adds IMDB, RottenTomatoes, Metacritic, MyAnimeList & Awards/Nominations to TMDB.

  • All reviews, scores and images are links to their respective page
  • Metacritic & IMDB data are obtained through IMDB scraping
  • RottenTomatoes data is obtained using "private" RT api & scraping (because the api is not well updated)
  • MAL data is obtained using unofficial MAL api
  • the script // ==UserScript== // @name TMDB with IMDB, RottenTomatoes, Metacritic, MyAnimeList & Awards/Nominations // @description It adds IMDB, RottenTomatoes, Metacritic, MyAnimeList & Awards/Nominations to TMDB // @match https://www.themoviedb.org/* // @version 2.8.4 // @author SH3LL // @grant GM_xmlhttpRequest // @namespace https://greasyfork.org/users/762057 // ==/UserScript==

function clean_t(title){ if(title===null||title===undefined) return ""; return title.toLowerCase() .replaceAll(/[$&+,:;=?@#|'<>.^*()%!-]+/g,'') //remove all special characters .replaceAll(/\s\s+/g,'') //remove multipla spaces .trim() }

function TMDB_search_api(TMDB_id,content) {

if (content==="movie"){
    return new Promise(function (resolve, reject) {
        GM_xmlhttpRequest({
            method: 'GET',
            responseType: 'json',
            synchronous: false,
            url: 'https://api.themoviedb.org/3/movie/'+TMDB_id+'?api_key=8d6d91941230817f7807d643736e8a49&language=en&append_to_response=external_ids,keywords',
            onload: (resp) => {

                let json = JSON.parse(resp.responseText);
                console.log('TMDB title api: https://api.themoviedb.org/3/movie/'+TMDB_id+'?api_key=8d6d91941230817f7807d643736e8a49&language=en&append_to_response=external_ids,keywords');

                if (json && json.Error) {
                  console.log("Error: " + json.Error);
                  resolve("error"); return;

                }

                let IMDB_id=0,TMDB_title=0, TMDB_original_title=0, TMDB_year=0,anime_flag=0;

                if(json.title!==undefined && json.title!==null) TMDB_title = json.title;
                if(json.original_title!==undefined && json.original_title!==null) TMDB_original_title = json.original_title;
                if(json.external_ids!==undefined && json.external_ids.imdb_id!== null) IMDB_id = json.external_ids.imdb_id;
                if(json.release_date!==null && json.release_date!==undefined) TMDB_year=json.release_date.slice(0,4);
                if(json.keywords!==undefined && json.keywords.keywords!==undefined && json.keywords.keywords!==null){
                  for(let keyword of json.keywords.keywords){
                    if(keyword.name==="anime"){anime_flag=1; break;}
                  }
                }
                resolve([TMDB_title,TMDB_original_title,TMDB_year,IMDB_id,anime_flag]); return;

            }
        });
    });

}else if(content==="tv"){
  return new Promise(function (resolve, reject) {
        GM_xmlhttpRequest({
            method: 'GET',
            responseType: 'json',
            synchronous: false,
            url: 'https://api.themoviedb.org/3/tv/'+TMDB_id+'?api_key=8d6d91941230817f7807d643736e8a49&language=en&append_to_response=external_ids,keywords',
            onload: (resp) => {

                let json = JSON.parse(resp.responseText);
                console.log('TMDB title api: https://api.themoviedb.org/3/tv/'+TMDB_id+'?api_key=8d6d91941230817f7807d643736e8a49&language=en&append_to_response=external_ids,keywords');

                if (json && json.Error) {
                  console.log("Error: " + json.Error);
                  resolve("error"); return;

                }

                let IMDB_id=0,TMDB_title=0, TMDB_original_title=0,seasons_count=0,anime_flag=0;

                if(json.name!==undefined && json.name!==null) TMDB_title = json.name;
                if(json.original_name!==undefined && json.original_name!==null) TMDB_original_title = json.original_name;
                if(json.external_ids!==undefined && json.external_ids.imdb_id!== null) IMDB_id = json.external_ids.imdb_id; //imdb id
                if(json.seasons!==undefined && json.seasons!== null) seasons_count = (json.seasons).length;
                if(json.keywords!==undefined && json.keywords.results!==undefined && json.keywords.results!==null){
                  for(let keyword of json.keywords.results){
                    if(keyword.name==="anime"){anime_flag=1; break;}
                  }
                }

                //years range
                let first_year="N/A",last_year="N/A",years_range;

                if(json.first_air_date!==undefined && json.first_air_date!==null) first_year = json.first_air_date.slice(0,4);
                if(json.last_air_date!==undefined && json.last_air_date!==null) {
                  if(json.last_air_date.slice(2,4) !== first_year.slice(2,4)) last_year = json.last_air_date.slice(2,4);
                }

                if(last_year !=="N/A") years_range=first_year + "-" + last_year; else years_range=first_year;

                resolve([TMDB_title,TMDB_original_title,first_year,years_range,IMDB_id,seasons_count,anime_flag]); return;

            }
        });
    });
}

}

function IMDB_info_scrape(IMDB_id) { return new Promise(function (resolve, reject) { GM_xmlhttpRequest({ method: 'GET', responseType: 'document', synchronous: false, url: "https://www.imdb.com/title/"+IMDB_id, onload: (resp) => { const doc = document.implementation.createHTMLDocument().documentElement; doc.innerHTML = resp.responseText; console.log("IMDB link: "+"https://www.imdb.com/title/"+IMDB_id)

            let IMDB_rating=0, IMDB_votes_number=0, IMDB_awards=0, IMDB_next_title=0,IMDB_next_date=0;
            IMDB_rating = doc.querySelectorAll('.sc-7ab21ed2-1')[0].innerText;
            IMDB_votes_number = doc.querySelectorAll('.sc-7ab21ed2-3')[0].innerText;
            let awards_hook=doc.querySelectorAll('.sc-fcdc3619-2');
            if(awards_hook.length!==0) IMDB_awards = awards_hook[0].children[0].children[0].innerText + ". "+awards_hook[0].children[0].children[1].innerText;
            if(IMDB_awards===undefined) IMDB_awards=0;
            resolve([IMDB_rating,IMDB_votes_number,IMDB_awards]); return;
    }
    });
  })

}

function RT_search_api(title,year,content,version) {

if (content==="movie"){
    return new Promise(function (resolve, reject) {
        GM_xmlhttpRequest({
            method: 'GET',
            responseType: 'json',
            synchronous: false,
            url: 'https://www.rottentomatoes.com/api/private/v'+version+'.0/search/?limit=25&q='+ title.replaceAll(" ", "%20") +'&t=movie',
            onload: (resp) => {

                let json = JSON.parse(resp.responseText);
                console.log('RT search api: https://www.rottentomatoes.com/api/private/v'+version+'.0/search/?limit=25&q='+ title.replaceAll(" ", "%20") +'&t=movie');

                if(json.movieCount === 0){
                  console.log("Error: No movies found in RT");
                  resolve("error"); return;
                }

                let fresh_certificate=0, meterscore = 0, url=0;
                for(let movie of json.movies){
                  if(parseInt(movie.year) === parseInt(year) && clean_t(movie.name) === clean_t(title)){ //fix rotten tomatoes errors
                    if(movie.meterClass === "fresh" || movie.meterClass === "certified_fresh") fresh_certificate='fresh';
                    if(movie.meterClass === "rotten") fresh_certificate='rotten';
                    if(movie.meterScore !== "N/A" && movie.meterScore !== undefined) meterscore=movie.meterScore;
                    url=movie.url;
                    break;
                  }else if(( parseInt(movie.year) === parseInt(year) + 1 || parseInt(movie.year) === parseInt(year) -1 )&& clean_t(movie.name) === clean_t(title)){
                    if(movie.meterClass === "fresh" || movie.meterClass === "certified_fresh") fresh_certificate='fresh';
                    if(movie.meterClass === "rotten") fresh_certificate='rotten';
                    if(movie.meterScore !== "N/A" && movie.meterScore !== undefined) meterscore=movie.meterScore;
                    url=movie.url;
                    break;
                  }else if(parseInt(movie.year) === parseInt(year) && clean_t(movie.name).includes(clean_t(title))){
                    if(movie.meterClass === "fresh" || movie.meterClass === "certified_fresh") fresh_certificate='fresh';
                    if(movie.meterClass === "rotten") fresh_certificate='rotten';
                    if(movie.meterScore !== "N/A" && movie.meterScore !== undefined) meterscore=movie.meterScore;
                    url=movie.url;
                    break;
                  }else if(( parseInt(movie.year) === parseInt(year) + 1 || parseInt(movie.year) === parseInt(year) -1 )&& clean_t(movie.name).includes(clean_t(title))){
                    if(movie.meterClass === "fresh" || movie.meterClass === "certified_fresh") fresh_certificate='fresh';
                    if(movie.meterClass === "rotten") fresh_certificate='rotten';
                    if(movie.meterScore !== "N/A" && movie.meterScore !== undefined) meterscore=movie.meterScore;
                    url=movie.url;
                    break;
                  }

                }
               if(url!==0) {resolve([url,meterscore,fresh_certificate]); return;} else{resolve("error"); return;}
            }
        });
    });

}else if(content==="tv"){
  return new Promise(function (resolve, reject) {
        GM_xmlhttpRequest({
            method: 'GET',
            responseType: 'json',
            synchronous: false,
            url: 'https://www.rottentomatoes.com/api/private/v'+version+'.0/search/?limit=25&q='+ title.replaceAll(" ", "%20") +'&t=tvSeries',
            onload: (resp) => {
                let json = JSON.parse(resp.responseText);
                console.log('RT search api: https://www.rottentomatoes.com/api/private/v'+version+'.0/search/?limit=25&q='+ title.replaceAll(" ", "%20") +'&t=tvSeries');

                if(json.tvCount === 0){
                 console.log("Error: No series found in RT");
                  resolve("error"); return;
                }
                let fresh_certificate=0, meterscore = 0, url=0;
                for(let serie of json.tvSeries){
                  if(parseInt(serie.startYear) === parseInt(year) && clean_t(serie.title) === clean_t(title)){ //fix rotten tomatoes errors
                    if(serie.meterClass === "fresh" || serie.meterClass === "certified_fresh") fresh_certificate='fresh';
                    if(serie.meterClass === "rotten") fresh_certificate='rotten';
                    if(serie.meterScore !== "N/A" && serie.meterScore !== undefined) meterscore=serie.meterScore;
                    url=serie.url;
                    break;
                  }else if((parseInt(serie.startYear) === parseInt(year)+1 || parseInt(serie.startYear) === parseInt(year) -1) && clean_t(serie.title) === clean_t(title)){
                    if(serie.meterClass === "fresh" || serie.meterClass === "certified_fresh") fresh_certificate='fresh';
                    if(serie.meterClass === "rotten") fresh_certificate='rotten';
                    if(serie.meterScore !== "N/A" && serie.meterScore !== undefined) meterscore=serie.meterScore;
                    url=serie.url;
                    break;
                  }else if(parseInt(serie.startYear) === parseInt(year) && clean_t(serie.title).includes(clean_t(title))){
                    if(serie.meterClass === "fresh" || serie.meterClass === "certified_fresh") fresh_certificate='fresh';
                    if(serie.meterClass === "rotten") fresh_certificate='rotten';
                    if(serie.meterScore !== "N/A" && serie.meterScore !== undefined) meterscore=serie.meterScore;
                    url=serie.url;
                    break;
                  }else if((parseInt(serie.startYear) === parseInt(year)+1 || parseInt(serie.startYear) === parseInt(year) -1) && clean_t(serie.title).includes(clean_t(title))){
                    if(serie.meterClass === "fresh" || serie.meterClass === "certified_fresh") fresh_certificate='fresh';
                    if(serie.meterClass === "rotten") fresh_certificate='rotten';
                    if(serie.meterScore !== "N/A" && serie.meterScore !== undefined) meterscore=serie.meterScore;
                    url=serie.url;
                    break;
                  }
                }
               if(url!==0) {resolve([url,meterscore,fresh_certificate]); return;} else{resolve("error"); return;}
            }
        });
    });
}

}

function RT_info_scrape(RT_delta_url){ return new Promise(function (resolve, reject) { GM_xmlhttpRequest({ method: 'GET', responseType: 'document', synchronous: false, url: "https://www.rottentomatoes.com"+RT_delta_url, onload: (resp) => { const doc = document.implementation.createHTMLDocument().documentElement; doc.innerHTML = resp.responseText; console.log("Scraping RT: "+"https://www.rottentomatoes.com"+RT_delta_url)

            let tomatometer_score=0, tomatometer_state=0, audience_score=0,audience_state=0,tomatometer_icon_box=0,tomatometer_score_box=0,audience_icon_box=0,audience_score_box=0;
            let scoreboard = doc.getElementsByClassName("scoreboard")[0];
            if(scoreboard!==undefined){
              tomatometer_score = scoreboard.getAttributeNode('tomatometerscore').value ==="" ? 0 : scoreboard.getAttributeNode('tomatometerscore').value;
              tomatometer_state = scoreboard.getAttributeNode('tomatometerstate').value==="" ? 0 : scoreboard.getAttributeNode('tomatometerstate').value;
              audience_score = scoreboard.getAttributeNode('audiencescore').value==="" ? 0 : scoreboard.getAttributeNode('audiencescore').value;
              audience_state = scoreboard.getAttributeNode('audiencestate').value==="" ? 0 : scoreboard.getAttributeNode('audiencestate').value;
            }else{
              let scoreboxes = doc.getElementsByClassName("mop-ratings-wrap__half");

              if(scoreboxes.length===0){resolve([0,0,0,0]); return;}
              let tomatometer_box=scoreboxes[0]; let audience_box=scoreboxes[1];

              if(tomatometer_box.getElementsByClassName("mop-ratings-wrap__icon")!==undefined) tomatometer_icon_box = tomatometer_box.getElementsByClassName("mop-ratings-wrap__icon")[0]; tomatometer_score_box = tomatometer_box.getElementsByClassName("mop-ratings-wrap__percentage")[0];
              if(audience_box.getElementsByClassName("mop-ratings-wrap__icon")!==undefined) audience_icon_box = audience_box.getElementsByClassName("mop-ratings-wrap__icon")[0]; audience_score_box = audience_box.getElementsByClassName("mop-ratings-wrap__percentage")[0];

              if(tomatometer_icon_box!==undefined){
                if(tomatometer_icon_box.className.includes("rotten")) tomatometer_state="rotten";
                if(tomatometer_icon_box.className.includes("certified-fresh")) tomatometer_state="certified-fresh";
                if(tomatometer_icon_box.className.includes("fresh")) tomatometer_state="fresh";
                tomatometer_score=tomatometer_score_box.innerText.trim().replaceAll("%","");
              }
              if(audience_icon_box!==undefined){
                if(audience_icon_box.className.includes("upright")) audience_state="upright";
                if(audience_icon_box.className.includes("spilled")) audience_state="spilled";
                audience_score=audience_score_box.innerText.trim().replaceAll("%","");
              }

            }
            resolve([tomatometer_score,tomatometer_state,audience_score,audience_state]); return;
    }
    });
  })

}

function MC_search_scrape(title,year,content) { // title= ORIGINAL->movies, TITLE->anime if (content==="movie"){

return new Promise(function (resolve, reject) {
    GM_xmlhttpRequest({
        method: 'GET',
        responseType: 'document',
        synchronous: false,
        url: "https://www.metacritic.com/search/movie/"+title+"/results",
        onload: async (resp) => {
            const doc = document.implementation.createHTMLDocument().documentElement;
            doc.innerHTML = resp.responseText;
            console.log("MC link: "+"https://www.metacritic.com/search/movie/"+title.replaceAll(" ", "%20")+"/results")

            let result_list = doc.getElementsByClassName('search_results module')[1];
            if (result_list!==undefined){
              for(let curr_result of result_list.children){
                let curr_title_link = curr_result.querySelectorAll(".product_title")[0].children[0].href.replace("https://www.themoviedb.org/","https://www.metacritic.com/").replace("https://www.themoviedb.org/movie/","https://www.metacritic.com/");
                let curr_title = curr_result.querySelectorAll(".product_title")[0].children[0].innerText.trim();
                let curr_rating = curr_result.children[0].children[1].children[0].children[0].innerText.trim();
                let curr_year = curr_result.children[0].children[1].children[0].innerText.replaceAll(/\s\s+/g,'').trim().slice(-4);
                console.log("MC->>>>>> ["+clean_t(curr_title)+"]=["+clean_t(title)+"] ["+curr_year+"]=["+year+"]");
                if(clean_t(curr_title)===clean_t(title) && ( parseInt(curr_year)===parseInt(year) || parseInt(curr_year)+1===parseInt(year) || parseInt(curr_year)-1===parseInt(year) )){
                  let MC_info = await MC_info_scrape(curr_title_link);
                  resolve([MC_info[0],MC_info[1],MC_info[2],MC_info[3],MC_info[4],curr_title_link]); return;

                }
              }


            }
            resolve("error"); return;
    }
  });
})

}else if(content==="tv"){

return new Promise(function (resolve, reject) {
    GM_xmlhttpRequest({
        method: 'GET',
        responseType: 'document',
        synchronous: false,
        url: "https://www.metacritic.com/search/tv/"+title+"/results",
        onload: async (resp) => {
            const doc = document.implementation.createHTMLDocument().documentElement;
            doc.innerHTML = resp.responseText;
            console.log("MC link: "+"https://www.metacritic.com/search/tv/"+title.replaceAll(" ", "%20")+"/results")

            let result_list = doc.getElementsByClassName('search_results module')[1];
            if (result_list!==undefined){
              for(let curr_result of result_list.children){
                let curr_title_link = curr_result.children[0].children[1].children[0].children[1].children[0].href.replace("https://www.themoviedb.org/","https://www.metacritic.com/").replace("https://www.themoviedb.org/movie/","https://www.metacritic.com/");
                let curr_title = curr_result.children[0].children[1].children[0].children[1].children[0].innerText.trim();
                let curr_rating = curr_result.children[0].children[1].children[0].children[0].innerText.trim();
                let curr_year = curr_result.children[0].children[1].children[0].innerText.replaceAll(/\s\s+/g,'').trim().slice(-4);
                console.log("MC->>>>>> ["+clean_t(curr_title)+"]=["+clean_t(title)+"] ["+curr_year+"]=["+year+"]");
                if(clean_t(curr_title)===clean_t(title) && ( parseInt(curr_year)===parseInt(year) || parseInt(curr_year)+1===parseInt(year) || parseInt(curr_year)-1===parseInt(year) )){
                  let MC_info = await MC_info_scrape(curr_title_link);
                  resolve([MC_info[0],MC_info[1],MC_info[2],MC_info[3],MC_info[4],curr_title_link]); return;

                }
              }


            }
           resolve("error"); return;
    }
  });
})

} }

function MC_info_scrape(link){ return new Promise(function (resolve, reject) { GM_xmlhttpRequest({ method: 'GET', responseType: 'document', synchronous: false, url: link, onload: (resp) => { const doc = document.implementation.createHTMLDocument().documentElement; doc.innerHTML = resp.responseText;

            let MC_MetaScore=0, MC_UserScore=0, MC_Critics=0, MC_Users=0,MC_must_see=0;

            MC_Critics = doc.querySelectorAll('.ms_wrapper')[0].querySelectorAll(".based_on")[0];
            if(MC_Critics!==undefined){MC_Critics=MC_Critics.innerText.replace(/[^0-9]/g,'').trim();}else{MC_Critics="n/a"}
            MC_MetaScore = doc.querySelectorAll('.ms_wrapper')[0].querySelectorAll(".metascore_anchor")[0].innerText.trim();
            if(doc.querySelectorAll(".must-see")[0]!==undefined) MC_must_see=1;
            MC_Users = doc.querySelectorAll('.us_wrapper')[0].querySelectorAll(".based_on")[0];
            if(MC_Users!==undefined){MC_Users=MC_Users.innerText.replace(/[^0-9]/g,'').trim();}else{MC_Users="n/a"}
            MC_UserScore = doc.querySelectorAll('.us_wrapper')[0].querySelectorAll(".metascore_anchor")[0].innerText.trim();

            resolve([MC_MetaScore,MC_Critics,MC_UserScore,MC_Users,MC_must_see]); return;
    }
    });
  })

}

function JIKAN_search_api(title,original_title,year,content) {

if (content==="movie"){
    return new Promise(function (resolve, reject) {
        GM_xmlhttpRequest({
            method: 'GET',
            responseType: 'json',
            synchronous: false,
            url: 'https://api.jikan.moe/v4/anime?q='+original_title.replaceAll(" ","%20")+'&page=1',
            onload: (resp) => {
                let json = JSON.parse(resp.responseText);
                console.log('MAL search api: https://api.jikan.moe/v4/anime?q='+original_title.replaceAll(" ","%20")+'&page=1');

                if (json.data==undefined || json.Error) {
                  console.log("Error: " + json.Error);
                  resolve("error"); return;

                }

                let MAL_url=0, MAL_title_name=0, MAL_score=0, MAL_image_url=0, content_type=0, episodes_count=0, start_date=0;
                for(let result of json.data){

                  console.log("JIKAN en:"+result.title_english+" ||||| JIKAN:"+result.title+" ||||| TMDB:"+title)

                  if(result.aired.from!== null) console.log("JIKAN year:"+result.aired.from.slice(0,4)+" ||||| TMDB year:"+year)

                  if(result.type!==null && result.aired.from!==null &&
                     (parseInt(result.aired.from.slice(0,4))===parseInt(year) || parseInt(result.aired.from.slice(0,4))===parseInt(year)-1 || parseInt(result.aired.from.slice(0,4))===parseInt(year)-2) &&
                     (result.type === "Movie" /*TV*/ || result.type === "ONA" || result.type === "OVA") &&
                     (clean_t(result.title_english) === clean_t(title) || clean_t(result.title) === clean_t(title))){

                    if(result.url!== null) MAL_url = result.url;
                    if(result.score!== null) MAL_score = result.score;
                    if(result.images.jpg.image_url!== null) MAL_image_url = result.images.jpg.image_url;
                    if(result.episodes!== null) episodes_count = result.episodes;
                    if(result.aired.from!== null) start_date = result.aired.from.slice(0,4);

                    resolve([MAL_url, MAL_score, episodes_count, start_date]); return;
                  }
                }
                console.log("JIKAN [MAL]: Error, title not found");
                resolve("error"); return;

            }
        });
    });

}else if(content==="tv"){
  return new Promise(function (resolve, reject) {
        GM_xmlhttpRequest({
            method: 'GET',
            responseType: 'json',
            synchronous: false,
            url: 'https://api.jikan.moe/v4/anime?q='+title+'&page=1&limit=10',
            onload: (resp) => {

                let json = JSON.parse(resp.responseText);
                console.log('MAL search api: https://api.jikan.moe/v4/anime?q='+title+'&page=1&limit=10');

                if (json.data==undefined || json.Error) {
                  console.log("Error: " + json.Error);
                  resolve("error"); return;

                }

                let MAL_url=0, MAL_score=0, episodes_count=0, start_date=0, end_date=0, date_range=0;
                for(let result of json.data){
                  if(result.type!==null && result.aired.from!==null &&
                     (parseInt(result.aired.from.slice(0,4))===parseInt(year) || parseInt(result.aired.from.slice(0,4))===parseInt(year)-1 || parseInt(result.aired.from.slice(0,4))===parseInt(year)-2) &&
                     (result.type === "TV" || result.type === "ONA" || result.type === "OVA")){

                    if(result.url!== null) MAL_url = result.url;
                    if(result.score!== null) MAL_score = result.score;
                    if(result.episodes!== null) episodes_count = result.episodes;
                    if(result.aired.from!== null) start_date = result.aired.from.slice(0,4);
                    if(result.aired.to!== null) end_date = result.aired.to.slice(2,4);

                    if(start_date!== 0 && end_date!== 0) date_range = start_date + "-" + end_date

                    resolve([MAL_url, MAL_score, episodes_count, date_range]); return;
                  }
                }

                console.log("JIKAN [MAL]: Error, title not found");
                resolve("error"); return;

            }
        });
    });
}

}

async function main(){ let content=0; let TMDB_info=0, TMDB_id=0, TMDB_title=0, TMDB_original_title=0, TMDB_year=0, tv_year_range=0, seasons_count=0; let IMDB_info, IMDB_id=0, IMDB_score=0, IMDB_votes_number=0,IMDB_awards=0; let RT_info=0, RT_scraped_info=0, RT_url_delta=0, RT_audience_state=0, RT_audience_score=0, RT_tomatometer_state=0, RT_tomatometer_score=0;//RT_score=0, RT_url_delta=0, RT_certificate=0; let MAL_info=0, MAL_url=0, MAL_score=0, episodecount=0, MAL_year=0, anime_flag=0; let MC_info=0, MC_MetaScore=0,MC_Critics=0,MC_UserScore=0,MC_Users=0,MC_url=0,MC_must_see=0; //Remove bloats $(".tooltip").remove(); $(".play_trailer").remove();

//Hook per appendere i punteggi dei providers
let page_score_icon = document.getElementsByClassName("chart");
let loading_div = document.createElement("div");
let loading_label = document.createElement("label");
loading_label.innerText="⏳ Loading Results.."
loading_label.style.color="firebrick";
loading_div.style.paddingRight="20px";
loading_div.append(loading_label);

page_score_icon[0].after(loading_div);

//Grab TMDB ID
if(window.location.href.includes("https://www.themoviedb.org/movie/")){
  content="movie";
  TMDB_id = parseInt(window.location.href.split("https://www.themoviedb.org/movie/")[1].split("-")[0]);
}else if(window.location.href.includes("https://www.themoviedb.org/tv/")){
  content="tv";
  TMDB_id = parseInt(window.location.href.split("https://www.themoviedb.org/tv/")[1].split("-")[0]);
}else{return;}

//Get TMDB title info
TMDB_info = await TMDB_search_api(TMDB_id,content);
if(content==="movie"){
  TMDB_title=TMDB_info[0];
  TMDB_original_title=TMDB_info[1];
  TMDB_year=TMDB_info[2];
  IMDB_id=TMDB_info[3];
  if(parseInt(TMDB_info[4])===1)  anime_flag="movie";
}else if(content==="tv"){
  TMDB_title=TMDB_info[0];
  TMDB_original_title=TMDB_info[1];
  TMDB_year=TMDB_info[2];
  tv_year_range=TMDB_info[3];
  IMDB_id=TMDB_info[4];
  seasons_count=TMDB_info[5];
  if(parseInt(TMDB_info[6])===1)  anime_flag="tv";
}

//Get IMDB score
if(IMDB_id!==0 && IMDB_id!=="error") IMDB_info = await IMDB_info_scrape(IMDB_id);
if(IMDB_info!=="error" && IMDB_info!==0){
  IMDB_score=IMDB_info[0];
  IMDB_votes_number=IMDB_info[1];
  IMDB_awards=IMDB_info[2];
}

//Get RT score
if(TMDB_title!==0) RT_info = await RT_search_api(TMDB_title,TMDB_year,content,1); //test api 1.0
if(TMDB_title!==0 && RT_info==="error") RT_info = await RT_search_api(TMDB_title,TMDB_year,content,2); //test api 2.0

if(RT_info!=="error" && RT_info!==0){

  RT_url_delta=RT_info[0];
  RT_scraped_info = await RT_info_scrape(RT_url_delta);
  RT_tomatometer_score=RT_scraped_info[0];
  RT_tomatometer_state=RT_scraped_info[1];
  RT_audience_score=RT_scraped_info[2];
  RT_audience_state=RT_scraped_info[3];
}

//Get MAL score
if(TMDB_title!==0 && anime_flag!==0) MAL_info = await JIKAN_search_api(TMDB_title,TMDB_original_title,TMDB_year,content);
if(MAL_info!=="error" && MAL_info!==0 && anime_flag!==0){
  MAL_url=MAL_info[0];
  MAL_score=parseFloat(MAL_info[1]);
  if(Number.isInteger(MAL_score)){
    MAL_score = String(MAL_score)+".00"
  }else{
    let f_numbers = String(MAL_score).split(".")[1].length;
    if(f_numbers===1) MAL_score=MAL_score+"0";
  }
  episodecount=MAL_info[2];
  MAL_year=MAL_info[3];
}

//Get MC score
if(TMDB_original_title!==0 && anime_flag===0) MC_info = await MC_search_scrape(TMDB_original_title,TMDB_year,content);
if(TMDB_title!==0 && anime_flag!==0) MC_info = await MC_search_scrape(TMDB_title,TMDB_year,content)
if(MC_info!=="error" && MC_info!==0){

  MC_MetaScore=MC_info[0];
  MC_Critics=MC_info[1];
  MC_UserScore=MC_info[2];
  MC_Users=MC_info[3];
  MC_must_see=MC_info[4];
  MC_url=MC_info[5];
  console.log(MC_MetaScore+"-"+MC_Critics+"-"+MC_UserScore+"-"+MC_Users+"-"+MC_url+"- MustSee="+MC_must_see);
}

//Build IMDB label
let IMDB_image_link = document.createElement("a");
let IMDB_image = document.createElement("img");
let IMDB_image_div = document.createElement("div");
let IMDB_link = document.createElement("a");
let IMDB_link_div = document.createElement("div");
let IMDB_label = document.createElement("label");
let IMDB_div = document.createElement("div");

if(IMDB_info!=="error" && IMDB_info!==0){
  IMDB_image.src="https://i.postimg.cc/Y2VnQwMb/245px-IMDB-Logo-2016-svg.png"; IMDB_image.style.width="60px";
  IMDB_image_link.href="https://www.imdb.com/title/"+IMDB_id;
  IMDB_image_link.append(IMDB_image);
  IMDB_image_div.append(IMDB_image_link);

  IMDB_link.href="https://www.imdb.com/title/"+IMDB_id+"/ratings"; IMDB_link.innerText=IMDB_score; IMDB_link.style.color="gold"; IMDB_link.style.fontWeight = 'bold';  IMDB_link.style.marginLeft="auto";  IMDB_link.style.marginRight="auto";
  IMDB_label.innerText="("+IMDB_votes_number+")"; IMDB_label.style.fontSize="50%"; IMDB_label.style.color="gold"; IMDB_label.style.paddingLeft="5px";
  IMDB_link_div.append(IMDB_link,IMDB_label);

  IMDB_div.style.marginRight="15px"; IMDB_div.style.marginLeft="15px"; IMDB_div.style.width="60px"
  IMDB_div.append(IMDB_image_div,IMDB_link_div);
}

//Build RT label
let RT_image_link = document.createElement("a");
let RT_image = document.createElement("img");
let RT_image_critic = document.createElement("img");
let RT_image_audience = document.createElement("img");
let RT_image_div = document.createElement("div");
let RT_link_critic = document.createElement("a");
let RT_link_users = document.createElement("a");
let RT_link_div = document.createElement("div");
let RT_div = document.createElement("div");

if(RT_info!=="error" && RT_info!==0){
  RT_image.src="https://i.postimg.cc/YtNd2pYn/rotten-tomatoes-new-logo.png"; RT_image.style.borderRadius = "3px";
  RT_image.style.width="69px"; RT_image.style.marginRight="15px"; RT_image.style.marginLeft="5px"; if(RT_tomatometer_score==="100" || RT_audience_score==="100"){ RT_image.style.marginLeft="10px"}
  RT_image_link.href="https://www.rottentomatoes.com"+RT_url_delta;
  RT_image_link.append(RT_image);
  RT_image_div.append(RT_image_link);

  RT_image_critic.style.width= RT_tomatometer_score===0 ? "0px" : "12px"; RT_link_critic.style.paddingRight="5px"; RT_link_critic.style.paddingLeft="5px";
  RT_image_audience.style.width= RT_audience_score===0 ? "0px" : "12px"; RT_link_users.style.paddingRight="5px"; RT_link_users.style.paddingLeft="5px";
  if(RT_tomatometer_state==="fresh") RT_image_critic.src='https://i.postimg.cc/0xxLPX6n/fresh.png';
  if(RT_tomatometer_state==="certified-fresh") RT_image_critic.src='https://i.postimg.cc/FNmmCgXd/certified-fresh.png';
  if(RT_tomatometer_state==="rotten") RT_image_critic.src='https://i.postimg.cc/HW1HgbJN/rotten.png';
  if(RT_audience_state==="upright") RT_image_audience.src='https://i.postimg.cc/b81pRVWf/upright.png';
  if(RT_audience_state==="spilled") RT_image_audience.src='https://i.postimg.cc/2YsChNHx/spilled.png';
  RT_link_critic.href="https://www.rottentomatoes.com"+RT_url_delta+"/reviews";
  RT_link_critic.innerText= RT_tomatometer_score===0 ? "N/A" : RT_tomatometer_score ; RT_link_critic.style.color= RT_tomatometer_score===0 ? "grey" : "red"; RT_link_critic.style.fontWeight="bold";
  RT_link_users.href="https://www.rottentomatoes.com"+RT_url_delta+"/reviews?type=user";
  RT_link_users.innerText= RT_audience_score===0 ? "N/A" : RT_audience_score ; RT_link_users.style.color= RT_audience_score===0 ? "grey" : "red"; RT_link_users.style.fontWeight="bold";
  RT_link_div.append(RT_image_critic,RT_link_critic,RT_image_audience,RT_link_users); RT_link_div.style.paddingRight="15px";

  RT_div.append(RT_image_div,RT_link_div);
}

//Build MC Label
let MC_image_link = document.createElement("a");
let MC_image = document.createElement("img");
let MC_image_div = document.createElement("div");
let MC_critics_link = document.createElement("a");
let MC_critics_label = document.createElement("label");
let MC_users_link = document.createElement("a");
let MC_users_label = document.createElement("label");
let MC_scores_div = document.createElement("div");
let MC_div = document.createElement("div");

if(MC_info!==0 && MC_info!=="error"){
  if(MC_must_see===1){MC_image.src="https://i.postimg.cc/QNKCWSTq/mc.png"}else{MC_image.src="https://i.postimg.cc/dtLsHFTJ/mc.png"}
  MC_image.style.width="69px"; MC_image.style.marginLeft="5px"; MC_image.style.borderRadius = "3px";
  MC_image_link.href=MC_url;
  MC_image_link.append(MC_image);
  MC_image_div.append(MC_image_link);

  let compact_critics; if(parseInt(MC_Critics)>1000){compact_critics=String((MC_Critics/1000).toFixed(2)).slice(0,-1) + "k";}else{compact_critics=MC_Critics}
  let compact_users; if(parseInt(MC_Users)>1000){compact_users=String((MC_Users/1000).toFixed(2)).slice(0,-1) + "k";}else{compact_users=MC_Users}
  //critics
  MC_critics_link.innerText=MC_MetaScore; MC_critics_link.href=MC_url+"/critic-reviews"; MC_critics_link.style.fontWeight="bold"; MC_critics_link.style.paddingLeft="4px";
  if(!isNaN(MC_MetaScore) && MC_MetaScore<=39){MC_critics_link.style.color="red"; MC_critics_label.style.color=MC_critics_link.style.color;}
  else if(!isNaN(MC_MetaScore) && MC_MetaScore>=39 && MC_MetaScore<=60){MC_critics_link.style.color="burlywood"; MC_critics_label.style.color=MC_critics_link.style.color;}
  else if(!isNaN(MC_MetaScore) && MC_MetaScore>=61){MC_critics_link.style.color="greenyellow"; MC_critics_label.style.color=MC_critics_link.style.color;}
  MC_critics_label.innerText=" ("+compact_critics+")"; MC_critics_label.style.fontSize="50%";
  //users
  MC_users_link.innerText=MC_UserScore; MC_users_link.href=MC_url+"/user-reviews"; MC_users_link.style.fontWeight="bold"; MC_users_link.style.paddingLeft="4px";
  if(!isNaN(MC_UserScore) && parseFloat(MC_UserScore)<=3.9){MC_users_link.style.color="red"; MC_users_label.style.color=MC_users_link.style.color;}
  else if(!isNaN(MC_UserScore) && parseFloat(MC_UserScore)>=3.9 && parseFloat(MC_UserScore)<=6.0){MC_users_link.style.color="burlywood"; MC_users_label.style.color=MC_users_link.style.color;}
  else if(!isNaN(MC_UserScore) && parseFloat(MC_UserScore)>=6.1){MC_users_link.style.color="greenyellow"; MC_users_label.style.color=MC_users_link.style.color;}
  MC_users_label.innerText=" ("+compact_users+")"; MC_users_label.style.fontSize="50%";
  MC_scores_div.append(MC_critics_link,MC_critics_label,MC_users_link,MC_users_label);

  MC_div.append(MC_image_div,MC_scores_div); MC_div.style.paddingRight="15px";
}

//Build MAL Label
let MAL_image_link = document.createElement("a");
let MAL_image = document.createElement("img");
let MAL_image_div = document.createElement("div");
let MAL_link = document.createElement("a");
let MAL_link_div = document.createElement("div");
let MAL_div = document.createElement("div");

if(MAL_info!==0 && MAL_info!=="error"){
  MAL_image.src="https://i.postimg.cc/bwPmk7d2/apple-touch-icon-256.png"; MAL_image.style.width="30px"; MAL_image.style.borderRadius = '3px'
  MAL_image_link.href=MAL_url;
  MAL_image_link.append(MAL_image);
  MAL_image_div.append(MAL_image_link); MAL_image_div.style.paddingLeft="5px";

  MAL_link.innerText=MAL_score; MAL_link.href=MAL_url+"/reviews"; MAL_link.style.color="cornflowerblue"; MAL_link.style.fontWeight="bold"; MAL_link.style.paddingLeft="4px";
  MAL_link_div.append(MAL_link);

  MAL_div.append(MAL_image_div,MAL_link_div); MAL_div.style.paddingRight="15px";
}

//Build YouTube Label
let YT_image_link = document.createElement("a");
let YT_image = document.createElement("img");
let YT_image_div = document.createElement("div");
let YT_link = document.createElement("a");
let YT_link_div = document.createElement("div");
let YT_div = document.createElement("div");
if(TMDB_title!==0){
  YT_image.src="https://i.postimg.cc/CKGRZxLF/youtube-PNG102349.png"; YT_image.style.width="46px"; YT_image.style.paddingBottom="18px"; YT_image.style.borderRadius = '3px';
  YT_image_link.href="https://www.youtube.com/results?search_query="+TMDB_title+" trailer";
  YT_image_link.append(YT_image);
  YT_image_div.append(YT_image_link);

  //YT_link.innerText="Trailer"; YT_link.href=YT_image_link.href; YT_link.style.color="red"; YT_link.style.fontSize="80%"; YT_link.style.marginLeft="4px";
  //YT_link_div.append(YT_link);

  YT_div.append(YT_image_div); YT_div.style.paddingRight="15px";
}


//Build Oscars Label
let AWARDS_image = document.createElement("img");
let AWARDS_link = document.createElement("a");
let AWARDS_div = document.createElement("div");
if(IMDB_awards!==0){
  AWARDS_image.src="https://i.postimg.cc/vmmQ3SD0/Oscars-logo.png"; AWARDS_image.style.width="28px";
  AWARDS_link.innerText=IMDB_awards; AWARDS_link.href="https://www.imdb.com/title/"+IMDB_id+"/awards/"; AWARDS_link.style.fontSize="80%"; AWARDS_link.style.paddingLeft="5px";
  AWARDS_div.append(AWARDS_image,AWARDS_link); AWARDS_div.style.paddingBottom="25px";
}

//Remove Loading
page_score_icon[0].nextSibling.remove();

//Append SCORES
if(anime_flag!==0) page_score_icon[0].after(IMDB_div,RT_div,MC_div,MAL_div,YT_div); else page_score_icon[0].after(IMDB_div,RT_div,MC_div,YT_div);

//Append AWARDS
let top_bar = document.getElementsByClassName("auto actions");
if(IMDB_awards!==0) top_bar[0].after(AWARDS_div);

//set runtime color
let runtime_div= document.querySelectorAll(".facts")[0].querySelectorAll(".runtime")[0];
if(runtime_div!== undefined) runtime_div.style.color="orange";

}

main();works out of the box without configuration

The CSS style of this script is meant for dark pages (I use DarkReader plugin)

Alt text Alt text Alt text