Added ability for forum moderators to vote for banishment of a poster

New db tables banishment_vote and banishment_votes
Daemon script vote_monitor for timing the votes
New configuration option <moderators_vote_to_ban/>



svn path=/trunk/boinc/; revision=13917
This commit is contained in:
Eric J. Korpela 2007-10-19 20:01:36 +00:00
parent 068ac0cb37
commit 706b283b19
9 changed files with 490 additions and 2 deletions

View File

@ -9676,3 +9676,25 @@ Rom 18 Oct 2007
boinc_tray.h
boinc_tray.rc
tray_win.cpp
Eric K 19 Oct 2007
- Added ability for forum moderators to vote for banishment of a poster
- New db tables banishment_vote and banishment_votes
- Daemon script vote_monitor for timing the votes
- new configuration option <moderators_vote_to_ban/>
db/
schema.sql
tools/
vote_monitor
Makefile.am
html/
inc/
forum_email.inc
forum_moderators.inc
forum_banishment_vote.inc
html/
user/
forum_banishment_vote.php
forum_banishment_vote_action.php

View File

@ -335,7 +335,7 @@ create table forum (
post_min_interval integer not null,
post_min_expavg_credit integer not null,
post_min_total_credit integer not null,
is_dev_blog tinyint not null default 0,
is_dev_blog tinyint not null default 0,
primary key (id)
) type=InnoDB;
@ -510,3 +510,20 @@ create table team_delta (
joining tinyint(1) not null,
total_credit double not null
) TYPE=MyISAM;
-- tables for moderator banishment votes
create table banishment_vote (
id serial primary key,
userid integer not null,
modid integer not null,
start_time integer not null,
end_time integer not null
) TYPE=MyISAM;
create table banishment_votes (
id serial primary key,
voteid integer not null,
modid integer not null,
time integer not null,
yes tinyint(1) not null
) TYPE=MyISAM;

View File

@ -0,0 +1,150 @@
<?php
function current_tally($voteid) {
$query="select sum(yes) as ayes,count(id)-sum(yes) as nays from banishment_votes where voteid=".$voteid;
$result = mysql_query($query);
$foobar = mysql_fetch_object($result);
echo "<b>Current Tally</b> Ayes: ".$foobar->ayes." Nays: ".$foobar->nays."<p>";
return true;
}
function vote_is_in_progress($userid) {
// check whether a vote is already ongoing
$now=time();
$query="select count(id) as count from banishment_vote where userid=".$userid." and end_time>".$now;
$result = mysql_query($query);
if (!$result) {
echo "Database error attempting to read banishment_vote table 1.<p>";
return -1;
}
$foobar = mysql_fetch_object($result);
if (!$foobar) {
echo "Database error attempting to read banishment_vote table 2.<p>";
return -1;
}
return $foobar->count;
}
function start_vote($config,$logged_in_user,$user,$category,$reason) {
$now=time();
$fin=$now+21600;
if ( vote_is_in_progress($user->id) !=0 ) {
echo "A banishment vote is already underway for this user.<p>";
return 0;
}
$query="insert into banishment_vote (userid,modid,start_time,end_time) values ("
.$user->id.",".$logged_in_user->getID().",".$now.",".$fin.")";
$result = mysql_query($query);
if (!$result) {
echo "Database error attempting to insert to banishment_vote table.<p>";
return 0;
}
$voteid=mysql_insert_id();
$query="insert into banishment_votes (voteid,modid,time,yes) values ("
. $voteid .",". $logged_in_user->getID() .",". $now .",1)";
$result = mysql_query($query);
if (!$result) {
echo "Database error attempting to insert to banishment_votes table.<p>";
return 0;
}
$query="update forum_preferences set banished_until=".$fin." where userid=".$user->id;
$result = mysql_query($query);
echo "Banishment vote started.<p><p>";
current_tally($voteid);
return send_banish_vote_email($user, 86400*14, $reason, $now+21600);
}
function vote_yes($config,$logged_in_user,$user) {
$now=time();
// Check that a vote is underway.
if (vote_is_in_progress($user->id)<1) {
echo "No banishment vote is underway for this user.<p><p>";
return 0;
}
// Find the voteid
$query="select id as voteid from banishment_vote where userid=".$user->id." and end_time>".$now;
$result = mysql_query($query);
$foobar = mysql_fetch_object($result);
if (!$foobar) {
echo "Database error attempting to read banishment_vote table.<p>";
return 0;
}
$voteid=$foobar->voteid;
// Check whether mod has voted already.
$query="select count(id) as count from banishment_votes where voteid=".$voteid
." and modid=".$logged_in_user->getID();
$result = mysql_query($query);
$foobar = mysql_fetch_object($result);
if (!$foobar) {
echo "Database error attempting to read banishment_vote table.<p>";
return 0;
}
if ($foobar->count > 0) {
echo "You have already voted in this election.<p><p>";
current_tally($voteid);
return 0;
}
// insert the vote
$query="insert into banishment_votes (voteid,modid,time,yes) values ("
. $voteid .",". $logged_in_user->getID() .",". $now .",1)";
$result = mysql_query($query);
if (!$result) {
echo "Database error attempting to insert to banishment_votes table.<p>";
return 0;
}
echo "Vote recorded: Aye<p><p>";
current_tally($voteid);
return 1;
}
function vote_no($config,$logged_in_user,$user) {
// Check that a vote is underway.
$now=time();
if (vote_is_in_progress($user->id)<1) {
echo "No banishment vote is underway for this user.<p>";
return 0;
}
// Find the voteid
$query="select id as voteid from banishment_vote where userid=".$user->id." and end_time>".$now;
$result = mysql_query($query);
$foobar = mysql_fetch_object($result);
if (!$foobar) {
echo "Database error attempting to read banishment_vote table.<p>";
return 0;
}
$voteid=$foobar->voteid;
// Check whether mod has voted already.
$query="select count(id) as count from banishment_votes where voteid=".$voteid
." and modid=".$logged_in_user->getID();
$result = mysql_query($query);
$foobar = mysql_fetch_object($result);
if (!$foobar) {
echo "Database error attempting to read banishment_vote table.<p>";
return 0;
}
if ($foobar->count > 0) {
echo "You have already voted in this election.<p><p>";
current_tally($voteid);
return 0;
}
// insert the vote
$query="insert into banishment_votes (voteid,modid,time,yes) values ("
. $voteid .",". $logged_in_user->getID() .",". $now .",0)";
$result = mysql_query($query);
if (!$result) {
echo "Database error attempting to insert to banishment_votes table.<p>";
return 0;
}
echo "Vote recorded: Nay<p><p>";
current_tally($voteid);
return 1;
}
?>

View File

@ -189,4 +189,42 @@ because your postings have not followed our guidelines.
return re_send_email($user, $subject, $body);
}
function send_banish_vote_email($user, $duration, $reason, $end_time) {
$now=time();
$subject = PROJECT." banishment vote underway";
$vote_url=parse_config(get_config(), "<master_url>")."forum_banishment_vote.php";
$body = "
This email if to inform you that a vote has been started
regarding your banishment from the ".PROJECT." message boards until ".date('M j,
Y G:i', $duration+$now).",
because your postings have not followed our guidelines.
This vote will be underway until ".date('M j, Y G:i',$end_time)." or until a majority
decision has been reached. If the vote does not result in banishment, you will be
able to resume posting at that time.
";
if ($reason) {
$body .= "\n\nThe moderator gave the following reason for your pending suspension:\n";
$body .= $reason;
}
$success = send_email($user, $subject, $body);
$emails = explode("|", POST_REPORT_EMAILS);
$success = true;
$body .= "\n\n<a href=".$vote_url."?action=yes&userid="
.$user->id
.">[vote to banish author]</a>\n\n"
."<a href=".$vote_url."?action=no&userid="
.$user->id
.">[vote not to banish author]</a>";
foreach ($emails as $email) {
$admin->email_addr = $email;
if (!send_email($admin, "A banishment vote for ".$user->name." has been started.", $body)) {
$success = false;
}
}
}
?>

View File

@ -1,10 +1,13 @@
<?php
require_once('../inc/forum_banishment_vote.inc');
/**
* Show the links for possible moderation actions related to a single post
**/
function post_moderation_links($config,$logged_in_user,$post,$tokens){
$moderators_allowed_to_ban = parse_bool($config, "moderators_allowed_to_ban");
$moderators_vote_to_ban = parse_bool($config, "moderators_vote_to_ban");
if ($post->isHidden()){
$x = " - <a href=\"forum_moderate_post_action.php?action=unhide&id=".$post->getID()."$tokens\">[undelete post]</a>";
@ -15,6 +18,16 @@ function post_moderation_links($config,$logged_in_user,$post,$tokens){
if ($logged_in_user->isSpecialUser(S_ADMIN) || ($logged_in_user->isSpecialUser(S_MODERATOR) && $moderators_allowed_to_ban)) {
$x .= " - <a href=forum_moderate_post.php?action=banish_user&id=".$post->getID()."&userid=".$post->getOwnerID()."$tokens>[banish author]</a>";
}
if ($logged_in_user->isSpecialUser(S_MODERATOR) && $moderators_vote_to_ban) {
if (vote_is_in_progress($post->getOwnerID())) {
$x .= " - <a href=forum_banishment_vote.php?action=yes&userid=".$post->getOwnerID()
.">[vote to banish author]</a> - <a href=forum_banishment_vote.php?action=no&userid="
.$post->getOwnerID().">[vote not to banish author]</a>";
} else {
$x .= " - <a href=forum_banishment_vote.php?action=start&userid="
.$post->getOwnerID().">[start vote to banish author]</a>";
}
}
return $x;
}

View File

@ -0,0 +1,86 @@
<?php
/**
* The form where a moderator decides what he is going to do to a post.
* Submits informaiton to forum_moderate_post_action.php for actual action
* to be done.
**/
require_once('../inc/forum_std.inc');
require_once('../inc/forum_user.inc');
require_once('../inc/forum_banishment_vote.inc');
$config = get_config();
db_init();
$logged_in_user = re_get_logged_in_user();
if (!get_str('action')) {
error_page("You must specify an action...");
}
if (!$logged_in_user->isSpecialUser(S_MODERATOR)) {
// Can't moderate without being moderator
error_page("You are not authorized to banish users.");
}
$userid = get_int('userid');
$user=get_user_from_id($userid);
page_head('Banishment Vote');
//start form
echo "<form action=\"forum_banishment_vote_action.php?userid=".$userid."\" method=\"POST\">\n";
echo form_tokens($logged_in_user->getAuthenticator());
start_table();
row1("Banishment Vote");
if (get_str('action')=="start") {
if (!$user) {
error_page("no user");
}
$x = $user->banished_until;
if ($x>time()) {
error_page("User is already banished");
}
//display input that selects reason
echo "<input type=hidden name=action value=start>";
echo "<input type=\"hidden\" name=\"userid\" value=\"".$userid."\">\n";
row1("Are you sure you want to banish ".$user->name."?
This will prevent ".$user->name." from posting for chosen time period.<br />
It should be done only if ".$user->name."
has consistently exhibited trollish behavior.");
row2("",
"Select the reason category, optionally write a longer description of why the user should be banished.");
row2("Category",
"<select name=\"category\">
<option value=\"1\">Obscene</option>
<option value=\"2\">Flame/Hate mail</option>
<option value=\"3\">User Request</option>
<option value=\"4\">Other</option>
</select>");
row2("Reason<br>Mailed if nonempty",
"<textarea name=\"reason\" rows=\"10\" cols=\"80\"></textarea>");
row2(
"",
"<input type=\"submit\" name=\"submit\" value=\"Proceed with vote\">"
);
} elseif (get_str('action')=="yes") {
vote_yes($config,$logged_in_user,$user);
} elseif (get_str('action')=="no") {
vote_no($config,$logged_in_user,$user);
} else {
error_page( "Unknown action");
}
end_table();
echo "</form>";
page_tail();
?>

View File

@ -0,0 +1,63 @@
<?php
$cvs_version_tracker[]="\$Id: forum_moderate_post_action.php 13718 2007-09-30 11:17:11Z Rytis $"; //Generated automatically - do not edit
/**
* When a moderator does something to a post, this page actually
* commits those changes to the database.
**/
require_once("../inc/forum.inc");
require_once("../inc/forum_email.inc");
require_once("../inc/forum_std.inc");
db_init();
$config = get_config();
$logged_in_user = re_get_logged_in_user();
check_tokens($logged_in_user->getAuthenticator());
if (!$logged_in_user->isSpecialUser(S_MODERATOR)) {
// Can't moderate without being moderator
error_page("You are not authorized to banish users.");
}
// See if "action" is provided - either through post or get
if (!post_str('action', true)) {
if (!get_str('action', true)){
error_page("You must specify an action...");
} else {
$action = get_str('action');
}
} else {
$action = post_str('action');
}
$userid = post_int('userid');
$user=get_user_from_id($userid);
if ($action!="start"){
error_page("Unknown action ");
}
switch (post_int("category", true)) {
case 1:
$mod_category = "Obscene";
case 2:
$mod_category = "Flame/Hate mail";
case 3:
$mod_category = "User Request";
default:
$mod_category = "Other";
}
if (post_str('reason', true)){
start_vote($config,$logged_in_user,$user, $mod_category,post_str("reason"));
} else {
start_vote($config,$logged_in_user,$user, $mod_category,"None given");
}
?>

View File

@ -2,7 +2,7 @@ include $(top_srcdir)/Makefile.incl
bin_PROGRAMS = create_work sign_executable dir_hier_path dir_hier_move
EXTRA_DIST = make_project add xadd update_versions dbcheck_files_exist upgrade makelog.sh cleanlogs.sh
EXTRA_DIST = make_project add xadd update_versions dbcheck_files_exist upgrade makelog.sh cleanlogs.sh vote_monitor
# TODO: use libboinc for these:

99
tools/vote_monitor Executable file
View File

@ -0,0 +1,99 @@
#! /bin/sh
cd `dirname $0`
MOD_EMAIL_ADDRESS=`grep POST_REPORT_EMAILS ../html/project/project.inc | awk -F\" '{print $(NF-1);}'`
while true ; do
now=`date +%s`
msgfile=`mktemp -p /tmp setimods.XXXXXX` || exit 1
sec_from_hour=`expr $now % 3600`
dbhost=`grep db_host ../config.xml | tr '[\<\>]' '[ ]' | head -1 | awk '{print $2}'`
dbuser=`grep db_user ../config.xml | tr '[\<\>]' '[ ]' | head -1 | awk '{print $2}'`
dbname=`grep db_name ../config.xml | tr '[\<\>]' '[ ]' | head -1 | awk '{print $2}'`
MYSQL="mysql -D $dbname -h $dbhost -u $dbuser -N -B"
nmods=`$MYSQL --execute="select count(userid) from forum_preferences where special_user like '1%'"`
major=`expr $nmods / 2`
# send a report on ongoing elections.
if test $sec_from_hour -lt 300 ; then
voteids=`$MYSQL --execute="select id from banishment_vote where end_time>"$now`
if test -n "$voteids" ; then
echo Ongoing votes >> $msgfile
echo >> $msgfile
for voteid in $voteids; do
msgfile2=`mktemp -p /tmp setimods.XXXXXX` || exit 1
echo >> $msgfile
echo Vote: $voteid >> $msgfile
ayes=`$MYSQL --execute="select sum(yes) from banishment_votes where voteid=$voteid"`
nays=`$MYSQL --execute="select count(id)-sum(yes) from banishment_votes where voteid=$voteid"`
userid=`$MYSQL --execute="select userid from banishment_vote where id=$voteid"`
EMAIL=`$MYSQL --execute="select email_addr from user where id=$userid"`
$MYSQL --execute="select name,' - ',userid from user,banishment_vote where banishment_vote.id=$voteid and user.id=userid" >> $msgfile2
$MYSQL --execute="select 'Ayes: ',sum(yes),' Nays: ',count(id)-sum(yes) from banishment_votes where voteid=$voteid" >> $msgfile2
$MYSQL --execute="select name,' - ',userid from user,banishment_vote where banishment_vote.id=$voteid and user.id=userid" >> $msgfile
$MYSQL --execute="select 'Ayes: ',sum(yes),' Nays: ',count(id)-sum(yes) from banishment_votes where voteid=$voteid" >> $msgfile
if test $nays -ge $major ; then
echo Vote failed. >> $msgfile
mail -s "Vote failed. You have not been banished" $EMAIL < $msgfile2
$MYSQL --execute="update forum_preferences set banished_until=0 where userid=$userid"
$MYSQL --execute="update banishment_vote set end_time=start_time where id=$voteid"
elif `test $ayes -gt $major` ; then
echo Vote succeeded. >> $msgfile
mail -s "Vote succeeded. You have been banished" $EMAIL < $msgfile2
start_time=`$MYSQL --execute="select start_time from banishment_votes where voteid=$voteid"`
$MYSQL --execute="update forum_preferences set banished_until=$start_time+1209600 where userid=$userid"
$MYSQL --execute="update banishment_vote set end_time=start_time where id=$voteid"
else
$MYSQL --execute="select 'Ends in ',(end_time-$now)/3600,' hours' from banishment_vote where id=$voteid" >> $msgfile
fi
/bin/rm $msgfile2
done
mail -s "Ongoing Votes" $MOD_EMAIL_ADDRESS < $msgfile
fi
fi
/bin/rm $msgfile
# handle recently ended elections
msgfile=`mktemp -p /tmp setimods.XXXXXX` || exit 1
voteids=`$MYSQL --execute="select id from banishment_vote where end_time<"$now" and end_time+300>"$now`
if test -n "$voteids" ; then
echo Finished votes >> $msgfile
echo >> $msgfile
for voteid in $voteids; do
msgfile2=`mktemp -p /tmp setimods.XXXXXX` || exit 1
echo >> $msgfile
echo Vote: $voteid >> $msgfile
ayes=`$MYSQL --execute="select sum(yes) from banishment_votes where voteid=$voteid"`
nays=`$MYSQL --execute="select count(id)-sum(yes) from banishment_votes where voteid=$voteid"`
userid=`$MYSQL --execute="select userid from banishment_vote where id=$voteid"`
EMAIL=`$MYSQL --execute="select email_addr from user where id=$userid"`
$MYSQL --execute="select name,' - ',userid from user,banishment_vote where banishment_vote.id=$voteid and user.id=userid" >> $msgfile2
$MYSQL --execute="select 'Ayes: ',sum(yes),' Nays: ',count(id)-sum(yes) from banishment_votes where voteid=$voteid" >> $msgfile2
$MYSQL --execute="select name,' - ',userid from user,banishment_vote where banishment_vote.id=$voteid and user.id=userid" >> $msgfile
$MYSQL --execute="select 'Ayes: ',sum(yes),' Nays: ',count(id)-sum(yes) from banishment_votes where voteid=$voteid" >> $msgfile
nays=`expr $nays + 1`
if test $ayes -gt $nays ; then
echo Vote succeeded. >> $msgfile
mail -s "Vote succeeded. You have been banished" $EMAIL < $msgfile2
start_time=`$MYSQL --execute="select start_time from banishment_votes where voteid=$voteid"`
$MYSQL --execute="update forum_preferences set banished_until=$start_time+1209600 where userid=$userid"
$MYSQL --execute="update banishment_vote set end_time=start_time where id=$voteid"
else
echo Vote failed. >> $msgfile
mail -s "Vote failed. You have not been banished" $EMAIL < $msgfile2
$MYSQL --execute="update forum_preferences set banished_until=0 where userid=$userid"
$MYSQL --execute="update banishment_vote set end_time=start_time where id=$voteid"
fi
/bin/rm $msgfile2
done
mail -s "Completed Votes" $MOD_EMAIL_ADDRESS < $msgfile
fi
/bin/rm $msgfile
sleep 300
done
exit 0