您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Rozšíření profilů filmů na ČSFD o některé funkce jako jsou odkazy na torrenty či hodnocení IMDB.
当前为
// ==UserScript== // @name ČSFD Extended // @namespace CSFD-E // @version 0.4.0 // @description Rozšíření profilů filmů na ČSFD o některé funkce jako jsou odkazy na torrenty či hodnocení IMDB. // @author Jakub Rychecký <[email protected]> // @license WTFPL 2 // @include *csfd.cz/film/* // ==/UserScript== var csfd = new Csfd(); // Instance třídy pro práci s profilem filmu na ČSFD var omdb = new OmdbApi(csfd.parseCsfdImdbCode()); // Instance třídy pro práci s API OMDB a stažení informací o filmu var imdb = new Imdb(csfd.parseCsfdImdbCode()); // Instance třídy s informacemi z IMDB var metacritic = new Metacritic(); // Instance třídy s informacemi z Metacritic var tomato = new Tomato(); // Instance třídy s informacemi z RottenTomatoes var html = new Html(); // Instance třídy pro práci s HTML a úpravou profilu filmu dle získaných dat var floating = new Floating(); // Instance třídy spravující plovoucí okno s náhledem posterů či fotek tvůrců html.cssInit(); // Přidání externího CSS do stránky csfd.parseCsfdNameYear(); // Parsuje název filmu z profilu ČSFD. csfd.parseCsfdRating(); // Parsuje hodnocení ČSFDs html.ratingTable(); // Předělání tabulky hodnocení na profilu filmu html.toolbar(); // Vytvoření tlačítek pro rychlé vyhledávání na profilu filmu omdb.fetchOmdbData(); // Stažení dat z API OMDB floating.init(); // Inicializace plovoucího okna floating.bindPoster(); // Bindování eventu najetí kurzoru na poster floating.bindCreator(); // Bindování eventu najetí kurzoru na odkaz na profil tvůrce /* console.log(csfd); console.log(omdb); console.log(imdb); console.log(metacritic); console.log(tomato); console.log(html); */ /** * @class Csfd * @classdesc Parsuje a zpracovává základní údaje z ČSFD profilu filmu. */ function Csfd(){ /** * Originální název filmu * @type {string} */ this.name; /** * Rok vzniku filmu * @type {integer} */ this.year; /** * Hodnocení ČSFD v procentech * @type {integer} */ this.rating; /** * Počet hodnocení na ČSFD * @type {integer} */ this.votes; /** * Parsuje název filmu z profilu ČSFD. * @return {undefined} */ this.parseCsfdNameYear = function(){ var title = $('meta[property=\'og:title\']').attr('content'); // Získání popisu ČSFD profilu z metatagu Open Graph (OG) http://ogp.me/ title = title.replace(/\(TV seriál\)/, ''); // Odstranění označení TV seriálů z názvu title = title.replace(/\(TV film\)/, ''); // Odstranění označení TV filmů z názvu var title_regex = title.match(/(.+)\((\d{4})\)/); // Rozdělení na název a rok v závorce this.name = title_regex[1]; // Název filmu this.name = this.name.replace(/.+\//, ''); // Získání čehokoliv před lomítkem (= originální název) this.name = $.trim(this.name); // Oříznutí mezer názvu filmu this.year = parseInt(title_regex[2]); // Rok názvu jako integer } /** * Parsuje procentuální hodnocení a počet hlasů z profilu ČSFD. * @return {undefined} */ this.parseCsfdRating = function(){ this.rating = $('meta[itemprop="ratingValue"]').attr('content'); // Získání procentuálního hodnocení z metatagů this.rating = parseInt(this.rating); // Hodnocení v procentech jako integer this.votes = $('meta[itemprop="ratingCount"]').attr('content'); // Získání počtu hlasů z metatagů this.votes = parseInt(this.votes); // Počet hlasů jako integer } /** * Parsuje kód filmu na IMDB z tlačítka IMDB na profilu filmu na ČSFD. * @return {String} Kód filmu na IMDB */ this.parseCsfdImdbCode = function(){ var imdb_url = $('a[data-ga-event="imdb-film|click|logged"]').attr('href'); // Získání odkazu z tlačítka IMDB var imdb_code = imdb_url.match(/(tt\d+)/); // Extrahování kódu filmu na IMDB return imdb_code[1]; // Vrací extrahovaný kód IMDB } }; /** * @class OmdbApi * @classdesc Stahuje, parsuje a zpracovává údaje o filmu staženém z OMDB API http://www.omdbapi.com/ * @param {string} imdb_code IMDB kód filmu */ function OmdbApi(imdb_code){ /** * IMDB kód filmu * @type {string} */ this.imdb_code = imdb_code; /** * Počet hodin, za kolik expiruje cache údajů z OMDb * @type {integer} */ this.cache_expire = 48; /** * Objekt odpovědí OMDb API s údaji o filmu * @type {object} */ this.response; /** * Jé. :) * @type OmdbApi */ var parent = this; /** * Nastavuje cache odpovědi z OMDb do local storage pod kódem IMDB v JSON. * @return {String} Kód filmu na IMDB */ this.setCache = function(){ localStorage.setItem(parent.imdb_code, JSON.stringify(parent.response)); // Nastavení odpovědi z OMDb do local storage pod kódem IMDB } /** * Snaží se získat odpověď OMDb API z cache v local storage. * @returns {Boolean} Byly nalezeny informace z cache? */ this.getCache = function(){ var response = localStorage.getItem(this.imdb_code); // Získání údajů z cache tam, kde by měly být response = $.parseJSON(response); // Snaha naparsovat JSON obsah cache if(response == null || response.timestamp <= $.now() - parent.expire_cache * 60 * 60){ // Pokud nebylo nic nalezeno, či pokud je to starší než limit... return false; // Cache miss! }else{ this.response = response; // Nastavení naparsované odpovědi do objektu return true; // Cache hit! } } /** * Snaží se získat údaje z cache, při neúspěchu stahuje údaje z OMDb API. * @returns {undefined} */ this.fetchOmdbData = function(){ var cache_hit = this.getCache(); // Cache miss nebo hit? if(!cache_hit){ // Pokud údaje z cache nejsou dostupné... var request = $.ajax({ method: 'GET', url: 'http://www.omdbapi.com/', data: { // Dotaz pro OMDb API i: this.imdb_code, tomatoes: 'true', r: 'json' } }); request.done(function(response){ // Po stažení odpovědi... response.timestamp = $.now(); // Přidání aktuálního unixového času do objektu odpovědi parent.response = response; // Nastavení parent.setCache(); parent.processOmdbData(); }); }else{ this.processOmdbData(); } } this.processOmdbData = function(){ var response = this.response; imdb.rating = parseFloat(response.imdbRating); imdb.votes = response.imdbVotes.replace(',', ''); imdb.votes = parseInt(imdb.votes); metacritic.metascore = parseInt(response.Metascore); tomato.meter = parseInt(response.tomatoMeter); tomato.rating = parseFloat(response.tomatoRating); tomato.reviews = parseInt(response.tomatoReviews); tomato.userMeter = parseInt(response.tomatoUserMeter); tomato.userRating = parseFloat(response.tomatoUserRating); tomato.userReviews = parseInt(response.tomatoUserReviews); tomato.url = response.tomatoURL; html.fillRatingTable(); } }; function Imdb(imdb_code){ this.imdb_code = imdb_code; this.rating; this.votes; this.insertRatingHtml = function(){ if(this.rating > 0){ $('#csfd-e-rating .imdb').show(); } $('#csfd-e-rating .imdb .rating').html(imdb.rating.toLocaleString().replace('.', ',')); $('#csfd-e-rating .imdb .votes').html(imdb.votes.toLocaleString()+' hlasů'); $('#csfd-e-rating .imdb a').attr('href', this.link()); } this.link = function(){ return 'http://www.imdb.com/title/'+this.imdb_code+'/'; } }; function Metacritic(){ this.metascore; this.insertRatingHtml = function(){ if(this.metascore > 0){ $('#csfd-e-rating .metacritic').show(); } $('#csfd-e-rating .metacritic .rating').html(this.metascore); $('#csfd-e-rating .metacritic a').attr('href', this.link()); } this.link = function(){ return 'http://www.imdb.com/title/'+imdb.imdb_code+'/criticreviews'; } }; function Tomato(){ this.meter; this.rating; this.reviews; this.userMeter; this.userRating; this.userReviews; this.url; this.insertRatingHtml = function(){ if(this.meter > 0){ $('#csfd-e-rating .tomato').show(); } $('#csfd-e-rating .tomato-critic .rating').html(this.meter+' %'); $('#csfd-e-rating .tomato-critic .votes').html(this.reviews.toLocaleString()+' recenzí'); $('#csfd-e-rating .tomato-audience .rating').html(this.userMeter+' %'); $('#csfd-e-rating .tomato-audience .votes').html(this.userReviews.toLocaleString()+' hodnocení'); $('#csfd-e-rating .tomato a').attr('href', this.link()); } this.link = function(){ return this.url; } }; function Html(){ this.toolbar; this.cssInit = function(){ var css_url = 'http://csfd-extended.rychecky.cz/css/csfd-extended.css'; var css_html = '<link rel="stylesheet" type="text/css" href="'+css_url+'" />'; $('head').append(css_html); } this.fillRatingTable = function(){ imdb.insertRatingHtml(); metacritic.insertRatingHtml(); tomato.insertRatingHtml(); this.ratingTableShow(); } this.ratingTable = function(){ var html = '<div id="csfd-e-rating" class="ct-related" style="display: none;">'; html += '<div class="header"><h3>ČSFD Extended</h3></div>'; html += '<div class="content">'; html += '<table>'; html += '<tr class="imdb" style="display: none;">'; html += '<td class="favicon"><img src="http://www.google.com/s2/favicons?domain=imdb.com" alt="" /></td>'; html += '<td class="title"><a href="" class="link" title="Otevřít profil na IMDB">IMDB</a></td>'; html += '<td class="rating"></td>'; html += '<td class="votes"></td>'; html += '</tr>'; html += '<tr class="metacritic" style="display: none;">'; html += '<td class="favicon"><img src="http://www.google.com/s2/favicons?domain=metacritic.com" alt="" /></td>'; html += '<td class="title"><a href="" class="link" title="Otevřít seznam recenzí Metacritic">Metacritic</a></td>'; html += '<td class="rating"></td>'; html += '</tr>'; html += '<tr class="tomato tomato-critic" style="display: none;">'; html += '<td class="favicon"><img src="http://www.google.com/s2/favicons?domain=rottentomatoes.com" alt="" /></td>'; html += '<td class="title"><a href="" class="link" title="Otevřít profil na Rotten Tomatoes" >RT: kritici</a></td>'; html += '<td class="rating"></td>'; html += '<td class="votes"></td>'; html += '</tr>'; html += '<tr class="tomato tomato-audience" style="display: none;">'; html += '<td class="favicon"><img src="http://www.google.com/s2/favicons?domain=rottentomatoes.com" alt="" /></td>'; html += '<td class="title"><a href="" class="link" title="Otevřít profil na Rotten Tomatoes">RT: diváci</a></td>'; html += '<td class="rating"></td>'; html += '<td class="votes"></td>'; html += '</tr>'; html += '</table>'; html += '<div class="footer">by jaCUBE via <a href="https://greasyfork.org/cs/scripts/15784-%C4%8Csfd-extended">Greasy Fork</a>'; html += '</div>'; $('#rating').after(html); } this.ratingTableShow = function(){ $('#csfd-e-rating').slideDown(); } this.creatorPreview = function(){ $('body a').mouseenter(function(e){ var link = $(this).attr('href'); if(link.indexOf('/tvurce/') == -1){ return false; } var request = $.ajax({ method: 'GET', url: link }); request.done(function(response){ var name = $(response).find('#profile .info h1').text(); var age = $(response).find('#profile .info .age').text(); var img = $(response).find('#profile .image img').attr('src'); }); return true; }); } this.toolbar = function(){ var name_url = encodeURIComponent(csfd.name); var html = '<div id="csfd-e-toolbar">'; html += '<a href="'+imdb.link()+'" target="_blank">IMDB</a>'; html += '<a href="https://www.google.cz/search?q='+name_url+'" target="_blank">Google</a>'; html += '<a href="https://www.youtube.com/results?search_query='+name_url+'" target="_blank">YouTube</a>'; html += '<a href="https://www.reddit.com/search?q='+name_url+'+subreddit%3Amovies+OR+subreddit%3Atelevision+OR+subreddit%3Atrailers&sort=relevance&t=all" target="_blank">Reddit</a>'; // Omezeno na r/movies, r/television a r/trailers html += '<a href="https://www.facebook.com/search/pages/?q='+name_url+'" target="_blank">Facebook</a>'; html += '<a href="http://www.titulky.com/?Fulltext='+name_url+'" target="_blank">Titulky</a>'; html += '<a href="http://www.uloz.to/hledej?media=video&protected=notPassword&redir=0&q='+name_url+'" target="_blank">Ulož.to</a>'; html += '<a href="https://www.google.cz/search?q='+name_url+' site:yify-movies.net OR site:yify-movie.com" target="_blank">YIFY</a>'; html += '<a href="https://torrentz.eu/search?q='+name_url+'" target="_blank">Torrentz</a>'; html += '</div>'; $('#profile div.content').prepend(html); this.toolbar = $('#csfd-e-toolbar'); this.toolbar.find('a').css({background: $('#rating').css('background')}); } }; function Floating(){ this.content = ''; this.floating; this.request; var parent = this; this.init = function(){ var html = '<img id="csfd-e-floating" src="" alt="" />'; $('body').append(html); this.floating = $('#csfd-e-floating'); } this.refresh = function(obj){ obj.mousemove(function(e){ parent.floating.css({'top': e.clientY - 150, 'left': e.clientX + 20}); }); obj.mouseout(function(){ parent.floating.hide(); parent.floating.attr('src', ''); parent.request.abort(); }); } this.bindPoster = function(){ var poster = $('#poster img, #posters img'); $('#show-all-posters').click(function(){ parent.bindPoster(); }); poster.mouseenter(function(e){ var poster_url = $(this).attr('src'); poster_url = poster_url.replace(/\?.+/, ''); parent.floating.attr('src', poster_url); parent.floating.css({'display': 'inline'}); }); this.refresh(poster); } this.bindCreator = function(){ var links = $('body a'); links.mouseenter(function(e){ var href = $(this).attr('href'); parent.floating.css({'display': 'inline'}); if(href.indexOf('/tvurce/') == -1){ return false; } parent.request = $.ajax({ method: 'GET', url: href }); parent.request.done(function(response){ var img = $(response).find('#profile .image img').attr('src'); parent.floating.attr('src', img); }); return true; }); this.refresh(links); } };