Skip to content

Instantly share code, notes, and snippets.

@mendezcode
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mendezcode/773a2cb1a70eceb08522 to your computer and use it in GitHub Desktop.
Save mendezcode/773a2cb1a70eceb08522 to your computer and use it in GitHub Desktop.
twitter-utils.js
// twitter-util.js (c) 2014 Ernesto Méndez
// @version 1.0.0 / Fri, 30 May 2014 03:40:18 GMT
// MIT license: http://opensource.org/licenses/MIT
// twitterlib.js (c) 2011 Remy Sharp
// @version 1.0.9 / Sun, 19 Feb 2012 23:05:25 GMT
// MIT license: http://rem.mit-license.org
(function () {
var ENTITIES = {
'"': '"',
'&lt;': '<',
'&gt;': '>'
};
var ify = function() {
return {
entities: function (t) {
return t.replace(/(&[a-z0-9]+;)/g, function (m) {
return ENTITIES[m];
});
},
link: function(t) {
return t.replace(/[a-z]+:\/\/([a-z0-9-_]+\.[a-z0-9-_:~\+#%&\?\/.=]+[^:\.,\)\s*$])/ig, function(m, link) {
return '<a title="' + m + '" href="' + m + '">' + ((link.length > 36) ? link.substr(0, 35) + '&hellip;' : link) + '</a>';
});
},
at: function(t) {
return t.replace(/(^|[^\w]+)\@([a-zA-Z0-9_]{1,15}(\/[a-zA-Z0-9-_]+)*)/g, function(m, m1, m2) {
return m1 + '<a href="http://twitter.com/' + m2 + '">@' + m2 + '</a>';
});
},
hash: function(t) {
return t.replace(/(^|[^&\w'"]+)\#([a-zA-Z0-9_^"^<]+)/g, function(m, m1, m2) {
return m.substr(-1) === '"' || m.substr(-1) == '<' ? m : m1 + '<a href="http://search.twitter.com/search?q=%23' + m2 + '">#' + m2 + '</a>';
});
},
clean: function(tweet) {
return this.hash(this.at(this.link(tweet)));
}
};
}();
var expandLinks = function (tweet) {
if (tweet === undefined) return '';
var text = tweet.text,
i = 0;
if (tweet.entities) {
// replace urls with expanded urls and let the ify shorten the link
if (tweet.entities.urls && tweet.entities.urls.length) {
for (i = 0; i < tweet.entities.urls.length; i++) {
if (tweet.entities.urls[i].expanded_url) text = text.replace(tweet.entities.urls[i].url, tweet.entities.urls[i].expanded_url); // /g ?
}
}
// replace media with url to actual image (or thing?)
if (tweet.entities.media && tweet.entities.media.length) {
for (i = 0; i < tweet.entities.media.length; i++) {
if (tweet.entities.media[i].media_url || tweet.entities.media[i].expanded_url) text = text.replace(tweet.entities.media[i].url, tweet.entities.media[i].media_url ? tweet.entities.media[i].media_url : tweet.entities.media[i].expanded_url); // /g ?
}
}
}
return text;
};
var time = function () {
var monthDict = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return {
time: function (date) {
var hour = date.getHours(),
min = date.getMinutes() + "",
ampm = 'AM';
if (hour == 0) {
hour = 12;
} else if (hour == 12) {
ampm = 'PM';
} else if (hour > 12) {
hour -= 12;
ampm = 'PM';
}
if (min.length == 1) {
min = '0' + min;
}
return hour + ':' + min + ' ' + ampm;
},
date: function (date) {
var mon = monthDict[date.getMonth()],
day = date.getDate()+'',
dayi = ~~(day),
year = date.getFullYear(),
thisyear = (new Date()).getFullYear(),
th = 'th';
// anti-'th' - but don't do the 11th, 12th or 13th
if ((dayi % 10) == 1 && day.substr(0, 1) != '1') {
th = 'st';
} else if ((dayi % 10) == 2 && day.substr(0, 1) != '1') {
th = 'nd';
} else if ((dayi % 10) == 3 && day.substr(0, 1) != '1') {
th = 'rd';
}
if (day.substr(0, 1) == '0') {
day = day.substr(1);
}
return mon + ' ' + day + th + (thisyear != year ? ', ' + year : '');
},
shortdate: function (time_value) {
var values = time_value.split(" "),
parsed_date = Date.parse(values[1] + " " + values[2] + ", " + values[5] + " " + values[3]),
date = new Date(parsed_date),
mon = monthDict[date.getMonth()],
day = date.getDate()+'',
year = date.getFullYear(),
thisyear = (new Date()).getFullYear();
if (thisyear === year) {
return day + ' ' + mon;
} else {
return day + ' ' + mon + (year+'').substr(2, 2);
}
},
datetime: function (time_value) {
var values = time_value.split(" "),
date = new Date(Date.parse(values[1] + " " + values[2] + ", " + values[5] + " " + values[3]));
return this.time(date) + ' ' + this.date(date);
},
relative: function (time_value) {
var values = time_value.split(" "),
parsed_date = Date.parse(values[1] + " " + values[2] + ", " + values[5] + " " + values[3]),
date = new Date(parsed_date),
relative_to = (arguments.length > 1) ? arguments[1] : new Date(),
delta = ~~((relative_to.getTime() - parsed_date) / 1000),
r = '';
delta = delta + (relative_to.getTimezoneOffset() * 60);
if (delta <= 1) {
r = '1 second ago';
} else if (delta < 60) {
r = delta + ' seconds ago';
} else if (delta < 120) {
r = '1 minute ago';
} else if (delta < (45*60)) {
r = (~~(delta / 60)) + ' minutes ago';
} else if (delta < (2*90*60)) { // 2* because sometimes read 1 hours ago
r = '1 hour ago';
} else if (delta < (24*60*60)) {
r = (~~(delta / 3600)) + ' hours ago';
} else {
r = this.shortdate(time_value);
}
return r;
}
};
}();
var filter = (function () {
return {
match: function (tweet, search, includeHighlighted) {
var i = 0, s = '', text = tweet.text.toLowerCase(),
notonly = (!search['and'] || !search['and'].length) && (!search['or'] || !search['or'].length);
if (typeof search == "string") {
search = this.format(search);
}
// loop ignore first
if (search['not'] && search['not'].length) {
for (i = 0; i < search['not'].length; i++) {
if (text.indexOf(search['not'][i]) !== -1) {
return false;
}
}
if (notonly) {
return true;
}
} else if (({}).toString.call(search['not']) !== '[object Array]') {
if (search['not'].test(text)) {
return false;
}
if (notonly) {
return true;
}
}
if (search['and'] && search['and'].length) {
for (i = 0; i < search['and'].length; i++) {
s = search['and'][i];
if (s.substr(0, 3) === 'to:') {
if (!RegExp('^@' + s.substr(3)).test(text)) {
return false;
}
} else if (s.substr(0, 5) == 'from:') {
if (tweet.user.screen_name !== s.substr(5)) {
return false;
}
} else if (text.indexOf(s) === -1) {
return false;
}
}
} else if (typeof search['and'] == 'function') {
if (search['and'].test(text)) {
return true;
}
}
if (search['or'] && search['or'].length) {
for (i = 0; i < search['or'].length; i++) {
s = search['or'][i];
if (s.substr(0, 3) === 'to:') {
if (RegExp('^@' + s.substr(3)).test(text)) {
return true;
}
} else if (s.substr(0, 5) == 'from:') {
if (tweet.user.screen_name === s.substr(5)) {
return true;
}
} else if (text.indexOf(search['or'][i]) !== -1) {
return true;
}
}
} else if (typeof search['or'] == 'function') {
if (search['or'].test(text)) {
return true;
}
} else if (search['and'] && search['and'].length) {
return true;
}
return false;
},
format: function (search, caseSensitive) {
// search can match search.twitter.com format
var blocks = [], ors = [], ands = [], i = 0, negative = [], since = '', until = '';
search.replace(/(-?["'](.*?)["']|\S+)/g, function (m) { // removed \b for chinese character support
var neg = false;
if (m.substr(0, 1) == '-') {
neg = true;
}
m = m.replace(/["']+|["']+$/g, '');
if (neg) {
negative.push(m.substr(1).toLowerCase());
} else {
blocks.push(m);
}
});
for (i = 0; i < blocks.length; i++) {
if (blocks[i] == 'OR' && blocks[i+1]) {
ors.push(blocks[i-1].toLowerCase());
ors.push(blocks[i+1].toLowerCase());
i++;
ands.pop(); // remove the and test from the last loop
} else {
ands.push(blocks[i].toLowerCase());
}
}
return {
'or' : ors,
'and' : ands,
'not' : negative
};
},
// tweets typeof Array
matchTweets: function (tweets, search, includeHighlighted) {
var updated = [], tmp, i = 0;
if (typeof search == 'string') {
search = this.format(search);
}
for (i = 0; i < tweets.length; i++) {
if (this.match(tweets[i], search, includeHighlighted)) {
updated.push(tweets[i]);
}
}
return updated;
}
};
})();
window.twitterUtil = {
version: '1.0.0', //@version 1.0.9 / Fri, 30 May 2014 03:40:18 GMT
time: time,
ify: ify,
filter: filter,
expandLinks: expandLinks
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment