Greasy Fork is available in English.

IMDb Search

Search on imdb.com

// ==UserScript==
// @name         IMDb Search
// @version      1.5
// @description  Search on imdb.com
// @author       FuSiOn
// @match        https://*/*
// @match        http://*/*
// @require      http://code.jquery.com/jquery-latest.js
// @grant        GM_xmlhttpRequest
// @namespace https://greasyfork.org/users/10999
// ==/UserScript==

$.expr[":"].containsI = $.expr.createPseudo(function(arg) {
    return function( elem ) {
        return $(elem).text().trim().toUpperCase()
            .indexOf(arg.trim().toUpperCase()) >= 0;
    };
});
$.expr[":"].containsX = $.expr.createPseudo(function(arg) {
    return function( elem ) {
        return $(elem).text().trim()
            .replace(/\s\([IVX]+\)\s/," ")
            .replace(/\sII(?:\s|:|$)/g,"2")
            .replace(/\sIII(?:\s|:|$)/g,"3")
            .replace(/\sIV(?:\s|:|$)/g,"4")
            .replace(/\sV(?:\s|:|$)/g,"5")
            .replace(/\sVI(?:\s|:|$)/g,"6")
            .replace(/\sVII(?:\s|:|$)/g,"7")
            .replace(/\sIIX(?:\s|:|$)/g,"8")
            .replace(/\sIX(?:\s|:|$)/g,"9")
            .replace(/\sX(?:\s|:|$)/g,"10")
            .replace(/the\b|part(?=\s?\d)/ig,"")
            .replace(/and/ig,"&")
            .replace(/äàâ/ig,"A")
            .replace(/ç/ig,"C")
            .replace(/éèëê/ig,"E")
            .replace(/\W/g,"")
            .toUpperCase()
            .indexOf(arg.trim().replace(/\sII(?:\s|:|$)/g,"2")
                     .replace(/\sIII(?:\s|:|$)/g,"3")
                     .replace(/\sIV(?:\s|:|$)/g,"4")
                     .replace(/\sV(?:\s|:|$)/g,"5")
                     .replace(/\sVI(?:\s|:|$)/g,"6")
                     .replace(/\sVII(?:\s|:|$)/g,"7")
                     .replace(/\sIIX(?:\s|:|$)/g,"8")
                     .replace(/\sIX(?:\s|:|$)/g,"9")
                     .replace(/\sX(?:\s|:|$)/g,"10") 
                     .replace(/the\b|part(?=\s?\d)|p(?=\d)|3d/ig,"")
                     .replace(/and/ig,"&")
                     .replace(/äàâ/ig,"A")
                     .replace(/ç/ig,"C")
                     .replace(/éèëê/ig,"E")
                     .replace(/\W/g,"")
                     .toUpperCase()) >= 0;
    };
});
var IMDb = {
    search: function(arg){
        var argType = typeof arg;
        if((argType != "object" && argType != "string") || (argType=== "object" && typeof arg.title === "undefined")){
            console.log("IMDB_SEARCH: Illegal arguments",arg);
            return;
        }
        if(argType === "string"){
            var str = arg.trim().match(/(.+?)\(?((?:19|20)\d\d)?\)?$/);
            arg = {};
            arg.title = str[1];
            arg.year  = str[2]; 
        }
        arg.year     = (typeof arg.year === "undefined")     ? ""                                 : arg.year;
        arg.type     = (typeof arg.type === "undefined")     ? "movie"                            : arg.type;
        arg.node     = (typeof arg.node === "undefined")     ? ""                                 : arg.node;
        arg.callback = (typeof arg.callback === "undefined") ? function(info){console.log(info);} : arg.callback;
        arg.retry    = (typeof arg.retry === "undefined")    ? false                              : arg.retry;
        GM_xmlhttpRequest({
            method: "GET",
            url: "http://akas.imdb.com/find?ref_=nv_sr_fn&s=all&q=" + encodeURIComponent(arg.title) + ((arg.type === "tv")? "&ttype=tv":"&ttype=ft"),
            onload: function(response) {
                if (response.status == 200) {
                    if (!/<a name="tt"><\/a>[\w\W]+?<\/table>/i.test(response.responseText)) {
                        if (/No results found for/.test(response.responseText)) {
                            console.log("IMDB_Search: No result found for:", arg.title, arg.year);
                        } else {
                            console.log("IMDB_Search: A unknown error has occured:", arg.title, arg.year);
                        }
                        return;
                    }
                    var responseData = response.responseText.match(/<a name="tt"><\/a>[\w\W]+?<\/table>/i)[0]
                    .replace(/(<img[\w\W]+?src=)"[^"]+"/g, '$1""'),
                        selector = {
                            "movie" :'.findResult:containsX("' + arg.title + '"):not(:containsI("(video game)"),:containsI("(tv episode)"),:containsI("(tv series)"),:containsI("(tv mini-series)"),:containsI("(short)"))',
                            "tv":'.findResult:containsX("' + arg.title + '"):containsI("(TV Series)"),.findResult:containsX("' + arg.title + '"):containsI("(tv series)"),.findResult:containsX("' + arg.title + '"):containsI("(tv mini-series)")',
                            "game": '.findResult:containsX("' + arg.title + '"):containsI("(Video Game)")'
                        },
                        result,
                        results = $(selector[arg.type], responseData);
                    if (results.length > 0) {
                        if (results.length > 1) {
                            if (arg.year) {
                                if (results.find(":contains('" + arg.year + "')").length === 0) {
                                    if (results.find(":contains('" + (parseInt(arg.year) - 1) + "')").length === 0) {
                                        results = results.find(":contains('" + (parseInt(arg.year) + 1) + "')");
                                    }else{
                                        results = results.find(":contains('" + (parseInt(arg.year) - 1).toString() + "')");
                                    }
                                } else {
                                    results = results.find(":contains('" + arg.year + "')");
                                }
                            }
                            if (results.length > 0) {
                                $('small',results[0]).remove();
                                result = $(results[0]).find("a").attr("href").match(/tt\d+/)[0];
                                IMDb.info({id:result, node:arg.node, callback:arg.callback});
                            } else {
                                console.log("IMDB_Search: ", "Found no match with the given query and year:", arg.title, arg.year);
                            }
                        } else {
                            $('small',results[0]).remove();
                            result = $(results[0]).find("a").attr("href").match(/tt\d+/)[0];
                            IMDb.info({id:result, node:arg.node, callback:arg.callback});
                        }
                    } else {
                        if ($('.findResult', responseData).length === 1) {
                            results = $('.findResult', responseData);
                            $('small',results[0]).remove();
                            result = $(results[0]).find("a").attr("href").match(/tt\d+/)[0];
                            IMDb.info({id:result, node:arg.node, callback:arg.callback});
                        } else {
                            if(arg.type === 'movie' && arg.retry === false && /[\[(][^\])]+[\])]/.test(arg.title)){
                                IMDb.search({title:title.replace(/[\[(][^\])]+[\])]/,""), year:arg.year, node:arg.node, callback:arg.callback, retry:true});
                            }else{
                                console.log("IMDB_Search: ", "Found no match with the given query:", arg.title, arg.year);
                            }
                        }
                    }
                } else {
                    console.log(response.status + " " + response.statusText);
                }
            }
        });
    },
    info: function(arg){
        var argType = typeof arg;
        if((argType != "object" && argType != "string") || (argType=== "object" && typeof arg.id === "undefined") || (argType === "string" && !(/^tt\d+$/.test(arg.trim())))){
            console.log("IMDB_INFO: Illegal arguments",arg);
            return;
        }
        if(argType === "string"){
            arg = {id:arg.match(/tt\d+/)[0]};
        }
        arg.node     = (typeof arg.node === "undefined")     ? ""                                 : arg.node;
        arg.callback = (typeof arg.callback === "undefined") ? function(info){console.log(info);} : arg.callback;
        GM_xmlhttpRequest({
            method: "GET",
            url: "http://akas.imdb.com/title/" + arg.id,
            onload: function(response) {
                if (response.status == 200) {
                    if(/\/combined$/.test(response.finalUrl)){
                        console.log('Please disable the setting "Always display full cast and crew credits" in your account.');
                        return;
                    }
                    if(!/<div id="title-overview-widget"[^>]+>[\w\W]+?<\/div>\W+?(?=<script>)/i.test(response.responseText)){
                        console.log('IMDb_GetInfo: ','Unknown error occurred.');
                        return;
                    }
                    var fullResponse = response.responseText.replace(/(<img[\w\W]+?src)=("http:\/\/ia\.media-imdb\.com[^"]+")/g, '$1New=$2'),
                        responseData = fullResponse.match(/<div id="title-overview-widget"[^>]+>[\w\W]+?<\/div>\W+?(?=<script>)/i)[0],
                        Info = {
                            "Title":  	     $('.header [itemprop="name"],h1[itemprop="name"]',responseData).text().trim().replace(/\s?\((?:19|20)\d\d\)$/,"") ,
                            "Year":		     $('.header .nobr,#titleYear,[title="See more release dates"]',responseData)[0].textContent.trim().replace(/^.*\(|\)/g,""),
                            "ID":     	     arg.id,
                            "Rating": 	     $('span[itemprop="ratingValue"]', responseData).text(),
                            "ratingCount":   $('span[itemprop="ratingCount"]', responseData).text(),
                            "contentRating": $('[itemprop="contentRating"]', responseData).attr('content'),
                            "Duration":		 typeof($('[itemprop="duration"]', responseData).attr('datetime')) == 'undefined' ? null : $('[itemprop="duration"]', responseData).attr('datetime').replace(/PT(\d+)M/,'$1 min'),
                            "releaseDate":	 $('a [itemprop="datePublished"]', responseData).parent().text().trim(),
                            "Genre":  	     "",
                            "URL":    	     "http://www.imdb.com/title/" + arg.id,
                            "Poster": 	     $('img[alt*="Poster"]', responseData).attr('srcNew') || '',
                            "Trailer":	     typeof($("[itemprop=trailer]", responseData).attr("href")) == 'undefined' ? '' : "http://imdb.com" + $("[itemprop=trailer]",responseData).attr("href"),
                            "InWatchList":   null,
                            "InLists":	     null,
                            "Description":   $('[itemprop="description"]', responseData).text().trim(),
                            "Stars":	     [],
                            "Director": 	 [],
                            "Creator":		 []
                        },
                        stars 	 =  $('[itemprop="actors"] a', responseData).has('[itemprop="name"]'),
                        director = 	$('[itemprop="director"] a', responseData).has('[itemprop="name"]'),
                        creator	 =	$('[itemprop="creator"] a', responseData).has('[itemprop="name"]'),
                        logged 	 = 	/nblogout/.test(response.responseText);
                    $('span[itemprop="genre"]', responseData).each(function() {
                        if (Info.Genre !== "") {
                            Info.Genre += " | ";
                        }
                        Info.Genre += $(this).text();
                    });
                    stars.each(function(){
                        var Star = Info.Stars.push({
                            "Name": $('[itemprop="name"]',this).text(),
                            "URL":	'http://www.imdb.com' + $(this).attr('href'),
                            "Image":""
                        }) -1,
                            $image = $("img[alt=" + '"' + Info.Stars[Star].Name + '"' + "]",fullResponse),
                            image;
                        if($image.length > 0){
                            image = typeof($image.attr("loadlate")) === 'undefined' ? $image.attr("srcNew") : $image.attr("loadlate");
                        }
                        Info.Stars[Star].Image  = image;
                    });
                    director.each(function(){
                        Info.Director.push({
                            "Name": $('[itemprop="name"]',this).text(),
                            "URL":	'http://www.imdb.com' + $(this).attr('href'),
                        });
                    });
                    creator.each(function(){
                        Info.Creator.push({
                            "Name": $('[itemprop="name"]',this).text(),
                            "Type": this.nextSibling.nodeType === 3 ? this.nextSibling.textContent.replace(/\((.+)\)\W*$/,'$1').replace(',','').trim(): '',
                            "URL":	'http://www.imdb.com' + $(this).attr('href'),
                        });
                    });
                    if(logged){
                        GM_xmlhttpRequest({
                            method:  "POST",
                            url:     "http://www.imdb.com/list/_ajax/watchlist_has",
                            data:    "consts%5B%5D=" + Info.ID + "&tracking_tag=wlb-lite",
                            headers:    {
                                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
                            },
                            onload:  function(response) {
                                if(response.status == 200){
                                    var obj = JSON.parse(response.responseText);
                                    if(obj.status === 200){
                                        if(typeof(obj.has[Info.ID]) !== "undefined"){
                                            Info.InWatchList = true;
                                        }else Info.InWatchList = false;
                                        GM_xmlhttpRequest({
                                            method:  "POST",
                                            url:     "http://www.imdb.com/list/_ajax/wlb_dropdown",
                                            data:    "tconst=" + Info.ID,
                                            headers:    {
                                                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
                                            },
                                            onload:  function(response) {
                                                if(response.status == 200){
                                                    var obj = JSON.parse(response.responseText);
                                                    if(obj.status === 200){
                                                        obj.items.forEach(function(item){
                                                            if(item.data_list_item_ids !== null){
                                                                if(Info.InLists === null) Info.InLists = [];
                                                                Info.InLists.push(item.data_list_id);
                                                            }
                                                        });
                                                        arg.callback(Info,arg.node);
                                                    }
                                                }
                                            }
                                        });
                                    }
                                }
                            }
                        });
                    }else{
                        arg.callback(Info,arg.node);
                    }
                }
            }
        });
    },
    inLists: function(arg){
        if(typeof arg === "string" && /^tt\d+$/.test(arg.trim())){
            arg = {id:arg};
        }
        arg.node     = (typeof arg.node === "undefined")     ? ""                                  : arg.node;
        arg.callback = (typeof arg.callback === "undefined") ? function(info){console.log(info);}  : arg.callback;
        GM_xmlhttpRequest({
            method:  "POST",
            url:     "http://www.imdb.com/list/_ajax/watchlist_has",
            data:    "consts%5B%5D=" + arg.id + "&tracking_tag=wlb-lite",
            headers:    {
                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
            },
            onload:  function(response) {
                if(response.status == 200){
                    var obj = JSON.parse(response.responseText);
                    if(obj.status === 200){
                        var Info  = {};
                        if(typeof(obj.has[arg.id]) !== "undefined"){
                            Info.InWatchList = true;
                        }else Info.InWatchList = false;
                        GM_xmlhttpRequest({
                            method:  "POST",
                            url:     "http://www.imdb.com/list/_ajax/wlb_dropdown",
                            data:    "tconst=" + arg.id,
                            headers:    {
                                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
                            },
                            onload:  function(response) {
                                if(response.status == 200){
                                    var obj = JSON.parse(response.responseText);
                                    if(obj.status === 200){
                                        Info.InLists = [];
                                        obj.items.forEach(function(item){
                                            if(item.data_list_item_ids !== null){
                                                Info.InLists.push(item.data_list_id);
                                            }
                                        });
                                        arg.callback(Info,arg.node);
                                    }
                                }
                            }
                        });
                    }
                }
            }
        });
    },
    getYouTube: function(arg){
        var argType = typeof arg;
        if((argType != "object" && argType != "string") || (argType=== "object" && typeof arg.title === "undefined")){
            console.log("getYouTube: Illegal arguments",arg);
            return;
        }
        if(argType === "string"){
            var str = arg.trim().match(/(.+?)\(?((?:19|20)\d\d)?\)?$/);
            arg = {};
            arg.title = str[1];
            arg.year  = str[2]; 
        }
        arg.node     = (typeof arg.node === "undefined")     ? ""                                 : arg.node;
        arg.year     = (typeof arg.year === "undefined")     ? ""                                 : arg.year;
        arg.callback = (typeof arg.callback === "undefined") ? function(info){console.log(info);} : arg.callback;
        GM_xmlhttpRequest({
            method:  "GET",
            url:     encodeURI("https://www.youtube.com/results?search_query=" + arg.title + ' ' + arg.year + " HD trailer+" + arg.type),
            headers:    {
                "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
            },
            onload:  function(response) {
                if(response.status == 200){
                    var regex = new RegExp('href="\/watch\\?v=([^"]+)".*?title=".*?' + arg.title +'.+?(?:' + arg.year + ')?',"im"),
                        Info  = {Trailer:""};
                    if(regex.test(response.responseText)){
                        Info.Trailer  = "https://www.youtube.com/embed/" + regex.exec(response.responseText)[1];
                        arg.callback(Info,arg.node);
                    }
                }
            }
        });
    }
};
unsafeWindow.IMDb = IMDb;