MetaCPAN FTW!
Dec 20, 2010 / By Yanick Champoux
Right now, Galuga has a widget that lists my CPAN distributions. But it’s a boring old static affair that is updated manually. Surely in this age of the Web 2.0, I can do better than that.
My first instinct that to go straight for my CPAN author page and extract the information off the HTML:
sub distributions {
my $self = shift;
my $page = get $self->author_cpan_url;
my $dists = pQuery($page)->find('table:eq(1) tr');
my @dists;
$dists->each(
sub {
return unless shift; # first one is headers
my $row = pQuery($_);
my $name = $row->find('td:eq(0) a')->text();
$name =~ s/-v?([\d._]*)$//; # remove version
my $version = $1;
my $url = "http://search.cpan.org/dist/$name";
$name =~ s/-/::/g;
my $desc = $row->find('td:eq(1)')->text();
my $date = DateTime::Format::Flexible->parse_datetime(
$row->find('td:eq(3)')->text );
push @dists,
{ name => $name,
url => $url,
desc => $desc,
date => $date,
version => $version,
};
} );
return @dists;
}
Not too painful, all in all. Mind you, it’d be nicer not to have to fiddle with HTML tables, but short of having a bona fide API…
And that’s when Olaf’s blog reminds me of search.metacpan.org and the CPAN-API project. After a few minutes of peering at what they have to offer, the code above got simplified to:
sub distributions {
my $self = shift;
my $page =
get sprintf 'http://api.metacpan.org/dist/_search?q=author:"%s"',
$self->author_id;
my $json = from_json($page);
return map { {
name => $_->{name},
version => $_->{version},
url => 'http://search.cpan.org/dist/' . $_->{name},
date => DateTime::Format::Flexible->parse_datetime(
$_->{release_date}
), } }
map { $_->{_source} }
@{ $json->{hits}{hits} };
}
Sweet, isn’t?
(The code for both variants of the widget is available at my WWW-Widget GitHub repo.)

Recent Comments