ČSFD Extended

Rozšíření profilů filmů na ČSFD.

当前为 2016-02-03 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name ČSFD Extended
  3. // @namespace CSFD-E
  4. // @version 0.2.1
  5. // @description Rozšíření profilů filmů na ČSFD.
  6. // @author Jakub Rychecký <jakub@rychecky.cz>
  7. // @include *csfd.cz/film/*
  8. // ==/UserScript==
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17. var csfd = new Csfd(); // Instance třídy pro práci s profilem filmu na ČSFD
  18. var omdb = new OmdbApi(csfd.parseCsfdImdbCode()); // Instance třídy pro práci s API OMDB a stažení informací o filmu
  19. var imdb = new Imdb(csfd.parseCsfdImdbCode()); // Instance třídy s informacemi z IMDB
  20. var metacritic = new Metacritic(); // Instance třídy s informacemi z Metacritic
  21. var tomato = new Tomato(); // Instance třídy s informacemi z RottenTomatoes
  22.  
  23. var html = new Html(); // Instance třídy pro práci s HTML a úpravou profilu filmu dle získaných dat
  24. var floating = new Floating();
  25.  
  26.  
  27. omdb.fetchOmdbData(); // Stažení dat z API OMDB
  28.  
  29. csfd.parseCsfdNameYear(); // Parsuje název filmu z profilu ČSFD.
  30. csfd.parseCsfdRating(); // Parsuje hodnocení ČSFDs
  31.  
  32. html.cssInit(); // Přidání externího CSS do stránky
  33. html.ratingTable(); // Předělání tabulky hodnocení na profilu filmu
  34. html.toolbar(); // Vytvoření tlačítek pro rychlé vyhledávání na profilu filmu
  35.  
  36. floating.init();
  37. floating.bindPoster();
  38. floating.bindCreator();
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48. /*
  49. console.log(csfd);
  50. console.log(omdb);
  51. console.log(imdb);
  52. console.log(metacritic);
  53. console.log(tomato);
  54. console.log(html);
  55. */
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64. /**
  65. * @class Csfd
  66. * @classdesc Parsuje a zpracovává základní údaje z ČSFD profilu filmu.
  67. *
  68. * @param {String} name - Originální název filmu
  69. * @param {Integer} year - Rok vzniku filmu
  70. * @param {Integer} rating - ČSFD hodnocení filmu v procentech
  71. * @param {Integer} votes - Počet hlasů na ČSFD
  72. */
  73.  
  74. function Csfd(){
  75. this.name;
  76. this.year;
  77. this.rating;
  78. this.votes;
  79. /**
  80. * Parsuje název filmu z profilu ČSFD.
  81. * @return {undefined}
  82. */
  83. this.parseCsfdNameYear = function(){
  84. var title = $('meta[property=\'og:title\']').attr('content'); // Získání popisu ČSFD profilu z metatagu Open Graph (OG) http://ogp.me/
  85. title = title.replace(/\(TV seriál\)/, ''); // Odstranění označení TV seriálů z názvu
  86. title = title.replace(/\(TV film\)/, ''); // Odstranění označení TV filmů z názvu
  87. var title_regex = title.match(/(.+)\((\d{4})\)/); // Rozdělení na název a rok v závorce
  88. this.name = title_regex[1]; // Název filmu
  89. this.name = this.name.replace(/.+\//, ''); // Získání čehokoliv před lomítkem (= originální název)
  90. this.name = $.trim(this.name); // Oříznutí mezer názvu filmu
  91. this.year = parseInt(title_regex[2]); // Rok názvu jako integer
  92. }
  93. /**
  94. * Parsuje procentuální hodnocení a počet hlasů z profilu ČSFD.
  95. * @return {undefined}
  96. */
  97. this.parseCsfdRating = function(){
  98. this.rating = $('meta[itemprop="ratingValue"]').attr('content'); // Získání procentuálního hodnocení z metatagů
  99. this.rating = parseInt(this.rating); // Hodnocení v procentech jako integer
  100. this.votes = $('meta[itemprop="ratingCount"]').attr('content'); // Získání počtu hlasů z metatagů
  101. this.votes = parseInt(this.votes); // Počet hlasů jako integer
  102. }
  103. /**
  104. * Parsuje kód filmu na IMDB z tlačítka IMDB na profilu filmu na ČSFD.
  105. * @return {String} Kód filmu na IMDB
  106. */
  107. this.parseCsfdImdbCode = function(){
  108. var imdb_url = $('a[data-ga-event="imdb-film|click|logged"]').attr('href'); // Získání odkazu z tlačítka IMDB
  109. var imdb_code = imdb_url.match(/(tt\d+)/); // Extrahování kódu filmu na IMDB
  110. return imdb_code[1]; // Vrací extrahovaný kód IMDB
  111. }
  112.  
  113. };
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120. function OmdbApi(imdb_code){
  121. this.imdb_code = imdb_code;
  122. this.fetchOmdbData = function(){
  123. var request = $.ajax({
  124. method: 'GET',
  125. url: 'http://www.omdbapi.com/',
  126. data: {
  127. i: this.imdb_code,
  128. tomatoes: 'true',
  129. r: 'json'
  130. }
  131. });
  132.  
  133. request.done(function(response){
  134. imdb.rating = parseFloat(response.imdbRating);
  135. imdb.votes = response.imdbVotes.replace(',', '');
  136. imdb.votes = parseInt(imdb.votes);
  137.  
  138. metacritic.metascore = parseInt(response.Metascore);
  139.  
  140. tomato.meter = parseInt(response.tomatoMeter);
  141. tomato.rating = parseFloat(response.tomatoRating);
  142. tomato.reviews = parseInt(response.tomatoReviews);
  143. tomato.userMeter = parseInt(response.tomatoUserMeter);
  144. tomato.userRating = parseFloat(response.tomatoUserRating);
  145. tomato.userReviews = parseInt(response.tomatoUserReviews);
  146. tomato.url = response.tomatoURL;
  147.  
  148. imdb.insertRatingHtml();
  149. metacritic.insertRatingHtml();
  150. tomato.insertRatingHtml();
  151.  
  152. html.ratingTableShow();
  153. });
  154. }
  155.  
  156.  
  157. };
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169. function Imdb(imdb_code){
  170. this.imdb_code = imdb_code;
  171. this.rating;
  172. this.votes;
  173.  
  174. this.insertRatingHtml = function(){
  175. if(this.rating > 0){
  176. $('#csfd-e-rating .imdb').show();
  177. }
  178. $('#csfd-e-rating .imdb .rating').html(imdb.rating);
  179. $('#csfd-e-rating .imdb .votes').html(imdb.votes+'&nbsp;hlasů');
  180. $('#csfd-e-rating .imdb a').attr('href', this.link());
  181. }
  182. this.link = function(){
  183. return 'http://www.imdb.com/title/'+this.imdb_code+'/';
  184. }
  185. };
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197. function Metacritic(){
  198. this.metascore;
  199.  
  200. this.insertRatingHtml = function(){
  201. if(this.metascore > 0){
  202. $('#csfd-e-rating .metacritic').show();
  203. }
  204. $('#csfd-e-rating .metacritic .rating').html(this.metascore);
  205. $('#csfd-e-rating .metacritic a').attr('href', this.link());
  206. }
  207. this.link = function(){
  208. return 'http://www.imdb.com/title/'+imdb.imdb_code+'/criticreviews';
  209. }
  210. };
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221.  
  222. function Tomato(){
  223. this.meter;
  224. this.rating;
  225. this.reviews;
  226. this.userMeter;
  227. this.userRating;
  228. this.userReviews;
  229. this.url;
  230. this.insertRatingHtml = function(){
  231. if(this.meter > 0){
  232. $('#csfd-e-rating .tomato').show();
  233. }
  234. $('#csfd-e-rating .tomato-critic .rating').html(this.meter+'%');
  235. $('#csfd-e-rating .tomato-critic .votes').html(this.reviews+'&nbsp;recenzí');
  236. $('#csfd-e-rating .tomato-audience .rating').html(this.userMeter+'%');
  237. $('#csfd-e-rating .tomato-audience .votes').html(this.userReviews+'&nbsp;hodnocení');
  238. $('#csfd-e-rating .tomato a').attr('href', this.link());
  239. }
  240. this.link = function(){
  241. return this.url;
  242. }
  243. };
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255. function Html(){
  256. this.cssInit = function(){
  257. var css_url = 'http://csfd-extended.rychecky.cz/css/csfd-extended.css';
  258. var css_html = '<link rel="stylesheet" type="text/css" href="'+css_url+'" />';
  259. $('head').append(css_html);
  260. }
  261. this.ratingTable = function(){
  262. var html = '<div id="csfd-e-rating" class="ct-related" style="display: none;">';
  263. html += '<div class="header"><h3>ČSFD Extended</h3></div>';
  264. html += '<div class="content">';
  265. html += '<table>';
  266.  
  267. html += '<tr class="imdb" title="Otevřít profil na IMDB">';
  268. html += '<td class="favicon"><img src="http://www.google.com/s2/favicons?domain=imdb.com" alt="" /></td>';
  269. html += '<td class="title"><a href="" class="link">IMDB</a></td>';
  270. html += '<td class="rating"></td>';
  271. html += '<td class="votes"></td>';
  272. html += '</tr>';
  273.  
  274. html += '<tr class="metacritic" title="Otevřít seznam recenzí Metacritic">';
  275. html += '<td class="favicon"><img src="http://www.google.com/s2/favicons?domain=metacritic.com" alt="" /></td>';
  276. html += '<td class="title"><a href="" class="link">Metacritic</a></td>';
  277. html += '<td class="rating"></td>';
  278. html += '</tr>';
  279.  
  280. html += '<tr class="tomato tomato-critic" title="Otevřít profil na Rotten Tomatoes">';
  281. html += '<td class="favicon"><img src="http://www.google.com/s2/favicons?domain=rottentomatoes.com" alt="" /></td>';
  282. html += '<td class="title"><a href="" class="link">Tomatoes: kritici</a></td>';
  283. html += '<td class="rating"></td>';
  284. html += '<td class="votes"></td>';
  285. html += '</tr>';
  286.  
  287. html += '<tr class="tomato tomato-audience" title="Otevřít profil na Rotten Tomatoes">';
  288. html += '<td class="favicon"><img src="http://www.google.com/s2/favicons?domain=rottentomatoes.com" alt="" /></td>';
  289. html += '<td class="title"><a href="" class="link">Tomatoes: diváci</a></td>';
  290. html += '<td class="rating"></td>';
  291. html += '<td class="votes"></td>';
  292. html += '</tr>';
  293.  
  294. html += '</table>';
  295. html += '<div class="footer">by jaCUBE via <a href="https://greasyfork.org/cs/scripts/15784-%C4%8Csfd-extended">Greasy Fork</a>';
  296. html += '</div>';
  297.  
  298.  
  299. $('#rating').after(html);
  300. }
  301. this.ratingTableShow = function(){
  302. $('#csfd-e-rating').slideDown();
  303. }
  304. this.creatorPreview = function(){
  305. $('body a').mouseenter(function(e){
  306. var link = $(this).attr('href');
  307.  
  308. if(link.indexOf('/tvurce/') == -1){
  309. return false;
  310. }
  311. var request = $.ajax({
  312. method: 'GET',
  313. url: link
  314. });
  315.  
  316. request.done(function(response){
  317. var name = $(response).find('#profile .info h1').text();
  318. var age = $(response).find('#profile .info .age').text();
  319. var img = $(response).find('#profile .image img').attr('src');
  320. console.log(img);
  321. });
  322. return true;
  323. });
  324. }
  325. this.toolbar = function(){
  326. var name_url = encodeURIComponent(csfd.name);
  327. var toolbar = '<div id="csfd-e-toolbar" class="'+this.toolbarCssClass()+'">';
  328. toolbar += '<a href="'+imdb.link()+'" target="_blank">IMDB</a>';
  329. toolbar += '<a href="https://www.google.cz/search?q='+name_url+'" target="_blank">Google</a>';
  330. toolbar += '<a href="http://www.titulky.com/?Fulltext='+name_url+'" target="_blank">Titulky</a>';
  331. toolbar += '<a href="http://www.uloz.to/hledej?media=video&protected=notPassword&redir=0&q='+name_url+'" target="_blank">Ulož.to</a>';
  332. toolbar += '<a href="http://www.yify-movies.net/search/'+name_url+'/" target="_blank">YIFY</a>';
  333. toolbar += '<a href="https://torrentz.eu/search?q='+name_url+'" target="_blank">Torrentz</a>';
  334. toolbar += '</div>';
  335.  
  336. $('#profile .creators').before(toolbar);
  337. }
  338. this.toolbarCssClass = function(){
  339. if(csfd.rating >= 70){
  340. return 'red';
  341. }else if(csfd.rating >= 30){
  342. return 'blue';
  343. }else{
  344. return 'black';
  345. }
  346. }
  347. };
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356. function Floating(){
  357. this.content = '';
  358. this.floating;
  359. this.request;
  360. var parent = this;
  361.  
  362. this.init = function(){
  363. var html = '<img id="csfd-e-floating" src="" alt="" />';
  364. $('body').append(html);
  365. this.floating = $('#csfd-e-floating');
  366. }
  367. this.refresh = function(obj){
  368. obj.mousemove(function(e){
  369. parent.floating.css({'top': e.clientY + 20, 'left': e.clientX + 20});
  370. });
  371. obj.mouseout(function(){
  372. parent.floating.hide();
  373. parent.floating.attr('src', '');
  374. parent.request.abort();
  375. });
  376. }
  377. this.bindPoster = function(){
  378. var poster = $('#poster img, #posters img');
  379.  
  380. $('#show-all-posters').click(function(){
  381. parent.bindPoster();
  382. });
  383.  
  384. poster.mouseenter(function(e){
  385. var poster_url = $(this).attr('src');
  386. poster_url = poster_url.replace(/\?.+/, '');
  387. parent.floating.attr('src', poster_url);
  388. parent.floating.css({'display': 'inline'});
  389. });
  390. this.refresh(poster);
  391. }
  392. this.bindCreator = function(){
  393. var links = $('body a');
  394.  
  395. links.mouseenter(function(e){
  396. var href = $(this).attr('href');
  397. parent.floating.css({'display': 'inline'});
  398. if(href.indexOf('/tvurce/') == -1){
  399. return false;
  400. }
  401. parent.request = $.ajax({
  402. method: 'GET',
  403. url: href
  404. });
  405.  
  406. parent.request.done(function(response){
  407. var img = $(response).find('#profile .image img').attr('src');
  408. parent.floating.attr('src', img);
  409. });
  410. return true;
  411. });
  412. this.refresh(links);
  413. }
  414.  
  415. };