Don’t you wish you could do that neat “who are you following that’s not following you back” Twitter trick in Perl? Today I decided to learn a little more about the Twitter API by rolling a solution out on my own.
The idea was recently demonstrated in Ruby and was neatly done in 15 lines or less(you might have noticed something familiar about the post title?). It used a Ruby gem which contained the Twitter functions, so we had to roll out some Perls of our own(pun intended).
We pretty much get the same result in under 15 lines, except Perl 5 doesn’t offer the syntactic sugar of subtracting sets of objects from 2 arrays in just one statement. In Perl, the statement @friends – @followers will be evaluated in scalar context, which results in the number of items in @followers being subtracted from the number of items existent in @friends, not in the subtraction of the objects contained in @followers from @friends.
Another difference was in the choice of the Twitter web services function. The Ruby version fetched a list of numeric Twitter ID’s and then dispatched one remote service call per ID to fetch the rest of the user’s data. This method limits the script to 100 users queried per hour, as was explained on the post about the Ruby version.
I chose to fetch data for 100 users at a time using a heavier web service. This way you can verify sets of up to 10,000 users (friends + followers) per hour, which covers a pretty broad range of accounts(you know, I’ve got a whopping 30 followers).
We don’t want to waste all this data after it’s returned by the web service. So we can use an arrayref of Zen::Twitter::User objects to maintain local state for each User returned.
The examples, as well as the Perl modules, are available in the Zen::Twitter tarball.
Our first example checks which friends do not follow us back on Twitter:
use lib './lib';
use Zen::Twitter;
use Zen::Twitter::Authentication;
my $cred_args = {
filename => $ENV{HOME} . '/zen_twitter_tools/credentials.xml'
};
my $credentials = Zen::Twitter::Authentication::credentials($cred_args);
my $args = {
credentials => $credentials
};
my $friends_not_followers = Zen::Twitter::friends_not_followers($args);
foreach my $user ( @{$friends_not_followers} ) {
print "http://twitter.com/" . $user->screen_name() . "\n";
}
We use this to answer the opposite question – Which followers have we not befriended yet?
use lib './lib';
use Zen::Twitter;
use Zen::Twitter::Authentication;
my $cred_args = {
filename => $ENV{HOME} . '/zen_twitter_tools/credentials.xml'
};
my $credentials = Zen::Twitter::Authentication::credentials($cred_args);
my $args = {
credentials => $credentials
};
my $followers_not_friends = Zen::Twitter::followers_not_friends($args);
foreach my $user ( @{$followers_not_friends} ) {
print "http://twitter.com/" . $user->screen_name() . "\n";
}
Being the Unix fans that we are we print as little output as possible. In our case, we print the user’s Twitter profile url, which is just “http://twitter.com/” . $user->screen_name() . If you look closely, that $user (instance of Zen::Twitter::User) object being iterated on the foreach loop is loaded with juicy details about the user(see the Zen::Twitter documentation). We only used one instance method to obtain the user’s screen name but as you can see it’s possible to print a boatload of data if you need to.
And in python it takes 8 lines.
import wrapper
ts = wrapper.Twitter()
user = ‘scorpion032′
diff= set(ts.friends.ids(screen_name=user)) – set(ts.followers.ids(screen_name=user))
for i in diff:
try: non_fol1 = ts.users.show(id=i)
except: continue
print “%s with %d followers and %d following” %(non_fol1['name'],non_fol1['followers_count'],non_fol1['friends_count'])
[...] I’ll be implementing more and more of the published Twitter API(in my spare time, mostly). So far all we have here are some base classes and Friend/Follower functionality. [...]