X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/c4f3d0554a02eba93d94d4c0914f4afddf85274b..d98296d1db02febfa7cc4fbe7f304ca2a9858fef:/IkiWiki/Plugin/aggregate.pm?ds=inline

diff --git a/IkiWiki/Plugin/aggregate.pm b/IkiWiki/Plugin/aggregate.pm
index c667ee2a9..7789c4c2a 100644
--- a/IkiWiki/Plugin/aggregate.pm
+++ b/IkiWiki/Plugin/aggregate.pm
@@ -298,7 +298,7 @@ sub loadstate () {
 	return if $state_loaded;
 	$state_loaded=1;
 	if (-e "$config{wikistatedir}/aggregate") {
-		open(IN, "$config{wikistatedir}/aggregate") ||
+		open(IN, "<", "$config{wikistatedir}/aggregate") ||
 			die "$config{wikistatedir}/aggregate: $!";
 		while (<IN>) {
 			$_=IkiWiki::possibly_foolish_untaint($_);
@@ -335,7 +335,7 @@ sub savestate () {
 	garbage_collect();
 	my $newfile="$config{wikistatedir}/aggregate.new";
 	my $cleanup = sub { unlink($newfile) };
-	open (OUT, ">$newfile") || error("open $newfile: $!", $cleanup);
+	open (OUT, ">", $newfile) || error("open $newfile: $!", $cleanup);
 	foreach my $data (values %feeds, values %guids) {
 		my @line;
 		foreach my $field (keys %$data) {
@@ -356,6 +356,20 @@ sub savestate () {
 	close OUT || error("save $newfile: $!", $cleanup);
 	rename($newfile, "$config{wikistatedir}/aggregate") ||
 		error("rename $newfile: $!", $cleanup);
+
+	my $timestamp=undef;
+	foreach my $feed (keys %feeds) {
+		my $t=$feeds{$feed}->{lastupdate}+$feeds{$feed}->{updateinterval};
+		if (! defined $timestamp || $timestamp > $t) {
+			$timestamp=$t;
+		}
+	}
+	$newfile=~s/\.new$/time/;
+	open (OUT, ">", $newfile) || error("open $newfile: $!", $cleanup);
+	if (defined $timestamp) {
+		print OUT $timestamp."\n";
+	}
+	close OUT || error("save $newfile: $!", $cleanup);
 }
 
 sub garbage_collect () {
@@ -404,6 +418,7 @@ sub mergestate () {
 	}
 
 	# New guids can be created during aggregation.
+	# Guids have a few fields that may be updated during aggregation.
 	# It's also possible that guids were removed from the on-disk state
 	# while the aggregation was in process. That would only happen if
 	# their feed was also removed, so any removed guids added back here
@@ -412,6 +427,11 @@ sub mergestate () {
 		if (! exists $guids{$guid}) {
 			$guids{$guid}=$myguids{$guid};
 		}
+		else {
+			foreach my $field (qw{md5}) {
+				$guids{$guid}->{$field}=$myguids{$guid}->{$field};
+			}
+		}
 	}
 }
 
@@ -534,6 +554,11 @@ sub aggregate (@) {
 		}
 
 		foreach my $entry ($f->entries) {
+			# XML::Feed doesn't work around XML::Atom's bizarre
+			# API, so we will. Real unicode strings? Yes please.
+			# See [[bugs/Aggregated_Atom_feeds_are_double-encoded]]
+			local $XML::Atom::ForceUnicode = 1;
+
 			my $c=$entry->content;
 			# atom feeds may have no content, only a summary
 			if (! defined $c && ref $entry->summary) {
@@ -639,11 +664,13 @@ sub add_page (@) {
 		# creation time on record for the new page.
 		utime $mtime, $mtime, "$config{srcdir}/".htmlfn($guid->{page});
 		# Store it in pagectime for expiry code to use also.
-		$IkiWiki::pagectime{$guid->{page}}=$mtime;
+		$IkiWiki::pagectime{$guid->{page}}=$mtime
+			unless exists $IkiWiki::pagectime{$guid->{page}};
 	}
 	else {
 		# Dummy value for expiry code.
-		$IkiWiki::pagectime{$guid->{page}}=time;
+		$IkiWiki::pagectime{$guid->{page}}=time
+			unless exists $IkiWiki::pagectime{$guid->{page}};
 	}
 }