sub linkify ($$) { #{{{
my $content=shift;
- my $file=shift;
+ my $page=shift;
$content =~ s{(\\?)$config{wiki_link_regexp}}{
- $1 ? "[[$2]]" : htmllink(pagename($file), $2)
+ $1 ? "[[$2]]" : htmllink($page, $2)
}eg;
return $content;
", before, so not rendering from $src");
}
} #}}}
-
+
sub render ($) { #{{{
my $file=shift;
$links{$page}=[findlinks($content, $page)];
- $content=linkify($content, $file);
+ $content=linkify($content, $page);
$content=htmlize($type, $content);
$content=finalize($content, $page);
}
} #}}}
+sub lockwiki () { #{{{
+ # Take an exclusive lock on the wiki to prevent multiple concurrent
+ # run issues. The lock will be dropped on program exit.
+ if (! -d "$config{srcdir}/.ikiwiki") {
+ mkdir("$config{srcdir}/.ikiwiki");
+ }
+ open(WIKILOCK, ">$config{srcdir}/.ikiwiki/lockfile") || error ("cannot write to lockfile: $!");
+ if (! flock(WIKILOCK, 2 | 4)) {
+ debug("wiki seems to be locked, waiting for lock");
+ my $wait=600; # arbitrary, but don't hang forever to
+ # prevent process pileup
+ for (1..600) {
+ return if flock(WIKILOCK, 2 | 4);
+ sleep 1;
+ }
+ error("wiki is locked; waited $wait seconds without lock being freed (possible stuck process or stale lock?)");
+ }
+} #}}}
+
+sub unlockwiki () { #{{{
+ close WIKILOCK;
+} #}}}
+
sub loadindex () { #{{{
open (IN, "$config{srcdir}/.ikiwiki/index") || return;
while (<IN>) {
my $num=shift;
my @ret;
+ eval q{use CGI 'escapeHTML'};
eval q{use Date::Parse};
eval q{use Time::Duration};
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'`) {
+ foreach (`LANG=C svn log --limit $num -v '$svn_url'`) {
chomp;
if ($state eq 'start' && /$div/) {
$state='header';
@pages=@message=();
}
elsif ($state eq 'body') {
- push @message, {line => $_},
+ push @message, {line => escapeHTML($_)},
}
}
}
} #}}}
sub refresh () { #{{{
- # Find existing pages.
+ # find existing pages
my %exists;
my @files;
-
eval q{use File::Find};
find({
no_chdir => 1,
$File::Find::prune=1;
use warnings "all";
}
- elsif (! -d $_) {
+ elsif (! -d $_ && ! -l $_) {
my ($f)=/$config{wiki_file_regexp}/; # untaint
if (! defined $f) {
warn("skipping bad filename $_\n");
foreach my $page (keys %oldpagemtime) {
if (! $exists{$page}) {
debug("removing old page $page");
- push @del, $renderedfiles{$page};
+ push @del, $pagesources{$page};
prune($config{destdir}."/".$renderedfiles{$page});
delete $renderedfiles{$page};
$oldpagemtime{$page}=0;
print $q->redirect("$config{url}/".htmlpage($page));
return;
}
- if (! $form->submitted || ! $form->validate) {
+ elsif ($form->submitted eq "Preview") {
+ $form->tmpl_param("page_preview",
+ htmlize($config{default_pageext},
+ linkify($form->field('content'), $page)));
+ }
+ else {
+ $form->tmpl_param("page_preview", "");
+ }
+
+ if (! $form->submitted || $form->submitted eq "Preview" ||
+ ! $form->validate) {
if ($form->field("do") eq "create") {
if (exists $pagesources{lc($page)}) {
# hmm, someone else made the page in the
$form->title("creating $page");
}
elsif ($form->field("do") eq "edit") {
- my $content="";
- if (exists $pagesources{lc($page)}) {
- $content=readfile("$config{srcdir}/$pagesources{lc($page)}");
- $content=~s/\n/\r\n/g;
+ if (! length $form->field('content')) {
+ my $content="";
+ if (exists $pagesources{lc($page)}) {
+ $content=readfile("$config{srcdir}/$pagesources{lc($page)}");
+ $content=~s/\n/\r\n/g;
+ }
+ $form->field(name => "content", value => $content,
+ force => 1);
}
$form->tmpl_param("page_select", 0);
- $form->field(name => "content", value => $content,
- force => 1);
$form->field(name => "page", type => 'hidden');
$form->title("editing $page");
}
$form->tmpl_param("can_commit", $config{svn});
$form->tmpl_param("indexlink", indexlink());
- print $form->render(submit => ["Save Page", "Cancel"]);
+ print $form->render(submit => ["Save Page", "Preview", "Cancel"]);
}
else {
# save page
# presumably the commit will trigger an update
# of the wiki
rcs_commit($message);
+ # prevent deadlock with post-commit hook
+ unlockwiki();
}
else {
loadindex();
} #}}}
# main {{{
+lockwiki();
setup() if $config{setup};
if ($config{wrapper}) {
gen_wrapper(%config);