blob: a83350895fc8d3856de57ba2326fcc0e4c75d96c [file] [log] [blame]
class PPMC
def self.serialize(id, env)
response = {}
ppmc = ASF::Podling.find(id)
return unless ppmc # Not found
lists = ASF::Mail.lists(true).select do |list, mode|
list =~ /^(incubator-)?#{ppmc.mail_list}\b/
end
committers = ppmc.members
owners = ppmc.owners
# separate out the known ASF members and extract any matching committer details
unknownSubs = []
asfMembers = []
# Also look for non-ASF mod emails
nonASFmails=Hash.new
moderators = nil
modtime = nil
subscribers = nil # we get the counts only here
subtime = nil
pSubs = Array.new # private@ subscribers
unMatchedSubs = [] # unknown private@ subscribers
currentUser = ASF::Person.find(env.user)
analysePrivateSubs = false # whether to show missing private@ subscriptions
if currentUser.asf_member? or owners.include? currentUser
require 'whimsy/asf/mlist'
moderators, modtime = ASF::MLIST.list_moderators(ppmc.mail_list, true)
subscribers, subtime = ASF::MLIST.list_subscribers(ppmc.mail_list, true) # counts only
analysePrivateSubs = currentUser.asf_member?
unless analysePrivateSubs # check for private moderator if not already allowed access
# TODO match using canonical emails
user_mail = currentUser.all_mail || []
pMods = moderators["private@#{ppmc.mail_list}.apache.org"] || []
analysePrivateSubs = !(pMods & user_mail).empty?
end
if analysePrivateSubs
pSubs = ASF::MLIST.private_subscribers(ppmc.mail_list)[0]||[]
unMatchedSubs=Set.new(pSubs) # init ready to remove matched mails
pSubs.map!{|m| m.downcase} # for matching
end
moderators.each { |list,mods| mods.each {|m| nonASFmails[m]='' unless m.end_with? '@apache.org'} }
else
lists = lists.select {|list, mode| mode == 'public'}
end
pmc = ASF::Committee.find('incubator')
ipmc = pmc.owners
incubator_committers = pmc.committers
# Preload the committers; if a person has another role it will be set up below
roster = committers.map {|person|
[person.id, {
# notSubbed does not apply
name: person.public_name,
member: person.asf_member?,
icommit: incubator_committers.include?(person),
role: 'Committer',
githubUsername: (person.attrs['githubUsername'] || []).join(', ')
}]
}.to_h
# Merge the PPMC members (owners)
owners.each do |person|
notSubbed = false
if analysePrivateSubs
allMail = person.all_mail.map{|m| ASF::Mail.to_canonical(m.downcase)}
notSubbed = (allMail & pSubs.map{|m| ASF::Mail.to_canonical(m)}).empty?
unMatchedSubs.delete_if {|k| allMail.include? ASF::Mail.to_canonical(k.downcase)}
end
roster[person.id] = {
notSubbed: notSubbed,
name: person.public_name,
member: person.asf_member?,
icommit: incubator_committers.include?(person),
role: 'PPMC Member',
githubUsername: (person.attrs['githubUsername'] || []).join(', ')
}
end
# Finally merge the mentors
ppmc.mentors.each do |mentor|
person = ASF::Person.find(mentor)
roster[person.id] = {
name: person.public_name,
member: person.asf_member?,
ipmc: ipmc.include?(person),
icommit: incubator_committers.include?(person),
role: 'Mentor',
githubUsername: (person.attrs['githubUsername'] || []).join(', ')
}
if analysePrivateSubs
allMail = person.all_mail.map{|m| ASF::Mail.to_canonical(m.downcase)}
roster[person.id]['notSubbed'] = (allMail & pSubs.map{|m| ASF::Mail.to_canonical(m)}).empty?
unMatchedSubs.delete_if {|k| allMail.include? ASF::Mail.to_canonical(k.downcase)}
end
end
statusInfo = ppmc.podlingStatus || {news: []}
if unMatchedSubs.length > 0 or nonASFmails.length > 0
load_emails # set up @people
unMatchedSubs.each{ |addr|
who = nil
@people.each do |person|
if person[:mail].any? {|mail| mail.downcase == addr.downcase}
who = person
end
end
if who
if who[:member]
asfMembers << { addr: addr, person: who }
else
unknownSubs << { addr: addr, person: who }
end
else
unknownSubs << { addr: addr, person: nil }
end
}
nonASFmails.each {|k,v|
@people.each do |person|
if person[:mail].any? {|mail| ASF::Mail.to_canonical(mail.downcase) == ASF::Mail.to_canonical(k.downcase)}
nonASFmails[k] = person[:id]
end
end
}
end
response = {
id: id,
display_name: ppmc.display_name,
description: ppmc.description,
mail_list: ppmc.mail_list, # debug
schedule: ppmc.reporting,
monthly: ppmc.monthly,
established: ppmc.startdate.to_s,
enddate: ppmc.enddate.to_s,
status: ppmc.status,
mentors: ppmc.mentors,
hasLDAP: ppmc.hasLDAP?,
owners: owners.map {|person| person.id},
committers: committers.map {|person| person.id},
roster: roster,
mail: Hash[lists.sort],
moderators: moderators,
modtime: modtime,
subscribers: subscribers,
subtime: subtime,
nonASFmails: nonASFmails,
duration: ppmc.duration,
podlingStatus: statusInfo,
namesearch: ppmc.namesearch,
analysePrivateSubs: analysePrivateSubs,
unknownSubs: unknownSubs,
asfMembers: asfMembers,
}
response
end
private
def self.load_emails
# recompute index if the data is 5 minutes old or older
@people = nil if not @people_time or Time.now-@people_time >= 300
if not @people
# bulk loading the mail information makes things go faster
mail = Hash[ASF::Mail.list.group_by(&:last).
map {|person, list| [person, list.map(&:first)]}]
# build a list of people, their public-names, and email addresses
@people = ASF::Person.list.map {|person|
result = {id: person.id, name: person.public_name, mail: mail[person]}
result[:member] = true if person.asf_member?
result
}
# cache
@people_time = Time.now
end
@people
end
end