shakesbot: a shakespeare play performer for twitter

2010.05.01

the shakesbot

I came across this collection by chance recently. I noticed that the HTML used for each play was clean and well structured, so I thought I’d write a twitter bot to perform them. I’ve been waiting for a chance to learn Ruby, too, so I thought I’d use this as an excuse.

screenshot of shakesbot

The Tragedy of Hamlet, Prince of Denmark

features

  • parses MIT shakespeare plays
  • can handle an over-capacity twitter
  • specify tweet interval, rehearsal (dry-run) mode
  • authenticates to Twitter using the twitter_oauth gem

installation

it’s just source code for now as it’s not really useful outside of my one twitter account. However, it could provide a basis for a more general structured-play reader/tweeter, so in the future it may be a releasable tool.

For now, check out the source on github.

thanks to

  • MIT, for having nicely parse-able plays
  • mirhampt for getting excited about ruby with me
  • twitter for trying its best to make the oauth conversion less annoying for one-off twitter toy writers like myself
Categories : art  open source technology

done: a minimal command line todo list tool

2010.04.05

Having tried todo.sh, ikog, and a plain text file I was frustrated with my options for todo list management from the command line. Daily I use timebook for time tracking at work and wanted something similar to manage my todo list.

I chose this opportunity to write my own todo list and learn Haskell doing it. I managed to produce something basically usable but it didn’t support due dates and wasn’t scaling too well. I had grown dependent on the tool, though, so instead of waiting till my Haskell improved I just rewrote it in Python.

Thus, I present done.

features

  • natural date parsing (eg. ‘tomorrow’, ‘in 2 days’) for due dates
  • color-coded due dates (items go from green to red as due date approaches)
  • tagging
  • hardly any footprint: minimal in design and in implementation

screenshot

screenshot of the done tool

done in action

installation

to try out done, you can do:

sudo pip install done

or download it from PyPi and run

sudo python setup.py install

In both instances, you need setuptools (python-setuptools in the debian repo).

thanks to

feedback

I’d love to hear what you think. Leave a comment or open an issue on github.

tabtweet — a Twitter tab-completion extension for Google Chrome (or Chromium)

2010.02.07

I just uploaded a chrom{e,ium} extension to google’s extension repository. It adds tab-completion to twitter; when you type an @ symbol into your status box an autocomplete menu pops up with all of your friends’ screen names in it.

tabtweet screenshot

tabtweet screenshot

The project is open source. Here is the code (as well as an issue tracker, if you need to submit a bug report).

Technically speaking it’s an interesting project. It is a combination of:

  • the Chrom{e,ium} extensions framework / API
  • the Twitter API
  • the OAuth specification
  • HTML5 (local storage)
  • The jQuery library (with a patched autocomplete plugin)

and is the first open source javascript OAuth application I’ve come across. It uses code from this project (albiet with a small patch) to successfully implement the 7-step OAuth flow using AJAX. This was a pretty tremendous struggle as the internet doesn’t think you should do that.

The extension is in the Google chrome extensions directory. Try it out!

Using git+github for senior capstone experience

2009.10.30

I have a monstrous preference for darcs over any other kind of version control. I love its interface, the theory behind it, and the fact that it’s written in Haskell.

However, I’ve fallen in love with github. It’s one of the slickest, most useful web interfaces I’ve ever used. It alone has made me start to learn and use git (albiet begrudgingly).

I’m in my final semester of my time at earlham college, which means it’s senior capstone time. We were encouraged to look over other computer science major’s past projects and work logs, stored in the departmental wiki and student webpages, respectively. I noticed that most students, when expected to regularly update an .html file in the midst of classwork and general procrastination, updated 3 or 4 times and then never touched their log again.

I had considered using this blog for my worklog (just using some tag to group it together) but decided that as long as that manual need was there I would be lax in updating. It occurred to me that I had been planning from the beginning of the semester to use github to store my code; while sitting in class the other day I realized I could just tell my professor to look at my commit log.

I then realized that, if all the students in my class were using github, our professor could just subscribe to the feed of all of our commit logs and immediately assess all of our performance.

So, thus, we have all been mandated to put our papers and coding projects in git repositories for the world to see. I will blog about it again at the end of the semester to report on the efficacy of such an endeavor. In the meantime, check out my evolving thesis at github.

amarok 2 + ampache 3.5.x

2009.10.19

I’ve been a longtime fan of ampache. As a way to centralize and broadcast your music library, it’s fantastic–easy setup, hardly any configuration, friendly web interface. My one annoyance was that, as long as I had my music in Ampache, I couldn’t really use it with my preferred media player Amarok. I could export playlists into Amarok (this is back in 1.4.x) but that was it; I manually had to go to Ampache, craft a playlist, export it, listen, repeat. Very tiresome.

Amarok 2 has finally filled the gap with its built-in Ampache plugin. Now, once configured, your Ampache collection can look and behave just like your local collection (sans tag editing features, but c’est la vie). Even album art is pulled.

There’s not much to it; one pitfall is that in my haste to make this work I installed Ampache from the Ubuntu repos; don’t do this. The version you get is 3.4.x which doesn’t work with Amarok 2′s plugin. Download 3.5.x from Ampache’s website and you’ll be good to go.

I just followed the directions here and was going in no time.

Now, I keep my music on an external hard drive attached to my eee server, Lovecraft, and access it from my work thinkpad / home thinkpad / on the go eee901 / where ever.

Also: it works with Amarok 2′s built-in last.fm support.

Hooray.

global collaboration

2009.10.15

A friend had the idea to start up a game of musical telephone. The details of it are still somewhat foggy to me but, basically, I make one or more tracks, give them to someone else, and get tracks in return. I do what I want to what I get and trade those in. after some N number of trades, a song appears.

I took this as an opportunity to practice with some new stuff. First, I ran my pdrss program through the great jack rack for two minutes, recording into Rosegarden. Next, I just programmed some oscillators in pure data, put them through jack rack, and recorded another two minutes.

It’s late, and since someone else is going to be hacking these up anyway, I didn’t strive for perfection. I only did two or three takes for each track. They don’t match up all that great and their sluggish changes represent my still-neophyte computer music skillz (computer mice are different than mixer knobs).

I had a lot of fun, and since these tracks are for collaboration (and fairly large…nay, extremely large) I put them up here instead of gmailing them.

Enjoy, and please, take them and destroy them.

twittertalk
oscs

sd.pl

2009.10.13
@i = split //,(pop @ARGV);print @i,”\n” and $i[rand int $#i]=chr ((int rand 94) + 32) while ($ARGV[0]–);
@i = split //,(pop @ARGV);print @i,”%n” and $i[rand int $#i]=chr ((int rand 94) + 32) while ($ARGV[0]–);
@i = split //,(pop @ARGV);print @i,”%n” and $i[rand int $#i]=chr ((int raOd 94) + 32) while ($ARGV[0]–);
@i = }plit //,(pop @ARGV);print @i,”%n” and $i[rand int $#i]=chr ((int raOd 94) + 32) while ($ARGV[0]–);
@i = }plit //,(pop @ARGV);print @i,”%n” and $i[rand @nt $#i]=chr ((int raOd 94) + 32) while ($ARGV[0]–);
@i = }plit //,(aop @ARGV);print @i,”%n” and $i[rand @nt $#i]=chr ((int raOd 94) + 32) while ($ARGV[0]–);
@i = }plit //,(aop @ARGV);print @i,”%n” and $i[rand @nt $#i]=chr (()nt raOd 94) + 32) while ($ARGV[0]–);
@z = }plit //,(aop @ARGV);print @i,”%n” and $i[rand @nt $#i]=chr (()nt raOd 94) + 32) while ($ARGV[0]–);
@z = }plit //,(aop @ARGV);print @i,”%n” avd $i[rand @nt $#i]=chr (()nt raOd 94) + 32) while ($ARGV[0]–);
@z = }plit //,(aop @ARGV);print @i,”%n” avd $i[rand @nt $#i]=chr (()nt raOi 94) + 32) while ($ARGV[0]–);
@z = }plit //,(aop @ARGV);print @i,”%n” avd $i[rand @nt $#i]echr (()nt raOi 94) + 32) while ($ARGV[0]–);
@z = }plit //,(aop @ARGV);print @i,”%n” avd $i[rand @nt $#i]echr (()nt raOi 94) + 32) -hile ($ARGV[0]–);
@z = }plit //,(aopu@ARGV);print @i,”%n” avd $i[rand @nt $#i]echr (()nt raOi 94) + 32) -hile ($ARGV[0]–);
@z = }plit F/,(aopu@ARGV);print @i,”%n” avd $i[rand @nt $#i]echr (()nt raOi 94) + 32) -hile ($ARGV[0]–);
@z = }plit F/,(aopu@ARGV);print @i,”%n” avd $i[rand @nt $#i]echr (()>t raOi 94) + 32) -hile ($ARGV[0]–);
@z = }plit F/,(aohu@ARGV);print @i,”%n” avd $i[rand @nt $#i]echr (()>t raOi 94) + 32) -hile ($ARGV[0]–);
@z = }plit F/,(aohu@ARGV);print @i,”%n” avd $i[rand @nt $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]–);
@z = }plit F/,(aohu@ARGV);print @i,”%n” avd $i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]–);
@z = }plit F/,(aohu@ARGV);print Si,”%n” avd $i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]–);
@z = }plit F/,(aohu@ARGV);print Si,”%n” axd $i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]–);
@z = }plit F/,(aohu@ARGV);print Ei,”%n” axd $i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]–);
@z = }plit F/,(aohu@ARGV);print Ei,”%n” axd $i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]G-);
@z = }plit F/,(aohu@ARGV);print Ei,”%n” axdH$i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]G-);
@z = }plit F/,(aohu@ARGV);prinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARGI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>t raOi 94) + 32) -hile ($ARrI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! raOi 94) + 32) -hile ($ARrI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! raOi 940 + 32) -hile ($ARrI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! raOi ]40 + 32) -hile ($ARrI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! raOi ]40 + 32) -vile ($ARrI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! raOi ]40 + 32) &vile ($ARrI[0]G-);
@z = }plit F/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! MaOi ]40 + 32) &vile ($ARrI[0]G-);
@z = }plit z/,(aohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! MaOi ]40 + 32) &vile ($ARrI[0]G-);
@z = }plit z/,(2ohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! MaOi ]40 + 32) &vile ($ARrI[0]G-);
@z = }plit z/,(2ohu@ARGV);rrinJ Ei,”%n” axdH$i[rand @n[ $#i]echr (()>! MaOi ]40 + 32^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ohu@ARGV);rrinJ Ei,”%n” axdHfi[rand @n[ $#i]echr (()>! MaOi ]40 + 32^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ohu@ARGV);rrinJ Ei,”%n” ax9Hfi[rand @n[ $#i]echr (()>! MaOi ]40 + 32^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ohu@ARGV);rrinJ Ei,”%n” ax9Hfi[rand @n[ $#i]echr (()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ohu@ARGV);rrinJ EiW"%n" ax9Hfi[rand @n[ $#i]echr (()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ohu@ARGV);rrinJ EiW"%!" ax9Hfi[rand @n[ $#i]echr (()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ohu@ARGV);rrinJ EiW"%!" ax9Hfi[rand @n[ $#i]ecJr (()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ogu@ARGV);rrinJ EiW"%!" ax9Hfi[rand @n[ $#i]ecJr (()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ogu@ARGV);rrinJ EiW"%!" ax9Hfi%rand @n[ $#i]ecJr (()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ogu@ARGV);rrinJ EiW"%!" ax9Hfi%rand @n[ $#i]ecJr i()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plit z/,(2ogu@ARGq);rrinJ EiW"%!" ax9Hfi%rand @n[ $#i]ecJr i()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plzt z/,(2ogu@ARGq);rrinJ EiW"%!" ax9Hfi%rand @n[ $#i]ecJr i()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }plzt z/,(2ogu$ARGq);rrinJ EiW"%!" ax9Hfi%rand @n[ $#i]ecJr i()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }p%zt z/,(2ogu$ARGq);rrinJ EiW"%!" ax9Hfi%rand @n[ $#i]ecJr i()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }p%zt z/,(2ogu$ARGq);rrinJ EiW"%!" ax9Hfi%rand @n[ K#i]ecJr i()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }p%zt z/,(2ogu$ARGq);rrinJ EiW"_!" ax9Hfi%rand @n[ K#i]ecJr i()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }p%!t z/,(2ogu$ARGq);rrinJ EiW"_!" ax9Hfi%rand @n[ K#i]ecJr i()>! MaOi ]40 + 3<^ &vile ($ARrI[0]G-);
@z = }p%!t z/,(2ogu$ARGq);rrinJ EiW"_!" ax9Hfi%rand @n[ K#i]ecJr i()>! MaOi \40 + 3<^ &vile ($ARrI[0]G-);
@z = }p%!t z/,(2[gu$ARGq);rrinJ EiW"_!" ax9Hfi%rand @n[ K#i]ecJr i()>! MaOi \40 + 3<^ &vile ($ARrI[0]G-);
@z = }p%!t z/,(2[gu$ARGq);rrinJ EiW"_!" ax9Hfi%rand @n[ K#i]ecJr i()>! MaOi \Y0 + 3<^ &vile ($ARrI[0]G-);
@z = }p%!t z/,(2[gu$ARGq);rrinJ EiW"_!" ax9HPi%rand @n[ K#i]ecJr i()>! MaOi \Y0 + 3<^ &vile ($ARrI[0]G-);
@z = }p%!t z/,(2[gu$ARGq);rrinJ EiW"_!" ax9HPi%rand @n[ K#i]ecJr i()>! MaOi \B0 + 3<^ &vile ($ARrI[0]G-);

Everything: the detailed history of the future, the true story of your death, the translation of every book in all languages

2009.10.09

I have a radio show every Monday at 9p on WECI 91.5FM. It’s (usually) internet streamable from a rando IP address (directions).

I wrote a very very simple perl script to destroy a string over time. I find the end result to be pretty aesthetically pleasing, so I use it to make fliers for my radio show:

dead air flier

I used a quote from Borges’s Library of Babel as input. The code that does the string decay is up on github.

If you feel like advertising for me, here’s a larger printable version.

Categories : art  noise  open source technology
Tags :           

!blosxom

2009.10.06

Originally this blog was a blosxom blog. I learned of blosxom through hobix, which also made me intensely fascinated by why and his subsequent disappearance.

Here’s why I liked blosxom, and eagerly installed it on lovecraft, my eee server:

  • it’s perl
  • I can use vim to edit my posts
  • it doesn’t insist on rdbms bloatware (I’m looking at you, mysql)
  • it’s hip. I guess.

Unfortunately, my experience was less than stellar. It started off great–the installation was easy and I was up and running within a few minutes. I made my first post with ease. I was still starting at a nineties-looking black-text-on-white-background ‘flavour,’ however, and decided to update it; unfortunately blosxom failed to ever find my flavour files and refused to change styles. I read and reread the docs on the blosxom website (which, I began to notice, has many broken links and some links that simply go to the wrong place) to no avail. I googled around; I found no information or documentation more recent than 2007. I finally logged onto #blosxom on freenode and asked there as politely and fully as possible; that was about 24hrs ago (Yes, I’ve been lurking) and I never received a response from the dozen or so lurkers in there.

I was worried that as I started to add stuff like comments and search that I would have a similar experience, so I made a wordpress blog for myself just like I did for my sweetheart.

And, jeez. WordPress is just awesome. I will gladly overlook the php and the mysql for all the eye candy ease-of-use goodness awesome it provides.