www/officers/subscriptioncheck.cgi (160 lines of code) (raw):

#!/usr/bin/env ruby PAGETITLE = "Member-only private list checks" # Wvisible:board,mail $LOAD_PATH.unshift '/srv/whimsy/lib' require 'wunderbar' require 'wunderbar/bootstrap' require 'whimsy/asf' require 'whimsy/asf/mlist' user = ASF::Person.new($USER) unless user.asf_chair_or_member? print "Status: 401 Unauthorized\r\n" print "WWW-Authenticate: Basic realm=\"ASF Members and Officers\"\r\n\r\n" exit end # These are OK for member-announce MEMBER_ANNOUNCE_OK = %w(board-chair@apache.org secretary@apache.org) DEFAULT_LISTS = 'board,markpub,members,members-announce,members-notify,operations,press,trademarks,private@infra.apache.org' listnames = ENV['QUERY_STRING'] listnames = DEFAULT_LISTS if listnames == '' info_chairs = ASF::Committee.load_committee_info.group_by(&:chair) ldap_chairs = ASF.pmc_chairs member_statuses = ASF::Member.member_statuses _html do _body? do _whimsy_body( title: PAGETITLE, subtitle: 'How Subscribers Are Checked', relatedtitle: 'More Useful Links', related: { "/committers/tools" => "Whimsy Tool Listing", "/committers/subscribe" => "Committer Self-subscribe Tool", "/committers/moderationhelper" => "Mail List Moderation Helper", "https://github.com/apache/whimsy/blob/master/www#{ENV['SCRIPT_NAME']}" => "See This Source Code" }, helpblock: -> { _h2 'DRAFT - may not be 100% accurate' _p! do _ "This script takes a list of subscribers to a list" _ ' which are matched against ' _a 'members.txt', href: ASF::SVN.svnpath!('foundation', 'members.txt') _ ', ' _a 'iclas.txt', href: ASF::SVN.svnpath!('officers', 'iclas.txt') _ ', and ' _code 'ldapsearch mail' _ ' to match each email address to an Apache ID. ' _br _ 'Those that are not found are listed as ' _code.text_danger '*missing*' _ '. Non ASF member, non-committee chairs are also ' _span.text_danger 'listed in red' _ '.' end _p! do _ 'The resulting list is then cross-checked against ' _a 'committee-info.text', href: ASF::SVN.svnpath!('board', 'committee-info.txt') _ ' and ' _code 'ldapsearch cn=pmc-chairs' _ '. Membership that is only listed in one of these two sources is ' _span.text_danger 'listed in red' _ '.' end _p %q( If you want to check a particular list, append it to the URL, e.g. subscriptioncheck?listname ) _p %q( If the domain is not included, it is assumed to be @apache.org ) _p do _ 'The default list is:' _ DEFAULT_LISTS end } ) do _p "Checking: #{listnames}" listnames.split(',') do |entry| listname,domain = entry.split('@') domain ||= 'apache.org' listid = listname + '@' + domain subscribers, modtime = ASF::MLIST.sub_digest(domain, listname) ids = [] if subscribers.nil? _h2 "Could not find mailing list #{listid}" else _h2 do _ "Mailing list" _a listid, href: "https://lists.apache.org/list.html?#{listid}" _ "(updated #{modtime})" end subscribers -= MEMBER_ANNOUNCE_OK if listid == 'members-announce@apache.org' subscribers -= ['trademarks@gsuite.cloud.apache.org'] if listid = 'trademarks@apache.org' 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' else person = ASF::Person.find('notinavail') id = '*missing*' end ids << [id, person, line] end end _table_.table do _thead do _th 'ID' _th 'Email' _th 'Name' _th 'Committee' end _tbody do ids.sort.each do |id, person, email| status = member_statuses[person.name] next if status next if info_chairs.include? person or ldap_chairs.include? person _tr_ do href = "/roster/committer/#{id}" if id.include? '*' _td.text_danger id else _td.text_danger {_a id, href: href} end _td email if not id.include? '*' _td person.public_name else icla = ASF::ICLA.find_by_email(id) if icla _td.text_danger icla.name else _td.text_danger '*notinavail*' end end if info_chairs.include? person text = info_chairs[person].uniq.map(&:display_name).join(', ') if ldap_chairs.include? person or info_chairs[person].all? &:nonpmc? _td text else _td.text_danger text end elsif member_statuses[person.name] _td elsif ldap_chairs.include? person _td.text_danger '***LDAP only***' else pmcs = person.project_owners.map(&:name) if pmcs.length == 0 _td.text_danger '*** non-member, non-officer, non-pmc ***' else _td.text_warning "*** non-member, non-officer, pmcs: #{pmcs.join ','} ***" end end end end end end end end end end