#!/usr/bin/python ### ### This script is used to get lists of LISTSERV subscribers for a ### given list, who have a certain option set, and reformat the ### resulting email to match the format of the Mailman "who" command, ### which then allows the add_members script to take this file as ### input. ### ### It is thus primarily useful as part of migrating subscribers from ### old Listserv lists to new Mailman lists, while trying to preserve ### their options. ### ### For example, you could email LISTSERV a command like ### "QUERY listname with DIGEST FOR *@*" (or NODIGEST, NOMAIL, etc.) ### and then use a procmail filter to send the email reply into this ### script, which will save it into a file called digest-listname.txt ### in the directory specified by the savedir variable below. ### ### Then you could run the Mailman bin command ### add_members -d digest-listname.txt listname ### to subscribe the members in that file to the new list with their ### digest option already set. ### ### An example procmail filter to send the LISTSERV command results ### into this script might be something like the following: ### ### :0 ### * ^From:.*LISTSERV@ ### * ^Subject:.*Re:.* query ### | cat - | $HOME/.procmail/save_opt_query.py ### ### See the queryopt.pl script for a programmatic way to generate ### the LISTSERV emails which query lists for subscriber options. ### ### Anthony R. Thompson - Dec 2009 ### Contact: put @ between art and sigilservices.com ### ### Copyright (C) 1998-2010 by the Free Software Foundation, Inc. ### ### This program is free software; you can redistribute it and/or ### modify it under the terms of the GNU General Public License ### as published by the Free Software Foundation; either version 2 ### of the License, or (at your option) any later version. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ### 02110-1301, USA. http://www.fsf.org/licensing/licenses/gpl.html ### import email, re, sys # This has to be hard-coded because procmail doesn't have our environment savedir = '/path/to/place/to/save/outputfiles' # INSTALL from cStringIO import StringIO # needed later for faster string append # See http://www.skymind.com/~ocrow/python_string/ for more info def list_to_string(list): file_str = StringIO() for item in list: file_str.write(str(item)) return file_str.getvalue() msg = email.message_from_string(list_to_string(sys.stdin.readlines())) subject = msg.get('Subject') body = msg.get_payload() # Get type of digest query from subject line (digest or nodigest) # Example subject line is Re: DIGEST query # Note that subject of incoming message is Re: subject of command msg opttype = re.sub('^Re: ', '', subject) opttype = re.sub(' query.*', '', opttype) opttype = opttype.lower() if (opttype not in ['digest', 'nodigest', 'mail', 'nomail', 'mime', 'nomime', 'conceal', 'review', 'noreview', 'post', 'nopost', 'repro', 'norepro', 'subjecthdr', 'editor']): err = 'Unknown option type from subject line: ' + opttype raise ValueError(err) # Convert body to a list, if necessary if (type(body) is str): mail_body = re.split('\n', msg.get_payload()) elif (type(body) is list): mail_body = body else: err = 'Unknown object type from get_payload() - neither list nor string' raise ValueError(err) # Now go through the body and gather up the info we need, incl list name listname = '' sublines = [] for line in mail_body: if (re.search('^> QUERY', line)): listname = re.sub('^> QUERY ', '', line) listname = re.sub(' .*', '', listname) listname = listname.lower() elif (re.search('^Subscription options', line)): subinfo = re.sub('^Subscription options for ', '', line) subinfo = re.sub('>,.*', '>', subinfo) sublines.append(subinfo) if (listname == ''): print "Unable to obtain list name from email body - exiting" sys.exit(1) # Overwrite existing file with results of this command outfile = open("%s/%s-%s.txt" % (savedir, opttype, listname), 'w') for line in sublines: outfile.write(line) outfile.write("\n") outfile.close()