Skip to content

Instantly share code, notes, and snippets.

@mcroydon
Created August 11, 2010 17:24

Revisions

  1. mcroydon revised this gist Aug 12, 2010. 1 changed file with 0 additions and 1 deletion.
    1 change: 0 additions & 1 deletion twitter_finger.js
    Original file line number Diff line number Diff line change
    @@ -59,7 +59,6 @@ net.createServer(function (socket) {
    }
    else {
    console.log(' Serving user: ' + clean_data(data));
    // do_tweets(clean_data(data), socket);
    get_tweets(clean_data(data), socket);
    }
    });
  2. mcroydon revised this gist Aug 12, 2010. 1 changed file with 32 additions and 28 deletions.
    60 changes: 32 additions & 28 deletions twitter_finger.js
    Original file line number Diff line number Diff line change
    @@ -2,8 +2,7 @@
    // Released under the 3 clause BSD license by Matt Croydon <mcroydon@gmail.com> (http://postneo.com)

    var net = require('net');
    // npm install apricot
    var Apricot = require('apricot').Apricot;
    var http = require('http');

    // Padding for user lists.
    var pad = function(string, length) {
    @@ -19,31 +18,35 @@ var clean_data = function(string) {
    return string.replace('/W', '').replace('\r\n', '');
    };

    // Retrieve tweets using Apricot and node-rss
    var do_tweets = function(username, socket) {
    var name = '';
    // First we need to find the RSS feed based on the username.
    // If RSS feeds have the same rate limiting as API calls this is silly.
    Apricot.open('http://twitter.com/' + username + '/', function(doc){
    doc.find('span.fn').each(function(el) {
    name = el.innerHTML.replace('\r\n', '');
    });

    doc.find('link').each(function(el) {
    if (el.href.match('user_timeline')) {
    // Now download the RSS feed and parse it using Apricot.
    Apricot.open(el.href, function(doc) {
    socket.write(pad('Login: ' + username, 40) + pad('Name: ' + name, 40) + '\r\n');
    socket.write('Tweets:' + '\r\n');
    doc.find('item title').each(function(el) {
    socket.write(el.innerHTML.replace('&#8212;', '-'));
    });
    socket.end();
    });
    }
    });
    });
    };
    // 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");
    @@ -56,7 +59,8 @@ net.createServer(function (socket) {
    }
    else {
    console.log(' Serving user: ' + clean_data(data));
    do_tweets(clean_data(data), socket);
    // do_tweets(clean_data(data), socket);
    get_tweets(clean_data(data), socket);
    }
    });
    socket.on("end", function () {
    @@ -66,4 +70,4 @@ net.createServer(function (socket) {

    }).listen(79, "0.0.0.0");

    console.log('twitter_finger.js running. To test, run "finger mc@127.0.0.1"');
    console.log('twitter_finger.js running. To test, run "finger mc@127.0.0.1"');
  3. mcroydon revised this gist Aug 12, 2010. 1 changed file with 9 additions and 9 deletions.
    18 changes: 9 additions & 9 deletions twitter_finger.js
    Original file line number Diff line number Diff line change
    @@ -4,8 +4,6 @@
    var net = require('net');
    // npm install apricot
    var Apricot = require('apricot').Apricot;
    // http://github.com/ibrow/node-rss
    var rss = require('node-rss');

    // Padding for user lists.
    var pad = function(string, length) {
    @@ -22,22 +20,24 @@ var clean_data = function(string) {
    };

    // Retrieve tweets using Apricot and node-rss
    // This occasionaly dies with <ERROR>"Document: only comments, processing instructions, or whitespace allowed outside of document element"</ERROR>
    var do_tweets = function(username, socket) {
    var name = '';
    // First we need to find the RSS feed based on the username.
    // If RSS feeds have the same rate limiting as API calls this is silly.
    Apricot.open('http://twitter.com/' + username + '/', function(doc){
    doc.find('span.fn').each(function(el) {
    name = el.innerHTML;
    name = el.innerHTML.replace('\r\n', '');
    });

    doc.find('link').each(function(el) {
    if (el.href.match('user_timeline')) {
    var response = rss.parseURL(el.href, function(articles) {
    // Now download the RSS feed and parse it using Apricot.
    Apricot.open(el.href, function(doc) {
    socket.write(pad('Login: ' + username, 40) + pad('Name: ' + name, 40) + '\r\n');
    socket.write('Tweets:' + '\r\n');
    for(i=0; i<articles.length; i++) {
    socket.write(articles[i].description + '\r\n');
    }
    doc.find('item title').each(function(el) {
    socket.write(el.innerHTML.replace('&#8212;', '-'));
    });
    socket.end();
    });
    }
    @@ -66,4 +66,4 @@ net.createServer(function (socket) {

    }).listen(79, "0.0.0.0");

    console.log('twitter_finger.js running. To test, run "finger mc@127.0.0.1"');
    console.log('twitter_finger.js running. To test, run "finger mc@127.0.0.1"');
  4. mcroydon revised this gist Aug 12, 2010. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion twitter_finger.js
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ var net = require('net');
    // npm install apricot
    var Apricot = require('apricot').Apricot;
    // http://github.com/ibrow/node-rss
    var rss = require('./lib/node-rss/node-rss');
    var rss = require('node-rss');

    // Padding for user lists.
    var pad = function(string, length) {
    @@ -21,6 +21,7 @@ var clean_data = function(string) {
    return string.replace('/W', '').replace('\r\n', '');
    };

    // Retrieve tweets using Apricot and node-rss
    // This occasionaly dies with <ERROR>"Document: only comments, processing instructions, or whitespace allowed outside of document element"</ERROR>
    var do_tweets = function(username, socket) {
    var name = '';
  5. mcroydon revised this gist Aug 12, 2010. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion twitter_finger.js
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,7 @@ var clean_data = function(string) {
    return string.replace('/W', '').replace('\r\n', '');
    };

    // Retrieve tweets using Apricot and node-rss
    // This occasionaly dies with <ERROR>"Document: only comments, processing instructions, or whitespace allowed outside of document element"</ERROR>
    var do_tweets = function(username, socket) {
    var name = '';
    Apricot.open('http://twitter.com/' + username + '/', function(doc){
  6. mcroydon revised this gist Aug 12, 2010. 2 changed files with 97 additions and 0 deletions.
    29 changes: 29 additions & 0 deletions README.rst
    Original file line number Diff line number Diff line change
    @@ -29,4 +29,33 @@ This should return more information about that user::
    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 protocol: http://tools.ietf.org/html/rfc1288
    68 changes: 68 additions & 0 deletions twitter_finger.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    // 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');
    // npm install apricot
    var Apricot = require('apricot').Apricot;
    // http://github.com/ibrow/node-rss
    var rss = require('./lib/node-rss/node-rss');

    // 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', '');
    };

    // Retrieve tweets using Apricot and node-rss
    var do_tweets = function(username, socket) {
    var name = '';
    Apricot.open('http://twitter.com/' + username + '/', function(doc){
    doc.find('span.fn').each(function(el) {
    name = el.innerHTML;
    });

    doc.find('link').each(function(el) {
    if (el.href.match('user_timeline')) {
    var response = rss.parseURL(el.href, function(articles) {
    socket.write(pad('Login: ' + username, 40) + pad('Name: ' + name, 40) + '\r\n');
    socket.write('Tweets:' + '\r\n');
    for(i=0; i<articles.length; i++) {
    socket.write(articles[i].description + '\r\n');
    }
    socket.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));
    do_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"');
  7. mcroydon revised this gist Aug 11, 2010. 1 changed file with 32 additions and 0 deletions.
    32 changes: 32 additions & 0 deletions README.rst
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    ================
    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.

    .. _Finger protocol: http://tools.ietf.org/html/rfc1288
  8. mcroydon created this gist Aug 11, 2010.
    59 changes: 59 additions & 0 deletions finger_server.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    // 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"');