/*
* twitter_identica - A program to combine twitter and laconica feeds
*
* @fileOverview A script to combine multiple twitter and laconica feeds.
* @author Gavin Kinsey
* @version 1.1
*
* Copyright (c) 2009 Gavin Kinsey
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
/// @description Array to store the tweets in
var tweets = new Array();
/// @description Track which feed to pull from
var callCount = 0;
/**
* @description Convert a time string to the age of the tweet
* @param time The time string
* @returns The age
*/
function dateToAge(time) {
var month = 1000 * 60 * 60 * 24 * 30;
var week = 1000 * 60 * 60 * 24 * 7;
var day = 1000 * 60 * 60 * 24;
var hour = 1000 * 60 * 60;
var minute = 1000 * 60;
var second = 1000;
var now = new Date();
var then = new Date();
then.setTime(Date.parse(time));
var diff = now - then;
var text = '';
if (diff > month) {
text = Math.floor(diff / month) + ' months';
}
else if (diff > week) {
text = Math.floor(diff / week) + ' weeks';
}
else if (diff > day) {
text = Math.floor(diff / day) + ' days';
}
else if (diff > hour) {
text = Math.floor(diff / hour) + ' hours';
}
else if (diff > minute) {
text = Math.floor(diff / minute) + ' minutes';
}
else {
text = Math.floor(diff / second) + ' seconds';
}
text += ' ago';
return text;
}
/**
* @description Make a JSON call
* @param Url of handler to call
* @param Event to call when complete
* @param Event to call when an error is encountered
*/
function reqJSON(url, success, error)
{
var CallParams = { };
CallParams.type = "GET";
CallParams.url = url;
//CallParams.username = username;
//CallParams.password = password;
CallParams.processData = true;
//CallParams.cache = false;
CallParams.dataType = "json";
CallParams.success = success;
if (error) {
CallParams.error = error;
}
$.ajax(CallParams);
}
/**
* @description Compare two tweets based on their timestamps
* @param a First tweet
* @param b Second tweet
* @returns -1 if a is newer than b else 1
*/
function sortTweets(a, b)
{
var timea = new Date();
var timeb = new Date();
timea.setTime(Date.parse(a.created_at));
timeb.setTime(Date.parse(b.created_at));
if (timea > timeb) {
return -1;
}
else {
return 1;
}
}
/**
* @description Strip off the end of a URL to get the site address
* @param fullurl The URL http://www.example.com/some/other/text
* @returns http://www.example.com/
*/
function getBaseUrl(fullurl)
{
var stripped = '';
if (fullurl.substr(0, 8) == 'https://') {
stripped = fullurl.substring(8);
}
else {
stripped = fullurl.substring(7);
}
var endIndex = stripped.search('/');
stripped = stripped.substr(0, endIndex);
return stripped;
}
/**
* @description Go through all the existing tweets and check if the new one
* is there already
* @param oldTweets An array of all the existing tweets
* @param newTweet The new tweet
* @returns true or false
*/
function checkForDups(oldTweets, newTweet)
{
var dupe = false;
$.each(oldTweets, function(i, tweet) {
if (tweet.text == newTweet.text) {
dupe = true;
}
});
return dupe;
}
/**
* @description Search the text for links and make them clickable
* @param startMarker Text to look for that indicates a link
* @param text The original text
* @param prefix Text to put in front of the URL
* @returns Text with links
*/
function addLink(startMarker, text, prefix)
{
var endindex = 0;
while (endindex < text.length) {
startindex = text.indexOf(startMarker, endindex);
if (startindex >= 0) {
endindex = text.indexOf(' ', startindex);
if (endindex < 0) {
endindex = text.length;
}
before = text.substring(0, startindex);
url = text.substring(startindex, endindex);
after = text.substring(endindex);
href = url.link(prefix + url.replace('@', ''));
text = before + href + after;
endindex = before.length + href.length
}
else {
break;
}
}
return text;
}
/**
* @description Convert http https and @ replies to links
* @param text The original text
* @param baseUrl Site the tweet came from (to use for @s)
* @returns Text with links
*/
function addLinks(text, baseUrl)
{
text = addLink('https://', text, '');
text = addLink('http://', text, '');
text = addLink('@', text, baseUrl);
return text
}
function escapeHTML(text)
{
var escaped = text;
escaped = escaped.replace(/&/g, '&');
escaped = escaped.replace(//g, '>');
escaped = escaped.replace(/\"/g, '"');
escaped = escaped.replace(/\'/g, ''');
return escaped;
}
/**
* @description JSON request succeeded,
* process the data and insert it into the web page
* @param json The json data received
* @param textStatus Result code
*/
function readJson(json, textStatus)
{
//Successful call
//Do stuff with the JSON
//mb.append('Got json data ' + json.length + '
');
//mb.append(textStatus);
var requestUrl = this.url;
var baseUrl = getBaseUrl(requestUrl);
// Clear out any old tweets from the html
$("p.tweet").remove();
// Delete old tweets from this url from the list
var oldtweets = tweets;
tweets = new Array();
$.each(oldtweets, function(i, item) {
if (item.baseUrl != baseUrl) {
tweets[tweets.length] = item;
}
});
// Add newly retrieved tweets to the list
$.each(json, function(i, item) {
item.baseUrl = baseUrl;
if (checkForDups(tweets, item) == false) {
tweets[tweets.length] = item;
}
});
// Sort the tweet list by age
tweets.sort(sortTweets);
// Print the tweets to the html
var pretext = '
'; var postext = '
'; $.each(tweets, function(i, item) { //pretext = '';
var ago = dateToAge(item.created_at);
var base = 'http://' + item.baseUrl + '/';
var text = escapeHTML(item.text);
text = addLinks(text, base);
var userlink = item.user.screen_name.link(base + item.user.screen_name);
mb.append(pretext + ago + ': ' + userlink + ': ' + text + postext);
});
}
/**
* @description Called if JSON request failed
* @param XMLHttpRequest
* @param textStatus
* @param errorThrown
*/
function failJson(XMLHttpRequest, textStatus, errorThrown)
{
// typically only one of textStatus or errorThrown
// will have info
//
mb.append("Error getting json data
");
}
/**
* @description Main function
*/
function display() {
mb = $("#microblog");
//mb.append("Start
");
var urls = [ "https://identi.ca/api/statuses/friends_timeline.json?callback=?",
"https://twitter.com/statuses/friends_timeline.json?callback=?"
];
//var urls = [ "identica_friends.json",
// "twitter_friends.json"
// ];
//if ( 0 == $("p.tweet").length ) {
// $.each(urls, function(i, url) {
// reqJSON(url, readJson, failJson);
// });
//}
//else {
if (callCount < urls.length) {
reqJSON(urls[callCount], readJson, failJson);
callCount = callCount + 1;
}
else {
callCount = 0;
}
//}
}