Moved from Twitter to Jaiku

I have not been twittering much recently because of one and only one reason.

IM is still not working at Twitter

That has been on my status page for a few weeks now and I have only been twittering via IM (routing it through my own Jabber server). That sucks. While they have been triumphing the fact they have made it through WWDC, can someone please fix that IM thing?!

Or maybe it is not necessary. As of yesterday I am now updating my status on Jaiku (thanks to Glenn for giving me the invite). Currently you can't sign up new account there but hopefully soon after they have moved to Google AppEngine. At least their IM bot works...

The next task is to automatically post my Jaiku status to Twitter. Most cross-posting tools are online based, and you can only instruct Jaiku to sync with Twitter but not the other way around. Well I didn't really look long enough because "reinventing the wheel" here is actually relatively cheap, as both Jaiku and Twitter has well published RESTful API. I quickly do up a Python script that takes new entries from my Jaiku feed and publish them onto Twitter.

Here's the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/python

import anydbm
import feedparser
import os
import re
import sys
import urllib
import urllib2

# Configurable variables
JAIKU_USERNAME = 'scottyang'
TWITTER_USERNAME = 'scottyang'
TWITTER_PASSWORD = 'mypassword'

# Other constant
TWITTER_ENDPOINT = 'http://twitter.com/statuses/update.json'

def main():
    db = anydbm.open(os.path.join(os.environ.get('HOME', '/tmp'),
        '.jaiku2twitter.db'), 'c')
    feed = feedparser.parse('http://%s.jaiku.com/feed/rss' % JAIKU_USERNAME,
        etag=(db.get('etag') or None))
    if feed.get('status') == 304:
        pass
    elif feed.bozo:
        print 'Error: %s' % feed.bozo_exception
    else:
        auth = urllib2.HTTPBasicAuthHandler()
        auth.add_password('Twitter API',
            'twitter.com',
            TWITTER_USERNAME,
            TWITTER_PASSWORD)
        opener = urllib2.build_opener(auth)

        for entry in reversed(feed.entries):
            link = str(entry.link)
            if link.startswith('http://%s.jaiku.com/presence' % JAIKU_USERNAME):
                if link not in db:
                    value = entry.summary
                    value = re.search(r'^<p>(.*?)</p>', value, re.M | re.S)
                    if value:
                        value = value.group(1).strip()
                        print 'Jaiku->Twitter: %s' % value
                        response = opener.open(TWITTER_ENDPOINT,
                            'status=%s' % urllib.quote(value))
                        response.read()
                        db[link] = '1'

        if feed.etag:
            db['etag'] = feed.etag

        db.sync()
        db.close()

if __name__ == '__main__':
    main()

Or you can download it here. It requires the Universal Feed Parser, and it creates a BSDdb file in your home directory to track what entries have it posted. It supports etag to hopefully reduce load on Jaiku. Tested under Python 2.4 and 2.5. You just need to fill in your Jaiku username, Twitter username/password, and then instruct cron to run it every now and then. I run every 10 minutes to publish my presence/status on Jaiku to Twitter.