Follow your Followers using Ruby

Posted: May 20th, 2009 | Author: Daniel Higginbotham | Filed under: Uncategorized | 6 Comments »

I have the following in a rake task run every 30 minutes. You’ll need jnunemaker’s twitter gem.

Follow your followers in Ruby

  1. require 'twitter'
  2. # Check out the twitter gem docs for using oauth
  3. httpauth = Twitter::HTTPAuth.new("username", "password")
  4. base = Twitter::Base.new(httpauth)
  5. to_follow_ids = base.follower_ids - base.friend_ids
  6. unavailable_count = 0
  7. to_follow_ids.each do |tfid|
  8.   begin
  9.     base.friendship_create(tfid, true)
  10.   rescue Twitter::General
  11.     # Twitter::General is raised for 403 errors
  12.     # Which occur when you're trying to follow someone who's been banned by twitter
  13.     base.block(tfid)
  14.   rescue Twitter::Unavailable
  15.     # Wait and try again if twitter's telling you to wait
  16.     sleep 5
  17.     if unavailable_count < 3
  18.       retry
  19.       unavailable_count += 1
  20.     end
  21.   end
  22. end


Aikidoka Prevents Ruby Namespace Collisions

Posted: May 10th, 2009 | Author: Daniel Higginbotham | Filed under: Uncategorized | 4 Comments »

Recently I fell victim to the Twitter-Mash / Extlib-DataMapper-Mash namespace collision. To get around this problem, I’ve created a new gem, Aikidoka.

Here’s what happened when I tried to use Twitter when Extlib had already been loaded:

irb(main):001:0> require 'Twitter'
=> ["Twitter"]
irb(main):002:0> Twitter::Search.new("bokken").fetch
SystemStackError: stack level too deep

Here’s what happens when you use Aikidoka:

irb(main):001:0> require 'aikidoka'
=> ["Aikidoka"]
irb(main):002:0> Aikidoka.rename("Mash" => "Twitter::Mash"){require 'twitter'}
=> ["Mash"]
irb(main):003:0> Twitter::Search.new("aikidoka").fetch
=> <Mash completed_in=0.052875 max_id=1754360060 next_page="?page=2&max_id=1754360060&q=aikidoka"
etc...

It works! What this does is namespace the Mash defined when I require the Twitter gem, so that Mash is now Twitter::Mash. Also, Extlib’s Mash is still there, untouched, so you don’t need to worry about that. Here’s how Aikidoka does its magic:

  1. It temporarily renames existing constants so that they don’t get clobbered. In this case, “Mash” is renamed to “AikidokaMash”. Right now this only works with top-level constants.
  2. It yields to the given block. This block should define the constants you want permanently renamed/namespaced. In this case, we’re requiring “twitter”, which in turn requires “mash”. “mash” defines the constant we want to rename, Mash.
  3. It creates modules as necessary to create the namespace. In this case, the module Twitter is already defined so that’s used. However, if we wanted to rename “Mash” to “Potatoes::Mash”, then a module named “Potatoes” would have been created.
  4. It assigns the object referred to by the old constant to its new constant. “Twitter::Mash” now refers to the same object that “Mash” refers to.
  5. Old constants are removed to clean up the namespace. The constant “Mash” no longer exists, the object it used to refer to lives on.
  6. The constants temporarily renamed in step 1 are now given their original names back. Extlib’s “Mash” is no longer “AikidokaMash”; it’s “Mash” again.

The code is very simple – a total of 67 lines in one file with decent specs – so hopefully it’s easy to dig into.

Right now Aikidoka is best at nesting an existing top-level constant within another constant of a different name. I haven’t tried doing something like Aikidoka.rename("Mash" => "Mash::Twitter") or Aikidoka.rename("ActiveRecord::Base" => "ARBase"), and those examples probably wouldn’t work.

All in all, it does what I want it to and seems to work OK :) You can install it with “gem install flyingmachine-aikidoka“. If you’re wondering about the name, aikido is a martial art designed to resolve conflict harmoniously, and an aikidoka is a student of aikido.


Twitter and Datamapper fix

Posted: May 7th, 2009 | Author: Daniel Higginbotham | Filed under: Uncategorized | 1 Comment »

I’ve forked jnunemaker’s twitter and updated to use peterpunk’s Mhash gem instead of the Mash gem it was using. This avoids the namespace collision with Mash in datamapper’s extlib library.

http://github.com/flyingmachine/twitter/tree/master

git://github.com/flyingmachine/twitter.git