Created
July 9, 2010 03:18
-
-
Save moderation/468983 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
body { font-family: Helvetica; text-rendering: optimizeLegibility; } | |
section { display: block; width: 24.5%; float: left; border-left: 1px dotted #dcdcdc; } | |
a { text-decoration: none; } | |
img { border: 0; } | |
#tweets, #retweets, #favorites, #conversations { font-size: 14px; padding: 0; margin: 0; } | |
#tweets a, #retweets a, #favorites a, #conversations a { color: #2277bb; } | |
#tweets .meta a, #retweets .meta a, #favorites .meta a, #conversations .meta a { color: #999; background: #f7f7f7; } | |
.hentry { margin-left: 58px; margin-right: 29px; } | |
.hentry .meta { color: #dcdcdc; font-size: 11px; margin: 3px 0 0; display: block; } | |
.content { clear: left; min-height: 48px; padding: 9px; line-height: 1.1; position: relative; } | |
.content:hover { background-color: #F7F7F7; } | |
.vcard { float: left; } | |
a.at { background: #fcfebf; } | |
a.li { background: #ffe6ff; } | |
a.ha { background: #e6ffff; } | |
.conv { background-image: url(conversation.png); background-repeat: no-repeat; background-position: left center; padding-left: 20px; margin: auto 3px auto 5px; } | |
.retw { background-image: url(retweet.png); background-repeat: no-repeat; background-position: left center; padding-left: 20px; margin: auto 3px auto 5px; } | |
.veri { background-image: url(verified.png); background-repeat: no-repeat; background-position: left center; padding-left: 15px; margin: auto 3px auto 5px; } | |
.fvrt { background-image: url(star14.png); background-repeat: no-repeat; background-position: left center; padding-left: 20px; margin: auto 3px auto 5px; } |
This file contains hidden or 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
var twat = false, retweet = false, favorite = false, conversation = false, retweeter, favoriter, ENTITIES = { '"': '"','<': '<','>': '>' }, entries; | |
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) { return '<a target=_blank class=li href=' + m + ' title=' + m + '>' + ((m.length > 35) ? m.substr(0, 34) + '...' : m) + '</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 target=_blank class=at href=https://twitter.com/' + m2 + '>' + m2 + '</a>'; }); }, | |
hash: function(t) { return t.replace(/(^|[^&\w'"]+)\#([a-zA-Z0-9_]+)/g, function(m, m1, m2) { return m1 + '#<a target=_blank class=ha href=https://search.twitter.com/search?q=%23' + m2 + '>' + m2 + '</a>'; }); }, | |
clean: function(tweet) { return this.hash(this.at(this.link(tweet))); } | |
}; | |
}(); | |
function modifyText() { this.style.borderRight = "2px solid red"; } | |
$(document).ready(function(){ | |
if(!("WebSocket" in window)) { alert("Sorry, the build of your browser does not support WebSockets."); return; } | |
// var ws = new WebSocket("ws://127.0.0.1:8000/"); | |
// var ws = new WebSocket("ws://192.168.1.100:8000/"); | |
var ws = new WebSocket("ws://localhost:8000/"); | |
ws.onmessage = function (evt) { | |
var tweet = JSON.parse(evt.data); | |
if (tweet.error) { console.log('Error: ' + tweet.error); } | |
if (tweet.retweeted_status) { // reload tweet with retweet | |
retweet = true; | |
retweeter = tweet.user.screen_name; | |
tweet = tweet.retweeted_status; | |
} | |
else if (tweet.target_object) { // reload tweet with favorite | |
favorite = true; | |
favoriter = tweet.source.screen_name; | |
tweet = tweet.target_object; | |
} | |
else if (tweet.in_reply_to_screen_name != null) { // conversation | |
conversation = true; | |
} | |
else { | |
twat = true; | |
} | |
var html = '<div class=content><div class=vcard><a target=_blank class=url href=https://twitter.com/' + tweet.user.screen_name + '><img style=height:48px;width:48px; alt="' + tweet.user.name + '" class="photo fn" height=48 src=' + tweet.user.profile_image_url + ' width=48></a></div><div class=hentry><strong>'; | |
if (tweet.user.verified) { html += '<span class=veri>'; } | |
html += '<a target=_blank href=https://twitter.com/' + tweet.user.screen_name + ' title="' + tweet.user.name + '">' + tweet.user.screen_name + '</a></strong> '; | |
if (tweet.user.verified) { html += '</span>'; } | |
html += ify.clean(tweet.text) + '<span class=meta><a target=_blank href=https://twitter.com/' + tweet.user.screen_name; | |
html += '/status/' + tweet.id + ' class=entry-date rel=bookmark><span class=published title="'; | |
html += tweet.created_at + '">' + tweet.created_at.replace(" +0000 2010","") + '</span></a>'; | |
if (tweet.source) { html += ' | ' + tweet.source.replace("Twitter for iPhone","iTwitter"); } | |
if (tweet.in_reply_to_screen_name != null) { html += ' <a target=_blank href=https://twitter.com/' + tweet.in_reply_to_screen_name + '/status/' + tweet.in_reply_to_status_id + '><span class=conv>' + tweet.in_reply_to_screen_name + '</span></a> | <a target=_blank href=http://www.exquisitetweets.com/generate?end=' + tweet.id + '>thread</a>'; } | |
if (retweet) { html += ' @<a target=_blank class=url href=https://twitter.com/' + retweeter + '><span class=retw>' + retweeter + '</span></a>'; } | |
if (favorite) { html += ' via @<a target=_blank class=url href=https://twitter.com/' + favoriter + '><span class=fvrt>' + favoriter + '</span></a>'; } | |
html += '</span></div></div>'; | |
var p = $(html); | |
/* | |
if( $('#tweets > .tweet').length > 999) { | |
$('#tweets >li:last').slideDown(1000, function() { | |
$(this).remove(); | |
}); | |
} | |
*/ | |
if (retweet) { | |
$('#retweets').prepend(p); | |
} else if (favorite) { | |
$('#favorites').prepend(p); | |
} else if (conversation) { | |
$('#conversations').prepend(p); | |
} else { | |
$('#tweets').prepend(p); | |
} | |
p.bind('click', modifyText); | |
p.slideDown(140); | |
if (window.webkitNotifications && !conversation) { | |
if (window.webkitNotifications.checkPermission() == 0) { | |
var popup = window.webkitNotifications.createNotification(tweet.user.profile_image_url, tweet.user.screen_name, tweet.text); // note the show() | |
popup.show(); | |
setTimeout(function(){ popup.cancel(); }, '15000'); // 15 seconds | |
} else { | |
window.webkitNotifications.requestPermission(); | |
} | |
} | |
favorite = false; retweet = false; twat = false; conversation = false; | |
}; | |
ws.onopen = function() { console.log("Socket opened"); }; | |
ws.onclose = function() { console.log("Socket closed"); }; | |
}); |
This file contains hidden or 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
<!DOCTYPE html> | |
<head> | |
<meta charset=utf-8> | |
<title>@hartley userstream</title> | |
<link rel=stylesheet href=twitter.css media=all> | |
<script src=http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js></script> | |
<script src=twitter.js></script> | |
</head> | |
<body> | |
<section id=tweets><div class=content><p>tweets</p></div></section> | |
<section id=retweets><div class=content><p>retweets</p></div></section> | |
<section id=conversations><div class=content><p>conversations</p></div></section> | |
<section id=favorites><div class=content><p>favorites</p></div></section> | |
</body> |
This file contains hidden or 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
var USERNAME = 'XXXXXX' | |
, PASSWORD = 'XXXXXX' | |
, sys = require('sys') | |
, http = require('http') | |
, ws = require('./vendor/ws') | |
, base64 = require('./vendor/base64') | |
, logger = require("./vendor/logger"); | |
var a, wait = false; | |
// Authentication Headers for Twitter | |
var auth = base64.encode(USERNAME + ':' + PASSWORD) | |
, headers = {'authorization':'Basic ' + auth, 'host':'betastream.twitter.com', 'content-type':'application/json'}; | |
// Connection to Twitter's streaming API | |
var twitter = http.createClient(443, "betastream.twitter.com", true) | |
// , request = twitter.request("GET", "/2b/user.json", headers); | |
, request = twitter.request("GET", "/2b/user.json?replies=all", headers); | |
request.on('response', function (response) { | |
sys.debug("STATUS: " + response.statusCode); | |
sys.debug("HEADER: " + JSON.stringify(response.headers)); | |
response.setEncoding("utf8"); | |
response.on("data", function (chunk) { | |
if ( chunk.substr(0,8) == "{\"friend" && lastchar != '}') { sys.debug("FRIEND: " + chunk); return; } // check for friends header and abort | |
if ( chunk.length < 3 ) { return; } // check for heartbeat and abort | |
if ( chunk.substr(0,8) == "{\"delete" ) { sys.debug("Delete ####"); return; } // check for delete and abort | |
var firstchar = chunk.charAt(0), lastchar = chunk.charAt(chunk.length - 3); | |
// START | |
if ( firstchar == '{' && lastchar != '}' ) { // looking for partial sends and then combining them | |
a = chunk; | |
wait = true; | |
sys.debug('firstchar ####: ' + firstchar + ' | lastchar ####: ' + lastchar); | |
// sys.debug("START ####: " + a); | |
sys.debug( "START: " + chunk ); | |
sys.debug( "AAAAA: " + a ); | |
return; | |
} | |
// MIDDLE | |
if ( wait && firstchar != '{' && lastchar != '}' ) { | |
a += chunk; | |
sys.debug('firstchar ####: ' + firstchar + ' | lastchar ####: ' + lastchar); | |
// sys.debug("MDDLE ####: " + a); | |
sys.debug( "MDDLE: " + chunk ); | |
sys.debug( "AAAAA: " + a ); | |
return; | |
} | |
// FINISH | |
if ( wait && firstchar != '{' && lastchar == '}' ) { | |
a += chunk; | |
sys.debug('firstchar ####: ' + firstchar + ' | lastchar ####: ' + lastchar); | |
// sys.debug("FINSH ####: " + a); | |
sys.debug( "FINSH: " + chunk ); | |
sys.debug( "AAAAA: " + a ); | |
wait = false; | |
} | |
// sys.debug( "Length: " + chunk.length + " ####" ); | |
// sys.debug( "Chunk: " + chunk ); | |
try { | |
var check = JSON.parse(chunk); | |
if ( check.event == "follow" ) { sys.debug("Follow ####"); return; } // check for follow and abort | |
if ( check.event == "list_member_added" ) { sys.debug("List ####"); return; } // check for list and abort | |
} | |
catch (e) { | |
sys.debug("WRONG ###"); | |
} | |
server.broadcast(chunk); | |
}); | |
}); | |
request.end(); | |
// Websockets server setup | |
var server = ws.createServer({ | |
debug: true | |
, version: "auto" | |
}); | |
server.on("listening", function(){ | |
sys.debug("Listening for connections."); | |
}); | |
// Handle WebSocket Requests | |
server.on("connection", function(conn){ | |
function log(data){ | |
sys.debug((+new Date())+" \033[0;32m<"+conn.id+"> "+data.toString()+"\033[0m"); | |
}; | |
log("connected"); | |
server.broadcast("<"+conn.id+"> connected"); | |
conn.on("close", function(){ | |
log("onClose"); | |
server.broadcast("<"+conn.id+"> disconnected"); | |
}); | |
conn.on("message", function(message){ | |
log([message.length, JSON.stringify(message)].join(" | ")); | |
server.broadcast("<"+conn.id+"> "+message); | |
}); | |
}); | |
// Handle HTTP Requests: | |
server.on("request", function(req, res){ | |
res.writeHead(200, {'Content-Type': 'text/plain'}); | |
res.end('This is, infact a websocket server, but we can do http!\n'); | |
}); | |
server.listen(8000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment