module ASF::MLIST

Constants

ARCHIVERS
ARCHIVERS_PRV

Private archivers

ARCH_EXT_MAIL_ARCHIVE

Standard external archivers (necessarily public)

ARCH_EXT_MARKMAIL_RE
ARCH_MBOX_PRV
ARCH_MBOX_PUB

Standard ASF archivers

ARCH_MBOX_RST
ARCH_PONY_PRV
ARCH_PONY_PUB
LIST_BASE

TODO alias archivers: either add list or use RE to filter them

LIST_CACHE
LIST_TIME

If this file exists, it is the time when the data was last extracted The mods and subs files are only updated if they have changed

Public Class Methods

board_subscribers(archivers=true) click to toggle source

Return an array of board subscribers followed by the file update time

# File lib/whimsy/asf/mlist.rb, line 30
def self.board_subscribers(archivers=true)
  return list_filter('sub', 'apache.org', 'board', archivers), File.mtime(LIST_TIME)
end
digests(emails, response = {}) click to toggle source

return a hash of digest subscriptions for the list of emails provided the following keys are added to the response hash: :digtime - the timestamp when the data was last updated :digests - an array of pairs: [list name, subscriber email] N.B. not the same format as the moderates() method

# File lib/whimsy/asf/mlist.rb, line 110
def self.digests(emails, response = {})

  response[:digests] = []
  response[:digtime] = File.mtime(LIST_TIME)

  emailslc = emails.map {|email| ASF::Mail.to_canonical(email.downcase)}
  list_parse('dig') do |dom, list, subs|
    subs.each do |sub|
      if emailslc.include? ASF::Mail.to_canonical(sub.downcase)
        response[:digests] << ["#{list}@#{dom}", sub]
      end
    end
  end
  response
end
domain_lists(project, show_all) click to toggle source

return a hash of lists for a project, together with privacy setting tlp - the prefix for the full domain This is a replacement for ASF::Mail.lists

# File lib/whimsy/asf/mlist.rb, line 261
def self.domain_lists(project, show_all)
  lists = {}
  list_types(show_all) do |dom, list, type|
    if matches_list?(project, dom, list)
      lists["#{list}@#{dom}"] = type
    end
  end
  lists
end
each_list() { |parts, parts| ... } click to toggle source

return the [domain, list] for all entries in the subscriber listings the subscribers are not included

# File lib/whimsy/asf/mlist.rb, line 272
def self.each_list
  Find.find(LIST_CACHE) do |path|
    parts = path.split('/')
    if parts[-1] == 'sub'
      yield [parts[-3], parts[-2]]
    end
  end
end
list_archivers() { |dom, list, select {|s| is_archiver? s}.map {|m| [m, archiver_type(m, dom, list)].flatten}| ... } click to toggle source
# File lib/whimsy/asf/mlist.rb, line 238
def self.list_archivers
  list_parse('sub') do |dom, list, subs|
    yield [dom, list, subs.select {|s| is_archiver? s}.map {|m| [m, archiver_type(m, dom, list)].flatten}]
  end
end
list_moderators(mail_domain, _podling=false) click to toggle source

for a mail domain, extract related lists and their moderators also returns the time when the data was last checked If podling==true, then also check for old-style podling names returns: [{dev@a.o=>[email1, email2]}, mod-time] if mail_domain is nil, matches all lists except infra test lists

# File lib/whimsy/asf/mlist.rb, line 161
def self.list_moderators(mail_domain, _podling=false)

  moderators = {}
  list_parse('mod') do |dom, list, subs|

    # drop infra test lists
    next if list =~ /^infra-[a-z]$/
    next if dom == 'incubator.apache.org' && list =~ /^infra-dev2?$/

    # does the list match our target?
    next unless mail_domain.nil? or matches_list?(mail_domain, dom, list)

    moderators["#{list}@#{dom}"] = subs.sort
  end
  return moderators.to_h, File.mtime(LIST_TIME)
end
list_subs(mail_domain, podling=false, list_subs=false) click to toggle source

for a mail domain, extract related lists and their subscribers (default only the count) also returns the time when the data was last checked N.B. excludes known archivers For top-level apache.org lists, the mail_domain is either:

  • the full list name (e.g. press), or:

  • the list prefix (e.g. legal)

If podling==true, then also check for old-style podling names If list_subs==true, return subscriber emails else sub count Matches: {mail_domain}.apache.org/* apache.org/{mail_domain}(-.*)? (e.g. press, legal) incubator.apache.org/{mail_domain}-.* (if podling==true) Returns: {list}@{dom}

# File lib/whimsy/asf/mlist.rb, line 229
def self.list_subs(mail_domain, podling=false, list_subs=false)
  self.list_subscribers(mail_domain, podling, list_subs, true)
end
list_subscribers(mail_domain, _podling=false, list_subs=false, skip_archivers=false) click to toggle source

for a mail domain, extract related lists and their subscribers (default only the count) also returns the time when the data was last checked N.B. by default includes archivers as subscribers For top-level apache.org lists, the mail_domain is either:

  • the full list name (e.g. press), or:

  • the list prefix (e.g. legal)

If podling==true, then also check for old-style podling names If list_subs==true, return subscriber emails else sub count If skip_archivers==true, exclude archivers Matches: {mail_domain}.apache.org/* apache.org/{mail_domain}(-.*)? (e.g. press, legal) incubator.apache.org/{mail_domain}-.* (if podling==true) Returns: {list}@{dom}

# File lib/whimsy/asf/mlist.rb, line 192
def self.list_subscribers(mail_domain, _podling=false, list_subs=false, skip_archivers=false)

  subscribers = {}
  list_parse('sub') do |dom, list, subs|

    # drop infra test lists
    next if list =~ /^infra-[a-z]$/
    next if dom == 'incubator.apache.org' && list =~ /^infra-dev2?$/

    # normal tlp style:
    #/home/apmail/lists/commons.apache.org/dev/mod

    # does the list match our target?
    next unless matches_list?(mail_domain, dom, list)

    if skip_archivers
      subscribers["#{list}@#{dom}"] = list_subs ? subs.reject {|sub| is_archiver?(sub)}.sort : subs.reject {|sub| is_archiver?(sub)}.size
    else
      subscribers["#{list}@#{dom}"] = list_subs ? subs.sort : subs.size
    end
  end
  return subscribers.to_h, File.mtime(LIST_TIME)
end
list_time() click to toggle source

returns the list time

# File lib/whimsy/asf/mlist.rb, line 234
def self.list_time
  File.mtime(LIST_TIME)
end
list_types(show_all=false) { |dom, list, type| ... } click to toggle source

return the [domain, list, types=public|private|…] for all entries in the subscriber listings the subscribers are not included

# File lib/whimsy/asf/mlist.rb, line 246
def self.list_types(show_all=false)
  list_archivers do |dom, list, subs|
    types = {}
    subs.each do |sub|
      type = sub[2]
      types[type] = 1 unless %w(alias direct).include? type
    end
    type = types.keys.sort.join(',')
    yield [dom, list, type] if show_all || type == 'public'
  end
end
matches_list?(mail_domain, dom, list) click to toggle source

helper function for matching against mod and subs entries does the target mail_domain match the current list?

# File lib/whimsy/asf/mlist.rb, line 145
def self.matches_list?(mail_domain, dom, list)
  # normal tlp style (now also podlings):
  #/home/apmail/lists/commons.apache.org/dev/mod
  #Apache lists (e.g. some non-PMCs)
  #/home/apmail/lists/apache.org/list/mod
  return "#{mail_domain}.apache.org" == dom ||
          (dom == 'apache.org' &&
          (list == mail_domain || list.start_with?("#{mail_domain}-"))
          ) || "#{list}@#{dom}" == mail_domain # e.g. planners@apachecon.com
end
members_notify_subscribers(archivers=true) click to toggle source

Return an array of members-notify@ subscribers followed by the file update time

# File lib/whimsy/asf/mlist.rb, line 40
def self.members_notify_subscribers(archivers=true)
  return list_filter('sub', 'apache.org', 'members-notify', archivers), File.mtime(LIST_TIME)
end
members_subscribers(archivers=true) click to toggle source

Return an array of members@ subscribers followed by the file update time

# File lib/whimsy/asf/mlist.rb, line 35
def self.members_subscribers(archivers=true)
  return list_filter('sub', 'apache.org', 'members', archivers), File.mtime(LIST_TIME)
end
moderates(user_emails, response = {}) click to toggle source

return the mailing lists which are moderated by any of the list of emails the following keys are added to the response hash: :modtime - the timestamp when the data was last updated :moderates - a hash. key: list name; entry: array of emails that match a moderator for the list N.B. not the same format as the subscriptions() method

# File lib/whimsy/asf/mlist.rb, line 131
def self.moderates(user_emails, response = {})

  response[:moderates] = {}
  response[:modtime] = File.mtime(LIST_TIME)
  umails = user_emails.map {|m| ASF::Mail.to_canonical(m.downcase)} # outside loop
  list_parse('mod') do |dom, list, emails|
    matching = emails.select {|m| umails.include? ASF::Mail.to_canonical(m.downcase)}
    response[:moderates]["#{list}@#{dom}"] = matching unless matching.empty?
  end
  response
end
private_subscribers(pmc, archivers=false) click to toggle source

Return an array of private@pmc subscribers (including digests) followed by the file update time Returns nil if the subs file does not exist By default does not return the standard archivers pmc can either be a pmc name, in which case it uses private@<pmc>.apache.org or it can be an ASF list name, e.g. w3c@apache.org

# File lib/whimsy/asf/mlist.rb, line 49
  def self.private_subscribers(pmc, archivers=false)
    return [] unless Dir.exist? LIST_BASE
    parts = pmc.split('@', 3) # want to detect trailing '@'
    if parts.length == 1
      dom = "#{pmc}.apache.org"
      list = 'private'
    elsif parts.length == 2 && %w{apache.org apachecon.com}.include?(parts[1])
      dom = parts[1]
      list = parts[0]
    else
      raise "Unexpected parameter: #{pmc}"
    end
    subs = list_filter('sub', dom, list, archivers)
    digs = list_filter('digest', dom, list, archivers)
    if subs.nil?
      subs = digs # may also be nil
    elsif !digs.nil? # i.e. neither nil, so merge
      subs = (subs + digs).uniq
    end
    return subs, File.mtime(LIST_TIME)
end
security_subscribers(pmc, archivers=false) click to toggle source

Return security subscribers (including digests)

# File lib/whimsy/asf/mlist.rb, line 72
def self.security_subscribers(pmc, archivers=false)
  return [] unless Dir.exist? LIST_BASE
  subs = list_filter('sub', "#{pmc}.apache.org", 'security', archivers)
  digs = list_filter('digest', "#{pmc}.apache.org", 'security', archivers)
  if subs.nil?
    subs = digs # may also be nil
  elsif !digs.nil? # i.e. neither nil, so merge
    subs = (subs + digs).uniq
  end
  return subs, File.mtime(LIST_TIME)
end
subscriptions(emails, response = {}) click to toggle source

return a hash of subscriptions for the list of emails provided the following keys are added to the response hash: :subtime - the timestamp when the data was last updated :subscriptions - an array of pairs: [list name, subscriber email] N.B. not the same format as the moderates() method

# File lib/whimsy/asf/mlist.rb, line 89
def self.subscriptions(emails, response = {})

  response[:subscriptions] = []
  response[:subtime] = File.mtime(LIST_TIME)

  emailslc = emails.map {|email| ASF::Mail.to_canonical(email.downcase)}
  list_parse('sub') do |dom, list, subs|
    subs.each do |sub|
      if emailslc.include? ASF::Mail.to_canonical(sub.downcase)
        response[:subscriptions] << ["#{list}@#{dom}", sub]
      end
    end
  end
  response
end