X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/02b9f69ba5da59cca9ff198b731d63d643fff4db..edc6a7b7b1df39e4353a0a48f5a6f2cd61a89520:/IkiWiki/Plugin/aggregate.pm diff --git a/IkiWiki/Plugin/aggregate.pm b/IkiWiki/Plugin/aggregate.pm index bb5edfa65..eb5067d9f 100644 --- a/IkiWiki/Plugin/aggregate.pm +++ b/IkiWiki/Plugin/aggregate.pm @@ -4,7 +4,7 @@ package IkiWiki::Plugin::aggregate; use warnings; use strict; -use IkiWiki; +use IkiWiki 2.00; use HTML::Entities; use HTML::Parser; use HTML::Tagset; @@ -31,22 +31,29 @@ 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}; + loadstate(); # if not already loaded # Mark all feeds originating on this page as removable; # preprocess will unmark those that still exist. remove_feeds($page); @@ -117,7 +124,9 @@ 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: $!"); @@ -148,6 +157,8 @@ sub loadstate () { #{{{ } close IN; + + $state_loaded=1; } } #}}} @@ -199,6 +210,12 @@ 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}; @@ -229,6 +246,8 @@ sub expire () { #{{{ sub aggregate () { #{{{ eval q{use XML::Feed}; error($@) if $@; + eval q{use URI::Fetch}; + error($@) if $@; eval q{use HTML::Entities}; error($@) if $@; @@ -237,6 +256,9 @@ sub aggregate () { #{{{ time - $feed->{lastupdate} >= $feed->{updateinterval}; $feed->{lastupdate}=time; $feed->{newposts}=0; + $feed->{message}=sprintf(gettext("processed ok at %s"), + displaytime($feed->{lastupdate})); + $feed->{error}=0; $IkiWiki::forcerebuild{$feed->{sourcepage}}=1; debug(sprintf(gettext("checking feed %s ..."), $feed->{name})); @@ -251,7 +273,29 @@ sub aggregate () { #{{{ } $feed->{feedurl}=pop @urls; } - my $f=eval{XML::Feed->parse(URI->new($feed->{feedurl}))}; + my $res=URI::Fetch->fetch($feed->{feedurl}); + if (! $res) { + $feed->{message}=URI::Fetch->errstr; + $feed->{error}=1; + debug($feed->{message}); + next; + } + if ($res->status == URI::Fetch::URI_GONE()) { + $feed->{message}=gettext("feed not found"); + $feed->{error}=1; + debug($feed->{message}); + next; + } + my $content=$res->content; + my $f=eval{XML::Feed->parse(\$content)}; + if ($@) { + # One common cause of XML::Feed crashing is a feed + # that contains invalid UTF-8 sequences. Convert + # feed to ascii to try to work around. + $feed->{message}.=" ".sprintf(gettext("(invalid UTF-8 stripped from feed)")); + $content=Encode::decode_utf8($content); + $f=eval{XML::Feed->parse(\$content)}; + } if ($@) { $feed->{message}=gettext("feed crashed XML::Feed!")." ($@)"; $feed->{error}=1; @@ -270,15 +314,11 @@ sub aggregate () { #{{{ feed => $feed, title => defined $entry->title ? decode_entities($entry->title) : "untitled", link => $entry->link, - content => $entry->content->body, + content => defined $entry->content->body ? $entry->content->body : "", guid => defined $entry->id ? $entry->id : time."_".$feed->name, ctime => $entry->issued ? ($entry->issued->epoch || time) : time, ); } - - $feed->{message}=sprintf(gettext("processed ok at %s"), - displaytime($feed->{lastupdate})); - $feed->{error}=0; } } #}}} @@ -319,7 +359,6 @@ sub add_page (@) { #{{{ # Make sure that the file name isn't too long. # NB: This doesn't check for path length limits. - eval q{use POSIX}; my $max=POSIX::pathconf($config{srcdir}, &POSIX::_PC_NAME_MAX); if (defined $max && length(htmlfn($page)) >= $max) { $c=""; @@ -432,7 +471,7 @@ sub remove_feeds () { #{{{ sub pagefile ($) { #{{{ my $page=shift; - return "$config{srcdir}/".htmlpage($page); + return "$config{srcdir}/".htmlfn($page); } #}}} sub htmlfn ($) { #{{{