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 ebc9a6c4 Allow for potential duplicates; return Set
ebc9a6c4 is described below
commit ebc9a6c45c4d5fa516b45433bbce6b3aea175e2c
Author: Sebb <[email protected]>
AuthorDate: Fri Mar 13 23:11:34 2026 +0000
Allow for potential duplicates; return Set
---
lib/whimsy/asf/mail.rb | 36 ++++++++++++++++++++++--------------
www/board/subscriptions.cgi | 19 +++++++++++--------
www/members/moderator_checks.cgi | 7 ++-----
www/members/subscriptions.cgi | 20 +++++++++++---------
www/members/subscriptions2.cgi | 19 +++++++++++--------
www/officers/subscriptioncheck.cgi | 23 +++++++++++++----------
6 files changed, 70 insertions(+), 54 deletions(-)
diff --git a/lib/whimsy/asf/mail.rb b/lib/whimsy/asf/mail.rb
index ac523500..eb8bde6d 100644
--- a/lib/whimsy/asf/mail.rb
+++ b/lib/whimsy/asf/mail.rb
@@ -3,28 +3,26 @@ require 'weakref'
module ASF
# Convenience functions related to emails or mailing lists.
class Mail
- # return a Hash containing complete list of all known emails, and the
- # ASF::Person that is associated with that email.
- def self.list
- begin
- return @list.to_h if @list
- rescue NoMethodError, WeakRef::RefError
- end
+ # return a hash containing down-cased email names, together with a Set of
people with whom
+ # they are associated. In almost all cases there is only a single
associated person.
+ # The emails are sourced from LDAP, and optionally members.txt and
iclas.txt
+ def self.listall
+ # Note: no point currently caching the list in memory, as this method is
only used by cgi scripts
- list = {}
+ list = Hash.new{|h,k| h[k] = Set.new} # this creates a default Proc,
which we remove later
# load info from LDAP
- people = ASF::Person.preload(['mail', 'asf-altEmail'])
+ people = ASF::Person.preload(['mail', 'asf-altEmail', 'cn'])
people.each do |person|
(person.mail + person.alt_email).each do |mail|
- list[mail.downcase] = person
+ list[mail.downcase] << person # there may be more that one person
associated with a single email
end
end
# load all member emails in one pass
ASF::Member.each do |id, text|
Member.emails(text).each do |mail|
- list[mail.downcase] ||= Person.find(id)
+ list[mail.downcase] << Person.find(id) # this should find one of the
pre-loads
end
end
@@ -32,17 +30,27 @@ module ASF
ASF::ICLA.each do |icla|
person = Person.find(icla.id)
icla.emails.each do |email|
- list[email.downcase] ||= person
+ list[email.downcase] << person
end
next if icla.noId?
- list["#{icla.id.downcase}@apache.org"] ||= person
+ list["#{icla.id.downcase}@apache.org"] << person # is this needed?
end
- @list = WeakRef.new(list)
+ list.default_proc = nil # no longer create an empty set when a key is
missing
list
end
+ # Allow for trailing +- suffix in emails.
+ # e.g.
+ # [email protected] => [email protected]
+ # [email protected] => [email protected]
+ def self.remove_email_suffix(email)
+ # TODO: may need to tighten this to avoid ambiguities
+ # e.g. selectively apply '-xxx' or '+xxx' removal, depending on domain
+ email.downcase.sub(/[-+]\w+@/,'@') # drop suffix
+ end
+
# return a list of people ids, their public-name, whether they are an ASF
member, and email addresses
def self.people_mails
member_statuses = ASF::Member.member_statuses # cache the statuses.
TODO: should be done in ASF.Member
diff --git a/www/board/subscriptions.cgi b/www/board/subscriptions.cgi
index 0740aca5..dfd512ad 100755
--- a/www/board/subscriptions.cgi
+++ b/www/board/subscriptions.cgi
@@ -65,18 +65,21 @@ _html do
end
ids = []
- maillist = ASF::Mail.list
- subscribers.each do |line|
- person = maillist[line.downcase]
- person ||= maillist[line.downcase.sub(/\+\w+@/,'@')]
- if person
- id = person.id
- id = '*notinavail*' if id == 'notinavail'
+ maillist = ASF::Mail.listall
+ subscribers.each do |email|
+ people = maillist[email.downcase] # email may match more than one
person
+ people ||= maillist[ASF::Mail.remove_email_suffix(email)]
+ if people
+ people.each do |person|
+ id = person.id
+ id = '*notinavail*' if id == 'notinavail'
+ ids << [id, person, email]
+ end
else
person = ASF::Person.find('notinavail')
id = '*missing*'
+ ids << [id, person, email]
end
- ids << [id, person, line]
end
_table_.table do
diff --git a/www/members/moderator_checks.cgi b/www/members/moderator_checks.cgi
index 8335174b..cd050c1d 100755
--- a/www/members/moderator_checks.cgi
+++ b/www/members/moderator_checks.cgi
@@ -34,17 +34,14 @@ _html do
_h2 'DRAFT - List moderators whose email addresses are not recognised'
_p 'If the domain is @apache.org, the email is most likely a typo'
_p 'In other cases, perhaps the email is not registered'
- _p do
- _b 'Emails are matched exactly - case is treated significant, even
for domains'
- end
}
) do
lists, _time = ASF::MLIST.list_moderators(nil)
- emails = ASF::Mail.list
+ emails = ASF::Mail.listall
unknown = Hash.new { |h, k| h[k] = []}
lists.each do |lid, mods|
mods.each do |mod|
- unknown[mod] << lid unless MODERATORS.include? mod or emails[mod] or
private_mod(lid, mod)
+ unknown[mod] << lid unless MODERATORS.include? mod or
emails[mod.downcase] or private_mod(lid, mod)
end
end
diff --git a/www/members/subscriptions.cgi b/www/members/subscriptions.cgi
index aaa622c1..cc913df9 100755
--- a/www/members/subscriptions.cgi
+++ b/www/members/subscriptions.cgi
@@ -62,20 +62,22 @@ _html do
members = ASF::Member.new.map {|id, text| ASF::Person.find(id)}
ASF::Person.preload('cn', members)
- maillist = ASF::Mail.list
-
+ maillist = ASF::Mail.listall
subscriptions = []
- subscribers.each do |line|
- person = maillist[line.downcase]
- person ||= maillist[line.downcase.sub(/[-+]\w+@/,'@')] # allow for
trailing +- suffix
- if person
- id = person.id
- id = '*notinavail*' if id == 'notinavail'
+ subscribers.each do |email|
+ people = maillist[email.downcase]
+ people ||= maillist[ASF::Mail.remove_email_suffix(email)]
+ if people
+ people.each do |person| # email may match more than one person
+ id = person.id
+ id = '*notinavail*' if id == 'notinavail'
+ subscriptions << [id, person, email]
+ end
else
person = ASF::Person.find('notinavail')
id = '*missing*'
+ subscriptions << [id, person, email]
end
- subscriptions << [id, person, line]
end
_table.table do
diff --git a/www/members/subscriptions2.cgi b/www/members/subscriptions2.cgi
index e28f6788..62009f35 100755
--- a/www/members/subscriptions2.cgi
+++ b/www/members/subscriptions2.cgi
@@ -68,20 +68,23 @@ _html do
nonASFemails = []
members = ASF::Member.new.map {|id, _text| ASF::Person.find(id)}
ASF::Person.preload('cn', members)
- maillist = ASF::Mail.list
+ maillist = ASF::Mail.listall
subscriptions = []
- subscribers.each do |line|
- person = maillist[line.downcase]
- person ||= maillist[line.downcase.sub(/[-+]\w+@/, '@')] # allow for
trailing +- suffix
- if person
- id = person.id
- id = '*notinavail*' if id == 'notinavail'
+ subscribers.each do |email|
+ people = maillist[email.downcase]
+ people ||= maillist[ASF::Mail.remove_email_suffix(email)]
+ if people
+ people.each do |person| # email may match more than one person
+ id = person.id
+ id = '*notinavail*' if id == 'notinavail'
+ subscriptions << [id, person, email]
+ end
else
person = ASF::Person.find('notinavail')
id = '*missing*'
+ subscriptions << [id, person, email]
end
- subscriptions << [id, person, line]
end
_table.table do
diff --git a/www/officers/subscriptioncheck.cgi
b/www/officers/subscriptioncheck.cgi
index 30b33f6b..09eab509 100755
--- a/www/officers/subscriptioncheck.cgi
+++ b/www/officers/subscriptioncheck.cgi
@@ -19,7 +19,7 @@ MEMBER_ANNOUNCE_OK = %w([email protected]
[email protected])
DEFAULT_LISTS =
'board,markpub,members,members-announce,members-notify,operations,press,trademarks,[email protected]'
listnames = ENV['QUERY_STRING']
-listnames = DEFAULT_LISTS if listnames == ''
+listnames = DEFAULT_LISTS if listnames == '' or listnames.nil?
info_chairs = ASF::Committee.load_committee_info.group_by(&:chair)
ldap_chairs = ASF.pmc_chairs
@@ -93,19 +93,22 @@ _html do
_ "(updated #{modtime})"
end
subscribers -= MEMBER_ANNOUNCE_OK if listid ==
'[email protected]'
- subscribers -= ['[email protected]'] if listid =
'[email protected]'
- maillist = ASF::Mail.list
- subscribers.each do |line|
- person = maillist[line.downcase]
- person ||= maillist[line.downcase.sub(/\+\w+@/,'@')]
- if person
- id = person.id
- id = '*notinavail*' if id == 'notinavail'
+ subscribers -= ['[email protected]'] if listid ==
'[email protected]'
+ maillist = ASF::Mail.listall
+ subscribers.each do |email|
+ people = maillist[email.downcase]
+ people ||= maillist[ASF::Mail.remove_email_suffix(email)]
+ if people
+ people.each do |person|
+ id = person.id
+ id = '*notinavail*' if id == 'notinavail'
+ ids << [id, person, email]
+ end
else
person = ASF::Person.find('notinavail')
id = '*missing*'
+ ids << [id, person, email]
end
- ids << [id, person, line]
end
end