Instantly share code, notes, and snippets.
Created
March 29, 2010 10:50
-
Star
3
(3)
You must be signed in to star a gist -
Fork
1
(1)
You must be signed in to fork a gist
-
Save saitamanodoruji/347734 to your computer and use it in GitHub Desktop.
Share2chOnTumblr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Share2chOnTumblr | |
// @namespace http://saitamanodoruji.tumblr.com/ | |
// @description Share 2ch conversation on Tumblr as Quote | |
// @include http://*.2ch.net/test/read.cgi/* | |
// @include http://*.2ch.net/*/kako/* | |
// @include http://*.bbspink.com/test/read.cgi/* | |
// @include http://jbbs.livedoor.jp/bbs/read.cgi/* | |
// @include http://jbbs.livedoor.jp/*/*/*/*.html | |
// @include http://p2.chbox.jp/read.php?url=http://*.2ch.net/test/read.cgi/* | |
// @include http://mimizun.com/* | |
// @include http://unkar.org/r/* | |
// @include http://yomi.mobi/read.cgi/temp/* | |
// @include http://ex14.vip2ch.com/test/read.cgi/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://*.2ch.net/test/read.cgi/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://*.2ch.net/*/kako/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://*.bbspink.com/test/read.cgi/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://jbbs.livedoor.jp/bbs/read.cgi/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://jbbs.livedoor.jp/*/*/*/*.html | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://p2.chbox.jp/read.php?url=http://*.2ch.net/test/read.cgi/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://mimizun.com/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://unkar.org/r/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://yomi.mobi/read.cgi/temp/* | |
// @include http://webcache.googleusercontent.com/search?q=cache:http://ex14.vip2ch.com/test/read.cgi/* | |
// @version 0.2.12 | |
// @update 2013-12-26 | |
// ==/UserScript== | |
// 必要なもの: | |
// LDRize http://coderepos.org/share/browser/lang/javascript/userscripts/ldrize.user.js? | |
// Minibuffer http://coderepos.org/share/browser/lang/javascript/userscripts/minibuffer.user.js? | |
// sharedObject http://exe.tyo.ro/2011/11/greasemonkey0912minibufferldrize.html | |
// | |
// 使い方: | |
// 1. 2ちゃんねるのスレを開く | |
// 2. j、k で Quote したいレスを選んで p で pin する | |
// 3. ショートカットキーの q を押すか、Alt + x で Minibuffer を開いて | |
// pinned-or-current-node|share2chontumblr|clear-pin と入れて Enter を押す | |
// 4. pin したレスがまとまって 1 個の Quote ポストになる | |
// | |
// reference: | |
// ShareTwitterOnTumblr by snj14 | |
// http://white.s151.xrea.com/blog/2008-03-02-09-30.html | |
// 2ch.extractor.js by ku | |
// http://gist.github.com/123087 | |
// http://ku.tumblr.com/post/27747617 | |
(function(){ | |
// ---------------------------------------------------------------------------------------- | |
// 設定 | |
// ---------------------------------------------------------------------------------------- | |
const KEY_TO_SHARE_IN_PLAIN_TEXT = 'q'; | |
// プレーンテキストで Quote するためのショートカットキー | |
// 使わないときは 'q' を '' にする | |
// | |
const KEY_TO_SHARE_IN_HTML = 'Q'; | |
// HTML で Quote するためのショートカットキー | |
// 使わないときは 'Q' を '' にする | |
// | |
const SHARE2CHONTUMBLR_HTML_QUOTE_FORMAT = 0; | |
// HTML Quote の形式 | |
// 0: そのまま | |
// 1: 成形する (2ch.extractor.js 方式。dd,dt を使わないので Dashboard では見やすい) | |
// | |
const SHARE2CHONTUMBLR_POST_STATE = 0; | |
// 公開設定 | |
// 0: publish now | |
// 1: save as draft | |
// 2: add to queue | |
// 3: private | |
// | |
const SHARE2CHONTUMBLR_ALLOW_PHOTO_REPLIES = 1; | |
// photo reply の許可 | |
// 0: 不許可 | |
// 1: 許可 | |
// | |
const SEND_TO_TWITTER = 0; | |
// twitter にも送るか(送るには Tumblr に twitter account を登録する必要がある) | |
// 0: 送らない | |
// 1: 送る | |
// ---------------------------------------------------------------------------------------- | |
const DSBD_URL = 'http://www.tumblr.com/dashboard'; | |
const SECURE_FORM_KEY_URL = 'http://www.tumblr.com/svc/secure_form_key'; | |
const UPDATE_URL = 'http://www.tumblr.com/svc/post/update'; | |
var boot = function() { | |
var $X = sharedObject.Minibuffer.$X | |
var D = sharedObject.Minibuffer.D | |
var status = sharedObject.Minibuffer.status | |
var createDocumentFromString = sharedObject.Minibuffer.createDocumentFromString | |
function getSource(url){with(D()){return xhttp.get(url)}} | |
function postData(url, aData){with(D()){return xhttp.post(url, aData)}} | |
function createBody(stdin, format) { | |
var res = []; | |
var dt = stdin.map(function(s){return s.innerHTML;}); | |
var dd = stdin.map(function(s){ | |
if ( window.location.href.match(/^http:\/\/mimizun\.com/) ) { | |
var r = $X('./following-sibling::div[contains(concat(" ", @class, " "), " res ")]', s)[0] | |
.innerHTML.replace(/<br>/g, '<br />') + "<br /><br />"; | |
var mimizunAdXPath = './/img[contains(@alt, "ads")] |' + | |
'.//img[contains(@alt, "ads")]/following-sibling::a |' + | |
'.//img[contains(@alt, "ads")]/following-sibling::br |' + | |
'.//script | .//noscript | .//noscript/following-sibling::br |' + | |
'.//iframe | .//iframe/following-sibling::br'; | |
var doc = createDocumentFromString(r); | |
$X(mimizunAdXPath, doc).forEach(function(n) {n.parentNode.removeChild(n);}); | |
return $X('//body', doc)[0].innerHTML.replace(/<br>/g, '<br />').replace(/\s+$/, '').replace(/<!--.*?-->/g, ''); | |
} else { | |
return $X('./following-sibling::dd[not(contains(concat(" ", @class, " "), " respopup "))]', s)[0] | |
.innerHTML.replace(/<br>/g, '<br />'); | |
} | |
}); | |
if ( window.location.href.match(/^http:\/\/unkar\.org\/r/) ) { | |
var dd0 = createDocumentFromString(dd[0]); | |
var div0 = $X('//div[script]', dd0)[0]; | |
if (div0) div0.parentNode.removeChild(div0); | |
dd[0] = $X('//body', dd0)[0].innerHTML; | |
dd = dd.map(function(dd){ | |
return dd + '<br /><br />'; | |
}); | |
} | |
switch(format) { | |
// HTML (raw) | |
case 0: | |
for (i = 0; i < stdin.length; i++) { | |
dt[i] = '<dt>' + dt[i] + '</dt>'; | |
dd[i] = '<dd>' + dd[i] + '</dd>'; | |
res[i] = [dt[i], dd[i]].join(''); | |
} | |
break; | |
// HTML (2ch.extractor.js) | |
case 1: | |
for (i = 0; i < stdin.length; i++) { | |
res[i] = [dt[i], dd[i]].join('<br />'); | |
} | |
break; | |
// plain text | |
case 2: | |
for (i = 0; i < stdin.length; i++) { | |
dt[i] = stdin[i].textContent; | |
dd[i] = dd[i].replace(/<br \/>/g, '\n').replace(/<[^>]+>/g, ''); | |
res[i] = [dt[i], dd[i]].join('\n'); | |
} | |
break; | |
} | |
return res.join(''); | |
} | |
function createSource(stdin) { | |
var resNums = []; | |
var resRange = ''; | |
for (i = 0; i < stdin.length; i++) { | |
try { | |
resNums[i] = stdin[i].innerHTML.match(/^\s*(\d+)/)[1]; | |
} catch(e) {} | |
} | |
if(resNums.length > 1) { | |
resNums.sort(function(a, b) { return a - b }); | |
resRange = resNums[0] + '-' + resNums[resNums.length - 1]; | |
} else if(resNums.length == 1) { | |
resRange = resNums[0]; | |
} | |
if ( document.location.toString().match(/^((?:http:\/\/p2\.chbox\.jp\/read\.php\?url=)?http:\/\/(?:[^.]+\.(?:2ch\.net|bbspink\.com)\/test\/read\.cgi\/|mimizun\.com\/log\/2ch\/|yomi\.mobi\/read\.cgi\/temp\/[^_]+_[^_]+_)[^\/]+\/\d+)/) ) { | |
var url = RegExp.$1 + '/' + resRange; | |
} else { | |
var url = document.location.toString(); | |
} | |
return '<a href="' + url + '">' + document.title + '</a>'; | |
} | |
function parseParams(doc){ | |
var elms = $X('id("edit_post")//*[translate(name(),"input", "INPUT") ="INPUT" or translate(name(),"textarea", "TEXTAREA")="TEXTAREA" or translate(name(),"select", "SELECT")="SELECT"]', doc); | |
var params = {}; | |
elms.forEach(function(elm){ | |
if(elm.nodeName == 'INPUT' && elm.type=='checkbox' && !elm.checked) { | |
params[elm.name] = ''; | |
} else { | |
params[elm.name] = elm.value; | |
} | |
}); | |
return params; | |
} | |
function createPostData(params, body, source){ | |
var arr = []; | |
var param; | |
var postState = [0, 1, 2, 'private']; | |
for(param in params){ | |
if (!/(?:preview_post|send_to_twitter|post\[promotion_type\]|post\[highlight\]|post\[typekit\])/.test(param) | |
|| (param == 'send_to_twitter' && SEND_TO_TWITTER) ) { | |
arr.push(encodeURIComponent(param)); | |
arr.push('='); | |
if(param == 'post[one]') { | |
arr.push(body); | |
} else if(param == 'post[two]') { | |
arr.push(source); | |
} else if(param == 'post[source_url]') { | |
arr.push(decodeURIComponent(source).replace(/^<a href="([^"]*)">[^<]*<\/a>/, '$1')); | |
} else if(param == 'post[state]') { | |
arr.push(postState[SHARE2CHONTUMBLR_POST_STATE]); | |
} else if(param == 'allow_photo_replies' && SHARE2CHONTUMBLR_ALLOW_PHOTO_REPLIES) { | |
arr.push('on'); | |
} else { | |
arr.push(encodeURIComponent(params[param])); | |
} | |
arr.push('&'); | |
} | |
} | |
return arr.join('') | |
} | |
function share(body, source) { | |
var form_key, channel_id, secure_form_key, shared = D(); | |
shared.xhttp.get(DSBD_URL). | |
next(function(res){ | |
var doc = createDocumentFromString(res.responseText); | |
form_key = doc.querySelector('#search_form input[name="form_key"]').value; | |
channel_id = doc.querySelector('#search_form input[name="t"]').value; | |
return shared.xhttp({ | |
method : 'post', | |
url : SECURE_FORM_KEY_URL, | |
headers : { 'X-tumblr-form-key': form_key }, | |
}); | |
}). | |
next(function(res){ | |
secure_form_key = res.responseHeaders.match(/(?:^|\s)X-tumblr-secure-form-key: (.+)(?:$|\s)/)[1]; | |
var data = { | |
form_key: form_key, | |
post: {}, | |
context_id: '', | |
context_page: 'dashboard', | |
'is_rich_text[one]': '0', | |
'is_rich_text[two]': '0', | |
'is_rich_text[three]': '0', | |
channel_id: channel_id, | |
'post[slug]': '', | |
'post[source_url]': 'http://', | |
'post[date]': '', | |
'post[type]': 'quote', | |
'post[one]': body, | |
'post[two]': source, | |
'post[tags]': '', | |
'post[publish_on]': '', | |
'post[state]': '' | |
}; | |
return shared.xhttp({ | |
method: 'post', | |
url: UPDATE_URL, | |
data: JSON.stringify(data), | |
headers: { | |
'Content-Type' : 'application/json', | |
'X-tumblr-puppies' : secure_form_key, | |
}, | |
}); | |
}). | |
error(function(arg){ | |
console.log('error',arg); | |
}); | |
} | |
function share2chOnTumblr(stdin, format) { | |
if(!stdin.length){ | |
status('Share2chOnTumblr', 'no item', 100); | |
} else { | |
var body = createBody(stdin, format); | |
var source = createSource(stdin); | |
var time = new Date().getTime(); | |
with(D()){ | |
next(function() { | |
share(body, source); | |
}) | |
.next(function(res){ | |
status('Share2chOnTumblr'+time, 'Share', 100); | |
}) | |
} | |
} | |
} | |
sharedObject.Minibuffer.addCommand({ | |
name: 'share-2ch-on-tumblr', | |
command: function(stdin) { | |
share2chOnTumblr(stdin, 2); | |
return stdin; | |
} | |
}); | |
sharedObject.Minibuffer.addCommand({ | |
name: 'share-2ch-on-tumblr-html', | |
command: function(stdin) { | |
share2chOnTumblr(stdin, SHARE2CHONTUMBLR_HTML_QUOTE_FORMAT); | |
return stdin; | |
} | |
}); | |
if (KEY_TO_SHARE_IN_PLAIN_TEXT) { | |
sharedObject.Minibuffer.addShortcutkey({ | |
key: KEY_TO_SHARE_IN_PLAIN_TEXT, | |
description: 'Share2chOnTumblr', | |
command : function(){ | |
sharedObject.Minibuffer.execute('pinned-or-current-node|share-2ch-on-tumblr|clear-pin'); | |
} | |
}); | |
} | |
if (KEY_TO_SHARE_IN_HTML) { | |
sharedObject.Minibuffer.addShortcutkey({ | |
key: KEY_TO_SHARE_IN_HTML , | |
description: 'Share2chOnTumblr-HTML', | |
command : function(){ | |
sharedObject.Minibuffer.execute('pinned-or-current-node|share-2ch-on-tumblr-html|clear-pin'); | |
} | |
}); | |
} | |
} | |
if (sharedObject.Minibuffer) { | |
boot(); | |
} else { | |
window.addEventListener('GM_MinibufferLoaded', boot, false); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment