From 288881ab4befd4f7cd9392ddb650b9b5fee239da Mon Sep 17 00:00:00 2001 From: Rodolphe Geiler <6977414+RodolpheGeiler@users.noreply.github.com> Date: Mon, 19 Feb 2024 19:03:36 +0100 Subject: [PATCH] Add senscritique support (#44) * feat: add support for senscritique website * docs: add senscritique to supported site list * Add mediaType update on page location change * Remove version upgrade from PR --------- Co-authored-by: RemiRigal --- README.md | 1 + background.js | 15 +++++ js/content-scripts/senscritique.js | 96 ++++++++++++++++++++++++++++++ manifest.json | 4 ++ 4 files changed, 116 insertions(+) create mode 100644 js/content-scripts/senscritique.js diff --git a/README.md b/README.md index 2704113..587a77f 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Supported media websites: - [Trakt.tv](https://trakt.tv/) - [Taste.io](https://www.taste.io/) - [Allociné](https://www.allocine.fr/) +- [Senscritique](https://www.senscritique.com/) ## Install diff --git a/background.js b/background.js index 8a73cce..14f157a 100644 --- a/background.js +++ b/background.js @@ -91,5 +91,20 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { chrome.runtime.openOptionsPage(); return true; } + + else if (request.contentScriptQuery === 'listenForUrlChange') { + chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { + if ( + changeInfo.status === 'complete' && + tab.status === 'complete' && + tab.url && + tab.url.startsWith('https://www.senscritique.com') + ) { + chrome.tabs.sendMessage(tab.id, { + newUrl: tab.url + }); + } + }); + } return false; }); diff --git a/js/content-scripts/senscritique.js b/js/content-scripts/senscritique.js new file mode 100644 index 0000000..18214d5 --- /dev/null +++ b/js/content-scripts/senscritique.js @@ -0,0 +1,96 @@ +let overseerrContainer, senscritiqueId, currentSenscritiqueUrl, tmdbId, mediaType, mediaInfo; + +containerOptions.anchorElement = 'div[data-testid="product-infos"]'; +containerOptions.textClass = 'text-sm'; +containerOptions.containerClass = 'oa-mt-2 oa-py-2'; +containerOptions.plexButtonClass = 'oa-bg-gray-800'; +containerOptions.badgeBackground = '#032541'; + +mediaType = document.location.pathname.startsWith('/film') ? 'movie' : 'tv'; +const senscritiqueRegex = /\/(?:film|serie)\/\w*\/(\d+)/; + +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.newUrl && message.newUrl !== currentSenscritiqueUrl) { + currentSenscritiqueUrl = message.newUrl; + setTimeout(() => { + checkForMedia(message.newUrl); + }, 500); + } +}); + +chrome.runtime.sendMessage({contentScriptQuery: 'listenForUrlChange'}); + +const checkForMedia = async (urlToCheck) => { + let matches = urlToCheck.match(senscritiqueRegex); + if (matches !== null && matches.length > 1) { + mediaType = document.location.pathname.startsWith('/film') ? 'movie' : 'tv'; + + const titleElement = document.querySelector('h1'); + let title = titleElement.textContent; + let releaseYear = extractYear(document.querySelector('p[data-testid="creators"]').textContent); + let displayedYear = parseInt(titleElement.nextElementSibling.querySelector('p:not([opacity])').textContent); + + initializeContainer(); + insertSpinner(); + + pullStoredData(async function () { + if (!userId) { + removeSpinner(); + insertNotLoggedInButton(); + return; + } + + try { + let json = await sendMessageToBackground({contentScriptQuery: 'search', title: title}); + json.results = filterResults(json.results, releaseYear, displayedYear); + if (json.results.length === 0) { + removeSpinner(); + insertStatusButton('Media not found', 0); + return; + } + const firstResult = json.results[0]; + json = await sendMessageToBackground({contentScriptQuery: 'queryMedia', tmdbId: firstResult.id, mediaType: mediaType}); + mediaInfo = json; + tmdbId = json.id; + console.log(`TMDB id: ${tmdbId}`); + removeSpinner(); + fillContainer(json.mediaInfo); + } catch (error) { + console.error(error); + } + }); + } +} + +const extractYear = (creatorInformationsString) => { + let parts = creatorInformationsString.split('·'); + if (parts.length >= 3) { + let yearPart = parts[2].trim(); + let regex = /\b(\d{4})\b/; + let match = yearPart.match(regex); + if (match) { + let year = match[1]; + return parseInt(year); + } + } + return false; +} + +const sendMessageToBackground = (message) => { + return new Promise((resolve, reject) => { + chrome.runtime.sendMessage(message, (response) => { + if (chrome.runtime.lastError) { + reject(chrome.runtime.lastError); + } else { + resolve(response); + } + }); + }); +} + +const filterResults = (results, releaseYear, displayedYear) => { + return results.filter((result) => { + return result.mediaType === mediaType && + (!releaseYear || (result.releaseDate && [releaseYear, displayedYear].includes(parseInt(result.releaseDate.slice(0, 4))))); + }); +} \ No newline at end of file diff --git a/manifest.json b/manifest.json index 1ea1c7c..1489574 100644 --- a/manifest.json +++ b/manifest.json @@ -31,6 +31,10 @@ "matches": ["https://www.allocine.fr/film/*", "https://www.allocine.fr/series/*"], "css": ["css/style.css"], "js": ["js/lib/jquery-3.5.1.min.js", "js/storage.js", "js/overseerr-container.js", "js/content-scripts/allocine.js"] + }, { + "matches": ["https://www.senscritique.com/*"], + "css": ["css/style.css"], + "js": ["js/lib/jquery-3.5.1.min.js", "js/storage.js", "js/overseerr-container.js", "js/content-scripts/senscritique.js"] },{ "matches": ["https://thetvdb.com/movies/*", "https://thetvdb.com/series/*"], "css": ["css/style.css"],