diff --git a/checkin_notes b/checkin_notes index 8f6c1e3edd..500727bf3c 100644 --- a/checkin_notes +++ b/checkin_notes @@ -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 + + 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 + diff --git a/db/schema.sql b/db/schema.sql index 0130f490d1..7ee2917adc 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -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; diff --git a/html/inc/forum_banishment_vote.inc b/html/inc/forum_banishment_vote.inc new file mode 100644 index 0000000000..902870c628 --- /dev/null +++ b/html/inc/forum_banishment_vote.inc @@ -0,0 +1,150 @@ +Current Tally Ayes: ".$foobar->ayes." Nays: ".$foobar->nays."

"; + 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.

"; + return -1; + } + $foobar = mysql_fetch_object($result); + if (!$foobar) { + echo "Database error attempting to read banishment_vote table 2.

"; + 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.

"; + 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.

"; + 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.

"; + return 0; + } + + $query="update forum_preferences set banished_until=".$fin." where userid=".$user->id; + $result = mysql_query($query); + + echo "Banishment vote started.

"; + 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.

"; + 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.

"; + 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.

"; + return 0; + } + if ($foobar->count > 0) { + echo "You have already voted in this election.

"; + 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.

"; + return 0; + } + echo "Vote recorded: Aye

"; + 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.

"; + 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.

"; + 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.

"; + return 0; + } + if ($foobar->count > 0) { + echo "You have already voted in this election.

"; + 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.

"; + return 0; + } + echo "Vote recorded: Nay

"; + current_tally($voteid); + return 1; +} + + + +?> diff --git a/html/inc/forum_email.inc b/html/inc/forum_email.inc index ab2aee8a49..6d5468941b 100644 --- a/html/inc/forum_email.inc +++ b/html/inc/forum_email.inc @@ -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(), "")."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\nid + .">[vote to banish author]\n\n" + ."id + .">[vote not to banish author]"; + + foreach ($emails as $email) { + $admin->email_addr = $email; + if (!send_email($admin, "A banishment vote for ".$user->name." has been started.", $body)) { + $success = false; + } + } +} + + + ?> diff --git a/html/inc/forum_moderators.inc b/html/inc/forum_moderators.inc index 16e0ff674f..42bcc64a82 100644 --- a/html/inc/forum_moderators.inc +++ b/html/inc/forum_moderators.inc @@ -1,10 +1,13 @@ isHidden()){ $x = " - getID()."$tokens\">[undelete post]"; @@ -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 .= " - getID()."&userid=".$post->getOwnerID()."$tokens>[banish author]"; } + if ($logged_in_user->isSpecialUser(S_MODERATOR) && $moderators_vote_to_ban) { + if (vote_is_in_progress($post->getOwnerID())) { + $x .= " - getOwnerID() + .">[vote to banish author] - getOwnerID().">[vote not to banish author]"; + } else { + $x .= " - getOwnerID().">[start vote to banish author]"; + } + } return $x; } diff --git a/html/user/forum_banishment_vote.php b/html/user/forum_banishment_vote.php new file mode 100644 index 0000000000..767495eefb --- /dev/null +++ b/html/user/forum_banishment_vote.php @@ -0,0 +1,86 @@ +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 "

\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 ""; + echo "\n"; + row1("Are you sure you want to banish ".$user->name."? + This will prevent ".$user->name." from posting for chosen time period.
+ 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", + ""); +row2("Reason
Mailed if nonempty", + ""); + +row2( + "", + "" +); +} 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 "
"; + +page_tail(); + +?> diff --git a/html/user/forum_banishment_vote_action.php b/html/user/forum_banishment_vote_action.php new file mode 100644 index 0000000000..75ca37b944 --- /dev/null +++ b/html/user/forum_banishment_vote_action.php @@ -0,0 +1,63 @@ +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"); +} + +?> diff --git a/tools/Makefile.am b/tools/Makefile.am index e7c4bbbdd4..29dd935594 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -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: diff --git a/tools/vote_monitor b/tools/vote_monitor new file mode 100755 index 0000000000..69e49d0ac9 --- /dev/null +++ b/tools/vote_monitor @@ -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