TwitterやFacebookのアイコンを画像検索してヒット数とかを表示するユーザースクリプト

元ネタ:

TwitterのアイコンやFacebookプロフィールをGoogle画像検索とかして、有名人の写真や既存の画像を丸パクリしているかどうか検索結果数を表示する拡張機能とかあればいいのか

— ǝunsʇo ıɯnɟɐsɐɯさん (@otsune) 8月 27, 2012

TwitterやFacebookのユーザーページにアクセスすると、そのユーザーのアイコンをGoogleで画像検索して検索結果数を表示する。「この画像の最良の推測結果」があればそれも表示する。

動作している様子はこんな感じ。“約 15,200 件”とかいうのが検索結果数で、括弧内が「この画像の最良の推測結果」。




// ==UserScript==
// @name            Avatar Image Automatic Search
// @description     Search avatar images in Google
// @version         0.1
// @license         public domain
// @match           https://twitter.com/*
// @match           http://www.facebook.com/*
// @match           https://plus.google.com/*
// ==/UserScript==

var site = [{url: /^https?:\/\/twitter\.com\/\w+\/?$/,
             avatarSelector: ".avatar.size128",        // avatar img
             resultSelector: ".profile-card-inner"},   // append result here
            {url: /^https?:\/\/www\.facebook\.com\/\w+\/?$/,
             avatarSelector: ".profilePic img",
             resultSelector: ".name h2"},
            {url: /^https?:\/\/plus.google.com\/\d+\/posts\/?$/,
             avatarSelector: ".l-tk",
             resultSelector: ".KC"}];

var cache = {
    lifetime: 86400000, // millsecond (86400000 ms = 1 day)
    get: function(key){
        var t = GM_getValue(key + "_time");
        if(t === undefined) return;
        if(cache.lifetime < new Date - (+t)){
            GM_deleteValue(key);
            GM_deleteValue(key + "_time");
        }else{
            return GM_getValue(key);
        }
    },
    set: function(key, value){
        GM_setValue(key, value);
        GM_setValue(key + "_time", +new Date + ""); // 大きな数値を入れると失敗するらしいので文字列に変換して保存
    },
    clear: function(){  // use manually
        for(var key in GM_listValues())
            GM_deleteValue(key);
    }
};

if(GM_getValue("noCache")){
    cache.get = cache.set = function(){};
    cache.clear();
}

for(var i = 0, l = site.length; i < l; i++){
    if(site[i].url.test(location.href)){
        var avatarElement = document.querySelector(site[i].avatarSelector);
        if(!avatarElement) continue;
        var avatarUrl = URLabsolutify(avatarElement.src);

        var resultContainer = document.createElement("div");
        resultContainer.id = "avatar_image_search_user_js_result";
        document.querySelector(site[i].resultSelector).appendChild(resultContainer);

        function putResult(result){
            resultContainer.appendChild(result);
            cache.set(avatarUrl, resultContainer.innerHTML);
        }

        var resultHtml = cache.get(avatarUrl);
        if(resultHtml){
            resultContainer.innerHTML = resultHtml;
        }else{
            var searchUrl = "https://www.google.com/searchbyimage?image_url="
                + encodeURIComponent(avatarUrl);
            GM_xmlhttpRequest({url: searchUrl, method: "GET", 
                               onload: handleSearchResult.bind(this, putResult),
                               onerror: handleSearchError.bind(this, putResult)});
        }
        break;
    }
}

function URLabsolutify(url){
    var a = document.createElement("a");
    a.href = url;
    return a.href;
}

function handleSearchResult(putResult, response){
    if(!response.responseXML)
        response.responseXML = new DOMParser().parseFromString(response.responseText, "text/html");

    var hitNum = response.responseXML.querySelector("#resultStats");
    var imageSearchLink = document.createElement("a");
    imageSearchLink.href = response.finalUrl;
    imageSearchLink.textContent = hitNum ? hitNum.firstChild.textContent : "アバター検索:件数取得失敗";

    var guess = response.responseXML.querySelector('a[style="font-weight:bold;font-style:italic"]');
    if(guess){
        var guessLink = document.createElement("a");
        guessLink.href = "https://www.google.com" + guess.href;
        guessLink.textContent = "(" + guess.textContent +")";
    }

    var result = document.createDocumentFragment();
    result.appendChild(imageSearchLink);
    if(guessLink) result.appendChild(guessLink);
    putResult(result);
}

function handleSearchError(putResult, response){
    var result = document.createElement("a");
    result.textContent = "アバター検索失敗";
    result.href = response.finalUrl;
    putResult(result);
}