AMC Movies IMDB Rating Display

Displays IMDB ratings next to movie titles on AMC Theatres website

Size

7.4 KB

Version

1.1.2

Created

Dec 30, 2025

Updated

about 1 month ago

1// ==UserScript==
2// @name		AMC Movies IMDB Rating Display
3// @description		Displays IMDB ratings next to movie titles on AMC Theatres website
4// @version		1.1.2
5// @match		https://*.amctheatres.com/*
6// @icon		https://www.amctheatres.com/favicon.ico
7// @grant		GM.xmlhttpRequest
8// @grant		GM.getValue
9// @grant		GM.setValue
10// @connect		www.omdbapi.com
11// ==/UserScript==
12(function() {
13    'use strict';
14
15    // OMDb API key (free tier - 1000 requests per day)
16    const OMDB_API_KEY = '4e3ee3be'; // Public demo key
17    const OMDB_API_URL = 'https://www.omdbapi.com/';
18
19    // Cache to store ratings and avoid duplicate API calls
20    const ratingsCache = {};
21
22    console.log('AMC IMDB Rating Extension loaded');
23
24    // Function to fetch IMDB rating from OMDb API
25    async function fetchIMDBRating(movieTitle) {
26        // Check memory cache first
27        if (ratingsCache[movieTitle]) {
28            console.log(`Using memory cache for: ${movieTitle}`);
29            return ratingsCache[movieTitle];
30        }
31
32        // Check persistent storage cache
33        const cacheKey = `imdb_rating_${movieTitle}`;
34        const cachedRating = await GM.getValue(cacheKey, null);
35        
36        if (cachedRating !== null) {
37            console.log(`Using stored cache for: ${movieTitle}`);
38            const rating = JSON.parse(cachedRating);
39            ratingsCache[movieTitle] = rating;
40            return rating;
41        }
42
43        return new Promise((resolve) => {
44            console.log(`Fetching IMDB rating for: ${movieTitle}`);
45            
46            GM.xmlhttpRequest({
47                method: 'GET',
48                url: `${OMDB_API_URL}?apikey=${OMDB_API_KEY}&t=${encodeURIComponent(movieTitle)}&type=movie`,
49                onload: function(response) {
50                    try {
51                        console.log(`Response status for ${movieTitle}:`, response.status);
52                        console.log(`Response text for ${movieTitle}:`, response.responseText);
53                        
54                        const data = JSON.parse(response.responseText);
55                        console.log(`Data for ${movieTitle}:`, data);
56
57                        if (data.Response === 'True' && data.imdbRating && data.imdbRating !== 'N/A') {
58                            const rating = {
59                                imdbRating: data.imdbRating,
60                                imdbVotes: data.imdbVotes
61                            };
62                            ratingsCache[movieTitle] = rating;
63                            // Store in persistent cache
64                            GM.setValue(cacheKey, JSON.stringify(rating));
65                            console.log(`Found rating for ${movieTitle}: ${rating.imdbRating}`);
66                            resolve(rating);
67                        } else {
68                            console.log(`No rating found for: ${movieTitle}`);
69                            ratingsCache[movieTitle] = null;
70                            // Store null result to avoid repeated failed lookups
71                            GM.setValue(cacheKey, JSON.stringify(null));
72                            resolve(null);
73                        }
74                    } catch (error) {
75                        console.error(`Error parsing response for ${movieTitle}:`, error);
76                        resolve(null);
77                    }
78                },
79                onerror: function(error) {
80                    console.error(`Network error for ${movieTitle}:`, error);
81                    resolve(null);
82                },
83                ontimeout: function() {
84                    console.error(`Timeout for ${movieTitle}`);
85                    resolve(null);
86                }
87            });
88        });
89    }
90
91    // Function to create and insert rating badge
92    function createRatingBadge(rating, votes) {
93        const badge = document.createElement('span');
94        badge.className = 'imdb-rating-badge';
95        badge.style.cssText = `
96            display: inline-flex;
97            align-items: center;
98            gap: 4px;
99            background: #f5c518;
100            color: #000;
101            padding: 4px 8px;
102            border-radius: 4px;
103            font-weight: bold;
104            font-size: 14px;
105            margin-left: 8px;
106            vertical-align: middle;
107        `;
108        
109        // Create star icon
110        const star = document.createElement('span');
111        star.textContent = '⭐';
112        star.style.fontSize = '12px';
113        
114        // Create rating text
115        const ratingText = document.createElement('span');
116        ratingText.textContent = rating;
117        
118        badge.appendChild(star);
119        badge.appendChild(ratingText);
120        
121        // Add tooltip with vote count
122        if (votes) {
123            badge.title = `IMDB Rating: ${rating}/10 (${votes} votes)`;
124        } else {
125            badge.title = `IMDB Rating: ${rating}/10`;
126        }
127        
128        return badge;
129    }
130
131    // Function to add ratings to movie titles
132    async function addRatingsToMovies() {
133        console.log('Searching for movie titles...');
134        
135        // Find all movie title links
136        const movieLinks = document.querySelectorAll('a.headline.text-500[aria-label*="details"]');
137        console.log(`Found ${movieLinks.length} movie titles`);
138
139        for (const link of movieLinks) {
140            // Skip if already processed
141            if (link.dataset.imdbProcessed === 'true') {
142                continue;
143            }
144
145            const movieTitle = link.textContent.trim();
146            console.log(`Processing: ${movieTitle}`);
147
148            // Mark as processed
149            link.dataset.imdbProcessed = 'true';
150
151            // Fetch rating
152            const ratingData = await fetchIMDBRating(movieTitle);
153
154            if (ratingData && ratingData.imdbRating) {
155                // Create and insert rating badge
156                const badge = createRatingBadge(ratingData.imdbRating, ratingData.imdbVotes);
157                link.appendChild(badge);
158                console.log(`Added rating badge for: ${movieTitle}`);
159            }
160
161            // Small delay to avoid overwhelming the API
162            await new Promise(resolve => setTimeout(resolve, 300));
163        }
164
165        console.log('Finished processing all movies');
166    }
167
168    // Debounce function to avoid excessive calls
169    function debounce(func, wait) {
170        let timeout;
171        return function executedFunction(...args) {
172            const later = () => {
173                clearTimeout(timeout);
174                func(...args);
175            };
176            clearTimeout(timeout);
177            timeout = setTimeout(later, wait);
178        };
179    }
180
181    // Initialize when page is ready
182    function init() {
183        console.log('Initializing AMC IMDB Rating Extension...');
184        
185        // Wait for page to be fully loaded
186        if (document.readyState === 'loading') {
187            document.addEventListener('DOMContentLoaded', () => {
188                setTimeout(addRatingsToMovies, 1000);
189            });
190        } else {
191            setTimeout(addRatingsToMovies, 1000);
192        }
193
194        // Watch for dynamic content changes (infinite scroll, filters, etc.)
195        const debouncedAddRatings = debounce(addRatingsToMovies, 1000);
196        const observer = new MutationObserver(debouncedAddRatings);
197        
198        observer.observe(document.body, {
199            childList: true,
200            subtree: true
201        });
202
203        console.log('Observer set up for dynamic content');
204    }
205
206    // Start the extension
207    init();
208})();
AMC Movies IMDB Rating Display | Robomonkey