TinyURL Decoder
これなんか、どうも全部の短縮URLサービスの API を叩きにいってるらしい。力技はキライじゃないけど、こりゃあ、絶対に肉食っている人に違いない、間違いない! と思ったら、じつは日本の方らしい、というオチ。
// ==UserScript== // @name TinyURL Decoder // @namespace http://matatabi.homeip.net // @description decode shortened URLs to original ones // @include http://twitter.com/* // @include http://search.twitter.com/* // @include http://userscripts.org/scripts/show/40582 // @exclude http://0rz.tw/* // @exclude http://55c.cc/* // @exclude http://6url.com/* // @exclude http://alturl.com/* // @exclude http://arm.in/* // @exclude http://awe.sm/* // @exclude http://b23.ru/* // @exclude http://bacn.me/* // @exclude http://bit.ly/* // @exclude http://bitly.com/* // @exclude http://bloat.me/* // @exclude http://buttn.me/* // @exclude http://budurl.com/* // @exclude http://burnurl.com/* // @exclude http://chilp.it/* // @exclude http://cli.gs/* // @exclude http://cuthut.com/* // @exclude http://digg.com/* // @exclude http://doiop.com/* // @exclude http://elfurl.com/* // @exclude http://ff.im/* // @exclude http://fff.to/* // @exclude http://good.ly/* // @exclude http://gol.ly/* // @exclude http://href.in/* // @exclude http://hub.tm/* // @exclude http://hurl.me/* // @exclude http://i5.be/* // @exclude http://icanhaz.com/* // @exclude http://idek.net/* // @exclude http://is.gd/* // @exclude http://justlink.us/* // @exclude http://kissa.be/* // @exclude http://kl.am/* // @exclude http://korta.nu/* // @exclude http://lin.cr/* // @exclude http://linkbee.com/* // @exclude http://liurl.cn/* // @exclude http://ln-s.net/* // @exclude http://lnk.by/* // @exclude http://lnk.in/* // @exclude http://lnkd.in/* // @exclude http://m2lb.info/* // @exclude http://merky.de/* // @exclude http://migre.me/* // @exclude http://minify.me/* // @exclude http://minurl.fr/* // @exclude http://minurl.org/* // @exclude http://moourl.com/* // @exclude http://myurl.in/* // @exclude http://ninjalink.com/* // @exclude http://nsfw.in/* // @exclude http://ow.ly/* // @exclude http://p.zurl.ws/* // @exclude http://peaurl.com/* // @exclude http://ping.fm/* // @exclude http://piurl.com/* // @exclude http://pnt.me/* // @exclude http://ponyurl.com/* // @exclude http://poourl.com/* // @exclude http://poprl.com/* // @exclude http://qurlyq.com/* // @exclude http://r.im/* // @exclude http://reallytinyurl.com/* // @exclude http://ri.ms/* // @exclude http://rt.nu/* // @exclude http://rubyurl.com/* // @exclude http://short.ie/* // @exclude http://short.la/* // @exclude http://short.to/* // @exclude http://shortener.net/* // @exclude http://shorturl.com/* // @exclude http://shuurl.com/* // @exclude http://simurl.com/* // @exclude http://slnk.me/* // @exclude http://smallr.com/* // @exclude http://sn.im/* // @exclude http://snipr.com/* // @exclude http://snipurl.com/* // @exclude http://snurl.com/* // @exclude http://so-smart.be/* // @exclude http://tighturl.com/* // @exclude http://tcrn.ch/* // @exclude http://tii.li/* // @exclude http://tini.us/* // @exclude http://tiny.cc/* // @exclude http://tinyurl.com/* // @exclude http://to.ly/* // @exclude http://togotor.us/* // @exclude http://tr.im/* // @exclude http://tra.kz/* // @exclude http://traceurl.com/* // @exclude http://tweetburner.com/* // @exclude http://twurl.nl/* // @exclude http://u.mavrev.com/* // @exclude http://u.nu/* // @exclude http://unhub.com/* // @exclude http://ur1.ca/* // @exclude http://url.az/* // @exclude http://url.ie/* // @exclude http://url.so-smart.be/* // @exclude http://urlcut.com/* // @exclude http://urlenco.de/* // @exclude http://viigo.im/* // @exclude http://w3t.org/* // @exclude http://wurl.ws/* // @exclude http://www.cloakreferer.com/* // @exclude http://www.dwarfurl.com/* // @exclude http://www.urlxp.com/* // @exclude http://www.x.se/* // @exclude http://xii.li/* // @exclude http://xr.com/* // @exclude http://xrl.us/* // @exclude http://yatuc.com/* // @exclude http://yep.it/* // @exclude http://zurl.ws/* // @exclude http://zz.gd/* // ==/UserScript== (function(d){ function reset_cache() { var _cache = {}; GM_setValue('cache', _cache.toSource()); cache = _cache; show_cache(); } GM_registerMenuCommand("Reset cache of TinyURL Decoder", reset_cache); function show_cache() { var _counter = 0; GM_log('==== Cached URLs are shown below: ===='); for (key in cache) { GM_log(key + ' --> ' + cache[key]); _counter++; } GM_log('==== These ' + _counter + ' URLs are cached. ===='); } GM_registerMenuCommand("Show cache of TinyURL Decoder", show_cache); function init_cache() { var _cache = GM_getValue('cache'); if (typeof(_cache) === 'undefined') _cache = {}; else { _cache = eval(_cache); var _counter = 0; for (c in _cache) _counter++; var maxlength = GM_getValue('maxlength'); if (typeof(maxlength) === 'undefined') { maxlength = 100; GM_setValue('maxlength', maxlength); } var oversize = _counter - maxlength; if (oversize > 0) { var __cache = {}; for (key in _cache) if (oversize > 0) oversize--; else __cache[key] = _cache[key]; _cache = __cache; } } return _cache; } var cache = init_cache(); var services = { '0rz.tw': true, '55c.cc': true, '6url.com': true, 'alturl.com': true, 'arm.in': true, 'awe.sm': true, 'b23.ru': true, 'bacn.me': true, 'bit.ly': true, 'bitly.com': true, 'bloat.me': true, 'budurl.com': true, 'burnurl.com': true, 'buttn.me': true, 'chilp.it': true, 'cli.gs': true, 'cuthut.com': true, 'digg.com': true, 'doiop.com': true, 'dwarfurl.com': true, /*'elfurl.com': true,*/ 'ff.im': true, /*'fff.to': true,*/ 'good.ly': true, 'gol.ly': true, 'href.in': true, 'htxt.it': true, 'hub.tm': true, 'hurl.me': true, 'i5.be': true, 'icanhaz.com': true, 'idek.net': true, 'is.gd': true, 'justlink.us': true, 'kissa.be': true, 'kl.am': true, 'korta.nu': true, 'linkbee.com': true, 'link.gs': true, 'lin.cr': true, 'liurl.cn': true, 'lnkd.in': true, 'lnk.by': true, 'lnk.in': true, 'ln-s.net': true, 'm2lb.info': true, 'merky.de': true, 'migre.me': true, 'minify.me': true, 'minurl.fr': true, 'minurl.org': true, 'moourl.com': true, 'moveto.ws': true, 'myurl.in': true, 'ninjalink.com': true, 'nsfw.in': true, 'oneclip.jp': true, 'ow.ly': true, 'peaurl.com': true,'ping.fm': true, 'piurl.com': true, 'pnt.me': true, 'poourl.com': true, 'poprl.com': true, 'ponyurl.com': true, /*'p.zurl.ws': true,*/ 'qurlyq.com': true, 'r.im': true, 'reallytinyurl.com': true, 'ri.ms': true, 'rt.nu': true, 'rubyurl.com': true, 'shorturl.com': true, 'short.ie': true, 'short.la': true, 'short.to': true, 'shuurl.com': true, 'simurl.com': true, 'slnk.me': true, 'snurl.com': true, 'smallr.com': true, 'sn.im': true, 'snipr.com': true, 'snipurl.com': true, 'so-smart.be': true, 'tcrn.ch': true, 'tighturl.com': true, 'tii.li': true, 'tini.us': true, 'tinyurl.com': true, 'tiny.cc': true, 'togoto.us': true, 'to.ly': true, 'traceurl.com': true, 'tra.kz': true, 'tr.im': true, 'twurl.nl': true, 'u.nu': true, 'unhub.com': true, 'ur1.ca': true, 'urlcut.com': true, 'urlenco.de': true, 'urlxp.com': true,'url.az': true, 'url.ie': true, 'u.mavrev.com': true, 'viigo.im': true, 'w3t.org': true, 'wurl.ws': true, 'www.cloakreferer.com': true, 'www.shortener.net': true, 'www.x.se': true, 'xii.li': true, 'xrl.us': true, 'xr.com': true, 'yatuc.com': true, 'yep.it': true, /*'zurl.ws': true,*/ 'zz.gd': true }; function request_for(a) { if (a.hostname in {'bit.ly': true, 'bitly.com': true}) return 'http://api.bit.ly/expand?version=2.0.1&format=xml' + '&login=tinyurldecoder&apiKey=R_42e55650000a21fa8cf2caa2778b5aaf' + '&shortUrl=' + a.href; else if (a.hostname === 'chilp.it') return 'http://p.chilp.it/api.php' + a.search; else if (a.hostname === 'cli.gs' && a.pathname.indexOf('/api') !== 0) return 'http://cli.gs/api/v1/cligs/expand?clig=' + a.href; else if (a.hostname === 'digg.com' && a.search.length > 0) return null; else if (a.hostname === 'good.ly' && a.pathname.indexOf('/-') === 0) return null; else if (a.hostname === 'idek.net' && a.search.indexOf('?idek-api') !== 0) return a.href + '?idek-api=true'; else if (a.hostname === 'kissa.be' && a.pathname.indexOf('/api') !== 0) return 'http://kissa.be/api/expander' + a.pathname; else if (a.hostname === 'migre.me' && a.pathname.indexOf('/api') !== 0) return 'http://migre.me/api_redirect.xml?url=' + a.href; else if (a.hostname === 'poprl.com' && a.pathname.indexOf('/api') !== 0) return 'http://poprl.com/api/lookup/alias' + a.pathname; else if (a.hostname === 'r.im' && a.pathname.indexOf('/api') !== 0) return 'http://r.im/api/index.cfm?short_url=' + a.href; else if (a.hostname === 'togoto.us' && a.pathname.indexOf('l-api') !== 0) return 'http://togoto.us/l-api.php?t=' + a.pathname.substr(1); else if (a.hostname === 'tr.im') return 'http://api.tr.im/api/trim_destination.xml' + '?trimpath=' + a.pathname.substr(1); else if (a.hostname === 'u.nu' && a.href.indexOf('?') > 0) return 'http://u.nu' + a.pathname; else if (a.hostname === 'urlenco.de' && a.pathname.indexOf('PostJSON') !== 0) return 'http://urlenco.de/PostJSON.aspx?decode=' + a.href; else if (a.hostname === 'zz.gd' && a.pathname.indexOf('/api') !== 0) return 'http://zz.gd/api-decrypt.php?url=' + a.href; else return a.href; } function extract_from_response(resp) { var pat = null; var a = document.createElement('a'); a.href = resp.finalUrl; if (a.hostname === '6url.com') pat = '<title>Redirects\\s+to\\s+(.*?)</title>'; else if (a.hostname === 'arm.in') pat = 'noresize><frame\\s+src="(.*?)"\\s+name="ContentWindow"'; else if (a.href.indexOf('http://api.bit.ly/expand') === 0) pat = '<longUrl>(.*?)</longUrl>'; else if (a.href.indexOf('http://api.tr.im/api/trim_destination.xml') === 0) pat = '<destination>(.*?)</destination>'; else if (a.hostname === 'burnurl.com') pat = '<link\\s+rel="canonical"\\s+href="(.*?)"\\s*/>'; else if (a.hostname === 'digg.com') pat = 'id="diggiFrame"\\s+name="diggiFrame"\\s+noresize="noresize"\\s+src="(.*?)"'; else if (a.hostname === 'gol.ly' && a.pathname === '/tinyurl.php') pat = '<iframe\\s+id="tree"\\s+name="tree"\\s+src="(.*?)"'; else if (a.hostname === 'link.gs') pat = '<frame\\s+src="(.*?)"\\s+name="Body">' else if (a.hostname === 'lin.cr') pat = 'content="0;url=(.*?)"'; else if (a.hostname === 'lnk.by') pat = '<meta\\s+HTTP-EQUIV="REFRESH"\\s+content="0; url=(.*?)">' else if (a.hostname === 'lnk.in') pat = "redirect\\('(.*?)'\\)"; else if (a.hostname === 'm2lb.info') pat = '<meta\\s+http-equiv="REFRESH"\\s+content="10;url=(.*?)">'; else if (a.href.indexOf('http://migre.me/api_redirect.xml') === 0) pat = '<url>(.*?)</url>'; else if (a.hostname === 'minurl.org') pat = 'getTwitterSearchResults\\("(.*?)"\\);'; else if (a.hostname === 'myurl.in') pat = 'window.location.href=\\("(.*?)"\\);'; else if (a.hostname === 'nsfw.in') pat = 'name="query"\\s+value="(.*?)"'; else if (a.hostname === 'oneclip.jp') pat = '<input\\s+type="hidden"\\s+name="data\\[Source\\]\\[url\\]"\\s+value="(.*?)"\\s+id="SourceUrl"\\s+/>'; else if (a.hostname === 'ow.ly') pat = 'Click\\s+<a\\s+href="(.*?)">here</a>'; else if (a.hostname === 'p.zurl.ws') pat = '<blockquote><strong>(.*?)</strong></blockquote>'; else if (a.hostname === 'qurlyq.com') pat = 'redirect\\(\\\'(.*?)\\\'\\);'; else if (a.hostname === 'rt.nu') pat = '<title>(.*?)</title>'; else if (a.hostname === 'www.shortener.net') pat = 'window.location="(.*?)";'; else if (a.hostname === 'shuurl.com') pat = 'directed\\s+to:\\s+<a\\s+href="(.*?)"'; else if (a.hostname === 'simurl.com') pat = 'content="0;\\s+URL=(.*?)"'; else if (a.href.indexOf('http://tinyurl.com/preview.php') === 0) pat = 'id="redirecturl"\\s+href="(.*?)"'; else if (a.hostname === 'unhub.com') pat = '<link\\s+href="(.*?)"\\s+rel="canonical"/>' else if (a.href.indexOf('http://urlenco.de/PostJSON.aspx') === 0) pat = '"url"\\s+:\\s+"(.*?)"'; else if (a.hostname === 'viigo.im') pat = '<a\\s+href="(.*?)"\\s+title="Close">'; else if (a.hostname === 'w3t.org') pat = "window.location='(.*?)'"; else if (a.hostname === 'xr.com') pat = '<a\\s+href="(.*?)"\\s+target=parent>'; else if (a.href.indexOf('http://cli.gs/api/v1/cligs/expand') === 0 || (a.hostname === 'idek.net' && a.search === '?idek-api=true') || a.href.indexOf('http://kissa.be/api/expander/') === 0 || a.href.indexOf('http://poprl.com/api/lookup/alias') === 0 || a.href.indexOf('http://p.chilp.it/api.php') === 0 || a.href.indexOf('http://r.im/api/index.cfm?short_url=') === 0 || a.href.indexOf('http://togoto.us/l-api.php') === 0 || a.href.indexOf('http://zz.gd/api-decrypt.php') === 0) return resp.responseText.replace(/[\n\r]/g, ''); if (pat) try { theUrl = resp.responseText.match(pat, 'i')[1]; } catch (err) { theUrl = null; } else theUrl = resp.finalUrl; return theUrl; } var working = {}; function decode_shortened_url(_node) { if (cache[_node.href]) { _node.title = 'was ' + _node.href; _node.innerHTML = cache[_node.href]; _node.href = cache[_node.href]; } else { if (working[_node.href]) return; else working[_node.href] = true; var _url = request_for(_node); if (_url) GM_xmlhttpRequest({ method: "GET", url: _url, onload: function(resp) { finalUrl = extract_from_response(resp); if (finalUrl) { cache[_node.href] = finalUrl; working[_node.href] = false; } }, onerror: function(resp) { GM_log('Oops! Access error to ' + _node.href); } }); } } function main() { var counter = 0; var anchors = d.getElementsByTagName('a'); var anchors_length = anchors.length; for (var i=0; i<anchors_length; i++) { if (anchors[i].pathname.length === 1 && anchors[i].search.length < 2) continue; else if (anchors[i].hostname in services) { decode_shortened_url(anchors[i]); counter++; } } GM_setValue('cache', cache.toSource()); if (counter === 0) { setTimeout(main, 60000); working = {}; } else { setTimeout(main, 10000 / counter); } } main(); }(document));
こういうスタイルでやるヤツは、きっと wedata とか使えばいいんだと思われる。