ČSFD Extended

Rozšíření profilů filmů na ČSFD o některé funkce jako jsou odkazy na Ulož.to či hodnocení IMDB.

目前為 2016-03-26 提交的版本,檢視 最新版本

// ==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 Ulož.to č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()+'&nbsp;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+'&nbsp;%');
    $('#csfd-e-rating .tomato-critic .votes').html(this.reviews.toLocaleString()+'&nbsp;recenzí');
     
    $('#csfd-e-rating .tomato-audience .rating').html(this.userMeter+'&nbsp;%');
    $('#csfd-e-rating .tomato-audience .votes').html(this.userReviews.toLocaleString()+'&nbsp;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://gf.qytechs.cn/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);
 }
 
 
};

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址