From 4ee128f76553f3efec44f55a2c5d7a0c4cb965c5 Mon Sep 17 00:00:00 2001 From: Gianni Ceccarelli Date: Tue, 19 Mar 2013 17:02:31 +0000 Subject: factored code, better reporting when no diff --- meta.pl | 210 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 127 insertions(+), 83 deletions(-) diff --git a/meta.pl b/meta.pl index b039c3f..26eefc1 100644 --- a/meta.pl +++ b/meta.pl @@ -1,6 +1,7 @@ #!/usr/bin/env perl use strict; use warnings; +use 5.014; use MetaCPAN::API; use Text::Diff; use XML::Feed; @@ -10,35 +11,68 @@ use HTML::Escape 'escape_html'; my $api = MetaCPAN::API->new(); -sub get_recent_releases { - my $now = DateTime->now; - my $yesterday = $now->clone->subtract(hours=>3); - my $recent = $api->post( +package Release { +use Moose; +has [qw(distribution name author date abstract)] => ( + is => 'ro', +); + +around BUILDARGS => sub { + my ($orig,$class,$args) = @_; + if ($args->{fields}) { + $args = $args->{fields}; + } + return $class->$orig($args); +}; + +sub get_file { + my ($self,$path) = @_; + + my $file_response = $api->ua->get( + join '/',$api->base_url,'source', + $self->author,$self->name,$path + ); + return unless $file_response->{success}; + return $file_response->{content}; +} + +sub get_previous { + my ($self) = @_; + + my $prev_release = $api->post( 'release/_search', { - size => 500, - from => 0, + size => 1, + from => 0, query => { - range => { date => { - from => $yesterday->iso8601, - include_lower => 1, - } }, + filtered => { + query => { + range => { date => { + to => $self->date, + include_upper => 0, + } }, + }, + filter => { + and => [ { + term => { + 'release.distribution' => $self->distribution, + }, + } ] + } + } }, - sort => [ { 'date' => { order => "desc" } } ], - fields => [qw(distribution name date author abstract)], + sort => [ { date => 'desc' } ], + fields => [qw(name author)], }, ); - $recent=$recent->{hits}{hits}; - return $recent; + ($prev_release)=@{$prev_release->{hits}{hits}}; + return unless $prev_release; + return ref($self)->new($prev_release); } -sub get_changelog_diff { - my ($release) = @_; +sub search_files { + my ($self,@criteria) = @_; - my $dist_name = $release->{distribution}; - my $release_name = $release->{name}; - my $release_author = $release->{author}; - my $release_date = $release->{date}; my $files = $api->post( 'file/_search', { @@ -48,15 +82,8 @@ sub get_changelog_diff { query => { match_all => {} }, filter => { and => [ - { term => { level => 0 } }, - { term => { release => $release_name } }, - { - or => [ - { prefix => { name => 'Change' } }, - { prefix => { name => 'change' } }, - { prefix => { name => 'CHANGE' } }, - ], - }, + { term => { release => $self->name } }, + @criteria, ], }, }, @@ -64,62 +91,73 @@ sub get_changelog_diff { fields => [qw(name)], } ); + return map { $_->{fields}{name} } @{$files->{hits}{hits}//[]}; +} + +sub get_changelog_name { + my ($self) = @_; + my @potential_changelogs = $self->search_files( + { term => { level => 0 } }, + { + or => [ + { prefix => { name => 'Change' } }, + { prefix => { name => 'change' } }, + { prefix => { name => 'CHANGE' } }, + ], + }, + ); my ($changelog_name) = grep { /^change(s|log)$/i - } map { $_->{fields}{name} } @{$files->{hits}{hits}}; - - return 'no changelog file' unless $changelog_name; + } @potential_changelogs; + return $changelog_name; +} +}; - my $this_changelog = $api->ua->get( - join '/',$api->base_url,'source', - $release_author,$release_name,$changelog_name - )->{content}; - my $prev_release = $api->post( +sub get_recent_releases { + my $now = DateTime->now; + my $yesterday = $now->clone->subtract(hours=>3); + my $recent = $api->post( 'release/_search', { - size => 1, - from => 0, + size => 500, + from => 0, query => { - filtered => { - query => { - range => { date => { - to => $release_date, - include_upper => 0, - } }, - }, - filter => { - and => [ { - term => { - 'release.distribution' => $dist_name, - }, - } ] - } - } + range => { date => { + from => $yesterday->iso8601, + include_lower => 1, + } }, }, - sort => [ { date => 'desc' } ], - fields => [qw(name author)], + sort => [ { 'date' => { order => "desc" } } ], + fields => [qw(distribution name date author abstract)], }, ); - ($prev_release)=@{$prev_release->{hits}{hits}}; + return map { Release->new($_) } @{$recent->{hits}{hits}//[]}; +} + +sub get_changelog_diff { + my ($release) = @_; - return $this_changelog if !$prev_release; + my $changelog_name = $release->get_changelog_name; - my $prev_release_name = $prev_release->{fields}{name}; - my $prev_release_author = $prev_release->{fields}{author}; + return {error=>'no changelog file'} unless $changelog_name; - my $prev_changelog = $api->ua->get( - join '/',$api->base_url,'source', - $prev_release_author,$prev_release_name,$changelog_name - ); + my $this_changelog = $release->get_file($changelog_name); - return $this_changelog unless $prev_changelog->{success}; - $prev_changelog=$prev_changelog->{content}; + my $prev_release = $release->get_previous; + + return {diff=>$this_changelog} if !$prev_release; + + my $prev_changelog = $prev_release->get_file($changelog_name); + + return {diff=>$this_changelog} unless $prev_changelog; my $diff = diff \$prev_changelog,\$this_changelog; - return $diff; + return {diff=>$diff} if $diff; + + return {error=>'changelog not modified'}; } sub build_feed { @@ -129,32 +167,38 @@ sub build_feed { return $feed; } sub build_entry { - my ($release,$diff) = @_; + my ($release) = @_; my $e = XML::Feed::Entry->new('RSS'); - $e->title( $release->{name} ); + $e->title( $release->name ); $e->link( join( '/', 'http://metacpan.org', 'release', - $release->{author}, $release->{name} ) + $release->author, $release->name ) ); - $e->author( $release->{author} ); - $e->issued( DateTime::Format::ISO8601->parse_datetime( $release->{date} ) ); - $e->content( sprintf '

%s

%s
', - escape_html($release->{abstract}), - escape_html($diff//'') ); + $e->author( $release->author ); + $e->issued( DateTime::Format::ISO8601->parse_datetime( $release->date ) ); + my $diff = get_changelog_diff($release); + + my $content = sprintf '

%s

', + escape_html($release->abstract); + if ($diff->{diff}) { + $content .= sprintf '
%s
', + escape_html($diff->{diff}); + } + else { + $content .= sprintf '

%s

', + escape_html($diff->{error}); + } + $e->content($content); + return $e; } -my $recent = get_recent_releases(); my $feed = build_feed(); - -for my $rel (@{$recent}) { - my $release = $rel->{fields}; - - my $diff = get_changelog_diff($release); - - $feed->add_entry(build_entry($release,$diff)); +my @recent = get_recent_releases(); +for my $release (@recent) { + $feed->add_entry(build_entry($release)); } print $feed->as_xml; -- cgit v1.2.3