This is an automated email from the ASF dual-hosted git repository.

sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/whimsy.git


The following commit(s) were added to refs/heads/master by this push:
     new 09f6f2dc Hack to work-round #257
09f6f2dc is described below

commit 09f6f2dc58bf49a222b9efdf116ab88417073341
Author: Sebb <[email protected]>
AuthorDate: Wed Feb 26 15:42:03 2025 +0000

    Hack to work-round #257
    
    Need revisiting
---
 tools/whatif.rb        | 185 +++++++++++++++++++++++++++++++++++++++++++++++++
 www/members/whatif.cgi |  10 ++-
 2 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/tools/whatif.rb b/tools/whatif.rb
new file mode 100755
index 00000000..00c8d6de
--- /dev/null
+++ b/tools/whatif.rb
@@ -0,0 +1,185 @@
+# STV Explorer using Historical data from ASF Board Votes
+
+#####
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#####
+
+# N.B. This is a copy of the file 
+# https://raw.githubusercontent.com/apache/steve/refs/heads/trunk/whatif.rb
+# adjusted to remove untaint calls (and fix the jquery reference)
+# It's not currently possible to fix the code in Git and use that;
+# see members/whatif.cgi for explanation
+
+#
+# Prereqs:
+#
+#   * svn checkout of foundation:voter and foundation:Meetings
+#   * Web server with the ability to run cgi (Apache httpd recommended)
+#   * Python 2.6.x
+#   * Ruby 1.9.x
+#   * wunderbar gem ([sudo] gem install wunderbar)
+#   * (optional) jQuery http://code.jquery.com/jquery-min.js
+#
+# Installation instructions:
+#
+#    ruby whatif.rb --install=/var/www
+#
+#    1) Specify a path that supports cgi, like public-html or Sites.
+#    2) (optional, but highly recommended) download jquery-min.js into
+#       your installation directory.
+#
+# Execution instructions:
+#
+#   Point your web browser at your cgi script.  For best results, use
+#   Firefox 4 or a WebKit based browser, like Google Chrome.
+
+
+
+MEETINGS  = File.expand_path('../Meetings') unless defined? MEETINGS
+WHATIF = './whatif.py' unless defined? WHATIF
+
+require 'wunderbar'
+require 'tempfile'
+
+def raw_votes(date)
+  all_votes = Dir["#{MEETINGS}/*/raw_board_votes.txt"]
+  if date
+    result = "#{MEETINGS}/#{date}/raw_board_votes.txt"
+  else
+    result = all_votes.sort.last
+  end
+  result
+end
+
+def ini(vote)
+  vote.sub('/raw_','/').sub('votes.','nominations.').sub('.txt','.ini')
+end
+
+def filtered_election(votes, seats, candidates)
+  list = candidates.join(' ')
+
+  output = `#{WHATIF} #{votes} #{seats} #{list}`
+  output.scan(/.*elected$/).inject(Hash.new('none')) do |results, line|
+    name, status = line.scan(/^(.*?)\s+(n?o?t?\s?elected)$/).flatten
+    results.merge({name.gsub(/[^[[:alnum:]]]/,'') => status.gsub(/\s/, '-')})
+  end
+end
+
+# XMLHttpRequest (AJAX)
+_json do
+  nominees = File.read(ini(raw_votes(@date))).scan(/^\w:\s*(.*)/).flatten
+  candidates = params.keys & nominees.map {|name| 
name.gsub(/[^[[:alnum:]]]/,'')}
+  _! filtered_election(raw_votes(@date), @seats, candidates)
+end
+
+# main output
+_html do
+  _head_ do
+    _title 'STV Explorer'
+    _style! %{
+       h1 {font-family: sans-serif; font-weight: normal}
+       select {display: block; margin: 0 0 1em 1em; font-size: 140%}
+       label div {display: inline-block; min-width: 12em; font-size: x-large}
+       label div {-webkit-transition: background-color 1s}
+       label div {-moz-transition: background-color 1s}
+       label {float: left; clear: both}
+       label[for=seats] {display: inline; line-height: 500%}
+       p, input[type=checkbox] {margin-left: 1em}
+       p, input[type=submit] {display: block; clear: both}
+       .elected {background: #0F0}
+       .not-elected {background: #F00}
+       .none {background: yellow}
+    }
+    _script src: '../jquery-min.js'
+  end
+
+  _body? do
+    _h1_ 'STV Explorer'
+
+    nominees = Hash[File.read(ini(raw_votes(@date))).scan(/^\w:\s*(.*)/).
+      flatten.map {|name| [name.gsub(/[^[[:alnum:]]]/,''), name]}]
+    candidates = params.keys & nominees.keys
+    candidates = nominees.keys if candidates.empty? or @reset
+
+    @seats ||= '9'
+    results = filtered_election(raw_votes(@date), @seats, candidates)
+
+    # form of nominees and seats
+    _form method: 'post', id: 'vote' do
+      _select name: 'date' do
+        Dir["#{MEETINGS}/*/raw_board_votes.txt"].sort.reverse.each do |votes|
+         next unless File.exist? ini(votes)
+         date = votes[/(\d+)\/raw_board_votes.txt$/,1]
+          display = date.sub(/(\d{4})(\d\d)(\d\d)/,'\1-\2-\3')
+          _option display, value: date, selected: (votes == raw_votes(@date))
+       end
+      end
+
+      nominees.sort.each do |id, name|
+        _label_ id: id do
+          _input type: 'checkbox', name: id, checked: candidates.include?(id)
+          _div name, class: results[id]
+        end
+      end
+
+      _label_ for: 'seats' do
+        _span 'seats:'
+        _input name: 'seats', id: 'seats', value: @seats, size: 2,
+          type: 'number', min: 1, max: nominees.length-1
+      end
+
+      _input type: 'submit', value: 'submit', name: 'submit'
+    end
+
+    _p_ do
+      _a "Member's Meeting Information",
+        href: 'https://whimsy.apache.org/members/meeting'
+    end
+
+    _script %{
+      // submit form using XHR; update class for labels based on results
+      function refresh() {
+        $.post('', $('#vote').serialize(), function(results) {
+          for (var name in results) {
+            $('#'+name+' div').attr('class', results[name]);
+          }
+        }, 'json');
+        return false;
+      }
+
+      // On checkbox click, remove class from associated label & refresh
+      $(':checkbox').click(function() {
+        $('div', $(this).parent()).attr('class', 'none');
+        refresh();
+      });
+
+      // reset whenever the date changes
+      $('select').change(function() {
+        $('input[value=submit]').attr('name', 'reset');
+        $('input[value=submit]').click();
+      });
+
+      // If JS is enabled, we don't need a submit button
+      $('input[type=submit]').hide();
+
+      // Refresh on change in number of seats
+      $('#seats').on('input', function() {return refresh()});
+    }
+  end
+end
+
+__END__
+MEETINGS = '../Meetings'
diff --git a/www/members/whatif.cgi b/www/members/whatif.cgi
index c8e6fc99..b40a23e2 100755
--- a/www/members/whatif.cgi
+++ b/www/members/whatif.cgi
@@ -3,8 +3,16 @@ $LOAD_PATH.unshift '/srv/whimsy/lib'
 
 require 'whimsy/asf/config'
 require 'whimsy/asf/svn'
+require 'wunderbar'
 
 MEETINGS = ASF::SVN['Meetings']
 
+# This is a hack:
+# STeVe has moved to Git, however whatif.py no longer works in that 
environment due to changes in stv_tool.py
+# So for the time being, continue to use the old code in SVN
 Dir.chdir ASF::SVN['steve']
-require "./whatif"
+# However, whatif.rb no longer works with the current version of Ruby
+# See: https://github.com/apache/whimsy/issues/257
+# The file below is a corrected copy
+# 
+require '/srv/whimsy/tools/whatif'

Reply via email to