Friday, October 8, 2010

My Twitter/thimbl rival: fritter (Free Twitter)

At Twitter, thimbl is writing a rival to Twitter, whose website is available here . Details are a little thin as to how it actually works, but it seems that a system admin must enable sshd and fingerd through xinetd. The user writes to his ~/.plan file, and thimbl picks this up in some way, and creates a log message.

I thought I'd have my own go at a rival system. It's a toy system, of course. My solution is to rely on Apache - so that an admin doesn't even have to enable fingerd. My solution uses the fact that Apache can be made to serve files in ~/public_html . It might be automatically enabled - but it wasn't for my Slackware 13.1 system. To enable it, I had to edit /etc/httpd/httpd.conf, uncomment the line

Include /etc/httpd/extra/httpd-userdir.conf

and re-start Apache.
I then require that anyone who wants to create a"fritter" post must put some text in the file ~/public_html/fritter.txt

That takes care of the server side.

Now, on to the client side.To follow people, you must create a file caller fritter.conf. Each line must have a host and username, separated by a space. Here is my example fritter.conf file:

localhost mcarter

As you can see, it only contains one line, because there's only one person making fritters at the moment. Here is  the code that prints out the fritters, which I called

#!/usr/bin/env python

import datetime
import time
import urllib2

def once(conf, tweets):
    for line in conf:
        line = line.replace("\r","").replace("\n", "")
        host, person = line.split()
        url = "http://{0}/~{1}/fritter.txt".format(host, person)
        f = urllib2.urlopen(url)
        tweet =
        print_tweet = True
        if tweets.has_key(url):
            if tweets[url] == tweet: print_tweet = False
        tweets[url] = tweet
        if print_tweet:
            print "At {0}, {1} at {2} wrote:".format(, person, host)
            print tweet

# read configuration file
conf = file("fritter.conf","r").read().splitlines()
tweets = {}
    once(conf, tweets)

It's pretty primitive stuff, and is open to lots of enhancements - but I think it's quite good that I created a Twitter clone in 32 lines of code. Simply run it, and it will cycle through your conf file, and spit out any new posts that appear.

Anyone got any better ideas?

Edits 09-Oct-2010 12:22:
  • You can get the code over at pastebin (Blogger seems to mess up the layout).
  • Changed "server" to "client", and vice versa.
  • Changed ~/.project to ~/.plan


Quirk said...

Hey Mark! I love Fritter, this is exactly the sort of thinking we are trying to promote with Thimbl. The /~user http convention is also part of our plans as a fall back when finger is not available. The .plan file that Thimbl uses is JSON formatted, allowing us to include bio data and incorporate mentions/replies, etc finger to see it (or through the http gateway ( Once you start adding data structure and support for web-based clients, fritter will basically evolve into Thimbl!

Evan Prodromou said...

Nobody needs another Twitter clone that's not federated, folks.

If you want to make something awesome, make sure it supports OStatus, so people on other networks can follow you.

We've got a good tutorial on How to OStatus-enable your application. You should give it a shot.

Quirk said...

Hi Evan, federation and OStatus support is on our roadmap.