- $links{$file}=[];
- writefile("$destdir/$file", $content);
- $oldpagemtime{$file}=time;
- $renderedfiles{$file}=$file;
- }
-}
-
-sub loadindex () {
- open (IN, "$srcdir/.index") || return;
- while (<IN>) {
- $_=possibly_foolish_untaint($_);
- chomp;
- my ($mtime, $file, $rendered, @links)=split(' ', $_);
- my $page=pagename($file);
- $pagesources{$page}=$file;
- $oldpagemtime{$page}=$mtime;
- $oldlinks{$page}=[@links];
- $links{$page}=[@links];
- $renderedfiles{$page}=$rendered;
- }
- close IN;
-}
-
-sub saveindex () {
- open (OUT, ">$srcdir/.index") || error("cannot write to .index: $!");
- foreach my $page (keys %oldpagemtime) {
- print OUT "$oldpagemtime{$page} $pagesources{$page} $renderedfiles{$page} ".
- join(" ", @{$links{$page}})."\n"
- if $oldpagemtime{$page};
- }
- close OUT;
-}
-
-sub rcs_update () {
- if (-d "$srcdir/.svn") {
- if (system("svn", "update", "--quiet", $srcdir) != 0) {
- warn("svn update failed\n");
- }
- }
-}
-
-sub rcs_commit ($) {
- my $message=shift;
-
- if (-d "$srcdir/.svn") {
- if (system("svn", "commit", "--quiet", "-m",
- possibly_foolish_untaint($message), $srcdir) != 0) {
- warn("svn commit failed\n");
- }
- }
-}
-
-sub rcs_add ($) {
- my $file=shift;
-
- if (-d "$srcdir/.svn") {
- my $parent=dirname($file);
- while (! -d "$srcdir/$parent/.svn") {
- $file=$parent;
- $parent=dirname($file);
- }
-
- if (system("svn", "add", "--quiet", "$srcdir/$file") != 0) {
- warn("svn add failed\n");
- }
- }
-}
-
-sub rcs_recentchanges ($) {
- my $num=shift;
- my @ret;
-
- eval {use Date::Parse};
- eval {use Time::Duration};
-
- if (-d "$srcdir/.svn") {
- my $info=`LANG=C svn info $srcdir`;
- my ($svn_url)=$info=~/^URL: (.*)$/m;
-
- my $div=qr/^--------------------+$/;
- my $infoline=qr/^r(\d+)\s+\|\s+([^\s]+)\s+\|\s+(\d+-\d+-\d+\s+\d+:\d+:\d+\s+[-+]?\d+).*/;
- my $state='start';
- my ($rev, $user, $when, @pages, $message);
- foreach (`LANG=C svn log -v '$svn_url'`) {
- print STDERR "state: $state\n";
- chomp;
- if ($state eq 'start' && /$div/) {
- $state='header';
- }
- elsif ($state eq 'header' && /$infoline/) {
- $rev=$1;
- $user=$2;
- $when=ago(time - str2time($3));
- }
- elsif ($state eq 'header' && /^\s+(.*)/) {
- push @pages, $1;
- }
- elsif ($state eq 'header' && /^$/) {
- $state='body';
- }
- elsif ($state eq 'body' && /$div/) {
- push @ret, {rev => $rev, user => $user,
- date => $when, message => $message,
- pages => [@pages]},
- last if @ret >= $num;
-
- $state='header';
- $message=$rev=$user=$when=undef;
- @pages=();
- }
- elsif ($state eq 'body') {
- $message.="$_<br>\n";
- }
- }
- }
-
- return @ret;
-}
-
-sub prune ($) {
- my $file=shift;
-
- unlink($file);
- my $dir=dirname($file);
- while (rmdir($dir)) {
- $dir=dirname($dir);
- }
-}
-
-sub refresh () {
- # Find existing pages.
- my %exists;
- my @files;
- find({
- no_chdir => 1,
- wanted => sub {
- if (/$wiki_file_prune_regexp/) {
- $File::Find::prune=1;
- }
- elsif (! -d $_) {
- my ($f)=/$wiki_file_regexp/; # untaint
- if (! defined $f) {
- warn("skipping bad filename $_\n");
- }
- else {
- $f=~s/^\Q$srcdir\E\/?//;
- push @files, $f;
- $exists{pagename($f)}=1;
- }
- }
- },
- }, $srcdir);
-
- my %rendered;
-
- # check for added or removed pages
- my @add;
- foreach my $file (@files) {
- my $page=pagename($file);
- if (! $oldpagemtime{$page}) {
- debug("new page $page");
- push @add, $file;
- $links{$page}=[];
- $pagesources{$page}=$file;
- }
- }
- my @del;
- foreach my $page (keys %oldpagemtime) {
- if (! $exists{$page}) {
- debug("removing old page $page");
- push @del, $renderedfiles{$page};
- prune($destdir."/".$renderedfiles{$page});
- delete $renderedfiles{$page};
- $oldpagemtime{$page}=0;
- delete $pagesources{$page};
- }
- }
-
- # render any updated files
- foreach my $file (@files) {
- my $page=pagename($file);
-
- if (! exists $oldpagemtime{$page} ||
- mtime("$srcdir/$file") > $oldpagemtime{$page}) {
- debug("rendering changed file $file");
- render($file);
- $rendered{$file}=1;
- }
- }
-
- # if any files were added or removed, check to see if each page
- # needs an update due to linking to them
- # TODO: inefficient; pages may get rendered above and again here;
- # problem is the bestlink may have changed and we won't know until
- # now
- if (@add || @del) {
-FILE: foreach my $file (@files) {
- my $page=pagename($file);
- foreach my $f (@add, @del) {
- my $p=pagename($f);
- foreach my $link (@{$links{$page}}) {
- if (bestlink($page, $link) eq $p) {
- debug("rendering $file, which links to $p");
- render($file);
- $rendered{$file}=1;
- next FILE;
- }
- }
- }
- }
- }
-
- # handle linkbacks; if a page has added/removed links, update the
- # pages it links to
- # TODO: inefficient; pages may get rendered above and again here;
- # problem is the linkbacks could be wrong in the first pass render
- # above
- if (%rendered) {
- my %linkchanged;
- foreach my $file (keys %rendered, @del) {
- my $page=pagename($file);
- if (exists $links{$page}) {
- foreach my $link (@{$links{$page}}) {
- $link=bestlink($page, $link);
- if (length $link &&
- ! exists $oldlinks{$page} ||
- ! grep { $_ eq $link } @{$oldlinks{$page}}) {
- $linkchanged{$link}=1;
- }
- }
- }
- if (exists $oldlinks{$page}) {
- foreach my $link (@{$oldlinks{$page}}) {
- $link=bestlink($page, $link);
- if (length $link &&
- ! exists $links{$page} ||
- ! grep { $_ eq $link } @{$links{$page}}) {
- $linkchanged{$link}=1;
- }
- }
- }
- }
- foreach my $link (keys %linkchanged) {
- my $linkfile=$pagesources{$link};
- if (defined $linkfile) {
- debug("rendering $linkfile, to update its linkbacks");
- render($linkfile);
- }