Mrrrr
AdMiN
 Inregistrat: acum 19 ani
Postari: 2374
|
|
I needed a way to easily copy some data for movies or series from iMDB. I'm making a list of things to watch and would like to have some info locally. I know there are programs doing this already (such as EMDB for example and surely others), but I want my own script doing only the things I need.
The following Tampermonkey script provides buttons to do several things: - saves the top 3 actors in the "Stars" section to a text file with their names as file name - saves the rating as a text file with the rating as name, and the rating inside the file as well - saves the imdb link as .url internet shortcut - copies the genres to clipboard - searches for the name of the movie on a desired website, e.g. TMDB
When loading an IMDB page of a movie, the buttons corresponding to the above options appear in the bottom right of the page. If clicked, they do the actions above. The files get saved in the default Chrome download directory.
// ==UserScript== // @name IMDb Multi-Tool (copy some imdb metadata) // @namespace http://tampermonkey.net/ // @version 2.1 // @description Save info about top 3 actors, main genres, rating and url // @match https://www.imdb.com/title/tt* // @grant GM_setClipboard // @grant GM_download // @grant GM_xmlhttpRequest // ==/UserScript==
(function() { 'use strict';
// Helper: Utility to parse JSON-LD metadata safely function getImdbMetadata() { const jsonLdScript = document.querySelector('script[type="application/ld+json"]'); if (jsonLdScript) { try { return JSON.parse(jsonLdScript.textContent); } catch (err) { console.warn('JSON-LD parse failed', err); } } return null; }
// 1. Create a container for all buttons (Bottom Right) const buttonContainer = document.createElement('div'); buttonContainer.style.cssText = ` position: fixed; bottom: 20px; right: 20px; z-index: 99999; display: flex; flex-direction: column; gap: 10px; align-items: flex-end; font-family: sans-serif; `; document.body.appendChild(buttonContainer);
// 2. Button factory function createButton(text, color, clickHandler) { const btn = document.createElement('button'); btn.innerText = text; btn.style.cssText = ` padding: 10px 16px; background-color: ${color}; color: #000000; font-weight: bold; border: none; border-radius: 18px; box-shadow: 0 4px 10px rgba(0,0,0,0.3); cursor: pointer; font-size: 13px; transition: all 0.2s ease; white-space: nowrap; `; btn.addEventListener('click', () => clickHandler(btn)); buttonContainer.appendChild(btn); return btn; }
// Temporary button visual feedback function showSuccess(btn, message) { const origText = btn.innerText; const origBg = btn.style.backgroundColor; const origColor = btn.style.color;
btn.innerText = message; btn.style.backgroundColor = '#4CAF50'; btn.style.color = '#FFFFFF';
setTimeout(() => { btn.innerText = origText; btn.style.backgroundColor = origBg; btn.style.color = origColor; }, 2500); }
// --- BUTTON 1: Save Top 3 actors.txt --- createButton('📋 Save Top 3 Actors.txt', '#f5c518', (btn) => { let actors = []; const metadata = getImdbMetadata();
if (metadata && metadata.actor && Array.isArray(metadata.actor)) { actors = metadata.actor .filter(item => item['@type'] === 'Person' && item.name) .map(item => item.name.trim()); } else { const castEls = document.querySelectorAll('[data-testid="title-cast-item__actor"]'); castEls.forEach(el => actors.push(el.innerText.trim())); }
const top3 = actors.slice(0, 3); if (top3.length === 0) { alert('No actors found on page.'); return; }
const result = top3.join(', ');
// The following 2 lines to copy the names of the actors to clipboard: /* GM_setClipboard(result); showSuccess(btn, `✓ Copied: ${result}`); */
// Save file with actor names START ----> // Download the file to default download directory const fileName = `${result}.txt`; const blob = new Blob([' '], { type: 'text/plain;charset=utf-8' }); // this is what goes inside the text file const blobUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = blobUrl; a.download = fileName; document.body.appendChild(a); a.click();
// Cleanup document.body.removeChild(a); setTimeout(() => URL.revokeObjectURL(blobUrl), 100);
showSuccess(btn, `✓ Saved: ${fileName}`); // Save file with actor names END <----
});
// --- BUTTON 2: Save IMDb Rating --- createButton('⭐ Save iMDb rating.txt', '#f5c518', (btn) => { let rawRating = null; const metadata = getImdbMetadata();
if (metadata && metadata.aggregateRating && metadata.aggregateRating.ratingValue) { rawRating = metadata.aggregateRating.ratingValue; } else { // Fallback DOM selector const ratingEl = document.querySelector('[data-testid="hero-rating-bar__aggregate-rating__score"] span'); if (ratingEl) rawRating = ratingEl.innerText.trim(); }
if (!rawRating) { alert('Could not find IMDb rating on this page.'); return; }
// Format decimal dot into a comma (e.g., 5.7 -> 5,7) let formattedRating = String(rawRating).replace('.', ',');
// If rating is a single digit (e.g., "7"), append ",0" if (/^\d+$/.test(formattedRating)) { formattedRating += ',0'; }
const fileName = `iMDB = ${formattedRating}.txt`;
// Download the file to default download directory const blob = new Blob([formattedRating], { type: 'text/plain;charset=utf-8' }); const blobUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = blobUrl; a.download = fileName; // Forces the specific "iMDB = RATING_HERE.txt" filename document.body.appendChild(a); a.click();
// Cleanup document.body.removeChild(a); setTimeout(() => URL.revokeObjectURL(blobUrl), 100);
showSuccess(btn, `✓ Saved: ${fileName}`);
});
/* FOR THIS TO WORK WITHOUT RESULTING IN BLOCKED FILES (requiring right click -> properties -> unblock) Disable "Mark of the Web" in Windows Option 1 - gpedit.msc - User Configuration > Administrative Templates > Windows Components > Attachment Manager - Double-click Do not preserve zone information in file attachments. - Set it to Enabled and click OK. Option 2 - cmd/powershell command (as admin) - reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Attachments" /v SaveZoneInformation /t REG_DWORD /d 1 /f - Restart Windows */ // --- BUTTON 3: Save IMDb URL Shortcut --- createButton('🔗 Save iMDb link as url file', '#f5c518', (btn) => { // 1. Extract the 'tt' ID from the current page URL const match = window.location.href.match(/tt\d+/);
if (!match) { alert('Could not find IMDb title ID in URL.'); return; }
const titleId = match[0]; // e.g. "tt0104257" const cleanUrl = `https://www.imdb.com/title/${titleId}/`; // Trims everything after the ID const fileName = `${titleId}.url`;
// 2. Format as a standard Windows Internet Shortcut file content const fileContent = `[InternetShortcut]\r\nURL=${cleanUrl}\r\n`;
// 3. Trigger Download const blob = new Blob([fileContent], { type: 'application/x-mswinurl' }); const blobUrl = URL.createObjectURL(blob);
const a = document.createElement('a'); a.href = blobUrl; a.download = fileName; // Saves as tt0104257.url document.body.appendChild(a); a.click();
// Cleanup document.body.removeChild(a); setTimeout(() => URL.revokeObjectURL(blobUrl), 100);
showSuccess(btn, `✓ Saved: ${fileName}`); });
// --- BUTTON 4: Copy Genres --- createButton('🎭 Copy Genres to clipboard', '#f5c518', (btn) => {
let genres = [];
// 1. Try Next.js internal data script (contains full "genres" list) const nextDataScript = document.querySelector('script[id="__NEXT_DATA__"]'); if (nextDataScript) { try { const text = nextDataScript.textContent;
// Match the full "genres":{"genres":[{...}]} object const genreMatch = text.match(/"genres"\s*:\s*\{\s*"genres"\s*:\s*(\[\s*\{.*?\}\s*\])/); if (genreMatch && genreMatch[1]) { const parsedGenres = JSON.parse(genreMatch[1]); genres = parsedGenres.map(g => g.text).filter(Boolean); } } catch (err) { console.warn('Failed to parse __NEXT_DATA__ genres', err); } }
// 2. Fallback: Check standard JSON-LD if (genres.length === 0) { const metadata = getImdbMetadata(); if (metadata && metadata.genre) { genres = Array.isArray(metadata.genre) ? metadata.genre : [metadata.genre]; } }
// 3. Fallback: DOM Search if (genres.length === 0) { const genreEls = document.querySelectorAll('a[href*="/search/title/?genres="], a[href*="/genre/"]'); genreEls.forEach(el => { const txt = el.innerText.trim(); if (txt && !genres.includes(txt)) genres.push(txt); }); }
if (genres.length === 0) { alert('No genres found on page.'); return; }
const result = genres.join(', '); GM_setClipboard(result); showSuccess(btn, `✓ Copied: ${result}`); });
// --- BUTTON: Search TMDB --- createButton('🔍 Search TMDB', '#f5c518', (btn) => { let movieTitle = '';
// 1. Try getting clean title from JSON-LD metadata const metadata = getImdbMetadata(); if (metadata && metadata.name) { movieTitle = metadata.name; }
// 2. Fallback to h1 title if metadata wasn't available if (!movieTitle) { const titleEl = document.querySelector('h1[data-testid="hero__pageTitle"] span, h1'); if (titleEl) { movieTitle = titleEl.innerText.trim(); } }
if (!movieTitle) { alert('Could not find movie title on this page.'); return; }
// 3. Format title: replace spaces with "+" and trim extra whitespace const formattedTitle = movieTitle.trim().replace(/\s+/g, '+');
// 4. Construct target URL const targetUrl = `https://www.themoviedb.org/search?query=${formattedTitle}`;
// 5. Open in a new tab window.open(targetUrl, '_blank');
showSuccess(btn, '✓ Opening Search...'); }); })(); |
Source: Gemini
_______________________________________

|
|