By ku
—
Last update
Apr 2, 2008
—
Installed
9 times.
// ==UserScript==
// @name ShareTwitterOnHatenaDiary
// @namespace http://ido.nu/kuma/
// @description Share Twitter conversation on Hatena Diary s***s
// @include http://twitter.com/*
// @include https://twitter.com/*
// @include http://twitter.1x1.jp/search/*
// @include http://terraminds.com/twitter/*
// ==/UserScript==
// this script require Minibuffer.user.js and LDRize.user.js.
//
// How to use:
// 1. access http://twitter.com/home
// 2. type 'j' or 'k' to select status
// 3. type 'p' to pin
// 4. type M-x ( this mean Alt+x )
// 5. type "pinned-or-current-link | share-twitter-on-tumblr" ( not need " ) and Enter
// 6. access your tumblr. status you pinned will be listed.
//
(function(){
var $X = window.Minibuffer.$X
var D = window.Minibuffer.D
var status = window.Minibuffer.status
function getSource(url){with(D()){return xhttp.get(url)}}
function postData(url, aData){with(D()){return xhttp.post(url, aData)}}
function isTwitterStatusURL(aURL){
return aURL.match("^https?://twitter\\.com/[^/]+/statuses/\\d+") ? true : false;
}
function convertToHTMLDocument(html){
var xsl = (new DOMParser()).parseFromString(
'<?xml version="1.0"?>\
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">\
<output method="html"/>\
</stylesheet>', "text/xml");
var xsltp = new XSLTProcessor();
xsltp.importStylesheet(xsl);
var doc = xsltp.transformToDocument(document.implementation.createDocument("", "", null));
doc.appendChild(doc.createElement("html"));
var range = doc.createRange();
range.selectNodeContents(doc.documentElement);
doc.documentElement.appendChild(range.createContextualFragment(html));
return doc;
}
function parseStatus(doc, aURL){
function normalizeText(arr){
return arr.map(function(a){return a.nodeValue.replace(/^\s+|\s+$/g,'')}).join(' ')
}
// normalize external anchor
var arr = $X('id("permalink")/div/p[1]/a[starts-with(@href,"http")]',doc);
arr.forEach(function(node){
node.parentNode.replaceChild( doc.createTextNode(node.getAttribute('href')),node);
});
// normalize anchor for reply
var arr = $X('id("permalink")/div/p[1]/a[starts-with(@href,"/")]', doc);
arr.forEach(function(node){
node.parentNode.replaceChild(
doc.createTextNode(node.previousSibling.textContent +node.textContent) ,
node.previousSibling);
node.parentNode.removeChild(node);
});
// scrape status
var body = normalizeText($X('id("permalink")/div/p[1]//text()', doc));
var name = aURL.match('https?://twitter\\.com/([^/]+)')[1];
var ago = $X('id("permalink")//span[@class="meta"]/text()[1]', doc, String);
return {
name: name,
tweet: body,
permalink: aURL,
// FIXME: normalizeText() something wrong for this script.
ago: ago[0].nodeValue.replace(/^\s+|\s+$|from/g, '').replace(/\s+/g, ' ')
};
}
function HTMLForm(doc, base) {
function resolveLink(base, ref) {
if ( ref.match( /^\w+:\/\// ) ) {
return ref;
} else {
if ( ref[0] == "/" ) {
return base.match( /^\w+:\/\/[^\/]+/ )[0] + ref;
} else {
return base.replace( /[^\/]+$/, '' ) + ref.replace(/^\.\//, '');
}
}
}
var self = {};
var forms = $X("//form", doc).map( function(f, index) {
var form = {
action: resolveLink(base, f.action),
method: f.getAttribute('method') || 'GET',
_domnode: f,
click: function (name) {
var data = {};
var inputTypeSubmit = null;
if ( name ) {
inputTypeSubmit = self[name];
} else {
inputTypeSubmit = self.elements.filter( function (i) {
return ( i.type == 'submit' );
} ).shift();
}
if ( inputTypeSubmit ) {
data[ inputTypeSubmit.name ] = inputTypeSubmit.value;
}
this.elements.map( function (i) {
if ( i.name ) {
if ( i.type == 'submit' ) return;
if ( i.type == 'checkbox' && ! i.checked ) return;
data[ i.name ] = i.value
}
} );
var params = [];
for ( var k in data ) {
params.push( [k, data[k]].map(encodeURIComponent).join("=") );
}
var query = params.join("&");
return postData(this.action, query);
}
};
(
form.elements = $X('.//*[(name()="INPUT") or name()="TEXTAREA" or name()="SELECT"]', f)
).map( function (i) {
if ( i.name ) {
form[i.name] = i;
}
} );
self[index] = form;
if ( form._domnode.name ) {
self[form._domnode.name] = form;
}
} );
self.length = forms.length;
return self;
}
function share(body) {
with(D()) {
var u = 'http://www.hatena.ne.jp/login';
var d = xhttp.get(u).next( function (res) {
var doc = convertToHTMLDocument(res.responseText);
var result = $X('//td[@class="username"]//a/text()', doc, String);
if ( !result || result[0] == '' ) {
d.fail("notloggedin");
}
var username = result[0].nodeValue;
return username;
} ).next( function (username) {
return xhttp.get( [
'http://d.hatena.ne.jp',
username,
'edit'
].join('/') );
} ).next( function (res) {
try {
var doc = convertToHTMLDocument(res.responseText);
var htmlForm = new HTMLForm(doc, res.finalUrl);
var f = htmlForm.edit;
f.body.value = '*[chat]twitter log\n' +
body.map( function (stat) {
return [
'',
'[http://twitter.com/' + stat.name + ':title=' + stat.name + ']',
stat.tweet.replace(/\|/g, '|'),
'[' + stat.permalink + ':title=' + stat.ago + ']',
''
].join( '|');
} ).join("\n") + '\n\n\n' + f.body.value;
return f.click('edit');
}catch(e){
console.log(e)
}
} ).error( function(res) {
if ( res == 'notloggedin' ) {
window.Minibuffer.message('plz login.', 2000);
}
} );
}
}
window.Minibuffer.addCommand({
name: 'share-twitter-on-hatenaDiary',
command: function(stdin){
var args = this.args;
var urls = [];
if(!stdin.length){
// command line is just 'share-twitter-on-hatenaDiary'
urls = [window.location.href];
}else if(stdin.length && stdin.every(function(a){return a.nodeName == 'A'})){
// command line is 'pinned-or-current-link | share-twitter-on-hatenaDiary'
urls = stdin.map(function(node){return node.href});
}else{
status('ShareTwitterOnTumblr'+time, 'command line error!', 1000);
return stdin;
}
var time = new Date().getTime();
if(!urls.every(isTwitterStatusURL)){
status('ShareTwitterOnTumblr'+time, 'There is invalid URL', 1000);
return stdin;
}
// older -> newer
urls.sort(function(a,b){
return a.match(/\d+$/)[0] - b.match(/\d+$/)[0];
})
with(D()){
status('ShareTwitterOnTumblr'+time, 'Share ...');
parallel(urls.map(function(aURL){
return getSource(aURL).
next(function(res){
return parseStatus( convertToHTMLDocument(res.responseText), aURL);
})})).
next(function(arg){
function toArray(o){var res=[];for(var i in o)res[i]=o[i];return res;}
share(toArray(arg));
}).
next(function(arg){
status('ShareTwitterOnTumblr'+time, 'Share ... done', 100);
})
}
return stdin;
}
});
})()