rough in feedback email
diff --git a/www/board/agenda/Gemfile b/www/board/agenda/Gemfile
index 335df4b..85c171f 100644
--- a/www/board/agenda/Gemfile
+++ b/www/board/agenda/Gemfile
@@ -29,6 +29,6 @@
gem 'poltergeist'
end
-group :demo do
- gem 'puma'
+group :development do
+ gem 'passenger'
end
diff --git a/www/board/agenda/Rakefile b/www/board/agenda/Rakefile
index 70ca673..f07de50 100644
--- a/www/board/agenda/Rakefile
+++ b/www/board/agenda/Rakefile
@@ -6,9 +6,10 @@
task :spec => 'test:setup'
task :test => :spec
-task :server do
+task :server => [:bundle, :listen] do
ENV['RACK_ENV']='development'
- require 'wunderbar/listen'
+ at_exit {sleep 0.5}
+ sh 'bundle exec passenger start'
end
namespace :server do
@@ -145,3 +146,27 @@
end
end
end
+
+task :bundle => 'Gemfile.lock' do
+ require 'bundler'
+ Bundler.require(:default, :development)
+end
+
+# restart server when files update
+task :listen => :bundle do
+ dirs = [
+ File.expand_path('..', File.realpath(__FILE__)),
+ File.expand_path('../../../../lib', File.realpath(__FILE__))
+ ]
+
+ listener = Listen.to(*dirs) do |modified, added, removed|
+ puts "detected update: #{(modified + added + removed).join(', ')}"
+ FileUtils.touch "#{dirs.first}/tmp/restart.txt"
+ end
+
+ listener.ignore /~$/
+ listener.ignore /^\..*\.sw\w$/
+ listener.ignore /passenger.\d+\.(log|pid(\.lock)?)$/
+
+ listener.start
+end
diff --git a/www/board/agenda/routes.rb b/www/board/agenda/routes.rb
index 9489ba7..8130cc0 100755
--- a/www/board/agenda/routes.rb
+++ b/www/board/agenda/routes.rb
@@ -2,6 +2,15 @@
# Server side Sinatra routes
#
+# temporary
+get %r{^/(\d\d\d\d-\d\d-\d\d)/feedback$} do |date|
+ _html :feedback
+end
+get %r{^/(\d\d\d\d-\d\d-\d\d)/feedback.json$} do |date|
+ @agenda = "board_agenda_#{date.gsub('-', '_')}.txt".untaint
+ _json :'actions/feedback'
+end
+
# redirect root to latest agenda
get '/' do
agenda = dir('board_agenda_*.txt').sort.last
@@ -225,4 +234,3 @@
end
end
end
-
diff --git a/www/board/agenda/views/actions/feedback.json.rb b/www/board/agenda/views/actions/feedback.json.rb
new file mode 100644
index 0000000..b4de899
--- /dev/null
+++ b/www/board/agenda/views/actions/feedback.json.rb
@@ -0,0 +1,72 @@
+#
+# send feedback on reports
+#
+
+# fetch minutes
+@minutes = @agenda.sub('_agenda_', '_minutes_')
+minutes_file = "#{AGENDA_WORK}/#{@minutes.sub('.txt', '.yml')}"
+minutes_file.untaint if @minutes =~ /^board_minutes_\d+_\d+_\d+\.txt$/
+date = @agenda[/\d+_\d+_\d+/].gsub('_', '-')
+
+if File.exist? minutes_file
+ minutes = YAML.load_file(minutes_file) || {}
+else
+ minutes = {}
+end
+
+# utilize smtp without certificate verification
+Mail.defaults do
+ delivery_method :smtp, openssl_verify_mode: 'none'
+end
+
+# extract values for common fields
+unless @from
+ sender = ASF::Person.find(env.user || ENV['USER'])
+ @from = "#{sender.public_name} <#{sender.id}@apache.org>".untaint
+end
+
+output = []
+
+# iterate over the agenda
+Agenda.parse(@agenda, :full).each do |item|
+ # select exec officer, additional officer, and committee reports
+ next unless item[:attach] =~ /^(4[A-Z]|\d|[A-Z]+)$/
+ next unless item['chair_email']
+
+ text = ''
+
+ if item['comments'] and not item['comments'].empty?
+ text += "\nComments:\n#{item['comments'].gsub(/^/, ' ')}\n"
+ end
+
+ if minutes[item['title']]
+ text += "\nMinutes:\n#{minutes[item['title']].gsub(/^/, ' ')}\n"
+ end
+
+ next if text.strip.empty?
+
+ # construct email
+ mail = Mail.new do
+ from @from
+ to "#{item['owner']} <#{item['chair_email']}>".untaint
+ subject "Board feedback on #{date} #{item['title']} report"
+
+ if item['mail_list']
+ if item[:attach] =~ /^[A-Z]+/
+ cc "private@#{item['mail_list']}.apache.org".untaint
+ else
+ cc "#{item['mail_list']}@apache.org".untaint
+ end
+ end
+
+ body text.strip.untaint
+ end
+
+ output << {
+ attach: item[:attach],
+ title: item['title'],
+ mail: mail.to_s
+ }
+end
+
+output
diff --git a/www/board/agenda/views/feedback.html.rb b/www/board/agenda/views/feedback.html.rb
new file mode 100644
index 0000000..6aa590c
--- /dev/null
+++ b/www/board/agenda/views/feedback.html.rb
@@ -0,0 +1,20 @@
+_html do
+ _body do
+ _p 'loading'
+
+ _script %{
+ jQuery.getJSON('feedback.json', function(data) {
+ data.forEach(function(message) {
+ var h1 = document.createElement('h1');
+ h1.setAttribute('id', message.title);
+ h1.textContent = message.title;
+ var pre = document.createElement('pre');
+ pre.textContent = message.mail;
+ document.body.appendChild(h1);
+ document.body.appendChild(pre);
+ });
+ document.querySelector('p').remove();
+ });
+ }
+ end
+end