]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/aggregate.pm
Merge branch 'master' of ssh://git.kitenet.net/srv/git/ikiwiki.info
[ikiwiki.git] / IkiWiki / Plugin / aggregate.pm
index 78f8b409c1fb01960ba1b66c03989fafd346e08c..21c83e34a6f3fa6ddee43fc127e582ab037e7abb 100644 (file)
@@ -17,7 +17,7 @@ my %guids;
 sub import { #{{{
        hook(type => "getopt", id => "aggregate", call => \&getopt);
        hook(type => "checkconfig", id => "aggregate", call => \&checkconfig);
-       hook(type => "filter", id => "aggregate", call => \&filter);
+       hook(type => "needsbuild", id => "aggregate", call => \&needsbuild);
        hook(type => "preprocess", id => "aggregate", call => \&preprocess);
         hook(type => "delete", id => "aggregate", call => \&delete);
        hook(type => "savestate", id => "aggregate", call => \&savestate);
@@ -31,27 +31,36 @@ sub getopt () { #{{{
 } #}}}
 
 sub checkconfig () { #{{{
-       my $nolock=($config{post_commit} && ! IkiWiki::commit_hook_enabled());
-       IkiWiki::lockwiki() unless $nolock;
-       loadstate();
-       if ($config{aggregate} && ! $nolock) {
+       if ($config{aggregate} && ! ($config{post_commit} && 
+                                    IkiWiki::commit_hook_enabled())) {
+               if (! IkiWiki::lockwiki(0)) {
+                       debug("wiki is locked by another process, not aggregating");
+                       exit 1;
+               }
+       
+               loadstate();
                IkiWiki::loadindex();
                aggregate();
                expire();
                savestate();
+               clearstate();
+
+               IkiWiki::unlockwiki();
        }
-       IkiWiki::unlockwiki() unless $nolock;
 } #}}}
 
-sub filter (@) { #{{{
-       my %params=@_;
-       my $page=$params{page};
-
-       # Mark all feeds originating on this page as removable;
-       # preprocess will unmark those that still exist.
-       remove_feeds($page);
+sub needsbuild (@) { #{{{
+       my $needsbuild=shift;
+       
+       loadstate(); # if not already loaded
 
-       return $params{content};
+       foreach my $feed (values %feeds) {
+               if (grep { $_ eq $pagesources{$feed->{sourcepage}} } @$needsbuild) {
+                       # Mark all feeds originating on this page as removable;
+                       # preprocess will unmark those that still exist.
+                       remove_feeds($feed->{sourcepage});
+               }
+       }
 } # }}}
 
 sub preprocess (@) { #{{{
@@ -117,10 +126,12 @@ sub delete (@) { #{{{
        }
 } #}}}
 
+my $state_loaded=0;
 sub loadstate () { #{{{
+       return if $state_loaded;
        if (-e "$config{wikistatedir}/aggregate") {
-               open (IN, "$config{wikistatedir}/aggregate" ||
-                       die "$config{wikistatedir}/aggregate: $!");
+               open(IN, "$config{wikistatedir}/aggregate") ||
+                       die "$config{wikistatedir}/aggregate: $!";
                while (<IN>) {
                        $_=IkiWiki::possibly_foolish_untaint($_);
                        chomp;
@@ -148,15 +159,16 @@ sub loadstate () { #{{{
                }
 
                close IN;
+               
+               $state_loaded=1;
        }
 } #}}}
 
 sub savestate () { #{{{
+       return unless $state_loaded;
        eval q{use HTML::Entities};
        error($@) if $@;
        my $newfile="$config{wikistatedir}/aggregate.new";
-       # TODO: This cleanup function could use improvement. Any newly
-       # aggregated files are left behind unrecorded, and should be deleted.
        my $cleanup = sub { unlink($newfile) };
        open (OUT, ">$newfile") || error("open $newfile: $!", $cleanup);
        foreach my $data (values %feeds, values %guids) {
@@ -169,7 +181,8 @@ sub savestate () { #{{{
                                }
                        }
                        else {
-                               unlink pagefile($data->{page});
+                               unlink pagefile($data->{page})
+                                       if exists $data->{page};
                        }
                        next;
                }
@@ -199,10 +212,17 @@ sub savestate () { #{{{
                error("rename $newfile: $!", $cleanup);
 } #}}}
 
+sub clearstate () { #{{{
+       %feeds=();
+       %guids=();
+       $state_loaded=0;
+} #}}}
+
 sub expire () { #{{{
        foreach my $feed (values %feeds) {
                next unless $feed->{expireage} || $feed->{expirecount};
                my $count=0;
+               my %seen;
                foreach my $item (sort { $IkiWiki::pagectime{$b->{page}} <=> $IkiWiki::pagectime{$a->{page}} }
                                  grep { exists $_->{page} && $_->{feed} eq $feed->{name} && $IkiWiki::pagectime{$_->{page}} }
                                  values %guids) {
@@ -210,7 +230,7 @@ sub expire () { #{{{
                                my $days_old = (time - $IkiWiki::pagectime{$item->{page}}) / 60 / 60 / 24;
                                if ($days_old > $feed->{expireage}) {
                                        debug(sprintf(gettext("expiring %s (%s days old)"),
-                                               $item->{page}, $days_old));
+                                               $item->{page}, int($days_old)));
                                        $item->{expired}=1;
                                }
                        }
@@ -220,7 +240,10 @@ sub expire () { #{{{
                                $item->{expired}=1;
                        }
                        else {
-                               $count++;
+                               if (! $seen{$item->{page}}) {
+                                       $seen{$item->{page}}=1;
+                                       $count++;
+                               }
                        }
                }
        }
@@ -458,7 +481,7 @@ sub pagefile ($) { #{{{
 } #}}}
 
 sub htmlfn ($) { #{{{
-       return shift().".html";
+       return shift().".".$config{htmlext};
 } #}}}
 
 1