blob: 46faa81943a1eb120f507a1dc4f417ea4b8edb8f [file] [log] [blame]
require 'time'
module ASF
class Base
end
class Committee < Base
attr_accessor :info, :report, :roster, :established, :chairs,
:schedule
def initialize(*args)
@info = []
@chairs = []
@roster = {}
super
end
# mapping of committee names to canonical names (generally from ldap)
# See also www/roster/committee.cgi
@@aliases = Hash.new {|hash, name| name}
@@aliases.merge! \
'community development' => 'comdev',
'conference planning' => 'concom',
'conferences' => 'concom',
'http server' => 'httpd',
'httpserver' => 'httpd',
'java community process' => 'jcp',
'logging services' => 'logging',
'lucene.net' => 'lucenenet',
'portable runtime' => 'apr',
'quetzalcoatl' => 'quetz',
'security team' => 'security',
'open climate workbench' => 'climate',
'c++ standard library' => 'stdcxx',
'travel assistance' => 'tac',
'traffic server' => 'trafficserver',
'web services' => 'ws',
'xml graphics' => 'xmlgraphics',
'incubating' => 'incubator' # special for index.html
@@namemap = Proc.new do |name|
cname = @@aliases[name.sub(/\s+\(.*?\)/, '').downcase]
cname
end
def self.load_committee_info
board = ASF::SVN['private/committers/board']
file = "#{board}/committee-info.txt"
return unless File.exist? file
if @committee_info and File.mtime(file) == @committee_mtime
return @committee_info
end
list = Hash.new {|hash, name| hash[name] = find(name)}
@committee_mtime = File.mtime(file)
@@svn_change = Time.parse(
`svn info #{file}`[/Last Changed Date: (.*) \(/, 1]).gmtime
# Split the file on lines starting "* ", i.e. the start of each group in section 3
info = File.read(file).split(/^\* /)
# Extract the text before first entry in section 3 and split on section headers,
# keeping sections 1 (COMMITTEES) and 2 (REPORTING).
head, report = info.shift.split(/^\d\./)[1..2]
# Drop lines which could match group entries
head.gsub! /^\s+NAME\s+CHAIR\s*$/,'' # otherwise could match an entry with no e-mail
# extract the committee chairs (e-mail address is required here)
# Note: this includes the non-PMC entries
head.scan(/^[ \t]+(\w.*?)[ \t][ \t]+(.*)[ \t]+<(.*?)@apache\.org>/).
each do |committee, name, id|
list[committee].chairs << {name: name, id: id}
end
# Extract the non-PMC committees (e-mail address may be absent)
# first drop leading text so we only match non-PMCs
@nonpmcs = head.sub(/.*?also has /m,'').
scan(/^[ \t]+(\w.*?)(?:[ \t][ \t]|[ \t]?$)/).flatten.uniq.
map {|name| list[name]}
# for each committee in section 3
info.each do |roster|
# extract the committee name and canonicalise
committee = list[@@namemap.call(roster[/(\w.*?)\s+\(/,1])]
# get the start date
committee.established = roster[/\(est\. (.*?)\)/, 1]
# extract the availids (is this used?)
committee.info = roster.scan(/<(.*?)@apache\.org>/).flatten
# drop (chair) markers and extract 0: name, 1: availid, 2: [date], 3: date
committee.roster = Hash[roster.gsub(/\(\w+\)/, '').
scan(/^\s*(.*?)\s*<(.*?)@apache\.org>\s+(\[(.*?)\])?/).
map {|list| [list[1], {name: list[0], date: list[3]}]}]
end
# process report section
report.scan(/^([^\n]+)\n---+\n(.*?)\n\n/m).each do |period, committees|
committees.scan(/^ \s*(.*)/).each do |committee|
committee, comment = committee.first.split(/\s+#\s+/,2)
committee = list[committee]
if comment
committee.report = "#{period}: #{comment}"
elsif period == 'Next month'
committee.report = 'Every month'
else
committee.schedule = period
end
end
end
@committee_info = list.values.uniq
end
def self.nonpmcs
@nonpmcs
end
def self.find(name)
result = super(@@namemap.call(name))
result.display_name = name if name =~ /[A-Z]/
result
end
def self.svn_change
@@svn_change
end
def chair
Committee.load_committee_info
if @chairs.length >= 1
ASF::Person.find(@chairs.first[:id])
else
nil
end
end
def display_name
Committee.load_committee_info
@display_name || name
end
def display_name=(name)
@display_name ||= name
end
def report
@report || @schedule
end
def info=(list)
@info = list
end
def names
Committee.load_committee_info
Hash[@roster.map {|id, info| [id, info[:name]]}]
end
def nonpmc?
Committee.nonpmcs.include? self
end
end
end