Created
March 4, 2009 05:20
-
-
Save masukomi/73728 to your computer and use it in GitHub Desktop.
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
//twtplus | |
//Forked from: http://sites.google.com/site/coosgadgets/2ii | |
//Cleared out hacks, refactored code | |
//Additional features: | |
//*Shorten all urls in a post | |
//*d message with friend username autocompletion | |
//*Post as specified user using "as" modifier | |
//Visit for more explanation: http://damienh.org/2009/03/02/twtplus-the-missing-twitter-command-for-ubiquity-and-firefox/ | |
twitter_template = "\ | |
<div style=\"overflow: auto; height: 450px;\"> \ | |
{for entry in entries} \ | |
<div style=\"margin:0;padding:2px;padding-left:4px;background-color:{if entry_index%2 == 0}#555{else}#313131{/if};border:solid 1px;border-top-color:#484848;border-left:solid 3px #ccc;border-right-color:#2c2c2c;border-bottom-color:#2b2b2b;font-size:13px;-moz-border-radius:5px;\"> \ | |
<a href=\"http://twitter.com/home?in_reply_to=${entry.user.screen_name}&in_reply_to_status_id=${entry.id}&status=%40${entry.user.screen_name}+\" ><img src=\"${entry.user.profile_image_url}\" style=\"height: 2em; float: left;margin-right:3px; margin-top:4px;border:none;\"/></a> \ | |
<span style=\"font-weight: bold\">${entry.user.screen_name}</span> \ | |
<span>${entry.text}</span> \ | |
<div style=\"clear:both;\"></div> \ | |
</div> \ | |
{/for}</div>"; | |
const STATUS_MAXLEN = 140; | |
var store = Application.storage; | |
var prefs = Application.prefs; | |
const JWP_PREFIX = "ubiquity_twitter_plus"; | |
const JWP_TIMELINE = JWP_PREFIX+"_timeline"; | |
const JWP_TIMELINE_DATE = JWP_PREFIX+"_timeline_date"; | |
const JWP_CUR_LOGIN = JWP_PREFIX+"_cur_login"; | |
var $j = jQuery; | |
function setCurLogin(login){ | |
store.set(JWP_CUR_LOGIN, login); | |
} | |
function getCurLogin(){ | |
var login = store.get(JWP_CUR_LOGIN, ''); | |
if(!login){ | |
logins = getTwitterIds(); | |
if(logins.length > 0){ | |
login = logins[0]; | |
setCurLogin(login); | |
} | |
} | |
return login; | |
} | |
function make_basic_auth(user, password){ | |
var tok = user + ":" + password; | |
var hash = CmdUtils.getWindow().btoa(tok); //Base64 encode. | |
return "Basic " + hash; | |
} | |
function get_twitter_friends(callback) { | |
var curLogin = getCurLogin(); | |
if( curLogin ){ | |
var auth = make_basic_auth(curLogin.username, curLogin.password); | |
} else { | |
var auth = null; | |
} | |
$j.ajax({ | |
url: "http://twitter.com/statuses/friends.json", | |
type: "GET", | |
dataType: "json", | |
beforeSend: function(req) { | |
if( auth ) req.setRequestHeader("Authorization", auth); | |
}, | |
success: function(data) { | |
var friends = []; | |
for (var i in data) { | |
var friend = data[i]; | |
friends.push(friend.screen_name); | |
} | |
callback(friends); | |
}, | |
error: function() { | |
displayMessage('Failed to get twitter friends'); | |
}, | |
}); | |
} | |
var noun_twitter_friend = { | |
_name: "twitter friend", | |
friend_list: null, | |
callback: function(friends) { | |
noun_twitter_friend.friend_list = friends; | |
}, | |
suggest: function(text, html) { | |
if (noun_twitter_friend.friend_list == null) { | |
get_twitter_friends(this.callback); | |
return []; | |
} | |
if (text.length < 2) | |
return []; | |
var suggestions = []; | |
for (i=0;i<noun_twitter_friend.friend_list.length;i++) { | |
if (noun_twitter_friend.friend_list[i].match(text, "i")) | |
suggestions.push(CmdUtils.makeSugg(noun_twitter_friend.friend_list[i])); | |
} | |
return suggestions.splice(0, 5); | |
} | |
}; | |
function getTwitterIds () { | |
var passwordManager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); | |
var logins = passwordManager.findLogins({}, "http://twitter.com", "", null); | |
return logins; | |
} | |
var noun_twitter_id = { | |
_name: "Twitter ID", | |
id_list: null, | |
suggest: function(text, html){ | |
if (text.length < 2) return []; | |
if (noun_twitter_id.id_list == null){ | |
noun_twitter_id.id_list = getTwitterIds(); | |
} | |
var suggs = []; | |
for (var i = noun_twitter_id.id_list.length - 1; i >= 0; i--){ | |
if(noun_twitter_id.id_list[i].username.match(text, "i")) | |
suggs.push(CmdUtils.makeSugg(noun_twitter_id.id_list[i].username)); | |
}; | |
return suggs.splice(0,5); | |
} | |
} | |
CmdUtils.CreateCommand({ | |
name: "twtplus", | |
synonyms: ["twitter","tweet"], | |
icon: "http://assets1.twitter.com/images/favicon.ico", | |
author: { | |
name: "Damien Hou", | |
email: "[email protected]" | |
}, | |
description: "Post message to Twitter.com with nifty features", | |
homepage: "http://damienh.org/category/geek-stuff/ubiquity-geek-stuff/", | |
license: "MIT/MPL", | |
takes: { | |
"message": noun_arb_text | |
}, | |
modifiers: { | |
"@": noun_twitter_friend, | |
as: noun_twitter_id, | |
d: noun_twitter_friend | |
}, | |
getShortenedUrl: function(url){ | |
var shortUrl = url; | |
$j.ajax({ | |
type: "GET", | |
async: false, | |
url: 'http://is.gd/api.php', | |
data: { | |
'longurl': url | |
}, | |
error: function() { | |
displayMessage("Failed to shorten URL"); | |
}, | |
success: function(shortened) { | |
shortUrl = shortened; | |
} | |
}); | |
return shortUrl; | |
}, | |
hasTimeline: function () { | |
return store.has(JWP_TIMELINE); | |
}, | |
getTimeline: function () { | |
if (this.hasTimeline()) { | |
return store.get(JWP_TIMELINE,''); | |
}else{ | |
return ''; | |
} | |
}, | |
setTimeline: function (timeline){ | |
store.set(JWP_TIMELINE, timeline); | |
}, | |
timelineExpired: function () { | |
var now = new Date(); | |
var update = store.has(JWP_TIMELINE_DATE) ? store.get(JWP_TIMELINE_DATE,'') : undefined; | |
if (update != undefined) { | |
delta = now - update; | |
return delta > 120000; | |
}else{ | |
return false; | |
} | |
}, | |
_update_timeline: function(p) { | |
//CmdUtils.log('updating timeline'); | |
var now = new Date(); | |
if (this.hasTimeline() && !this.timelineExpired()) { | |
$j('#timeline',p).html(this.getTimeline()); | |
} else { | |
var curLogin = getCurLogin(); | |
if( curLogin ){ | |
var auth = make_basic_auth(curLogin.username, curLogin.password); | |
} else { | |
var auth = null; | |
} | |
$j.ajax({ | |
url:"http://twitter.com/statuses/friends_timeline.json", | |
params:{count: 10}, | |
type:'GET', | |
dataType:"json", | |
beforeSend: function(req) { | |
if( auth ) req.setRequestHeader("Authorization", auth); | |
}, | |
success: function(data) { | |
data = data.slice(0,10); | |
for (var entry in data) { | |
data[entry]['text'] = data[entry]['text'].replace(/(https*:\/\/.*?)(\s|$)/gi, "<nobr><a href=\"$1\">$1</a></nobr>").replace(/@(\w+)/g, "<a href=\"http://twitter.com/$1\">@$1</a>").replace(/<a href/g, "<a style=\"color:#9999FF;\" href"); | |
} | |
timeline = CmdUtils.renderTemplate(twitter_template, { | |
entries: data | |
}); | |
store.set(JWP_TIMELINE, timeline); | |
store.set(JWP_TIMELINE_DATE, new Date()); | |
$j('#timeline',p).html(store.get(JWP_TIMELINE, '')); | |
} | |
}); | |
} | |
}, | |
preview: function(p, input, mods) { | |
p.innerHTML = "<div id='status'></div><div id='help'></div><div id='movies'><ul></ul></div><div id='books'><ul></ul></div><div id='music'><ul></ul></div><div style='clear:both'></div><div id='timeline'></div>"; | |
var results = this._processStatus(input.text, mods); | |
var status = results['status']; | |
$j('#status', p).html('Preview: ' + results['status']); | |
var rem = STATUS_MAXLEN - status.length; | |
var help = "<p style=\"font-size:smaller;\">Remaining: " + rem + " chars. Type #url for the current URL. Click avatar to reply.</p>" | |
$j('#help',p).html(help); | |
this._update_timeline(p); | |
}, | |
_processStatus: function(status, mods) { | |
var elements = {}; | |
//first, replace #url tag with actual current url | |
var curUrl = CmdUtils.getDocument().URL; | |
status = status.replace(/(^|\s)#url(\s|$)/, "$1" + curUrl + "$2"); | |
//shorten all urls | |
var urls = status.match(/((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/g); | |
if(urls){ | |
for (var i=0; i < urls.length; i++) { | |
var shortened = this.getShortenedUrl(urls[i]); | |
status = status.replace(urls[i], shortened); | |
}; | |
} | |
if(mods.d && mods.d.text){ | |
status = 'd '+mods.d.text+' '+status; | |
} | |
if (mods["@"] && mods["@"].text) { | |
status = "@" + mods["@"].text + " " + status; | |
} | |
elements['status'] = status; | |
return elements; | |
}, | |
execute: function(directObj, mods) { | |
var statusText = this._processStatus(directObj.text, mods)['status']; | |
if (statusText.length < 1) { | |
displayMessage("Forgot something to say?"); | |
return; | |
} | |
// detect the "as" phrase to select current twitter login user to post message | |
var logins = getTwitterIds(); | |
if(mods.as && mods.as.text){ | |
var asLogin = mods.as.text; | |
for (var i = logins.length - 1; i >= 0; i--){ | |
if (logins[i].username == asLogin){ | |
setCurLogin(logins[i]); | |
var name = getCurLogin().username; | |
break; | |
} | |
} | |
} | |
var curLogin = getCurLogin(); | |
if( curLogin ){ | |
var auth = make_basic_auth(curLogin.username, curLogin.password); | |
} else { | |
var auth = null; | |
} | |
var updateUrl = "https://twitter.com/statuses/update.json"; | |
var updateParams = { | |
source: "ubiquity", | |
status: statusText | |
}; | |
$j.ajax({ | |
type: "POST", | |
url: updateUrl, | |
data: updateParams, | |
dataType: "json", | |
beforeSend: function(req) { | |
if( auth ) req.setRequestHeader("Authorization", auth); | |
}, | |
error: function(xhr, status, error) { | |
displayMessage("Twitter error - status not updated because: " + xhr.statusText); | |
}, | |
success: function() { | |
if(auth){ | |
displayMessage("Twitter message posted as " + getCurLogin().username); | |
}else{ | |
displayMessage("Twitter message posted"); | |
} | |
} | |
}); | |
} | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment