chiark / gitweb /
Support querying and downloading of decision reasons by moderators
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 20 Apr 2010 16:54:30 +0000 (17:54 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 20 Apr 2010 16:54:30 +0000 (17:54 +0100)
get-settings
webstump/scripts/html_output.pl
webstump/scripts/webstump.lib.pl

index 5c71c46..746a2e1 100644 (file)
@@ -5,10 +5,12 @@ pas="$paskeys"
 for k in $pas; do eval "$k=''"; export $k; done
 
 DIVERTPOSTINGS=''
+MODLOGSEARCH=false
+MODLOGDOWNLOAD=false
 
 . settings
 export GROUP ABBREV INFOHEADER MODEMAIL GROUPURL REJECTIONSLIST
-export DIVERTPOSTINGS
+export DIVERTPOSTINGS MODLOGSEARCH MODLOGDOWNLOAD
 
 . ../global-settings
 export ROOTBASEDIR CGIBASEURL DOMAIN SLIMYDOMAIN OURUSER ADMIN
index 59a6423..aca0509 100644 (file)
@@ -7,6 +7,7 @@
 #
 
 use POSIX;
+use CGI qw/escapeHTML/;
 
 sub begin_html {
   my $title = pop( @_ );
@@ -612,7 +613,7 @@ No articles present in the queue
   print "<FORM METHOD=$request_method action=$base_address>";
   &html_print_credentials;
   print "<INPUT NAME=action VALUE=moderator_admin TYPE=hidden>
-         <INPUT TYPE=submit VALUE=\"Manage pass/grey/block-lists\">
+         <INPUT TYPE=submit VALUE=\"Management\">
          </FORM>";
 
   &end_html;
@@ -630,6 +631,98 @@ sub html_print_credentials {
  <INPUT NAME=password VALUE=\"$password\" TYPE=hidden>\n";
 }
 
+# logs
+
+sub scanlogs ($$$) {
+    my ($forwards, $gotr, $callback) = @_;
+    my $dir= "$webstump_home/..";
+    opendir LOGSDIR, "$dir" or die "$dir $!";
+    my $num= sub {
+        local ($_) = @_;
+        return $forwards * (
+            m/^errs$/ ? -1 :
+            m/^errs\.(\d+)(?:\.gz$)$/ ? $1 :
+            undef
+                           );
+    };
+    foreach my $leaf (
+                      sort { $num->($a) <=> $num->($b) }
+                      grep { defined $num->($_) }
+                      readdir LOGSDIR
+                      ) {
+        my $file= "$dir/$leaf";
+        if ($file =~ m/\.gz$/) {
+            open LOGFILE, "zcat $file |" or die "zcat $file $!";
+        } else {
+            open LOGFILE, "< $file" or die "$file $!";
+        }
+        while (<LOGFILE>) {
+            my $tgot= $callback->();
+            next unless $tgot;
+            $$gotr= $tgot if $tgot > $$gotr;
+            last if $tgot > 1;
+        }
+        $!=0; $?=0; close LOGFILE or die "$file $? $!";
+        last if $$gotr > 1;
+    }
+    closedir LOGSDIR or die "$dir $!";
+}        
+
+sub html_search_logs {
+  &begin_html("Search logs for $request{'newsgroup'}");
+  my $reqnum;
+  my $forwards=1;
+  my $min= 9;
+  if ($request{'download_logs'}) {
+      print "<h2>Complete log download</h2>\n";
+      $min= 2;
+  } elsif ($request{'messagenum'} =~ m/^(\d+)$/) {
+      $reqnum= $1;
+      $forwards= -1;
+      $min= 1;
+      print "<h2>Log entry for single message $reqnum</h2>\n";
+  } else {
+      print "<h2>Log lookup - bad reference</h2>
+Please supply the numerical reference as found in the \"recent activity\"
+log or message headers.  Reference numbers consist entirely of digits,
+and are often quoted in message headers in [square brackets].<p>
+        ";
+      &end_html;
+      return;
+  }
+  if ($mod_log_access < $min) {
+      print "Not permitted [$mod_log_access<$min].  Consult administrator.\n";
+      &end_html;
+      return;
+  }
+
+  my $sofar= 0;
+  &scanlogs($forwards, \$sofar, sub {
+      return 0 unless chomp;
+      return 0 unless m/^DECISION: /;
+      my @vals = split / \| /, $';
+      return 0 unless @vals >= 5;
+      my $subj= pop @vals;
+      my ($group,$dir,$act,$reason) = @vals;
+      return 0 unless $group eq $request{'newsgroup'};
+      return 0 unless $subj =~ m,/(\d+)$,;
+      my $treqnum= $1;
+      return 0 if defined($reqnum) and $treqnum ne $reqnum;
+      print "<table rules=all><tr><th>Reference<th>Disposal<th>Reason</tr>\n"
+          unless $sofar;
+      print "<tr>", (map { "<td>".escapeHTML($_) } $treqnum,$act,$reason);
+      print "</tr>\n";
+      return defined($reqnum) ? 2 : 1;
+  });
+  if ($sofar) {
+      print "</table>" if $sofar;
+      print "\n";
+  } else {
+      print "Reference not found.";
+  }
+  &end_html;
+}
+
 # newsgroup admin page
 sub html_newsgroup_management {
   &begin_html( "Administer $request{'newsgroup'}" );
@@ -681,8 +774,29 @@ sub html_newsgroup_management {
 
   &link_to_help( "filter-lists", "filtering lists" );
 
+  print "</FORM><HR>";
+
+  if ($mod_log_access) {
+      print "<form>
+        Use this form to search logs of past moderation decisions:
+        <br>
+        <form method=$request_method action=$base_address>
+        <input name=action value=search_logs type=hidden>";
+
+      &html_print_credentials;
+
+      print "
+        Reference number: <input name=messagenum size=30>
+        <input type=submit value=\"Lookup\">";
+
+      print "
+        <input type=submit value=\"Download all logs\" name=\"download_logs\">"
+        if $mod_log_access >= 2;
+
+      print "</form><hr>\n";
+  }
+
   print "
-  </FORM><HR>
 
   List of current moderators:<P>
 
index e19be93..3e9e0ef 100644 (file)
@@ -712,6 +712,9 @@ sub processWebRequest {
   } elsif( $action eq "change_password" ) {
     &authenticate( $newsgroup, $moderator, $password );
     &html_change_password;
+  } elsif( $action eq "search_logs" ) {
+    &authenticate( $newsgroup, $moderator, $password );
+    &html_search_logs;
   } elsif( $action eq "validate_change_password" ) {
     &authenticate( $newsgroup, $moderator, $password );
     &validate_change_password;