ShareTwitterOnTumblr

By snj14 Last update Mar 1, 2008 — Installed 383 times. Daily Installs: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
// ==UserScript==
// @name           ShareTwitterOnTumblr
// @namespace      http://white.s151.xrea.com/
// @description    Share Twitter conversation on Tumblr as Chat
// @include        http://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.
// 
// latest version: 
//  http://coderepos.org/share/browser/lang/javascript/userscripts/sharetwitterontumblr.user.js?

(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/\\w+/statuses/\\d+")
}

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( document.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(
			document.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('http://twitter.com/([^/]+)')[1];
	return encodeURIComponent(name + ":" + body + " [" + aURL + "]")
}

function parseParams(doc){
	var elms = $X('id("edit_post")//*[name()="INPUT" or name()="TEXTAREA" or name()="SELECT"]', doc);
	var params = {};
	elms.forEach(function(elm){
		params[elm.name] = elm.value;
	});
	return params;
}

function createPostData(params, body){
	var arr = [];
	for(param in params){
		if(param != "preview_post"){
			arr.push(encodeURIComponent(param));
			arr.push("=");
			arr.push((param == "post[two]") ? body.join("%0D%0A") : encodeURIComponent(params[param]))
			arr.push("&");
		}
	}
	return arr.join('')
}

function share(body){
	var url = "http://www.tumblr.com/new/chat";
	getSource(url).
	next(function(res){
		return postData(url, createPostData( parseParams( convertToHTMLDocument(res.responseText)), body))
	}).
	error(function(arg){
		console.log('error',arg)
	});
}

window.Minibuffer.addCommand({
  name: 'share-twitter-on-tumblr',
  command: function(stdin){
	  var args = this.args;
	  var urls = [];
	  if(!stdin.length){
		  // command line is just 'share-twitter-on-tumblr'
		  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-tumblr'
		  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(i in o)res[i]=o[i];return res;}
				share(toArray(arg));
			}).
			next(function(arg){
				status('ShareTwitterOnTumblr'+time, 'Share ... done', 100);
			})
	  }
	  return stdin;
  }
});
})()