Twitter contact categorizer
Apr. 9th, 2008 03:51 amThis Perl script works like Twitter Karma in that it sorts your Twitter contacts into groups according to whether they are mutual friends, friends only, or followers only.
#!perl -w
#
# twfriend.pl - Categorize Twitter contacts according to whether they are
# mutual friends, only friends, or only followers.
#
# Usage: twfriend.pl [-p proxyserver:proxyport] username:password
#
# proxyserver:proxyport - Optional. HTTP proxy server and port.
# username:password - Required. Twitter login.
use strict;
use XML::Simple;
use LWP::UserAgent;
use Getopt::Std;
# Parse XML and store friends in a hash.
sub process_xml {
my $xmlstr = shift;
my $friends = shift;
my $xml = XMLin($xmlstr, ForceArray => ['user'], KeyAttr => ['id']);
for my $id (keys %{$xml->{user}}) {
$friends->{$id} = $xml->{user}{$id}{screen_name};
}
scalar(keys %{$xml->{user}});
}
# Display list of friends from a hash.
sub show_friends {
my $friends = shift;
my $friends_type = shift;
print scalar(keys %$friends), " $friends_type:\n";
my $i = 0;
for my $id (sort {$a <=> $b} keys %$friends) {
print ++$i, ": $friends->{$id}\n";
}
print"\n";
}
# Take a list of friends and a list of followers. See which ones are mutual
# friends, only friends, and only followers.
sub process_friends {
my $friends = shift;
my $followers = shift;
my %mutual;
my %only_friends;
my %only_followers;
for my $id (keys %$friends, keys %$followers) {
if (exists $friends->{$id}) {
(exists $followers->{$id} ? $mutual{$id} : $only_friends{$id}) =
$friends->{$id};
}
elsif (exists $followers->{$id}) {
$only_followers{$id} = $followers->{$id};
}
}
show_friends(\%mutual, "mutual friends");
show_friends(\%only_friends, "only friends");
show_friends(\%only_followers, "only followers");
}
# Download list of friends/followers through Twitter API.
sub twitter_api {
my $login = shift;
my $proxy = shift;
my $what = shift; # "friends" or "followers"
my $page = shift; # Page number. Twitter returns only 100 at a time.
my $ua = new LWP::UserAgent;
$proxy ne '' and $ua->proxy('http', "http://$proxy");
my $response =
$ua->get("http://$login\@twitter.com/statuses/$what.xml?page=$page");
$response->is_success or die $response->as_string;
$response->content;
}
# Get all pages of friends or followers and add them to a hash.
sub get_pages {
my $login = shift;
my $proxy = shift;
my $what = shift; # "friends" or "followers"
my $friends = shift;
my $page = 0;
my $count;
do {
++$page;
warn "Getting $what page $page...\n";
my $xmlstr = twitter_api($login, $proxy, $what, $page);
$count = process_xml($xmlstr, $friends);
} until $count < 100;
}
sub usage {
die "Usage: $0 [-p proxyhost:proxyport] user:password\n";
}
sub main {
my $proxy = '';
my $login = '';
my %opts;
getopts('p:', \%opts) or usage;
defined $opts{p} and $proxy = $opts{p};
@ARGV < 1 and usage;
$login = shift @ARGV;
my %friends;
my %followers;
get_pages($login, $proxy, "friends", \%friends);
get_pages($login, $proxy, "followers", \%followers);
process_friends(\%friends, \%followers);
}
main;
__END__