IMDB - add Rottentomatoes info

Adds info from Rottentomatoes to IMDB title pages

  1. // ==UserScript==
  2. // @name IMDB - add Rottentomatoes info
  3. // @namespace https://greasyfork.org/en/users/7864-curtis-gibby
  4. // @description Adds info from Rottentomatoes to IMDB title pages
  5. // @version 4.1.4
  6. // @include http://*.imdb.com/title/*/
  7. // @include http://*.imdb.com/title/*/?*
  8. // @include http://*.imdb.com/title/*/maindetails
  9. // @include http://*.imdb.com/title/*/combined
  10. // @include http://imdb.com/title/*/
  11. // @include http://imdb.com/title/*/maindetails
  12. // @include http://imdb.com/title/*/combined
  13. // @require http://code.jquery.com/jquery-1.11.0.min.js
  14. // ==/UserScript==
  15.  
  16. // ==Test Cases ==
  17. // http://www.imdb.com/title/tt1375666/ -- Inception (2010) -- RT IMDb Alias API normal (best case scenario)
  18. // http://www.imdb.com/title/tt1375666/combined -- Inception (2010) -- Old IMDb layout -- RT IMDb Alias API normal (best case scenario)
  19. // http://www.imdb.com/title/tt1187064/ -- Triangle (2009) -- Has a Tomatometer rating, but no consensus yet
  20. // http://www.imdb.com/title/tt1762308/ -- Midway to Heaven (2011) -- No Tomatometer rating and no consensus
  21. // http://www.imdb.com/title/tt1126618/ -- Morning Glory (2010) -- RT IMDb Alias API error, works through regular RT API
  22. // http://www.imdb.com/title/tt0386676/ -- The Office (TV Series 2005– ) -- TV show (shouldn't add any RT information)
  23. // http://www.imdb.com/title/tt1848620/ -- "The Office" Search Committee -- TV show episode (shouldn't add any RT information)
  24. // http://www.imdb.com/title/tt1848620/combined -- "The Office" Search Committee -- Old IMDb layout -- TV show episode (shouldn't add any RT information)
  25.  
  26. // http://www.imdb.com/title/tt1375666/ -- Inception (2010) -- certified fresh
  27. // http://www.imdb.com/title/tt1375666/ -- Inception (2010) -- upright bucket
  28. // http://www.imdb.com/title/tt0121765/ -- Star Wars: Episode II - Attack of the Clones (2002) -- fresh
  29. // http://www.imdb.com/title/tt0105643/ -- Troll 2 (1990) -- rotten
  30. // http://www.imdb.com/title/tt0105643/ -- Troll 2 (1990) -- spilled bucket
  31. // http://www.imdb.com/title/tt2543472/ -- Wonder (2017) -- *not* Wonder Woman (2017)
  32.  
  33.  
  34. // ==User-Defined Variables==
  35.  
  36. //useRottenTomatoesColors = false;
  37. useRottenTomatoesColors = true;
  38.  
  39. //showConsensus = false;
  40. showConsensus = true;
  41.  
  42. //showAverageRating = false;
  43. showAverageRating = true;
  44.  
  45. // showReviewCount = false;
  46. showReviewCount = true;
  47.  
  48. // showFreshReviewCount = false;
  49. showFreshReviewCount = true;
  50.  
  51. // showRottenReviewCount = false;
  52. showRottenReviewCount = true;
  53.  
  54. //showAudience = false;
  55. showAudience = true;
  56.  
  57. //showAudienceAverageRating = false;
  58. showAudienceAverageRating = true;
  59.  
  60. // ==/User-Defined Variables==
  61.  
  62.  
  63. var insertSelector = "div.star-box";
  64. var labelHtml = 'Rotten Tomatoes:';
  65.  
  66. if ($('table.probody').length > 0) {
  67. insertSelector = "table.probody";
  68. }
  69.  
  70. if ($('#tn15').length > 0) {
  71. insertSelector = "div.info:first";
  72. }
  73.  
  74. if ($('.plot_summary_wrapper').length > 0) {
  75. insertSelector = ".plot_summary_wrapper";
  76. }
  77.  
  78. if (useRottenTomatoesColors == true) {
  79. var stylesheet = ' \
  80. <style> \
  81. #rottenTomatoesResults { \
  82. padding: 5px; \
  83. margin-top: 5px; \
  84. clear: both; \
  85. color: #6F6A57; \
  86. border: 1px solid #dddddd; \
  87. border-radius: 10px; \
  88. -moz-box-shadow: 0px 0px 5px #ddd; \
  89. -webkit-box-shadow: 0px 0px 5px #ddd; \
  90. box-shadow: 0px 0px 5px #ddd; \
  91. background-image: -webkit-gradient( \
  92. linear, \
  93. left top, \
  94. left 25, \
  95. color-stop(0.1, rgb(255,227,125)), \
  96. color-stop(0.3, rgb(255,254,215)) \
  97. ); \
  98. background-image: -moz-linear-gradient( \
  99. center top, \
  100. rgb(255,227,125) 10%, \
  101. rgb(255,254,215) 30% \
  102. ); \
  103. } \
  104. #rottenTomatoesResults { \
  105. color: #506A16 !important; \
  106. text-decoration: none !important; \
  107. } \
  108. #rottenTomatoesResults img { \
  109. margin-right: 10px; \
  110. } \
  111. #rottenTomatoesResults div.rtIcon { \
  112. background: transparent url("https://www.rottentomatoes.com/static/images/redesign/icons-v2.png") no-repeat scroll -312px -160px; \
  113. float: left; \
  114. width: 48px; \
  115. height: 48px; \
  116. } \
  117. #rottenTomatoesResults div.rtIcon.fresh { \
  118. background-position: -192px -48px; \
  119. } \
  120. #rottenTomatoesResults div.rtIcon.certified { \
  121. background-position: -192px -96px; \
  122. } \
  123. #rottenTomatoesResults div.rtIcon.rotten { \
  124. background-position: -240px -96px; \
  125. } \
  126. #rottenTomatoesResults div.rtIcon.upright { \
  127. background-position: -240px -48px; \
  128. } \
  129. #rottenTomatoesResults div.rtIcon.spilled { \
  130. background-position: -192px 0; \
  131. } \
  132. #rottenTomatoesResults div.rtIcon.wts { \
  133. background-position: -240px 0px; \
  134. } \
  135. #rottenTomatoesResults .floater { \
  136. float:left; \
  137. padding: 0 3px; \
  138. } \
  139. #rottenTomatoesResults .rt-credits { \
  140. font-size: 11px; \
  141. } \
  142. #rottenTomatoesTomatoMeterScore, #rottenTomatoesAudience { \
  143. color: #506A16; \
  144. font-family: Arial, Helvetica, sans-serif; \
  145. font-size: 40px; \
  146. font-weight: 700; \
  147. font-style: normal; \
  148. width: 48%; \
  149. } \
  150. #rottenTomatoesTomatoMeterScore .rtIcon { \
  151. margin-right: 5px; \
  152. } \
  153. #rottenTomatoesTomatoMeterScore.noScore { \
  154. font-size: 26px; \
  155. } \
  156. #rottenTomatoesAudience { \
  157. font-size: 30px; \
  158. } \
  159. #rottenTomatoesConsensus { \
  160. clear:both; \
  161. font-size:11px; \
  162. margin-top:10px; \
  163. line-height:1.5em; \
  164. width:98%; \
  165. } \
  166. .rottenClear { \
  167. clear: both; \
  168. } \
  169. </style>';
  170.  
  171.  
  172. }
  173. else {
  174. var stylesheet = ' \
  175. <style> \
  176. #rottenTomatoesResults { \
  177. clear: both; \
  178. margin-top: 5px; \
  179. } \
  180. #rottenTomatoesResults .floater { \
  181. float:left; \
  182. padding: 0 3px; \
  183. } \
  184. #rottenTomatoesResults div.rtIcon { \
  185. background:url("http://images.rottentomatoescdn.com/images/redesign/icons-v2.png") 0 0; \
  186. float: left; \
  187. width: 32px; \
  188. height: 32px; \
  189. } \
  190. #rottenTomatoesResults div.rtIcon.fresh { \
  191. background-position: 249px 48px; \
  192. } \
  193. #rottenTomatoesResults div.rtIcon.certified { \
  194. background-position: 152px 48px; \
  195. } \
  196. #rottenTomatoesResults div.rtIcon.rotten { \
  197. background-position: 217px 48px; \
  198. } \
  199. #rottenTomatoesResults div.rtIcon.upright { \
  200. background-position: 24px 152px; \
  201. width: 24px; \
  202. height: 24px; \
  203. } \
  204. #rottenTomatoesResults div.rtIcon.spilled { \
  205. background-position: 24px 56px; \
  206. width: 24px; \
  207. height: 24px; \
  208. } \
  209. #rottenTomatoesResults div.rtIcon.wts { \
  210. background-position: 24px 176px; \
  211. width: 24px; \
  212. height: 24px; \
  213. } \
  214. #rottenTomatoesConsensus { \
  215. width:80%; \
  216. } \
  217. .rottenClear { \
  218. clear: both; \
  219. } \
  220. </style>';
  221. }
  222. $('head').append(stylesheet);
  223.  
  224. var spinnerGif = $('<img></img>').
  225. attr('alt', "...").
  226. attr('src', 'data:image/gif;base64,'+
  227. 'R0lGODlhEAAQAPYAAP///wAAANTU1JSUlGBgYEBAQERERG5ubqKiotzc3KSkpCQkJCgoKDAwMDY2'+
  228. 'Nj4+Pmpqarq6uhwcHHJycuzs7O7u7sLCwoqKilBQUF5eXr6+vtDQ0Do6OhYWFoyMjKqqqlxcXHx8'+
  229. 'fOLi4oaGhg4ODmhoaJycnGZmZra2tkZGRgoKCrCwsJaWlhgYGAYGBujo6PT09Hh4eISEhPb29oKC'+
  230. 'gqioqPr6+vz8/MDAwMrKyvj4+NbW1q6urvDw8NLS0uTk5N7e3s7OzsbGxry8vODg4NjY2PLy8tra'+
  231. '2np6erS0tLKyskxMTFJSUlpaWmJiYkJCQjw8PMTExHZ2djIyMurq6ioqKo6OjlhYWCwsLB4eHqCg'+
  232. 'oE5OThISEoiIiGRkZDQ0NMjIyMzMzObm5ri4uH5+fpKSkp6enlZWVpCQkEpKSkhISCIiIqamphAQ'+
  233. 'EAwMDKysrAQEBJqamiYmJhQUFDg4OHR0dC4uLggICHBwcCAgIFRUVGxsbICAgAAAAAAAAAAAACH/'+
  234. 'C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwA'+
  235. 'AAAAEAAQAAAHjYAAgoOEhYUbIykthoUIHCQqLoI2OjeFCgsdJSsvgjcwPTaDAgYSHoY2FBSWAAML'+
  236. 'E4wAPT89ggQMEbEzQD+CBQ0UsQA7RYIGDhWxN0E+ggcPFrEUQjuCCAYXsT5DRIIJEBgfhjsrFkaD'+
  237. 'ERkgJhswMwk4CDzdhBohJwcxNB4sPAmMIlCwkOGhRo5gwhIGAgAh+QQJCgAAACwAAAAAEAAQAAAH'+
  238. 'jIAAgoOEhYU7A1dYDFtdG4YAPBhVC1ktXCRfJoVKT1NIERRUSl4qXIRHBFCbhTKFCgYjkII3g0hL'+
  239. 'UbMAOjaCBEw9ukZGgidNxLMUFYIXTkGzOmLLAEkQCLNUQMEAPxdSGoYvAkS9gjkyNEkJOjovRWAb'+
  240. '04NBJlYsWh9KQ2FUkFQ5SWqsEJIAhq6DAAIBACH5BAkKAAAALAAAAAAQABAAAAeJgACCg4SFhQkK'+
  241. 'E2kGXiwChgBDB0sGDw4NDGpshTheZ2hRFRVDUmsMCIMiZE48hmgtUBuCYxBmkAAQbV2CLBM+t0pu'+
  242. 'aoIySDC3VC4tgh40M7eFNRdH0IRgZUO3NjqDFB9mv4U6Pc+DRzUfQVQ3NzAULxU2hUBDKENCQTtA'+
  243. 'L9yGRgkbcvggEq9atUAAIfkECQoAAAAsAAAAABAAEAAAB4+AAIKDhIWFPygeEE4hbEeGADkXBycZ'+
  244. 'Z1tqTkqFQSNIbBtGPUJdD088g1QmMjiGZl9MO4I5ViiQAEgMA4JKLAm3EWtXgmxmOrcUElWCb2zH'+
  245. 'kFQdcoIWPGK3Sm1LgkcoPrdOKiOCRmA4IpBwDUGDL2A5IjCCN/QAcYUURQIJIlQ9MzZu6aAgRgwF'+
  246. 'GAFvKRwUCAAh+QQJCgAAACwAAAAAEAAQAAAHjIAAgoOEhYUUYW9lHiYRP4YACStxZRc0SBMyFoVE'+
  247. 'PAoWQDMzAgolEBqDRjg8O4ZKIBNAgkBjG5AAZVtsgj44VLdCanWCYUI3txUPS7xBx5AVDgazAjC3'+
  248. 'Q3ZeghUJv5B1cgOCNmI/1YUeWSkCgzNUFDODKydzCwqFNkYwOoIubnQIt244MzDC1q2DggIBACH5'+
  249. 'BAkKAAAALAAAAAAQABAAAAeJgACCg4SFhTBAOSgrEUEUhgBUQThjSh8IcQo+hRUbYEdUNjoiGlZW'+
  250. 'QYM2QD4vhkI0ZWKCPQmtkG9SEYJURDOQAD4HaLuyv0ZeB4IVj8ZNJ4IwRje/QkxkgjYz05BdamyD'+
  251. 'N9uFJg9OR4YEK1RUYzFTT0qGdnduXC1Zchg8kEEjaQsMzpTZ8avgoEAAIfkECQoAAAAsAAAAABAA'+
  252. 'EAAAB4iAAIKDhIWFNz0/Oz47IjCGADpURAkCQUI4USKFNhUvFTMANxU7KElAhDA9OoZHH0oVgjcz'+
  253. 'rJBRZkGyNpCCRCw8vIUzHmXBhDM0HoIGLsCQAjEmgjIqXrxaBxGCGw5cF4Y8TnybglprLXhjFBUW'+
  254. 'VnpeOIUIT3lydg4PantDz2UZDwYOIEhgzFggACH5BAkKAAAALAAAAAAQABAAAAeLgACCg4SFhjc6'+
  255. 'RhUVRjaGgzYzRhRiREQ9hSaGOhRFOxSDQQ0uj1RBPjOCIypOjwAJFkSCSyQrrhRDOYILXFSuNkpj'+
  256. 'ggwtvo86H7YAZ1korkRaEYJlC3WuESxBggJLWHGGFhcIxgBvUHQyUT1GQWwhFxuFKyBPakxNXgce'+
  257. 'YY9HCDEZTlxA8cOVwUGBAAA7AAAAAAAAAAAA'
  258. );
  259. // try to avoid running on TV series pages
  260. if (document.title.indexOf('TV Series') < 0
  261. && document.title.indexOf('TV mini-series') < 0
  262. && $("#pagecontent").html().indexOf('<h2 class="tv_header">') < 0
  263. && $("#pagecontent").html().indexOf("<h5>TV Series:</h5>") < 0
  264. ) {
  265. getRTInfo();
  266. }
  267.  
  268. function getRTInfo() {
  269. var rottenTomatoesResults = $('<div/>').
  270. attr('id', "rottenTomatoesResults").
  271. html("Checking Rotten Tomatoes... ").
  272. append(spinnerGif);
  273. $(insertSelector).append(rottenTomatoesResults);
  274.  
  275. year = parseInt($('#titleYear').text().match(/[0-9]+/g)[0]);
  276. actorName = $('.plot_summary span[itemprop="actors"] span:first').text();
  277. var apiUrl = 'https://cinesift.com/api/values/getFilms?cast=' + actorName + '&comboScoreMax=100&comboScoreMin=0&countryCode=us&currentPage=0&director=&genreAND=false&imdbRatingMax=10&imdbRatingMin=0&imdbVotesMax=1600000&imdbVotesMin=0&inCinemas=true&includeDismissed=true&includeSeen=true&includeWantToWatch=true&isCastSearch=false&isDirectorSearch=false&language=all&letterboxdScoreMax=100&letterboxdScoreMin=0&letterboxdVotesMax=1400000&letterboxdVotesMin=0&metacriticMax=100&metacriticMin=0&netflixRegion=us&onAmazonPrime=false&onAmazonVideo=false&onDVD=false&onNetflix=false&plot=&popularityMax=100&popularityMin=0&queryType=GetFilmsToSieve&rtCriticFreshMax=300&rtCriticFreshMin=0&rtCriticMeterMax=100&rtCriticMeterMin=0&rtCriticRatingMax=10&rtCriticRatingMin=0&rtCriticReviewsMax=400&rtCriticReviewsMin=0&rtCriticRottenMax=200&rtCriticRottenMin=0&rtUserMeterMax=100&rtUserMeterMin=0&rtUserRatingMax=5&rtUserRatingMin=0&rtUserReviewsMax=40000000&rtUserReviewsMin=0&searchTerm=&sortOrder=comboScoreDesc&title=' + $('#star-rating-widget').data('title') + '&token=&watchedRating=0&writer=&yearMax=' + (year + 1) + '&yearMin=' + (year - 1);
  278. $.ajax({
  279. url: apiUrl
  280. }).done(function(data) {
  281. data = JSON.parse(data);
  282. parseValidResponse(data);
  283. }).error(function(err) {
  284. $('#rottenTomatoesResults').html('Error getting results from Cinesift.');
  285. });
  286. } // end function getRTInfo
  287.  
  288. function parseValidResponse(response) {
  289. if (response.length == 0) {
  290. $('#rottenTomatoesResults').html('No results from Cinesift.');
  291. return false;
  292. }
  293.  
  294. var movie = response[0];
  295. var tomatoUrl = 'https://duckduckgo.com/?q=site%3Arottentomatoes.com+' + encodeURIComponent($('#star-rating-widget').data('title')) + '+' + year + '+!&t=hg';
  296.  
  297. var rottenResults = $('#rottenTomatoesResults');
  298. // add tomato-meter score and icon
  299. var tomatoMeterScoreImage = '';
  300. if (movie.RTCriticMeter == 'N/A') {
  301. tomatoMeterScoreText = 'No Score Yet...';
  302. tomatoMeterScoreClass = ' noScore';
  303. } else {
  304. tomatoMeterScoreClass = '';
  305. tomatoMeterScoreText = movie.RTCriticMeter + '%';
  306.  
  307. var tomatoImage = 'rotten';
  308. if (movie.RTCriticMeter > 60) {
  309. tomatoImage = 'fresh';
  310. }
  311.  
  312. if (movie.RTCriticMeter > 75) {
  313. tomatoImage = 'certified';
  314. }
  315.  
  316. tomatoMeterScoreImage = $('<div/>').
  317. attr('class', 'rtIcon ' + tomatoImage).
  318. attr('title', tomatoImage + ' - ' + tomatoMeterScoreText);
  319. }
  320.  
  321. var tomatoMeterScore = $('<span/>').
  322. attr('id', 'rottenTomatoesTomatoMeterScore').
  323. text(tomatoMeterScoreText);
  324.  
  325. var tomatoMeter = $('<a/>').
  326. attr('href', tomatoUrl).
  327. attr('id', 'rottenTomatoesTomatoMeterScore').
  328. addClass('floater' + tomatoMeterScoreClass).
  329. html('<p class="rt-credits">Rotten Tomatoes® Score</p>') .
  330. append(tomatoMeterScoreImage) .
  331. append(tomatoMeterScoreText);
  332.  
  333. rottenResults.html(tomatoMeter);
  334.  
  335. if (showAudience) {
  336. var audienceRatingImageClass = 'spilled';
  337. var audienceRatingText = 'Spilled';
  338. var audienceRatingLabel = 'Liked It';
  339. var audienceRatingText = '';
  340.  
  341. if (movie.RTUserMeter == 'N/A') {
  342. audienceRatingImageClass = 'wts';
  343. audienceRatingText = 'No Audience Rating Yet';
  344. audienceRatingLabel = 'Want To See It';
  345. } else {
  346. audienceRatingText = movie.RTUserMeter + '%';
  347.  
  348. var userRating = parseInt(movie.RTUserMeter);
  349. if (userRating >= 60) {
  350. audienceRatingImageClass = 'upright';
  351. };
  352. }
  353. audienceScoreImage = $('<div/>').
  354. attr('class', 'rtIcon ' + audienceRatingImageClass).
  355. attr('title', audienceRatingLabel);
  356.  
  357. rottenResults.append(
  358. $('<a/>').
  359. attr('href', tomatoUrl).
  360. attr('id', 'rottenTomatoesAudience').
  361. addClass('floater').
  362. html('<p class="rt-credits">Audience</p>') .
  363. append(audienceScoreImage).
  364. append(audienceRatingText)
  365. );
  366. }
  367.  
  368. if (showAverageRating) {
  369. averageRating = movie.RTCriticRating + '/10';
  370. if (movie.RTCriticRating == null) {
  371. averageRating = 'n/a';
  372. };
  373. rottenResults.append(
  374. $('<p/>').
  375. attr('id', 'rottenTomatoesAverage').
  376. addClass('rottenClear').
  377. html('<b>Critics Average</b> : ' + averageRating)
  378. );
  379. }
  380. if (showAudienceAverageRating) {
  381. averageAudienceRating = movie.RTUserRating + '/5';
  382. if (movie.RTUserRating == null) {
  383. averageAudienceRating = 'n/a';
  384. };
  385. rottenResults.append(
  386. $('<div/>').
  387. attr('id', 'rottenTomatoesAudienceAverage').
  388. addClass('rottenClear').
  389. html('<b>Audience Average</b> : ' + averageAudienceRating)
  390. );
  391. }
  392. if (showReviewCount) {
  393. reviewText = '<b>Reviews</b> : ' + movie.RTCriticReviews;
  394. if (showFreshReviewCount || showRottenReviewCount) {
  395. reviewText = reviewText + ' (';
  396. if (showFreshReviewCount) {
  397. reviewText = reviewText + movie.RTCriticFresh + '&nbsp;Fresh';
  398. }
  399. if (showRottenReviewCount) {
  400. if (showFreshReviewCount) {
  401. reviewText = reviewText + ', ';
  402. }
  403. reviewText = reviewText + movie.RTCriticRotten + '&nbsp;Rotten';
  404. }
  405. reviewText = reviewText + ')';
  406. }
  407.  
  408. rottenResults.append(
  409. $('<p/>').
  410. attr('id', 'rottenTomatoesReviewCount').
  411. html(reviewText)
  412. );
  413. }
  414. if (showConsensus) {
  415. rottenResults.append(
  416. $('<div/>').
  417. attr('id', 'rottenTomatoesConsensus').
  418. addClass('rottenClear').
  419. html('<b>Consensus</b> : ' + movie.RTConsensus)
  420. );
  421. }
  422. rottenResults.append(
  423. $('<div/>').
  424. addClass("rottenClear").
  425. html("&nbsp;")
  426. );
  427. }