#!/usr/local/bin/perl -w # # Original version by Sam Ruby, written in Python. # Ported to Perl, and enhanced by Jim Jagielski # Enhanced to have links to personal pages by Sam Ruby. # Cleaned up, bugfixed and improved a bit by Ask Bjoern Hansen # # Usage: ./committers.pl # creates the projects.html, committers.html and projects.html which # lists the ASF CVS project modules and the committers of those # modules. If they are also ASF members, their CVS id and name will # be in bold. This must be run on cvs.apache.org, to read the # correct avail and passwd files. use strict; use lib '/home/ask/perl/lib'; use LWP::Simple; # # these used to be a "isin" function here. I changed that to just # use a hash in the data. If a array really is needed, then perl does # provide the "grep" function. # # populate dictionary fullname from passwd file my %fullname; open(PASSWD, '/etc/passwd') or die "Cannot open passwd file: $!\n"; while (my $line = ) { chomp $line; my ($username, $fullname) = (split ':', $line)[0,4]; next unless $fullname and $username; $fullname{$username} = (split ',', $fullname)[0]; } close PASSWD; # Now populate the members array my %members; open(MEMBERS, '/etc/group') or die "Cannot open /etc/group file: $!\n"; while (my $line = ) { next unless $line =~ s/^apmember:\*:\d+://; chomp $line; %members = map {$_, undef} split(/,/, $line); } close MEMBERS; # A fairly liberal regular expression that matches non-relative URLs my $urlre='[a-zA-Z][\w+\-.]*://[\w;/?:@&=+\$.\-_!~*\'()%,#]+'; # retrieve various lists my %website; # Consume Jakarta my $page = get 'http://jakarta.apache.org/site/whoweare.html' or die "Could not fetch http://jakarta.apache.org/site/whoweare.html"; $page =~ s/\s+/ /g; while ($page =~ m{ ?([\w ]+) ?}msg) { $website{$2} = $1; } # Consume httpd $page = get 'http://httpd.apache.org/contributors/'; while ($page =~ m!.*?

(.*?)

!gs) { my $p = $1; next unless $p =~ m/>Name:(.*?)!; my ($url) = $p =~ m!URL:.*?\s*([\w ]+)\s*}sg) { $website{$2} = $1; } #use Data::Dumper; #print Data::Dumper->Dump([\%website], [qw(website)]); # populate dictionary module from avail file # tally stores the CVS modules the user is a member of my %module; my %tally; open(AVAIL, '/home/cvs/CVSROOT/avail') || die "Cannot open avail file\n"; while (my $line = ) { chomp $line; my @data = split('\|', $line); if ($data[0] and $data[0] eq 'avail') { foreach my $name (split(',', $data[2])) { next unless -d "/home/cvspublic/$name"; foreach my $id (split(',', $data[1])) { $module{$name}->{$id} = 1; $module{"cvs-committers"}->{$id} = 1; $tally{$id}->{$name} = 1; } } } } my %links; my %fullname_field; for my $id (sort keys %tally) { $fullname{$id} ||= ""; # avoid use of uninitialized variable warning $links{$id} = $website{$id} || $website{$fullname{$id}} || ""; $fullname_field{$id} = $fullname{$id} || ''; $fullname_field{$id} = qq[$fullname_field{$id}] if $links{$id}; } write_file("projects", grep { $_ ne "cvs-committers" } sort keys %module ); write_file("committers", grep { $_ eq "cvs-committers" } sort keys %module ); write_file("people"); sub write_file { my $iam = shift; my @modules = @_; my $title = "Apache Committers"; $title .= " by Project Modules" if $iam eq "projects"; open(STDOUT, ">$iam.html.tmp") or die "Cannot open $iam.html.tmp: $!\n"; # Start of the HTML file. The LEFT SIDE NAVIGATION shamelessly # stolen from the main www.apache.org static pages. print < $title
The Apache Software Foundation

$title


Apache Projects

  • HTTP Server
  • APR
  • Jakarta
  • Perl
  • PHP
  • TCL
  • XML
  • Conferences
  • Foundation
  • Foundation

  • FAQ
  • Management
  • News & Status
  • Press Kit
  • Contact
  • Get Involved

  • Contributing
  • Mailing Lists
  • CVS Repositories
  • Download

  • from a mirror
  • from here
  • Sister Projects

  • Module Registry
  • Apache-SSL
  • mod_ssl
  • Java-Apache
  • EOF print "

    " . ($iam eq "people" ? "Apache Committers" : "Project Modules") . "

    "; # create at most a "table" with 5 columns... May need to reduce that # (making it longer) to avoid VERY wide pages. For now, we just # reduce the font size one more tic my $cols = 5; my $rows = (scalar(@modules) + $cols - 1) / $cols; print < EOF for my $row (0..$rows) { print " \n"; for my $col (0..$cols) { my $name = $modules[$row+$col*$rows]; if (defined($name)) { print " \n"; } } print " \n"; } print < EOF # The committers page includes an extra table cell, which lists the cvs # modules they are committers of my ($header, $listocvs); if ($iam eq "projects") { $header = ""; $listocvs = ""; } else { $header = ""; } if ($iam eq "people") { print q[
    $name
    CVS idName
    CVS idNameCVS Projects
    ]; my $cols = 3; my $i = 0; print ""; for my $id (sort { lc ($fullname{$a}||$a) cmp lc ($fullname{$b}||$b) } keys %tally) { # we could make it skip everyone without a page, but that # would just nto be right. #next unless $fullname_field{$id} =~ m/href=/; print "" unless $i++ % $cols; print "\n"; } print "" while $i++ % $cols; print ""; print q[
    " . ($fullname_field{$id} || $id) . "
    ]; } else { # produce a sorted list of committers to each project print "
    \n"; for my $name (@modules) { print <$name $header EOF for my $id (sort keys %{$module{$name}}) { if ($iam ne "projects") { $listocvs = ""; foreach my $cvss (sort keys %{$tally{$id}}) { $listocvs .= " $cvss,"; } chop $listocvs; $listocvs = qq[]; } # we'll print member names in bold my $usernamefield = $id; $usernamefield = "$id" if exists $members{$id}; my $fullnamefield = $fullname_field{$id} || ' '; $fullnamefield = "$fullnamefield" if exists $members{$id}; print < $listocvs EOF } print "
    $listocvs$usernamefield $fullnamefield
    \n"; } # closing print <
    EOF } # not $iam eq people print < EOF close STDOUT; rename "$iam.html.tmp", "$iam.html" or die "Could not rename $iam.html.tmp to $iam.html: $!"; } exit;