Skip to content

Instantly share code, notes, and snippets.

@mcroydon
Created August 11, 2010 17:24
Show Gist options
  • Save mcroydon/519344 to your computer and use it in GitHub Desktop.
Save mcroydon/519344 to your computer and use it in GitHub Desktop.

finger_server.js

An extremely minimal implementation of the Finger protocol using node.js.

To run (Finger uses port 79 which requires sudo):

sudo node finger_server.js

Most unix-like systems have a finger client. Get a list of all known users:

$ finger @127.0.0.1

This should return a list of users:

[127.0.0.1]
Login                Name                 Twitter
mcroydon             Matt Croydon         mc

To get information about a specific user:

$ finger mcroydon@127.0.0.1

This should return more information about that user:

[127.0.0.1]
Login: mcroydon                          Name: Matt Croydon
Twitter: mc
Plan: Watch out for zombies.

twitter_finger.js is a twitter proxy over Finger:

$ finger mc@127.0.0.1
[127.0.0.1]
Login: mc                                Name: Matt

Tweets:
mc: Shocker: the power is out.
mc: Reproducing the easy parts of archaic protocols with #node.js is fun.  Here's finger: http://gist.github.com/519344
mc: Achievement unlocked: Laird of Glenbogle (watch all 64 episodes of Monarch of the Glen).
mc: On the plane again...
mc: Nevermind weather delay! We're off the plane!
mc: Crew found and we're boarded!
mc: Dear US Airways Express: Please find our crew. Thanks.
mc: I just earned the Discoverer Pin on @gowalla! http://gowal.la/r/Ztox
mc: Really liking the Netgear WNDR3700 router so far. A/B/G/N, Gigabit switch, 680MHz processor, 64 megs RAM, 8 megs flash. Runds dd-wrt.
mc: I'm at Lawrence Journal-World News Center in Lawrence, KS http://gowal.la/r/Y6hs
mc: Who ate all the bananas?
mc: OH: "All aboard!"
mc: Train! ?@T at Baldwin City Train Depot http://gowal.la/r/Layh
mc: OH: "Silly ol bea"
mc: Celebrating our second power outage of the day.
mc: OH: "I could put a chicken on it."
mc: This "Issues" show on HLN is making me sick discussing a murder in detail. I would turn it off if I could.
mc: This plastic ukulele is tuned perfectly for Green Day's "All By Myself".
mc: Back for breakfast. ?@T at Schilo's http://gowal.la/r/gzB
mc: Dinner out. ?@T at Hard Rock Cafe http://gowal.la/r/cY6
// finger_server.js - a minimal finger protocol implementation in node.js.
// Released under the 3 clause BSD license by Matt Croydon <mcroydon@gmail.com> (http://postneo.com)
var net = require('net');
// User data goes here.
var users = {
mcroydon: {username: 'mcroydon', name:'Matt Croydon', twitter: 'mc', plan: 'Watch out for zombies.'},
};
// Padding for user lists.
var pad = function(string, length) {
length = length || 20;
while (string.length <= length) {
string = string + ' ';
}
return string
};
// Disregard verbosity and strip trailing <CR><LF>
var clean_data = function(string) {
return string.replace('/W', '').replace('\r\n', '');
};
net.createServer(function (socket) {
socket.setEncoding("ascii");
socket.on("data", function (data) {
console.log('Starting connection.');
if (data === '\r\n') {
console.log(' Serving index.');
socket.write(pad('Login') + pad('Name') + 'Twitter' + '\r\n');
for (var index in users) {
var user = users[index];
socket.write(pad(user.username) + pad(user.name) + user.twitter + '\r\n');
}
}
else if (clean_data(data) in users) {
console.log(' Serving user: ' + clean_data(data));
var user = users[clean_data(data)];
socket.write(pad('Login: ' + user.username, 40) + pad('Name: ' + user.name, 40) + '\r\n');
socket.write(pad('Twitter: ' + user.twitter, 40) + '\r\n');
if (user.plan) {
socket.write('Plan: ' + user.plan + '\r\n');
}
}
else {
console.log('Unhandled: ' + clean_data(data));
}
socket.end();
});
socket.on("end", function () {
console.log('Ending connection.');
socket.end();
});
}).listen(79, "127.0.0.1");
console.log('finger_server.js running. To test, run "finger @127.0.0.1"');
// twitter_finger.js - A twitter proxy using the Finger protocol.
// Released under the 3 clause BSD license by Matt Croydon <mcroydon@gmail.com> (http://postneo.com)
var net = require('net');
var http = require('http');
// Padding for user lists.
var pad = function(string, length) {
length = length || 20;
while (string.length <= length) {
string = string + ' ';
}
return string
};
// Disregard verbosity and strip trailing <CR><LF>
var clean_data = function(string) {
return string.replace('/W', '').replace('\r\n', '');
};
// Get tweets via the Twitter JSON API.
var twitter_client = http.createClient(80, "api.twitter.com");
function get_tweets(username, socket) {
var request = twitter_client.request("GET", "/1/statuses/user_timeline.json?screen_name=" + username, {"host": "api.twitter.com"});
request.addListener("response", function(response) {
var body = "";
response.addListener("data", function(data) {
body += data;
});
response.addListener("end", function() {
var tweets = JSON.parse(body);
if(tweets.length > 0) {
for (index in tweets) {
if (index == 0) {
socket.write(pad('Login: ' + username, 40) + pad('Name: ' + tweets[index].user.name, 40) + '\r\n');
socket.write('Tweets:' + '\r\n');
}
socket.write(username + ': ' + tweets[index].text + '\r\n');
}
}
socket.end();
});
});
request.end();
}
net.createServer(function (socket) {
socket.setEncoding("ascii");
socket.on("data", function (data) {
console.log('Starting connection.');
if (data === '\r\n') {
console.log(' Serving index.');
socket.write('Finger a specific twitter username, for example mc' + '\r\n');
}
else {
console.log(' Serving user: ' + clean_data(data));
get_tweets(clean_data(data), socket);
}
});
socket.on("end", function () {
console.log('Ending connection.');
socket.end();
});
}).listen(79, "0.0.0.0");
console.log('twitter_finger.js running. To test, run "finger mc@127.0.0.1"');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment