[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [websites/ballot-kde-org] /: Add results sending for active votes
From:       Jeff Mitchell <mitchell () kde ! org>
Date:       2011-10-31 18:55:17
Message-ID: 20111031185517.2B65CA60A6 () git ! kde ! org
[Download RAW message or body]

Git commit 2b84388789bb86f8d8125bdc65ab8599cfd81f50 by Jeff Mitchell.
Committed on 31/10/2011 at 19:54.
Pushed by mitchell into branch 'master'.

Add results sending for active votes for vote administrators

M  +74   -14   ballot.rb
M  +8    -1    views/vote.erb

http://commits.kde.org/websites/ballot-kde-org/2b84388789bb86f8d8125bdc65ab8599cfd81f50


diff --git a/ballot.rb b/ballot.rb
index ba2a3eb..a1ffc3b 100755
--- a/ballot.rb
+++ b/ballot.rb
@@ -62,11 +62,14 @@ def checkVotes
          votename = filename.rpartition(".vote")[0]
          next if votename.nil? or votename.empty?
          hash =  JSON.load(File.new("#{$configdir}/votes/#{filename}"))
-         if not hash.has_key?("active") or not hash["active"] or \
(hash.has_key?("expiration") and hash["expiration"] < Time.now.to_i) +         if not \
hash.has_key?("active") or not hash["active"]  newvotedata.delete(votename)
             newvotetimers.delete(votename)
             next
          end
+         if not hash.has_key?("choices") and hash.has_key?("votetype") and \
hash["votetype"] == "ev-membership" +            hash["choices"] = { "yes" => "Yes", \
"no" => "No", "abstain" => "Abstain" } +         end
          newvotedata[votename] = hash
          newvotetimers[votename] = Time.now
          if not $remindersent.has_key?(votename)
@@ -147,7 +150,6 @@ class Ballot < Sinatra::Base
          if attributes.include?("smsnumber")
             $userprops[username]["smsnumber"] = result.first["smsnumber"].first
          end
-
       end
 
       # Check the user's cookie. The cookie contains the username and a hash.
@@ -257,6 +259,24 @@ class Ballot < Sinatra::Base
          filter
       end
 
+      def getResults(votename)
+         results = {}
+         votedir = "#{$votebasedir}/#{votename}/values"
+         dir = Dir.new(votedir)
+         dir.each { |filename|
+            next unless File.file?("#{votedir}/#{filename}")
+            File.open("#{votedir}/#{filename}", "r") { |f|
+               value = f.read.chomp.to_s
+               if not results.has_key?(value)
+                  results[value] = 1
+               else
+                  results[value] = results[value] + 1
+               end
+            }
+         }
+         results 
+      end
+
       def sendMail(type, votename)
          if not $votedata[votename].has_key?("mailattr")
             puts "Need mail attribute value for #{votename}"
@@ -297,15 +317,46 @@ class Ballot < Sinatra::Base
          if type.to_s == "invite"
             mailtext = $invitemail
             subject = "New vote available: \
                \"#{$votedata[votename]["description"]}\""
-         else
+         elsif type.to_s == "reminder"
             mailtext = $remindermail
             subject = "Reminder: please vote on \
\"#{$votedata[votename]["description"]}\"" +         elsif type.to_s == "results"
+            mailtext = $resultsmail
+            subject = "Results of vote: \"#{$votedata[votename]["description"]}\""
+         else
+            puts "Cannot determine mail type, bailing"
+            return
          end
 
          mailtext = mailtext.sub("__VOTENAME__", $votedata[votename]["description"])
          mailtext = mailtext.sub("__VOTEURL__", $siteurl)
          mailtext = mailtext.sub("__VOTEEXPIRATION__", \
Time.at($votedata[votename]["expiration"]).to_s)  
+         if type.to_s == "results" and $votedata[votename]["votetype"] == \
"ev-membership" +            resultstext = ""
+            # check yes, no, abstain, and quorum
+            results = getResults(votename)
+            results.each_key { |key|
+               if not $votedata[votename]["choices"].has_key?(key)
+                  puts "Anomaly found -- some value doesn't match the vote choices!"
+                  return
+               end
+            }
+            availablevotes = mailaddrs.size
+            yes = (results.has_key?("yes") && results["yes"]) || 0
+            no = (results.has_key?("no") && results["no"]) || 0
+            abstain = (results.has_key?("abstain") && results["abstain"]) || 0
+            totalvotes = yes + no + abstain
+            quorum = (availablevotes*0.2).floor
+            resultstext += "Number of active members: " + availablevotes.to_s + " \
(#{totalvotes} voted, #{(totalvotes * 100 / (availablevotes*1.0)).round(2)}%)\n" +    \
resultstext += "Number of \"Yes\" votes: " + yes.to_s + " (#{(yes * 100 / \
(totalvotes*1.0)).round(2)}%)\n" +            resultstext += "Number of \"No\" votes: \
" + no.to_s + " (#{(no * 100 / (totalvotes*1.0)).round(2)}%)\n" +            \
resultstext += "Number of \"Abstain\" votes: " + abstain.to_s + " (#{(abstain * 100 / \
(totalvotes*1.0)).round(2)}%)\n" +            resultstext += "Yes/No votes needed for \
quorum: " + quorum.to_s + " (got #{yes + no})\n" +            resultstext += "Vote \
valid: " + ((((yes + no) > quorum) && "Yes") || "No") +            mailtext = \
mailtext.sub("__VOTERESULTS__", resultstext) +         end
+
          puts mailtext
 
          mailaddrs.each do |addr|
@@ -401,7 +452,7 @@ class Ballot < Sinatra::Base
       # explicitly or via group membership
       def populateMyVotes(username, myvotes)
          $votedata.each_key { |votename|
-            if accessCheck(username, votename)
+            if ($votedata[votename].has_key?("administrators") and \
$votedata[votename]["administrators"].include?(username)) or accessCheck(username, \
                votename)
                myvotes[votename] = { "id" => $votedata[votename]["id"], \
"description" => $votedata[votename]["description"] }  if \
                $votedata[votename].has_key?("expiration")
                   myvotes[votename]["expiration"] = \
$votedata[votename]["expiration"] @@ -583,16 +634,19 @@ class Ballot < Sinatra::Base
          return "Vote not active or does not exist"
       end
 
-      if not accessCheck(givenname, @votename)
+      @administrator = false
+      if @votedata.has_key?("administrators") and \
@votedata["administrators"].include?(givenname) +         @administrator = true
+      elsif not accessCheck(givenname, @votename)
          status 403
          return "You are not authorized to participate in this vote."
       end
 
-      @administrator = false
-      if @votedata.has_key?("administrators") and \
                @votedata["administrators"].include?(givenname)
-         @administrator = true
+      @votecomplete = false
+      if not @votedata.has_key?("expiration") or @votedata["expiration"] < \
Time.now.to_i +         @votecomplete = true
       end
-      
+
       @scramblevalues = nil
       $scrambledata[@votename] ||= {}
 
@@ -647,14 +701,17 @@ class Ballot < Sinatra::Base
          return "Vote not active or does not exist"
       end
 
-      if not accessCheck(givenname, @votename)
+      @administrator = false
+      if @votedata.has_key?("administrators") and \
@votedata["administrators"].include?(givenname) +         @administrator = true
+      elsif not accessCheck(givenname, @votename)
          status 403
          return "You are not authorized to participate in this vote."
       end
 
-      @administrator = false
-      if @votedata.has_key?("administrators") and \
                @votedata["administrators"].include?(givenname)
-         @administrator = true
+      @votecomplete = false
+      if not @votedata.has_key?("expiration") or @votedata["expiration"] < \
Time.now.to_i +         @votecomplete = true
       end
 
       # If the vote was scrambled, figure out the value that they actually selected
@@ -670,7 +727,7 @@ class Ballot < Sinatra::Base
       end
 
       skipvotecheck = false
-      if params.has_key?("send_sms") or params.has_key?("sendinvitemail") or \
params.has_key?("sendremindermail") +      if params.has_key?("send_sms") or \
params.has_key?("sendinvitemail") or params.has_key?("sendremindermail") or \
params.has_key?("sendresultsmail")  skipvotecheck = true
       end
 
@@ -716,6 +773,9 @@ class Ballot < Sinatra::Base
          elsif params.has_key?("sendremindermail")
             sendMail("reminder", @votename)
             @status = "remindermailsent"
+         elsif params.has_key?("sendresultsmail")
+            sendMail("results", @votename)
+            @status = "resultsmailsent"
          end
       else
          votedir = "#{$votebasedir}/#{@votename}"
diff --git a/views/vote.erb b/views/vote.erb
index 577a4dd..974096a 100644
--- a/views/vote.erb
+++ b/views/vote.erb
@@ -39,6 +39,8 @@ Vote Name: <%=@votedata["description"]%><br />
    <font color="green">Invite emails sent.</font>
 <% elsif @status == "remindermailsent" %>
    <font color="green">Reminder mails sent.</font>
+<% elsif @status == "resultsmailsent" %>
+   <font color="green">Results mails sent.</font>
 <% end %>
 <br /><br />
 Instructions: <%=@votedata["instructions"]%>
@@ -57,7 +59,12 @@ Instructions: <%=@votedata["instructions"]%>
          <br />
          <input type="submit" name="sendinvitemail" method="post" value="Send Invite \
Email">  <br />
-         <input type="submit" name="sendremindermail" method="post" value="Send \
Reminder Mail"> +         <input type="submit" name="sendremindermail" method="post" \
value="Send Reminder Email"> +         <br />
+         <% if @votecomplete %>
+            <input type="submit" name="sendresultsmail" method="post" value="Send \
Results Email"> +            <br />
+         <% end %>
       </form>
       <br />
    <% end %>


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic