From 639f464cb3c703697db2a8887ab32d7a8233508f Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 18 Jan 2009 14:52:49 -0500 Subject: Avoid feeding decoded unicode to Term::ReadLine That resulted in double encoded display when using perl's stub readline module. Apparently that module unconditionally upgrades text to utf8, in a quite braindead way. (Term::ReadLine::Gnu::Perl worked ok.) --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'debian') diff --git a/debian/changelog b/debian/changelog index 013dc1884..6e8a54d9d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +ikiwiki (3.03) UNRELEASED; urgency=low + + * Avoid feeding decoded unicode to Term::ReadLine. + Closes: 512169 + + -- Joey Hess Sun, 18 Jan 2009 14:50:57 -0500 + ikiwiki (3.02) unstable; urgency=low * blogspam: New plugin, adding spam filtering for page editing / comment -- cgit v1.2.3 From 8360e96a8661d3cc0532f377db81a3f37babd126 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 19 Jan 2009 14:11:15 -0500 Subject: blogspam: Log spam info on failure. --- IkiWiki/Plugin/blogspam.pm | 9 ++++++--- debian/changelog | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'debian') diff --git a/IkiWiki/Plugin/blogspam.pm b/IkiWiki/Plugin/blogspam.pm index cc6e840f0..8462a6d1d 100644 --- a/IkiWiki/Plugin/blogspam.pm +++ b/IkiWiki/Plugin/blogspam.pm @@ -83,7 +83,7 @@ sub checkcontent (@) { # and "buy". push @options, "exclude=stopwords"; - my $res = $client->send_request('testComment', { + my %req={ ip => $ENV{REMOTE_ADDR}, comment => $params{content}, subject => defined $params{subject} ? $params{subject} : "", @@ -92,17 +92,20 @@ sub checkcontent (@) { options => join(",", @options), site => $config{url}, version => "ikiwiki ".$IkiWiki::version, - }); + }; + my $res = $client->send_request('testComment', %req); if (! ref $res || ! defined $res->value) { debug("failed to get response from blogspam server ($url)"); return undef; } elsif ($res->value =~ /^SPAM:(.*)/) { + eval q{use Data::Dumper}; + debug("blogspam server reports ".$res->value.": ".Dumper(\%req)); return gettext("Sorry, but that looks like spam to blogspam: ").$1; } elsif ($res->value ne 'OK') { - debug(gettext("blogspam server failure: ").$res->value); + debug("blogspam server failure: ".$res->value); return undef; } else { diff --git a/debian/changelog b/debian/changelog index 6e8a54d9d..8bf45c30a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,7 @@ ikiwiki (3.03) UNRELEASED; urgency=low * Avoid feeding decoded unicode to Term::ReadLine. Closes: 512169 + * blogspam: Log spam info on failure. -- Joey Hess Sun, 18 Jan 2009 14:50:57 -0500 -- cgit v1.2.3 From b5309d2dd759872cc7db846a32c5f6bb61614669 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Tue, 20 Jan 2009 11:20:13 -0500 Subject: Remove nonstandard css. Closes: #512378 --- debian/changelog | 1 + doc/style.css | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'debian') diff --git a/debian/changelog b/debian/changelog index 8bf45c30a..7f6605fbf 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,7 @@ ikiwiki (3.03) UNRELEASED; urgency=low * Avoid feeding decoded unicode to Term::ReadLine. Closes: 512169 * blogspam: Log spam info on failure. + * Remove nonstandard css. Closes: #512378 -- Joey Hess Sun, 18 Jan 2009 14:50:57 -0500 diff --git a/doc/style.css b/doc/style.css index 81a260afd..c61015890 100644 --- a/doc/style.css +++ b/doc/style.css @@ -339,11 +339,6 @@ input#searchbox { border: 2px solid; background-color: #dee; color: black; - - /* Nonstandard, but very nice. */ - opacity: 0.95; - -moz-opacity: 0.95; - filter: alpha(opacity=95); } /* Formbuilder styling */ -- cgit v1.2.3 From ee74e61ffc6fa589361a080a2c1476b0fe5afaa3 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 25 Jan 2009 14:37:04 -0500 Subject: blogspam: Fix use of blogspam_options and blogspam_server config settings. --- IkiWiki/Plugin/blogspam.pm | 6 +++--- debian/changelog | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'debian') diff --git a/IkiWiki/Plugin/blogspam.pm b/IkiWiki/Plugin/blogspam.pm index 8552f3a1b..cbd9859a5 100644 --- a/IkiWiki/Plugin/blogspam.pm +++ b/IkiWiki/Plugin/blogspam.pm @@ -62,11 +62,11 @@ sub checkcontent (@) { } my $url=$defaulturl; - $url = $params{blogspam_server} if exists $params{blogspam_server}; + $url = $config{blogspam_server} if exists $config{blogspam_server}; my $client = RPC::XML::Client->new($url); - my @options = split(",", $params{blogspam_options}) - if exists $params{blogspam_options}; + my @options = split(",", $config{blogspam_options}) + if exists $config{blogspam_options}; # Allow short comments and whitespace-only edits, unless the user # has overridden min-words themselves. diff --git a/debian/changelog b/debian/changelog index 7f6605fbf..96089c101 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,8 +2,10 @@ ikiwiki (3.03) UNRELEASED; urgency=low * Avoid feeding decoded unicode to Term::ReadLine. Closes: 512169 - * blogspam: Log spam info on failure. + * blogspam: Log spam info on failure in debug mode. * Remove nonstandard css. Closes: #512378 + * blogspam: Fix use of blogspam_options and blogspam_server + config settings. -- Joey Hess Sun, 18 Jan 2009 14:50:57 -0500 -- cgit v1.2.3 From c154fa5d6cd1620be7b139b08040740a1bdfafbc Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 25 Jan 2009 15:42:13 -0500 Subject: comments: If comment content checks fail, store the comment (in .ikiwiki/comments_pending) for moderator review. --- IkiWiki/Plugin/comments.pm | 43 +++++++++++++++++++++++++++++++------------ IkiWiki/Plugin/editpage.pm | 5 +++-- debian/changelog | 2 ++ doc/plugins/comments.mdwn | 7 +++++++ 4 files changed, 43 insertions(+), 14 deletions(-) (limited to 'debian') diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index 6d0e45a97..4d225b90a 100644 --- a/IkiWiki/Plugin/comments.pm +++ b/IkiWiki/Plugin/comments.pm @@ -380,14 +380,7 @@ sub sessioncgi ($$) { IkiWiki::check_canedit($page, $cgi, $session); $postcomment=0; - # FIXME: rather a simplistic way to make the comments... - my $i = 0; - my $file; - my $location; - do { - $i++; - $location = "$page/$config{comments_pagename}$i"; - } while (-e "$config{srcdir}/$location._comment"); + my $location=unique_comment_location($page, $config{srcdir}); my $content = "[[!_comment format=$type\n"; @@ -470,21 +463,33 @@ sub sessioncgi ($$) { IkiWiki::checksessionexpiry($cgi, $session); $postcomment=1; - IkiWiki::check_content(content => $form->field('editcontent'), + my $ok=IkiWiki::check_content(content => $form->field('editcontent'), subject => $form->field('subject'), $config{comments_allowauthor} ? ( author => $form->field('author'), url => $form->field('url'), ) : (), page => $location, - cgi => $cgi, session => $session + cgi => $cgi, + session => $session, + nonfatal => 1, ); $postcomment=0; - - my $file = "$location._comment"; + + if (! $ok) { + my $penddir=$config{wikistatedir}."/comments_pending"; + $location=unique_comment_location($page, $penddir); + writefile("$location._comment", $penddir, $content); + print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")), + "

". + gettext("Your comment will be posted after moderator review"), + "

"); + exit; + } # FIXME: could probably do some sort of graceful retry # on error? Would require significant unwinding though + my $file = "$location._comment"; writefile($file, $config{srcdir}, $content); my $conflict; @@ -654,6 +659,20 @@ sub pagetemplate (@) { } } +sub unique_comment_location ($) { + my $page=shift; + my $dir=shift; + + my $location; + my $i = 0; + do { + $i++; + $location = "$page/$config{comments_pagename}$i"; + } while (-e "$dir/$location._comment"); + + return $location; +} + package IkiWiki::PageSpec; sub match_postcomment ($$;@) { diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index bba52e4fd..c206d96a4 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -105,11 +105,12 @@ sub check_content (@) { $ok=1; } elsif (ref $ret eq 'CODE') { - $ret->(); + $ret->() unless $params{nonfatal}; $ok=0; } elsif (defined $ret) { - error($ret); + error($ret) unless $params{nonfatal}; + $ok=0; } } diff --git a/debian/changelog b/debian/changelog index 96089c101..002ae12c1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,8 @@ ikiwiki (3.03) UNRELEASED; urgency=low * Remove nonstandard css. Closes: #512378 * blogspam: Fix use of blogspam_options and blogspam_server config settings. + * comments: If comment content checks fail, store the comment + (in .ikiwiki/comments_pending) for moderator review. -- Joey Hess Sun, 18 Jan 2009 14:50:57 -0500 diff --git a/doc/plugins/comments.mdwn b/doc/plugins/comments.mdwn index 72b11af64..4cee3b9ad 100644 --- a/doc/plugins/comments.mdwn +++ b/doc/plugins/comments.mdwn @@ -41,3 +41,10 @@ There are some global options for the setup file: specify a name for themselves, and the \[[!meta author]] and \[[!meta authorurl]] directives will not be overridden by the comments plugin + +## comment moderation + +If you enable the [[blogspam]] plugin, comments that appear spammy will be +held for moderation. These comments are stored in +`.ikiwiki/comments_pending/`, and can be deleted, or moved into the +wiki's srcdir to be posted. -- cgit v1.2.3 From 731fc9e7a2ce818f0b7069cf0353931ec2dc8b43 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 25 Jan 2009 18:49:57 -0500 Subject: comments: Add a moderation web interface. --- IkiWiki/Plugin/comments.pm | 196 +++++++++++++++++++++++++++++++++------ debian/changelog | 1 + templates/commentmoderation.tmpl | 23 +++++ 3 files changed, 193 insertions(+), 27 deletions(-) create mode 100644 templates/commentmoderation.tmpl (limited to 'debian') diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index 4d225b90a..388a983f7 100644 --- a/IkiWiki/Plugin/comments.pm +++ b/IkiWiki/Plugin/comments.pm @@ -134,8 +134,8 @@ sub preprocess { } # no need to bother with htmlize if it's just HTML - $content = IkiWiki::htmlize($page, $params{destpage}, $format, - $content) if defined $format; + $content = IkiWiki::htmlize($page, $params{destpage}, $format, $content) + if defined $format; IkiWiki::run_hooks(sanitize => sub { $content = shift->( @@ -263,13 +263,23 @@ sub linkcgi ($) { } } -# Mostly cargo-culted from IkiWiki::plugin::editpage sub sessioncgi ($$) { my $cgi=shift; my $session=shift; my $do = $cgi->param('do'); - return unless $do eq 'comment'; + if ($do eq 'comment') { + editcomment($cgi, $session); + } + elsif ($do eq 'commentmoderation') { + commentmoderation($cgi, $session); + } +} + +# Mostly cargo-culted from IkiWiki::plugin::editpage +sub editcomment ($$) { + my $cgi=shift; + my $session=shift; IkiWiki::decode_cgi_utf8($cgi); @@ -431,29 +441,8 @@ sub sessioncgi ($$) { # - this means that if they do, rocks fall and everyone dies if ($form->submitted eq PREVIEW) { - my $preview = IkiWiki::htmlize($location, $page, '_comment', - IkiWiki::linkify($location, $page, - IkiWiki::preprocess($location, $page, - IkiWiki::filter($location, - $page, $content), - 0, 1))); - IkiWiki::run_hooks(format => sub { - $preview = shift->(page => $page, - content => $preview); - }); - - my $template = template("comment.tmpl"); - $template->param(content => $preview); - $template->param(title => $form->field('subject')); - $template->param(ctime => displaytime(time)); - - IkiWiki::run_hooks(pagetemplate => sub { - shift->(page => $location, - destpage => $page, - template => $template); - }); - - $form->tmpl_param(page_preview => $template->output); + $form->tmpl_param(page_preview => + previewcomment($content, $location, $page, time)); } else { $form->tmpl_param(page_preview => ""); @@ -480,6 +469,7 @@ sub sessioncgi ($$) { my $penddir=$config{wikistatedir}."/comments_pending"; $location=unique_comment_location($page, $penddir); writefile("$location._comment", $penddir, $content); + IkiWiki::printheader($session); print IkiWiki::misctemplate(gettext(gettext("comment stored for moderation")), "

". gettext("Your comment will be posted after moderator review"), @@ -534,6 +524,158 @@ sub sessioncgi ($$) { exit; } +sub commentmoderation ($$) { + my $cgi=shift; + my $session=shift; + + IkiWiki::needsignin($cgi, $session); + if (! IkiWiki::is_admin($session->param("name"))) { + error(gettext("you are not logged in as an admin")); + } + + IkiWiki::decode_cgi_utf8($cgi); + + if (defined $cgi->param('sid')) { + IkiWiki::checksessionexpiry($cgi, $session); + + my %vars=$cgi->Vars; + my $added=0; + foreach my $id (keys %vars) { + if ($id =~ /(.*)\Q._comment\E$/) { + my $action=$cgi->param($id); + next if $action eq 'Defer'; + + # Make sure that the id is of a legal + # pending comment before untainting. + my ($f)= $id =~ /$config{wiki_file_regexp}/; + if (! defined $f || ! length $f || + IkiWiki::file_pruned($f, $config{srcdir})) { + error("illegal file"); + } + + my $page=IkiWiki::possibly_foolish_untaint(IkiWiki::dirname($1)); + my $file="$config{wikistatedir}/comments_pending/". + IkiWiki::possibly_foolish_untaint($id); + + if ($action eq 'Accept') { + my $content=eval { readfile($file) }; + next if $@; # file vanished since form was displayed + my $dest=unique_comment_location($page, $config{srcdir})."._comment"; + writefile($dest, $config{srcdir}, $content); + if ($config{rcs} and $config{comments_commit}) { + IkiWiki::rcs_add($dest); + } + $added++; + } + + # This removes empty subdirs, so the + # .ikiwiki/comments_pending dir will + # go away when all are moderated. + require IkiWiki::Render; + IkiWiki::prune($file); + } + } + + if ($added) { + my $conflict; + if ($config{rcs} and $config{comments_commit}) { + my $message = gettext("Comment moderation"); + IkiWiki::disable_commit_hook(); + $conflict=IkiWiki::rcs_commit_staged($message, + $session->param('name'), $ENV{REMOTE_ADDR}); + IkiWiki::enable_commit_hook(); + IkiWiki::rcs_update(); + } + + # Now we need a refresh + require IkiWiki::Render; + IkiWiki::refresh(); + IkiWiki::saveindex(); + + error($conflict) if defined $conflict; + } + } + + my @comments=map { + my $id=$_; + my $file="$config{wikistatedir}/comments_pending/$id"; + my $content=readfile($file); + my $ctime=(stat($file))[10]; + { + id => $id, + view => previewcomment($content, $id, + IkiWiki::dirname($_), $ctime), + } + } comments_pending(); + + my $template=template("commentmoderation.tmpl"); + $template->param( + sid => $session->id, + comments => \@comments, + ); + IkiWiki::printheader($session); + print IkiWiki::misctemplate(gettext("comment moderation"), $template->output); + exit; +} + +sub comments_pending () { + my $dir="$config{wikistatedir}/comments_pending/"; + return unless -d $dir; + + my @ret; + eval q{use File::Find}; + error($@) if $@; + find({ + no_chdir => 1, + wanted => sub { + $_=decode_utf8($_); + if (IkiWiki::file_pruned($_, $dir)) { + $File::Find::prune=1; + } + elsif (! -l $_ && ! -d _) { + $File::Find::prune=0; + my ($f)=/$config{wiki_file_regexp}/; # untaint + if (defined $f && $f =~ /\Q._comment\E$/) { + $f=~s/^\Q$dir\E\/?//; + push @ret, $f; + } + } + } + }, $dir); + + return @ret; +} + +sub previewcomment ($$$) { + my $content=shift; + my $location=shift; + my $page=shift; + my $time=shift; + + my $preview = IkiWiki::htmlize($location, $page, '_comment', + IkiWiki::linkify($location, $page, + IkiWiki::preprocess($location, $page, + IkiWiki::filter($location, + $page, $content), + 0, 1))); + IkiWiki::run_hooks(format => sub { + $preview = shift->(page => $page, + content => $preview); + }); + + my $template = template("comment.tmpl"); + $template->param(content => $preview); + $template->param(ctime => displaytime($time)); + + IkiWiki::run_hooks(pagetemplate => sub { + shift->(page => $location, + destpage => $page, + template => $template); + }); + + return $template->output; +} + sub commentsshown ($) { my $page=shift; diff --git a/debian/changelog b/debian/changelog index 002ae12c1..c9ebcd1e9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,6 +8,7 @@ ikiwiki (3.03) UNRELEASED; urgency=low config settings. * comments: If comment content checks fail, store the comment (in .ikiwiki/comments_pending) for moderator review. + * comments: Add a moderation web interface. -- Joey Hess Sun, 18 Jan 2009 14:50:57 -0500 diff --git a/templates/commentmoderation.tmpl b/templates/commentmoderation.tmpl new file mode 100644 index 000000000..3dadb791b --- /dev/null +++ b/templates/commentmoderation.tmpl @@ -0,0 +1,23 @@ + +
+

+ + + +
+
+ +
+Defer +Accept +Reject +
+
+
+ +
+ +

+No comments need moderation at this time. +

+ -- cgit v1.2.3 From ce39f8e0006253b7dd3489dbd414b5d4758c66ac Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 25 Jan 2009 23:13:14 -0500 Subject: git: Fix malformed utf8 recieved from git. If git log outputs malformed utf8 in, eg, usernames, detect it and fix it up. This avoids commits such as f71abc92aa279fbe0b7578b8c4752d775dd4a259 breaking things. --- IkiWiki/Plugin/git.pm | 6 ++++++ debian/changelog | 1 + 2 files changed, 7 insertions(+) (limited to 'debian') diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm index 3085a3b67..042c69f5a 100644 --- a/IkiWiki/Plugin/git.pm +++ b/IkiWiki/Plugin/git.pm @@ -139,6 +139,12 @@ sub safe_git (&@) { my @lines; while (<$OUT>) { chomp; + + # check for invalid utf-8, and toss it back to avoid crashes + if (! utf8::valid($_)) { + $_=encode_utf8($_); + } + push @lines, $_; } diff --git a/debian/changelog b/debian/changelog index c9ebcd1e9..6c1710fe1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -9,6 +9,7 @@ ikiwiki (3.03) UNRELEASED; urgency=low * comments: If comment content checks fail, store the comment (in .ikiwiki/comments_pending) for moderator review. * comments: Add a moderation web interface. + * git: Fix malformed utf8 recieved from git. -- Joey Hess Sun, 18 Jan 2009 14:50:57 -0500 -- cgit v1.2.3