diff --git a/README.md b/README.md index 02431fc..8af9c5a 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,5 @@ Opens the corresponding IMDB/TMDB/Letterboxd movie/tv page in just one click. Al 1. Install [Tampermonkey](https://chromewebstore.google.com/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en) extension. 2. Then, [Click me and press install](https://tetrax-10.github.io/imdb-tmdb-linker/linker.user.js) 3. After installing open the script and replace `YOUR_TMDB_API_KEY` with your [TMDB Api](https://www.themoviedb.org/settings/api) key. +4. Open this [TMDB movie page](https://www.themoviedb.org/movie/420622) you will be asked for permission to access cross-origin data to extract imdb ratings. [Click `Always allow`](https://raw.githubusercontent.com/Tetrax-10/imdb-tmdb-linker/main/screenshot/permission.png). +5. Done 🎉. diff --git a/linker.user.js b/linker.user.js index ab6121c..b81502a 100644 --- a/linker.user.js +++ b/linker.user.js @@ -2,16 +2,18 @@ // @name IMDb TMDB Linker // @description Opens the corresponding IMDB/TMDB/Letterboxd movie/tv show page in just one click. Also adds the ability to see IMDB ratings on TMDB pages. // @author Tetrax-10 -// @namespace http://tampermonkey.net/ -// @version 1.0 +// @namespace https://github.com/Tetrax-10/imdb-tmdb-linker +// @version 1.1 // @license MIT // @match *://*.imdb.com/title/tt* // @match *://*.themoviedb.org/movie/* // @match *://*.themoviedb.org/tv/* +// @homepageURL https://tetrax-10.github.io/imdb-tmdb-linker +// @supportURL https://github.com/Tetrax-10/imdb-tmdb-linker/issues // @icon https://tetrax-10.github.io/imdb-tmdb-linker/assets/icon.png // @updateURL https://tetrax-10.github.io/imdb-tmdb-linker/linker.user.js // @downloadURL https://tetrax-10.github.io/imdb-tmdb-linker/linker.user.js -// @grant none +// @grant GM_xmlhttpRequest // ==/UserScript== ;(function () { @@ -240,7 +242,7 @@ html.k-mobile #linker-parent { } } - const ImdbSvg = `` // prettier-ignore + const ImdbSvg = `` // prettier-ignore const tmdbUtils = (() => { async function waitForElement(selector, timeout = null) { @@ -275,18 +277,6 @@ html.k-mobile #linker-parent { }) } - function formatNumber(number) { - if (number >= 1000000) { - const million = number / 1000000 - return million % 1 === 0 ? million.toFixed(0) + "M" : million.toFixed(1) + "M" - } else if (number >= 1000) { - const thousand = number / 1000 - return thousand.toFixed(0) + "K" - } else { - return number - } - } - function createParentElement() { const parentElement = document.createElement("div") parentElement.id = "linker-parent" @@ -340,7 +330,7 @@ html.k-mobile #linker-parent { } function createImdbRatingElement(rating, numRatings) { - const text = rating !== undefined ? `${rating.toFixed(1)}${numRatings !== undefined ? ` ( ${formatNumber(numRatings)} )` : ""}` : null + const text = rating !== undefined ? `${rating}${numRatings !== undefined ? ` ( ${numRatings} )` : ""}` : null const ratingElement = document.createElement("div") ratingElement.id = "linker-imdb-rating" @@ -353,9 +343,30 @@ html.k-mobile #linker-parent { } } + async function getImdbRating(imdbId) { + return new Promise((resolve) => { + GM_xmlhttpRequest({ + method: "GET", + url: `https://www.imdb.com/title/${imdbId}/ratings`, + onload: function (response) { + const parser = new DOMParser() + const dom = parser.parseFromString(response.responseText, "text/html") + + const rating = dom.querySelector(`div[data-testid="rating-button__aggregate-rating__score"] > span`)?.innerText + const numRating = dom.querySelector(`div[data-testid="rating-button__aggregate-rating__score"] + div`)?.innerText + + resolve([rating, numRating]) + }, + onerror: function (error) { + console.error("Request failed:", error) + }, + }) + }) + } + return { waitForElement: waitForElement, - formatNumber: formatNumber, + getImdbRating: getImdbRating, element: { parent: createParentElement, letterboxd: createLetterboxdElement, @@ -409,17 +420,9 @@ html.k-mobile #linker-parent { const imdbLink = tmdbUtils.element.imdbLink(imdbId, ImdbSvg) imdbContainer.insertBefore(imdbLink, loadingElement) - const imdbRawRes = await ((encodeURI,...[data,response])=>encodeURI(`${"xml:"+"//"&&""}${"themoviedb.org/redirect"&&tmdbId&&"?external_source=imdb_id"&&data+"movie"&&((alert)=>((filter,...sync)=>((concat,screen,filter)=>((self)=>((...clear)=>self(self(filter))||clear)("querySelector"))(concat,screen,filter))(atob,sync,filter,sync))(...[YUhSMGNITTZM],alert))(tmdbId.matchAll()||isMobile.toString())}/${"&external_id="&&`${response+"episodes"||""}+"tv_shows"`&&`${isMobile?"cast":"people"}`&&"title"}/${imdbId}`))(fetch,document,console) // prettier-ignore - // *://*.themoviedb.org/redirect?external_source=imdb_id&external_id&title - if (imdbRawRes.status !== 200) { - imdbContainer.removeChild(loadingElement) - return - } - - const imdbRes = await imdbRawRes.json() - // inject imdb rating - const imdbRatingElement = tmdbUtils.element.imdbRating(imdbRes.rating?.star, imdbRes.rating?.count) + const [imdbRating, imdbNumRating] = await tmdbUtils.getImdbRating(imdbId) + const imdbRatingElement = tmdbUtils.element.imdbRating(imdbRating, imdbNumRating) imdbContainer.removeChild(loadingElement) if (!imdbRatingElement) return imdbContainer.appendChild(imdbRatingElement) diff --git a/screenshot/permission.png b/screenshot/permission.png new file mode 100644 index 0000000..7249dd4 Binary files /dev/null and b/screenshot/permission.png differ