X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/1916f974722ff509e44c16b4c07c054ef9a11f96..bd8198fb77ed5cf77ddeb860ca1ac983bfaacbbd:/IkiWiki/Plugin/comments.pm diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index c2b2d919d..1a50d1865 100644 --- a/IkiWiki/Plugin/comments.pm +++ b/IkiWiki/Plugin/comments.pm @@ -35,6 +35,7 @@ sub import { # Load goto to fix up user page links for logged-in commenters IkiWiki::loadplugin("goto"); IkiWiki::loadplugin("inline"); + IkiWiki::loadplugin("transient"); } sub getsetup () { @@ -90,17 +91,31 @@ sub getsetup () { safe => 0, rebuild => 0, }, + comments_allowformats => { + type => 'string', + default => '', + example => 'mdwn txt', + description => 'Restrict formats for comments to (no restriction if empty)', + safe => 1, + rebuild => 0, + }, + } sub checkconfig () { $config{comments_commit} = 1 unless defined $config{comments_commit}; + if (! $config{comments_commit}) { + $config{only_committed_changes}=0; + } $config{comments_pagespec} = '' unless defined $config{comments_pagespec}; $config{comments_closed_pagespec} = '' unless defined $config{comments_closed_pagespec}; $config{comments_pagename} = 'comment_' unless defined $config{comments_pagename}; + $config{comments_allowformats} = '' + unless defined $config{comments_allowformats}; } sub htmlize { @@ -128,12 +143,18 @@ sub safeurl ($) { } } +sub isallowed ($) { + my $format = shift; + return ! $config{comments_allowformats} || $config{comments_allowformats} =~ /\b$format\b/; +} + sub preprocess { my %params = @_; my $page = $params{page}; my $format = $params{format}; - if (defined $format && ! exists $IkiWiki::hooks{htmlize}{$format}) { + if (defined $format && (! exists $IkiWiki::hooks{htmlize}{$format} || + ! isallowed($format))) { error(sprintf(gettext("unsupported page format %s"), $format)); } @@ -185,10 +206,12 @@ sub preprocess { $commentopenid = $commentuser; } else { - $commentauthorurl = IkiWiki::cgiurl( - do => 'goto', - page => IkiWiki::userpage($commentuser) - ); + if (length $config{cgiurl}) { + $commentauthorurl = IkiWiki::cgiurl( + do => 'goto', + page => IkiWiki::userpage($commentuser) + ); + } $commentauthor = $commentuser; } @@ -302,7 +325,7 @@ sub editcomment ($$) { my @buttons = (POST_COMMENT, PREVIEW, CANCEL); my $form = CGI::FormBuilder->new( fields => [qw{do sid page subject editcontent type author - url subscribe}], + email url subscribe anonsubscribe}], charset => 'utf-8', method => 'POST', required => [qw{editcontent}], @@ -332,7 +355,7 @@ sub editcomment ($$) { my @page_types; if (exists $IkiWiki::hooks{htmlize}) { - foreach my $key (grep { !/^_/ } keys %{$IkiWiki::hooks{htmlize}}) { + foreach my $key (grep { !/^_/ && isallowed($_) } keys %{$IkiWiki::hooks{htmlize}}) { push @page_types, [$key, $IkiWiki::hooks{htmlize}{$key}{longname} || $key]; } } @@ -349,24 +372,33 @@ sub editcomment ($$) { my $username=$session->param('name'); $form->tmpl_param(username => $username); - if (defined $username && IkiWiki::Plugin::notifyemail->can("subscribe")) { - $form->field(name => "subscribe", - options => [gettext("email replies to me")]); - } - else { - $form->field(name => "subscribe", type => 'hidden'); + + $form->field(name => "subscribe", type => 'hidden'); + $form->field(name => "anonsubscribe", type => 'hidden'); + if (IkiWiki::Plugin::notifyemail->can("subscribe")) { + if (defined $username) { + $form->field(name => "subscribe", type => "checkbox", + options => [gettext("email replies to me")]); + } + elsif (IkiWiki::Plugin::passwordauth->can("anonuser")) { + $form->field(name => "anonsubscribe", type => "checkbox", + options => [gettext("email replies to me")]); + } } if ($config{comments_allowauthor} and ! defined $session->param('name')) { $form->tmpl_param(allowauthor => 1); $form->field(name => 'author', type => 'text', size => '40'); + $form->field(name => 'email', type => 'text', size => '40'); $form->field(name => 'url', type => 'text', size => '40'); } else { $form->tmpl_param(allowauthor => 0); $form->field(name => 'author', type => 'hidden', value => '', force => 1); + $form->field(name => 'email', type => 'hidden', value => '', + force => 1); $form->field(name => 'url', type => 'hidden', value => '', force => 1); } @@ -408,6 +440,16 @@ sub editcomment ($$) { $page)); } + # There's no UI to get here, but someone might construct the URL, + # leading to a comment that exists in the repository but isn't + # shown + if (!pagespec_match($page, $config{comments_pagespec}, + location => $page)) { + error(sprintf(gettext( + "comments on page '%s' are not allowed"), + $page)); + } + if (pagespec_match($page, $config{comments_closed_pagespec}, location => $page)) { error(sprintf(gettext( @@ -428,16 +470,16 @@ sub editcomment ($$) { $username =~ s/"/"/g; $content .= " username=\"$username\"\n"; } + if (defined $session->param('nickname')) { my $nickname = $session->param('nickname'); $nickname =~ s/"/"/g; $content .= " nickname=\"$nickname\"\n"; } - elsif (defined $session->remote_addr()) { - my $ip = $session->remote_addr(); - if ($ip =~ m/^([.0-9]+)$/) { - $content .= " ip=\"$1\"\n"; - } + + if (!(defined $session->param('name') || defined $session->param('nickname')) && + defined $session->remote_addr()) { + $content .= " ip=\"".$session->remote_addr()."\"\n"; } if ($config{comments_allowauthor}) { @@ -467,8 +509,7 @@ sub editcomment ($$) { $subject = "comment ".(num_comments($page, $config{srcdir}) + 1); } $content .= " subject=\"$subject\"\n"; - - $content .= " date=\"" . strftime_utf8('%Y-%m-%dT%H:%M:%SZ', gmtime) . "\"\n"; + $content .= " date=\"" . commentdate() . "\"\n"; my $editcontent = $form->field('editcontent'); $editcontent="" if ! defined $editcontent; @@ -500,10 +541,18 @@ sub editcomment ($$) { if ($form->submitted eq POST_COMMENT && $form->validate) { IkiWiki::checksessionexpiry($cgi, $session); - if (defined $username && length $form->field("subscribe") && - IkiWiki::Plugin::notifyemail->can("subscribe")) { - IkiWiki::Plugin::notifyemail::subscribe($username, - "comment($page)"); + if (IkiWiki::Plugin::notifyemail->can("subscribe")) { + my $subspec="comment($page)"; + if (defined $username && + length $form->field("subscribe")) { + IkiWiki::Plugin::notifyemail::subscribe( + $username, $subspec); + } + elsif (length $form->field("email") && + length $form->field("anonsubscribe")) { + IkiWiki::Plugin::notifyemail::anonsubscribe( + $form->field("email"), $subspec); + } } $postcomment=1; @@ -521,8 +570,8 @@ sub editcomment ($$) { $postcomment=0; if (! $ok) { - $location=unique_comment_location($page, $content, $config{srcdir}, "._comment_pending"); - writefile("$location._comment_pending", $config{srcdir}, $content); + $location=unique_comment_location($page, $content, $IkiWiki::Plugin::transient::transientdir, "._comment_pending"); + writefile("$location._comment_pending", $IkiWiki::Plugin::transient::transientdir, $content); # Refresh so anything that deals with pending # comments can be updated. @@ -588,9 +637,14 @@ sub editcomment ($$) { exit; } +sub commentdate () { + strftime_utf8('%Y-%m-%dT%H:%M:%SZ', gmtime); +} + sub getavatar ($) { my $user=shift; - + return undef unless defined $user; + my $avatar; eval q{use Libravatar::URL}; if (! $@) { @@ -646,10 +700,17 @@ sub commentmoderation ($$) { } my $page=IkiWiki::dirname($f); - my $file="$config{srcdir}/$f"; + my $filedir=$IkiWiki::Plugin::transient::transientdir; + my $file="$filedir/$f"; if (! -e $file) { # old location - $file="$config{wikistatedir}/comments_pending/".$f; + $file="$config{srcdir}/$f"; + $filedir=$config{srcdir}; + if (! -e $file) { + # older location + $file="$config{wikistatedir}/comments_pending/".$f; + $filedir="$config{wikistatedir}/comments_pending"; + } } if ($action eq 'Accept') { @@ -664,7 +725,7 @@ sub commentmoderation ($$) { } require IkiWiki::Render; - IkiWiki::prune($file); + IkiWiki::prune($file, $filedir); } } @@ -763,6 +824,8 @@ sub comments_pending () { chdir($origdir) || die "chdir $origdir: $!"; }; + $find_comments->($IkiWiki::Plugin::transient::transientdir, "._comment_pending"); + # old location $find_comments->($config{srcdir}, "._comment_pending"); # old location $find_comments->("$config{wikistatedir}/comments_pending/", @@ -954,7 +1017,7 @@ sub num_comments ($$) { return int @comments; } -sub unique_comment_location ($$$$) { +sub unique_comment_location ($$$;$) { my $page=shift; eval q{use Digest::MD5 'md5_hex'}; error($@) if $@;