[Mailman-Users] Perl scripts to convert Listproc lists to Mailman

Michael James michael at james.st
Mon Oct 7 18:48:40 CEST 2002

Dear Mailman-users,

Well, no replies came in and the need was great
 so I have just started hacking.

My users getported or disconnected.
Their (and my) choice is Mailman-how-it-comes-out or nothing.  So.

I figure that most of the users
 were living with the preferences listproc wished on them anyway.
Once they get the web interface
 they will be able to actually configure subs how they want.

Here is the second installment   "add-members-from-listproc"

It creates a directory called "Listproc-subscribers"
 reads the subscribers file
 from as many list configuration directories as you give it,
 generates an alphabetical file of "email at addresses  (Real Names)"
 offers you the option to edit it with vi,
 and loads it in using mailman/bin/add_users
The list files are called <listname>.digest and
 they are left in Listproc-subscribers after a run.

The only preference users carry with them is digest or not.

I can't see a scriptable way of configuring things like
 ACK  NoReview  etc.

Short of learning the email interface that is
 and forging subscription modification emails out of perl.

The likely usage for the script is:

	add-members-from-listproc ~server/lists/*

ie: give it one or more list directories with .subscriber files in them.

Run it without parameters and it'll give a usage prompt.

Perl follows:


$LISTPROC       = '/home/alianet/server';
$MAILMAN        = '/usr/lib/mailman';
$TMP_DIR        = 'Listproc-subscribers';

$VI             = '/bin/vi';
$ADD_MEMBERS    = "$MAILMAN/bin/add_members";

use File::Basename;

@ARGV or die "Usage: add-users-from-listproc list_dir [list_dir] ...\n",
                "Hint: add-users-from-listproc ~server/lists/*\n";

-d $TMP_DIR or mkdir $TMP_DIR;

foreach $list_dir (@ARGV)
        $list_dir =~ s%/$%%;
        -d "$list_dir" or next;
        $list = basename($list_dir);
        $list =~ tr/A-Z/a-z/;   # cannonicalize $list

        # Now get the subscribers to add
        print "\nLooking at $list\n";

        # Initialize some variables
        %entries = ();
        $digest_file = "$TMP_DIR/$list.digest";
        $non_digest = "$TMP_DIR/$list.non";

        open(IN, "$list_dir/.subscribers") or do
                { warn "No subscribers file for $_ list\n"; next; };
        while (<IN>)
                ($address, @options) = split;
                $address =~ tr/A-Z/a-z/;        # lowercase it
                # check it has an @ with something either side
                $address =~ /.\@./ or next;

                # Looks like a valid line

               $ack=0; $type='non'; $yes=0;
               while ($_=shift(@options))
                        /ACK/ and do { $ack=1; next; };
                        /\d+/ and next;
                        /DIGEST/ and do { $type='digest'; next; };
                        /^NO$/ and last;
                        /^YES$/ and do { $yes=1; last; };
                $name = join ' ', @options;

                # If there are no capitals then uppercase first letters
                $name =~ tr/A-Z/A-Z/ or $name =~ s/\b(\w)/\u\1/g;

                # We will have to eyeball a lot of these
                # The columns might as well line up
                length($address) <  8 and $address .= "\t";
                length($address) < 16 and $address .= "\t";
                length($address) < 24 and $address .= "\t";
                length($address) < 32 and $address .= "\t";

                if ( $entries{digest}{$address} || $entries{non}{$address} )
                {       print "\tDuplicate entries:\t",
                else { $entries{$type}{$address} = "$address\t($name)\n"; }
        # Entries loaded into entries hash

        $count = load_list( $list, $digest_file, $entries{digest} ) and
                print "\t$count digest entries loaded into $list\n";

        $count = load_list( $list, $non_digest, $entries{non} ) and
                print "\t$count regular entries loaded into $list\n";

sub load_list
# expects a filename and a ref to a hash of entries
# returns
{       my($list, $file, $ref) = @_;
        my $count = 0;

        open(OUT, "> $file") or
                die "Can't write $file\n";
        foreach (sort(keys(%$ref)))
        {       ++$count;
                print OUT $$ref{$_};

        # If it's empty, forget it
        unless ( $count ) { unlink($file); return; }

        print "\t$file has $count entries, Load, Edit, Skip or Quit? ";
        my $answer = <STDIN>;
        $answer =~ /^q/i and exit;
        $answer =~ /^s/i and return;
        $answer =~ /^e/i and system $VI, $file;

        # Count lines again and if it's empty, forget it
        $count = 0; open(IN, "< $file"); ++$count while <IN>;
        unless ( $count ) { unlink($file); return; }

        system $ADD_MEMBERS, '-cn', '-wn', '-n', $file, $list;
A right not exercised is a privilege
a privilege not exercised is illegal.

Michael James			michael at james.st
8 Brennan St			Phone: +61 2 6247 2556
Hackett, ACT 2602		Mobile: +61 4 1747 4065
AUSTRALIA			Fax: +61 2 6278 0011

More information about the Mailman-Users mailing list