Index: openacs-4/packages/oct-election/oct-election.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/oct-election.info,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/oct-election.info 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,24 @@ + + + + + OCT Election + OCT Elections + f + f + oct-election + + + Joel Aufrecht + Web app for voting in OCT elections. + + + + + + + + + + + Index: openacs-4/packages/oct-election/sql/postgresql/oct-election-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/sql/postgresql/oct-election-create.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/sql/postgresql/oct-election-create.sql 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,34 @@ +create table oct_election ( + election_id serial + primary key, + start_time timestamptz, + end_time timestamptz, + vote_forum_cutoff timestamptz, + number_of_candidates integer, + label varchar(100) +); + +create table oct_candidate ( + candidate_id serial + primary key, + election integer + references oct_election, + label varchar(50) +); + +create table oct_vote ( + candidate_id integer + references oct_candidate +); + +create table oct_ballot ( + user_id integer + references users, + election_id integer + references oct_election, + primary key (user_id, election_id) +); + + + + \ No newline at end of file Index: openacs-4/packages/oct-election/sql/postgresql/oct-election-drop.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/sql/postgresql/oct-election-drop.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/sql/postgresql/oct-election-drop.sql 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,10 @@ +drop table oct_ballot; +drop table oct_vote; +drop table oct_candidate; +drop table oct_election; + + + + + + \ No newline at end of file Index: openacs-4/packages/oct-election/tcl/oct-election-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/tcl/oct-election-procs.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/tcl/oct-election-procs.tcl 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,61 @@ +ad_library { + Procs for election +} + +namespace eval oct-election {} + +ad_proc -private oct-election::valid_voter_p { + -election_id + -user_id +} { + @author Joel Aufrecht +} { + set status 1 + # Has the user already voted in this election? + set ballot_p [db_string get_ballot { + select count(*) + from oct_ballot + where user_id = :user_id + and election_id = :election_id + }] + + if {$ballot_p} { + set status 0 + set text "You have already voted in this election." + return [list $status $text] + } + + set num_days 90 + set valid_voter_p 0 + db_1row get_election { + select start_time, + end_time, + vote_forum_cutoff, + label + from oct_election + where election_id = :election_id + } + + set before_sql "to_date(:vote_forum_cutoff, 'YYYY-MM-DD')" + + #TODO: enable and test this on openacs + set num_posts 2 + # set num_posts [db_string get_count " + # select count(message_id) as num_posts + # from cc_users, forums_messages + # where cc_users.user_id = forums_messages.user_id + # and posting_date between $before_sql - interval '$num_days days' and $before_sql + # and cc_users.user_id = $user_id + # group by cc_users.user_id + #"] + + if {$num_posts < 2} { + set status 0 + set text "You are not a valid voter for this election. See OpenACS Governance" + return [list $status $text] + } + + set status 1 + set text "You have already voted in this election." + return [list $status $text] +} Index: openacs-4/packages/oct-election/www/candidate-add.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/candidate-add.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/candidate-add.tcl 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,19 @@ +ad_page_contract { + @cvs-id $Id: candidate-add.tcl,v 1.1 2005/05/14 19:49:49 joel Exp $ +} { + election_id:integer + candidate +} + +auth::require_login +permission::require_permission -object_id [ad_conn package_id] -privilege create + +db_dml candidate_add { + insert into oct_candidate + (election, label) + values (:election_id, :candidate) +} + +ad_returnredirect [export_vars -base "election" {election_id}] + + Index: openacs-4/packages/oct-election/www/candidate-delete.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/candidate-delete.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/candidate-delete.tcl 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,18 @@ +ad_page_contract { + @cvs-id $Id: candidate-delete.tcl,v 1.1 2005/05/14 19:49:49 joel Exp $ +} { + candidate_id:integer + election_id:integer +} + +auth::require_login +permission::require_permission -object_id [ad_conn package_id] -privilege create + +db_dml candidate_delete { + delete from oct_candidate + where candidate_id = :candidate_id +} + +ad_returnredirect [export_vars -base "election" {election_id}] + + Index: openacs-4/packages/oct-election/www/election-edit.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/election-edit.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/election-edit.adp 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,5 @@ + + @page_title;noquote@ + @context;noquote@ + + \ No newline at end of file Index: openacs-4/packages/oct-election/www/election-edit.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/election-edit.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/election-edit.tcl 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,53 @@ +ad_page_contract { + @cvs-id $Id: election-edit.tcl,v 1.1 2005/05/14 19:49:49 joel Exp $ +} { + election_id:integer,optional +} + +set page_title "Editing Election" +set context [list $page_title] + +ad_form -name election -form { + {election_id:key} + {label:text {label Election}} + {start_time:text {label "Start Time (2005-04-01 10:00PST)"}} + {end_time:text {label "End Time"}} + {vote_forum_cutoff:text {label "Forum Posting cutoff date (2005-04-01 10:00PST)"}} + {number_of_candidates:integer {label "Number of Candidates"}} +} -new_request { + auth::require_login + permission::require_permission -object_id [ad_conn package_id] -privilege create + set page_title "Add an election" + set context [list $page_title] +} -edit_request { + auth::require_login + permission::require_write_permission -object_id $election_id + + db_1row get_election { + select start_time, + end_time, + label, + vote_forum_cutoff, + number_of_candidates + from oct_election + where election_id = :election_id; + } + set page_title "Edit $label" + set context [list $page_title] +} -new_data { + db_dml create_election { + insert into oct_election + (start_time, end_time, number_of_candidates, label) + values (:start_time, :end_time, :number_of_candidates, :label); + } +} -edit_data { + db_dml update_election { + update oct_election + set start_time = :start_time, + end_time = :end_time, + vote_forum_cutoff = :vote_forum_cutoff, + number_of_candidates = :number_of_candidates, + label = :label + where election_id = :election_id} + ad_returnredirect [export_vars -base election {election_id}] +} Index: openacs-4/packages/oct-election/www/election.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/election.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/election.adp 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,30 @@ + + @page_title;noquote@ + @context;noquote@ + +

Election: @label@ +

Start time: @start_time@ +

End time: @end_time@ +

Label: @label@ +

Candidates

+ + +

+

+ + + +
+

+
+ + +
+ + +
+
+ + @valid_voter_text@ + + Index: openacs-4/packages/oct-election/www/election.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/election.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/election.tcl 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,59 @@ +ad_page_contract { + @cvs-id $Id: election.tcl,v 1.1 2005/05/14 19:49:49 joel Exp $ +} { + election_id:integer +} + +set user_id [auth::require_login] +set admin_p [acs_user::site_wide_admin_p] +set valid_voter [oct-election::valid_voter_p -election_id $election_id -user_id $user_id] +set valid_voter_p [lindex $valid_voter 0] +set valid_voter_text [lindex $valid_voter 1] + +db_1row get_election { + select start_time, + end_time, + vote_forum_cutoff, + label + from oct_election + where election_id = :election_id +} + +set page_title $label +set context $page_title + +template::list::create \ + -name candidates \ + -multirow candidates \ + -elements { + candidate_label { + label "Candidate" + } + delete { + link_url_col delete_url + display_template { + + } + sub_class narrow + } + } + +db_multirow \ + -extend { + delete_url + } candidates candidates_select { + select candidate_id, + label as candidate_label + from oct_candidate + where election = :election_id + } { + set delete_url [export_vars -base "candidate-delete" {candidate_id election_id}] + } + +#TODO: show vote total if election is over +#TODO: hide delete button if not admin +#TODO: sort candidates by vote total if election is over, or alpha if not + + + + Index: openacs-4/packages/oct-election/www/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/index.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/index.adp 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,8 @@ + + @page_title;noquote@ + @context;noquote@ + + + +

Add an Election

+
\ No newline at end of file Index: openacs-4/packages/oct-election/www/index.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/index.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/index.tcl 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,33 @@ +ad_page_contract { + @cvs-id $Id: index.tcl,v 1.1 2005/05/14 19:49:49 joel Exp $ +} { +} + +set page_title "OCT Elections" +set context $page_title +set admin_p [acs_user::site_wide_admin_p] + +template::list::create \ + -name elections \ + -multirow elections \ + -elements { + label { + link_url_col election_url + label "Election" + } + } + +db_multirow \ + -extend { + election_url + } elections elections_select { + select election_id, + label, + start_time, + end_time + from oct_election + } { + set election_url [export_vars -base "election" {election_id}] + } + + Index: openacs-4/packages/oct-election/www/vote-process.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/vote-process.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/vote-process.adp 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,2 @@ + + Your vote has been tallied. Index: openacs-4/packages/oct-election/www/vote-process.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/vote-process.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/vote-process.tcl 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,49 @@ +ad_page_contract { + @cvs-id $Id: vote-process.tcl,v 1.1 2005/05/14 19:49:49 joel Exp $ +} { + election_id:integer + q:integer,array,optional +} + +set user_id [auth::require_login] +set valid_voter [oct-election::valid_voter_p -election_id $election_id -user_id $user_id] +set valid_voter_p [lindex $valid_voter 0] +set valid_voter_text [lindex $valid_voter 1] + +if {!$valid_voter_p} { + ad_return_complaint 1 "$valid_voter_text" + ad_script_abort +} + +set votes 0 +set max_votes [db_string get_max_votes { + select number_of_candidates + from oct_election + where election_id = :election_id}] + +# TODO: this should all be in a transaction, and would if I knew/trusted how to do that + +# process the ballot one candidate at a time, keeping an eye on the total vote limit +set searchId [array startsearch q] +while {[array anymore q $searchId]} { + if {$votes > $max_votes} { + #don't process this vote or any others + # this may be early by 1 - should it go after set candidate? + break + } + + set candidate_id [array nextelement q $searchId] + set votes [expr $votes + 1] + + # TODO: verify that the candidate is actually in the election + db_dml tally_vote { + insert into oct_vote values (:candidate_id); + } + + +} + +db_dml mark_user_ballot { + insert into oct_ballot values (:user_id, :election_id); +} + Index: openacs-4/packages/oct-election/www/vote.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/vote.adp,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/vote.adp 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,14 @@ + + @page_title;noquote@ + @context;noquote@ + +

Vote for up to @number_of_candidates@ candidates. (Extra votes will be ignored.) Ballots are anonymous and cannot be revoked or altered.

+
+ + + +

@candidates.candidate_label@

+
+ +

+
\ No newline at end of file Index: openacs-4/packages/oct-election/www/vote.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oct-election/www/vote.tcl,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/oct-election/www/vote.tcl 14 May 2005 19:49:49 -0000 1.1 @@ -0,0 +1,36 @@ +ad_page_contract { + @cvs-id $Id: vote.tcl,v 1.1 2005/05/14 19:49:49 joel Exp $ +} { + election_id:integer +} + +#TODO: add javascript to prevent people from voting too many times + +db_1row get_election { + select start_time, + end_time, + vote_forum_cutoff, + number_of_candidates, + label + from oct_election + where election_id = :election_id +} + +set user_id [auth::require_login] +set page_title "Vote for $label" +set context [list $page_title] +set valid_voter [oct-election::valid_voter_p -election_id $election_id -user_id $user_id] +set valid_voter_p [lindex $valid_voter 0] +set valid_voter_text [lindex $valid_voter 1] + +if {!$valid_voter_p} { + ad_return_complaint 1 "$valid_voter_text" + ad_script_abort +} + +db_multirow candidates candidates_select { + select candidate_id, + label as candidate_label + from oct_candidate + where election = :election_id + }