gnuworld/doc/cmaster/regproc/appjudge

236 lines
12 KiB
Plaintext

#!/usr/local/pgsql/bin/pgtclsh
# $Id: appjudge,v 1.12 2003/08/29 13:52:33 nighty Exp $
# Author: sengaia@undernet.org, 20010619
# Last modif: nighty@undernet.org, 20030823 (fixed the feature, added more traps, packed a couple of procs, added ability of running the judge remotely)
# This script automates a good part of the channel-registration process, you need
# to set up sensible settings in appjudge-config for it to do you any good though.
# Load configuration
source [file dirname $argv0]/appjudge-config
proc clock_stamp {} {
return [clock format [clock seconds] -format "%Y%m%d %H:%M"]
}
proc log_channel {hDB channel_id state areason acode} {
global AS_REJECTED AS_COMPLETED
# who manager? he manager!
pg_select $hDB "SELECT channel_id,manager_id FROM pending WHERE channel_id=$channel_id" mgr_res { set mgr_id [lindex [array get mgr_res "manager_id"] 1] }
pg_select $hDB "SELECT id,user_name,flags FROM users WHERE id=$mgr_id" mgr_res {
set mgr_name [lindex [array get mgr_res "user_name"] 1]
set mgr_flags [lindex [array get mgr_res "flags"] 1]
set mgr_what "$mgr_name ($mgr_id"
if {[expr $mgr_flags & 8]} { set mgr_what "${mgr_what}, fraud)" } else { set mgr_what "${mgr_what})" }
}
# gather the supporters
set supporter_ids ""
pg_select $hDB "SELECT channel_id,user_id FROM supporters WHERE (channel_id = $channel_id)" sup_res {
lappend supporter_ids [lindex [array get sup_res "user_id"] 1]
}
set sup_list ""
foreach sup_id $supporter_ids {
pg_select $hDB "SELECT id,user_name,flags FROM users where id=$sup_id" user_res {
set user_name [lindex [array get user_res "user_name"] 1]
set user_flags [lindex [array get user_res "flags"] 1]
set user_what "$user_name ($sup_id"
if {[expr $user_flags & 8]} { set user_what "${user_what}, fraud)" } else { set user_what "${user_what})" }
set sup_list "${sup_list}, $user_what"
}
}
set sup_list [string trim $sup_list ", "]
set log_msg "\[The Judge\]: Application ${state}. ${areason} Applicant: ${mgr_what}. Supporters: ${sup_list}."
pg_exec $hDB "INSERT INTO channellog (ts,channelid,event,message,last_updated) VALUES(now()::abstime::int4,$channel_id,$acode,'\[The Judge\]: Application ${state}. ${areason} Applicant: ${mgr_what}. Supporters: ${sup_list}.',now()::abstime::int4)"
}
proc get_channel {hDB channel_id} {
pg_select $hDB "SELECT id,name FROM channels WHERE id=$channel_id" chname { return [lindex [array get chname "name"] 1]}
}
proc reject_app {hDB channel_id reason} {
global AS_REJECTED REVIEWER_ID
puts [format "%s: Rejecting application for channel %s: %s" [clock_stamp] [get_channel $hDB $channel_id] $reason]
log_channel $hDB $channel_id "REJECTED" $reason 13
pg_exec $hDB "UPDATE pending SET status=$AS_REJECTED, last_updated=now()::abstime::int4, reviewed_by_id=$REVIEWER_ID, decision_ts=now()::abstime::int4, decision='Rejected: $reason' WHERE channel_id=$channel_id"
# Need the associated userid
pg_select $hDB "SELECT channel_id,manager_id FROM pending WHERE channel_id=$channel_id" res_ch {
set notify_user [lindex [array get res_ch "manager_id"] 1]
}
}
proc check_comments {hDB channel_id} {
global AS_PENDREVIEW
set check_res 0
# Check for objections
pg_select $hDB "SELECT COUNT(*) AS objcount FROM objections WHERE channel_id=$channel_id" res_obj {
set objcount [lindex [array get res_obj "objcount"] 1]
if {$objcount} {
puts [format "%s: Moving channel %s to status %d (there are %d objections/comments)" [clock_stamp] [get_channel $hDB $channel_id] $AS_PENDREVIEW $objcount]
pg_exec $hDB "UPDATE pending SET status=$AS_PENDREVIEW,last_updated=now()::abstime::int4 WHERE channel_id=$channel_id"
set check_res 1
}
}
# Check wether or not the application was labeled for review
pg_select $hDB "SELECT channel_id,comments FROM pending WHERE channel_id=$channel_id" res_cmt {
set comments [string trim [lindex [array get res_cmt "comments"] 1]]
if {[string match "REVIEW:*" $comments]} {
puts [format "%s: Moving channel %s to status %d (it was labeled for review)" [clock_stamp] [get_channel $hDB $channel_id] $AS_PENDREVIEW]
pg_exec $hDB "UPDATE pending SET status=$AS_PENDREVIEW, last_updated=now()::abstime::int4 WHERE channel_id=$channel_id"
set check_res 1
}
}
return $check_res
}
proc check_fraudulous {hDB chan_id mgr_id} {
global AS_PENDREVIEW
set supporter_ids ""
pg_select $hDB "SELECT channel_id,user_id FROM supporters WHERE (channel_id = $chan_id)" sup_res {
lappend supporter_ids [lindex [array get sup_res "user_id"] 1]
}
# check for fraudulous users
set isfraud 0
foreach sup_id $supporter_ids {
pg_select $hDB "SELECT id,user_name,flags FROM users where id=$sup_id" user_res {
set user_flags [lindex [array get user_res "flags"] 1]
if {[expr $user_flags & 8]} { incr isfraud }
}
}
pg_select $hDB "SELECT id,user_name,flags FROM users where id=$mgr_id" user_res {
set user_flags [lindex [array get user_res "flags"] 1]
if {[expr $user_flags & 8]} { incr isfraud }
}
if {$isfraud > 0} {
# move it to 'Ready for review' if anyone is fraudulous
puts [format "%s: Moving channel %s to status %d (%d fraudulent applicant/supporters found)" [clock_stamp] [get_channel $hDB $chan_id] $AS_PENDREVIEW $isfraud]
pg_exec $hDB "UPDATE pending SET status=$AS_PENDREVIEW,last_updated=now()::abstime::int4 WHERE channel_id=$chan_id"
}
return $isfraud
}
proc check_suspended {hDB chan_id mgr_id} {
global AS_REJECTED
set supporter_ids ""
pg_select $hDB "SELECT channel_id,user_id FROM supporters WHERE (channel_id = $chan_id)" sup_res {
lappend supporter_ids [lindex [array get sup_res "user_id"] 1]
}
# check for suspended applicant/supporter
set issusp 0
foreach sup_id $supporter_ids {
pg_select $hDB "SELECT id,user_name,flags FROM users where id=$sup_id" user_res {
set user_flags [lindex [array get user_res "flags"] 1]
if {[expr $user_flags & 1]} { incr issusp }
}
}
pg_select $hDB "SELECT id,user_name,flags FROM users where id=$mgr_id" user_res {
set user_flags [lindex [array get user_res "flags"] 1]
if {[expr $user_flags & 1]} { incr issusp }
}
if {$issusp > 0} {
# reject the channel if any suspended found !
puts [format "%s: Moving channel %s to status %d (%d suspended applicant/supporters found)" [clock_stamp] [get_channel $hDB $chan_id] $AS_REJECTED $issusp]
reject_app $hDB $chan_id "The applicant and/or one or more of the supporters are suspended."
}
return $issusp
}
# Open the DB
if {$SQL_PASS == ""} {
set hSQL [pg_connect -conninfo "host=$SQL_HOST dbname=$SQL_DB user=$SQL_USER"]
} else {
set hSQL [pg_connect -conninfo "host=$SQL_HOST dbname=$SQL_DB password=$SQL_PASS user=$SQL_USER"]
}
puts [format "%s: The court is now in session." [clock_stamp]]
# Step 0.5: Reject applications that are still in status 0 after x days.
set sup_timeout [expr $DAY * $SUPPORT_DAYS]
pg_select $hSQL "SELECT channel_id,status,check_start_ts FROM pending WHERE (status = $AS_PENDING_SUPPORT) AND (now()::abstime::int4 > (created_ts + $sup_timeout))" sup_expired {
set chan_id [lindex [array get sup_expired "channel_id"] 1]
reject_app $hSQL $chan_id "One or more of the supporters did not confirm their support."
}
# Step 1: reject applications that failed to pass the activity test within the required timeframe
set app_timeout [expr $DAY * $MAX_DAYS]
pg_select $hSQL "SELECT channel_id,status,check_start_ts,unique_join_count FROM pending WHERE (status = $AS_TRAFFIC_CHECK) AND (now()::abstime::int4 > (check_start_ts + $app_timeout))" t_expired {
set chan_id [lindex [array get t_expired "channel_id"] 1]
set joins [lindex [array get t_expired "unique_join_count"] 1]
# Were there less than $MIN_SUPPORTERS?
pg_select $hSQL "SELECT COUNT(*) AS supcount FROM supporters WHERE (channel_id = $chan_id) AND (join_count > 0)" sup_res {
set sup_joins [lindex [array get sup_res "supcount"] 1]
}
if {$sup_joins < $MIN_SUPPORTERS} {
reject_app $hSQL $chan_id "Not enough supporter activity in the channel."
} else {
# Does it pass the unique join check?
if {$joins >= $UNIQUE_JOINS} {
# Yes - Label it for human inspection and pass it on
# get supporter count
pg_select $hSQL "SELECT COUNT(*) AS supcount FROM supporters WHERE channel_id=$chan_id" res_supc { set sup_joins [lindex [array get sup_res "supcount"] 1] }
puts [format "%s: Moving channel %s to status %d (application labeled for human inspection)" [clock_stamp] [get_channel $hSQL $chan_id] $AS_NOTIFICATION]
pg_exec $hSQL "UPDATE pending SET status=$AS_NOTIFICATION,check_start_ts=now()::abstime::int4,comments='REVIEW: Only $sup_joins supporters have been seen.', last_updated=now()::abstime::int4 WHERE channel_id=$chan_id"
} else {
# No - Reject
reject_app $hSQL $chan_id "Not enough activity in the channel."
}
}
}
# Step 2: pass along applications that have passed the activity test
pg_select $hSQL "SELECT channel_id,status FROM pending WHERE (status=$AS_TRAFFIC_CHECK) AND (unique_join_count >= $UNIQUE_JOINS)" t_check {
# check if supporters joined often enough
set chan_id [lindex [array get t_check "channel_id"] 1]
pg_select $hSQL "SELECT COUNT(*) AS supcount FROM supporters WHERE (channel_id = $chan_id) AND (join_count > 0)" sup_res {
set sup_joins [lindex [array get sup_res "supcount"] 1]
}
if {$sup_joins >= $MIN_SUPPORTERS} {
puts [format "%s: Moving channel %s to status %d (traffic check passed)" [clock_stamp] [get_channel $hSQL $chan_id] $AS_NOTIFICATION]
pg_exec $hSQL "UPDATE pending SET status=$AS_NOTIFICATION,check_start_ts=now()::abstime::int4,last_updated=now()::abstime::int4 WHERE channel_id=$chan_id"
}
}
# Step 3: check for end of notify period
set notify_delay [expr $DAY * $NOTIFY_DAYS]
pg_select $hSQL "SELECT channel_id,status,manager_id,reviewed FROM pending WHERE (status = $AS_NOTIFICATION) AND ((check_start_ts + $notify_delay) < now()::abstime::int4)" t_notified {
set chan_id [lindex [array get t_notified "channel_id"] 1]
set mgr_id [lindex [array get t_notified "manager_id"] 1]
set reviewed [lindex [array get t_notified "reviewed"] 1]
# Figure out what to do
if {![check_comments $hSQL $chan_id]} { # NO objection found !, good.
# Has a human being seen this application?
if {$reviewed == "Y"} {
if {![check_suspended $hSQL $chan_id $mgr_id]} {
if {![check_fraudulous $hSQL $chan_id $mgr_id]} {
# Register the channel
log_channel $hSQL $chan_id "ACCEPTED" "All checks passed." 7
puts [format "%s: Moving channel %s to status %d (notify period ended)" [clock_stamp] [get_channel $hSQL $chan_id] $AS_COMPLETED]
pg_exec $hSQL "UPDATE pending SET status=$AS_COMPLETED,reviewed_by_id=$REVIEWER_ID,decision_ts=now()::abstime::int4,decision='Accepted by The Judge', last_updated=now()::abstime::int4 WHERE channel_id=$chan_id"
puts [format "%s: Registering channel %s (all checks passed)" [clock_stamp] [get_channel $hSQL $chan_id]]
pg_exec $hSQL "UPDATE channels SET registered_ts=now()::abstime::int4, last_updated = now()::abstime::int4 WHERE id=$chan_id"
pg_exec $hSQL "INSERT INTO levels (channel_id,user_id,access,added,added_by,last_modif,last_modif_by,last_updated) VALUES($chan_id,$mgr_id,500,now()::abstime::int4,'The Judge',now()::abstime::int4,'The Judge',now()::abstime::int4)"
}
}
} else {
# No, label it for review if no one is suspended on it
if {![check_suspended $hSQL $chan_id $mgr_id]} {
puts [format "%s: Moving channel %s to status %d (it was never reviewed)" [clock_stamp] [get_channel $hSQL $chan_id] $AS_PENDREVIEW]
pg_exec $hSQL "UPDATE pending SET status=$AS_PENDREVIEW,last_updated=now()::abstime::int4 WHERE channel_id=$chan_id"
}
}
} else {
# Objections found, label it for review if no one is suspended on it ;)
if {![check_suspended $hSQL $chan_id $mgr_id]} {
puts [format "%s: Moving channel %s to status %d (it was never reviewed)" [clock_stamp] [get_channel $hSQL $chan_id] $AS_PENDREVIEW]
pg_exec $hSQL "UPDATE pending SET status=$AS_PENDREVIEW,last_updated=now()::abstime::int4 WHERE channel_id=$chan_id"
}
}
}
# Now that wasn't so hard...
pg_disconnect $hSQL