dynamic page-name publishing for mediawiki
Robert 'phaylon' Sedlacek [Tue, 18 Sep 2012 00:42:36 +0000 (00:42 +0000)]
lib/System/Introspector/Report/Publish/MediaWiki.pm
lib/System/Introspector/Report/Publish/MediaWiki/Connection.pm
lib/System/Introspector/Report/Publish/MediaWiki/Page.pm

index 878beea..274b6c1 100644 (file)
@@ -14,22 +14,22 @@ has connection => (is => 'ro', lazy => 1, builder => 1, handles => {
   put_page => 'put',
 });
 
-has api_uri     => (is => 'ro', required => 1);
-has username    => (is => 'ro', required => 1);
-has password    => (is => 'ro', required => 1);
-has create      => (is => 'ro', default => sub { 0 });
-has http_auth   => (is => 'ro');
-has http_realm  => (is => 'ro');
+has api_uri         => (is => 'ro', required => 1);
+has username        => (is => 'ro', required => 1);
+has password        => (is => 'ro', required => 1);
+has allow_create    => (is => 'ro', default => sub { 0 });
+has http_auth       => (is => 'ro');
+has http_realm      => (is => 'ro');
 
 sub _build_producer { Producer->new }
 
 sub _build_connection {
   my ($self) = @_;
   return Connection->new(
-    api_uri  => $self->api_uri,
-    username => $self->username,
-    password => $self->password,
-    create   => $self->create,
+    api_uri         => $self->api_uri,
+    username        => $self->username,
+    password        => $self->password,
+    allow_create    => $self->allow_create,
     $self->http_auth ? (
       http_auth  => 1,
       http_realm => $self->http_realm,
@@ -42,9 +42,9 @@ sub publish {
   my $pages = $self->page_options;
   printf "Pushing reports to MediaWiki at '%s'\n", $self->api_uri;
   for my $page (sort keys %$pages) {
-    print "Updating page '$page'\n";
     $self->_publish_page($reports, $page, $pages->{$page});
   }
+  print "Finished pushing to MediaWiki\n";
   return 1;
 }
 
@@ -65,18 +65,53 @@ sub _sort_reports {
   return [ map { (@$_) } @grouped ];
 }
 
+sub _publish_dynamic {
+  my ($self, $reports, $page_name, $key, $options) = @_;
+  my %reports_by_key;
+  for my $report (@$reports) {
+    my $value = $report->{meta}{$key};
+    next unless defined $value;
+    push @{ $reports_by_key{$value} ||= [] }, $report;
+  }
+  for my $value (keys %reports_by_key) {
+    (my $effective_page = $page_name)
+      =~ s{\%\(meta:\Q$key\E\)}{$value};
+    my $assoc = $reports_by_key{$value};
+    $self->_publish_page($assoc, $effective_page, $options);
+  }
+  return 1;
+}
+
 sub _publish_page {
   my ($self, $reports, $page_name, $options) = @_;
+  if ($page_name =~ m{\%\(meta:(.+?)\)}) {
+    return $self->_publish_dynamic($reports, $page_name, $1, $options);
+  }
   my $sorted = $self->_sort_reports($reports, $options->{report} || []);
-  try {
+  unless (scalar @$sorted) {
+    print "Skipping page '$page_name': No reports to publish\n";
+    return 1;
+  }
+  print "Updating page '$page_name'\n";
+  my $do_create = $options->{create};
+  return try {
     my $page = $self->get_page($page_name);
-    $page->update($sorted);
+    if ($page->is_new and not $do_create) {
+      print "Skipping page '$page_name': Does not yet exist\n";
+      return 1;
+    }
+    my $is_changed = $page->update($sorted);
+    unless ($is_changed) {
+      print "Not pushing page '$page_name': No changes\n";
+      return 1;
+    }
     $self->put_page($page);
+    return 1;
   }
   catch {
     print "Error during page update: $_\n";
+    return 1;
   };
-  return 1;
 }
 
 with $_ for qw(
index d308d5b..1826063 100644 (file)
@@ -4,13 +4,13 @@ use MediaWiki::API;
 use URI;
 use aliased 'System::Introspector::Report::Publish::MediaWiki::Page';
 
-has api         => (is => 'lazy');
-has api_uri     => (is => 'ro', required => 1);
-has username    => (is => 'ro', required => 1);
-has password    => (is => 'ro', required => 1);
-has create      => (is => 'ro', default => sub { 0 });
-has http_auth   => (is => 'ro');
-has http_realm  => (is => 'ro');
+has api             => (is => 'lazy');
+has api_uri         => (is => 'ro', required => 1);
+has username        => (is => 'ro', required => 1);
+has password        => (is => 'ro', required => 1);
+has allow_create    => (is => 'ro', default => sub { 0 });
+has http_auth       => (is => 'ro');
+has http_realm      => (is => 'ro');
 
 my $_api_fail = sub {
   my $api = shift;
@@ -24,7 +24,7 @@ sub _build_api {
   my $api_uri = URI->new($self->api_uri);
   my $api = MediaWiki::API->new({ api_url => $self->api_uri });
   my $passwd = $self->password;
-  if ($ENV{TEST_SI_MEDIAWIKI_GETPWD}) {
+  if ($ENV{TEST_SI_MEDIAWIKI_GETPW}) {
     system "stty -echo";
     printf "MediaWiki password for '%s': ", $self->username;
     $passwd = <STDIN>;
@@ -51,7 +51,7 @@ sub get {
     or $self->api->$_api_fail;
   if (defined $page->{missing}) {
     die "MediaWiki page '$page_name' does not exist\n"
-      unless $self->create;
+      unless $self->allow_create;
     return Page->new(
       name      => $page_name,
       content   => '',
index 4ac1748..40853f4 100644 (file)
@@ -9,15 +9,29 @@ has name      => (is => 'ro', required => 1);
 has timestamp => (is => 'ro', predicate => 'has_timestamp');
 has content   => (is => 'rwp', required => 1);
 
+sub is_new { not $_[0]->has_timestamp }
+
 my $_producer = Producer->new;
 my $_parser   = Parser->new;
 my $_updater  = Updater->new;
 
+my $_trim = sub {
+  my ($body) = @_;
+  $body =~ s{^\s+}{};
+  $body =~ s{\s+$}{};
+  return $body;
+};
+
 sub update {
   my ($self, $update_stream) = @_;
-  my $original_stream = $_parser->parse($self->content);
+  my $content_before  = $self->content;
+  my $original_stream = $_parser->parse($content_before);
   my $merged_stream   = $_updater->merge($original_stream, $update_stream);
-  $self->_set_content($_producer->render($merged_stream));
+  my $content_updated = $_producer->render($merged_stream);
+  if ($content_updated->$_trim eq $content_before->$_trim) {
+    return 0;
+  }
+  $self->_set_content($content_updated);
   return 1;
 }