blob: f521de8677f99b7cfee494dc034e7b40e5b6654c [file] [log] [blame]
require 'weakref'
module ASF
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 Hash[@list.to_a] if @list
rescue NoMethodError, WeakRef::RefError
end
list = Hash.new
# load info from LDAP
people = ASF::Person.preload(['mail', 'asf-altEmail'])
people.each do |person|
(person.mail+person.alt_email).each do |mail|
list[mail.downcase] = person
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)
end
end
# load all ICLA emails in one pass
ASF::ICLA.each do |icla|
person = Person.find(icla.id)
list[icla.email.downcase] ||= person
next if icla.id == 'notinavail'
list["#{icla.id.downcase}@apache.org"] ||= person
end
@list = WeakRef.new(list)
list
end
# Parse the .archives file to get the list names
def self._load_lists
apmail_bin = ASF::SVN['infra/infrastructure/apmail/trunk/bin']
file = File.join(apmail_bin, '.archives')
if not @lists or File.mtime(file) != @list_mtime
lists = Hash[File.read(file).scan(
/^\s+"(\w[-\w]+)", "\/home\/apmail\/(public|private)-arch\//
)]
# Drop the infra test lists
lists.delete_if {|list| list =~ /-infra-[a-z]$/ or list == 'incubator-infra-dev' }
@lists = lists
@list_mtime = File.mtime(file)
end
end
# get a list of all mailing lists. If <tt>public_private</tt> is
# <tt>false</tt> this will be a simple list. If <tt>public_private</tt> is
# <tt>true</tt>, return a Hash where the values are either <tt>public</tt>
# or <tt>private</tt>.
def self.lists(public_private=false)
Mail._load_lists
public_private ? @lists : @lists.keys
end
# list of mailing lists that aren't actively seeking new subscribers
def self.deprecated
apmail_bin = ASF::SVN['infra/infrastructure/apmail/trunk/bin']
YAML.load_file(File.join(apmail_bin, 'deprecated_mailing_lists.yml'))
end
# which lists are available for subscription via Whimsy?
def self.cansub(member, pmc_chair)
Mail._load_lists
if member
lists = @lists.keys
# These are not subscribable via Whimsy
lists.delete_if {|list| list =~ /^(ea|secretary|president|treasurer|chairman|committers|pmc-chairs)$/ }
lists.delete_if {|list| list =~ /(^|-)security$|^security(-|$)/ }
lists
else
whitelist = ['infra-users', 'jobs', 'site-dev', 'committers-cvs', 'site-cvs', 'concom', 'party']
# Can always subscribe to public lists and the whitelist
lists = @lists.keys.select{|key| @lists[key] == 'public' or whitelist.include? key}
# Chairs need the board lists
if pmc_chair
lists += ['board', 'board-commits', 'board-chat']
end
lists
end
end
# common configuration for sending mail; loads <tt>:sendmail</tt>
# configuration from <tt>~/.whimsy</tt> if available; otherwise default
# to disable openssl verification as that is what it required in order
# to work on the infrastructure provided whimsy-vm.
def self.configure
# fetch overrides
sendmail = ASF::Config.get(:sendmail)
if sendmail
# convert string keys to symbols
options = Hash[sendmail.map {|key, value| [key.to_sym, value.untaint]}]
# extract delivery method
method = options.delete(:delivery_method).to_sym
else
# provide defaults that work on whimsy-vm* infrastructure. Since
# procmail is configured with a self-signed certificate, verification
# isn't a possibility
method = :smtp
options = {openssl_verify_mode: 'none'}
end
::Mail.defaults do
delivery_method method, options
end
end
def self.qmail_ids
return [] unless File.exist? '/srv/subscriptions/qmail.ids'
File.read('/srv/subscriptions/qmail.ids').split
end
def self.taken?(id)
self.qmail_ids.include? id
end
end
class Person < Base
# find a Person by email address
def self.find_by_email(value)
value.downcase!
person = Mail.list[value]
return person if person
end
# List of inactive email addresses: currently only contains the address in
# <tt>iclas.txt</tt> if it is not contained in the list of active email
# addresses.
def obsolete_emails
return @obsolete_emails if @obsolete_emails
result = []
if icla
unless active_emails.any? {|mail| mail.downcase == icla.email.downcase}
result << icla.email
end
end
@obsolete_emails = result
end
# Active emails: primary email address, alt email addresses, and
# member email addresses.
def active_emails
(mail + alt_email + member_emails).uniq
end
# All known email addresses: includes active, obsolete, and apache.org
# email addresses.
def all_mail
(active_emails + obsolete_emails + ["#{id}@apache.org"]).uniq
end
end
class Committee
# mailing list for this committee. Generally returns the first name in
# the dns (e.g. whimsical). If so, it can be prefixed by a number of
# list names (e.g. dev, private) and <tt>.apache.org</tt> is to be
# appended. In some cases, the name contains an <tt>@</tt> sign and
# is the fill name for the mail list.
def mail_list
case name.downcase
when 'comdev'
'community'
when 'httpcomponents'
'hc'
when 'whimsy'
'whimsical'
when 'brand management'
'trademarks@apache.org'
when 'executive assistant'
'ea@apache.org'
when 'infrastructure'
'infra'
when 'legal affairs'
'legal-internal@apache.org'
when 'marketing and publicity'
'press@apache.org'
when 'tac'
'travel-assistance@apache.org'
when 'w3c relations'
'w3c@apache.org'
else
name
end
end
end
class Podling
# base name used in constructing mailing list name.
def mail_list
name
end
end
end