tokuhirom's Blog

cpan をベロッと検索するやつ

c9s の http://github.com/c9s/cpansearch とかは別に PP でもいいんじゃないの?とおもったので、PP でかいてみた。

#!/usr/bin/perl
use strict;
use warnings;
use File::HomeDir;
use File::Spec;
use Getopt::Long;

our $VERSION = 0.01;

my $mirror = 'http://cpan.nctu.edu.tw/';
my $localfile = File::Spec->catfile(File::HomeDir->my_home(), '.cpanspp.gz');

&main;exit;

sub main {
    my $pattern = shift @ARGV || die "Usage: $0 pattern";

    GetOptions(
        'mirror' => \$mirror,
        'help'   => \my $help,
    );

    make_mirror();
    search($localfile, $pattern);
}

sub search {
    my ($src, $pattern) = @_;
    open my $fh, '<', $src;
    while (<$fh>) {
        if (/$pattern/) {
            print $_;
        }
    }
}

sub should_get_index {
    my @stat = stat($localfile) or return 1;
    return 1 if $stat[9] < time()-24*60*60; # 9 mtime
    return 0;
}

sub make_mirror {
    if (should_get_index()) {
        require LWP::UserAgent;
        require File::Temp;

        my $ua = LWP::UserAgent->new(
            timeout => 20,
            agent   => "$0/$VERSION",
        );
        my $url = "$mirror/modules/02packages.details.txt.gz";
        my $tmp = File::Temp->new();
        $ua->mirror($url, $tmp);

        open my $ifh, '<:gzip', "$tmp" or die "cannot open file: $tmp";
        open my $ofh, '>', "$localfile" or die "cannot open file: $localfile";
        while (<$ifh>) {
            my ($mod,$ver) = split /\s/, $_;
            next if $ver eq 'undef';
            print {$ofh} "$mod\n";
        }
    }
}