Hi all,

I've been working on a filter for CPAN's uploads.rdf feed. Basically it
fetches the RDF from search.cpan.org or reads it from standard input,
and adds the changelog to the item descriptions if available.

All changelogs are cached to keep the additional load to a bare minimum.

I'd like to make this tool available for a larger audience, but wanted
to get your advice on feasibility and recommended packaging first.

Do you think I should upload this to CPAN, and if yes, how should this
be done? I've found tons of docs about releasing modules but non about
small scripts as this one.

Cheers,
  Sebastian 

---

#!/usr/bin/perl

use warnings;
use strict;

use XML::RSS;
use LWP::Simple;
use List::Util qw(first);
use File::Save::Home
  qw/make_subhome_directory get_subhome_directory_status/;
use Cache::File;
use Getopt::Long;
use Pod::Usage;
use HTML::Entities;

my ($show_man,$show_help,$act_as_filter,$reload_changes, $debug);
my $feed_uri = 'http://search.cpan.org/uploads.rdf';
my $log = sub{};

GetOptions(
  'filter!' => \$act_as_filter, 'uri' => \$feed_uri,
  'debug' => \$debug, 'reload' => \$reload_changes,
  'help|?' => \$show_help, man => \$show_man,
);

pod2usage(0) if $show_help;
pod2usage(-exitstatus => 0, -verbose => 2) if $show_man;
$log = sub{ print STDERR @_, "\n" } if $debug;

my $uploads = $act_as_filter ? join( '', <> ) : get( $feed_uri );
die( "Unable to obtain uploads from standard input or http" )
  unless $uploads;

my $cache_dir = get_subhome_directory_status( '.cpan-changes' );
make_subhome_directory( $cache_dir );

my $cache = Cache::File->new
  ( cache_root => $cache_dir->{abs}, default_expires => '1 week' );

my $rss = XML::RSS->new();
$rss->parse( $uploads );

foreach my $item (@{$rss->{'items'}}) {
  $log->( "title: ", $item->{'title'} ,"\nlink: $item->{'link'}" );

  my $changes;
  $changes = $cache->get( $item->{link} ) unless $reload_changes;

  if ( not $changes ) {
    ( my $src_dir = $item->{'link'} ) =~ s|/~([^/]+)/|/src/\U$1\E/|;
    my $uri = first{ head( $_ ) } map{ $src_dir . $_ }
      map{( $_, uc )} qw/Changes ChangeLog/;
    $changes = $uri ? get( $ uri ) : 'No changelog found';
    $cache->set( $item->{link}, $changes );
  };

  # for some reason we will need to double encode the changes here
  my $encoded = encode_entities(encode_entities( $changes ),'&');

  $item->{description} .= sprintf( "<hr /><pre>%s</pre>", $encoded );
  $log->( "description: ", $item->{description} );
}

print $rss->as_rss_1_0;
$log->( $rss->as_rss_1_0, "\n\nDONE!\n" );

__END__

=head1 NAME

cpan-changes.pl - Enrich CPAN recent module feed with change-log info

=head1 SYNOPSIS

cpan-changes.pl [options]

 Options:
   -uri      feed uri (defaults to 'http://search.cpan.org/uploads.rdf')
   -filter   use as filter, i.e. retrieve RDF from standard input
   -reload   omits cache look-up and reload all changelogs
   -debug    processed info is logged to standard error
   -help     brief help message
   -man      full documentation

=head1 DESCRIPTION

B<This program> loads the CPAN recent modules feed, parses it and tries
to fetch the changelog for this module. All retrieved changelogs are
stored in a cache to minimize the load put onto your local CPAN mirror.

=head1 BUGS

Probably many. Up until now this program has only be tested under Linux
and in combination with the Liferea feed reader (both as conversion
filter
and as programmatic source). I'd love to get feedback about your
experiences
with this module.

=head1 AUTHOR

Sebastian Willert <[EMAIL PROTECTED]>

=cut


Reply via email to