diff options
Diffstat (limited to 'Mailman/bin')
| -rw-r--r-- | Mailman/bin/Makefile.in | 71 | ||||
| -rw-r--r-- | Mailman/bin/__init__.py | 0 | ||||
| -rwxr-xr-x | Mailman/bin/newlist.py | 229 | ||||
| -rwxr-xr-x | Mailman/bin/rmlist.py | 153 |
4 files changed, 453 insertions, 0 deletions
diff --git a/Mailman/bin/Makefile.in b/Mailman/bin/Makefile.in new file mode 100644 index 000000000..1ba409155 --- /dev/null +++ b/Mailman/bin/Makefile.in @@ -0,0 +1,71 @@ +# Copyright (C) 1998-2006 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. + +# NOTE: Makefile.in is converted into Makefile by the configure script +# in the parent directory. Once configure has run, you can recreate +# the Makefile by running just config.status. + +# Variables set by configure + +VPATH= @srcdir@ +srcdir= @srcdir@ +bindir= @bindir@ +prefix= @prefix@ +exec_prefix= @exec_prefix@ +DESTDIR= + +CC= @CC@ +CHMOD= @CHMOD@ +INSTALL= @INSTALL@ + +DEFS= @DEFS@ + +# Customizable but not set by configure + +OPT= @OPT@ +CFLAGS= $(OPT) $(DEFS) +PACKAGEDIR= $(prefix)/Mailman/bin +SHELL= /bin/sh + +MODULES= *.py + +# Modes for directories and executables created by the install +# process. Default to group-writable directories but +# user-only-writable for executables. +DIRMODE= 775 +EXEMODE= 755 +FILEMODE= 644 +INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE) + + +# Rules + +all: + +install: + for f in $(MODULES); \ + do \ + $(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \ + done + +finish: + +clean: + +distclean: + -rm *.pyc + -rm Makefile diff --git a/Mailman/bin/__init__.py b/Mailman/bin/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Mailman/bin/__init__.py diff --git a/Mailman/bin/newlist.py b/Mailman/bin/newlist.py new file mode 100755 index 000000000..79b584eee --- /dev/null +++ b/Mailman/bin/newlist.py @@ -0,0 +1,229 @@ +# Copyright (C) 1998-2006 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. + +import os +import sha +import sys +import getpass +import optparse + +from Mailman import Errors +from Mailman import MailList +from Mailman import Message +from Mailman import Utils +from Mailman import Version +from Mailman import i18n +from Mailman import mm_cfg + +_ = i18n._ + + + +def parseargs(): + parser = optparse.OptionParser(version='GNU Mailman ' + Version.VERSION, + usage=_("""\ +Create a new, unpopulated mailing list. + +Usage: %%prog [options] [listname [listadmin-addr [admin-password]]] + +You can specify as many of the arguments as you want on the command line: +you will be prompted for the missing ones. + +Every Mailman list has two parameters which define the default host name for +outgoing email, and the default URL for all web interfaces. When you +configured Mailman, certain defaults were calculated, but if you are running +multiple virtual Mailman sites, then the defaults may not be appropriate for +the list you are creating. + +You also specify the domain to create your new list in by typing the command +like so: + + newlist --urlhost=www.mydom.ain mylist + +where `www.mydom.ain' should be the base hostname for the URL to this virtual +hosts's lists. E.g. with this setting people will view the general list +overviews at http://www.mydom.ain/mailman/listinfo. Also, www.mydom.ain +should be a key in the VIRTUAL_HOSTS mapping in mm_cfg.py/Defaults.py if +the email hostname to be automatically determined. + +If you want the email hostname to be different from the one looked up by the +VIRTUAL_HOSTS or if urlhost is not registered in VIRTUAL_HOSTS, you can specify +`emailhost' like so: + + newlist --urlhost=www.mydom.ain --emailhost=mydom.ain mylist + +where `mydom.ain' is the mail domain name. If you don't specify emailhost but +urlhost is not in the virtual host list, then mm_cfg.DEFAULT_EMAIL_HOST will +be used for the email interface. + +For backward compatibility, you can also specify the domain to create your +new list in by spelling the listname like so: + + mylist@www.mydom.ain + +where www.mydom.ain is used for `urlhost' but it will also be used for +`emailhost' if it is not found in the virtual host table. Note that +'--urlhost' and '--emailhost' have precedence to this notation. + +If you spell the list name as just `mylist', then the email hostname will be +taken from DEFAULT_EMAIL_HOST and the url will be taken from DEFAULT_URL (as +defined in your Defaults.py file or overridden by settings in mm_cfg.py). + +Note that listnames are forced to lowercase.""")) + parser.add_option('-l', '--language', + type='string', action='store', + default=mm_cfg.DEFAULT_SERVER_LANGUAGE, + help=_("""\ +Make the list's preferred language LANGUAGE, which must be a two letter +language code.""")) + parser.add_option('-u', '--urlhost', + type='string', action='store', + help=_('The hostname for the web interface')) + parser.add_option('-e', '--emailhost', + type='string', action='store', + help=_('The hostname for the email server')) + parser.add_option('-q', '--quiet', + default=False, action='store_true', + help=_("""\ +Normally the administrator is notified by email (after a prompt) that their +list has been created. This option suppresses the prompt and +notification.""")) + opts, args = parser.parse_args() + # Is the language known? + if opts.language not in mm_cfg.LC_DESCRIPTIONS: + parser.print_help() + print >> sys.stderr, _('Unknown language: $opts.language') + sys.exit(1) + return parser, opts, args + + + +def main(): + parser, opts, args = parseargs() + + # Handle variable number of positional arguments + if args: + listname = args.pop(0) + else: + listname = raw_input(_('Enter the name of the list: ')) + + listname = listname.lower() + if '@' in listname: + # Note that --urlhost and --emailhost have precedence + listname, domain = listname.split('@', 1) + urlhost = opts.urlhost or domain + emailhost = opts.emailhost or mm_cfg.VIRTUAL_HOSTS.get(domain, domain) + + urlhost = opts.urlhost or mm_cfg.DEFAULT_URL_HOST + host_name = (opts.emailhost or + mm_cfg.VIRTUAL_HOSTS.get(urlhost, mm_cfg.DEFAULT_EMAIL_HOST)) + web_page_url = mm_cfg.DEFAULT_URL_PATTERN % urlhost + + if Utils.list_exists(listname): + parser.print_help() + print >> sys.stderr, _('List already exists: $listname') + + if args: + owner_mail = args.pop(0) + else: + owner_mail = raw_input( + _('Enter the email of the person running the list: ')) + + if args: + listpasswd = args.pop(0) + else: + listpasswd = getpass.getpass(_('Initial $listname password: ')) + + # List passwords cannot be empty + listpasswd = listpasswd.strip() + if not listpasswd: + parser.print_help() + print >> sys.stderr, _('The list password cannot be empty') + + mlist = MailList.MailList() + try: + pw = sha.new(listpasswd).hexdigest() + # Guarantee that all newly created files have the proper permission. + # proper group ownership should be assured by the autoconf script + # enforcing that all directories have the group sticky bit set. + oldmask = os.umask(002) + try: + try: + mlist.Create(listname, owner_mail, pw) + except Errors.BadListNameError, s: + parser.print_help() + print >> sys.stderr, _('Illegal list name: $s') + sys.exit(1) + except Errors.EmailAddressError, s: + parser.print_help() + print >> sys.stderr, _('Bad owner email address: $s') + sys.exit(1) + except Errors.MMListAlreadyExistsError: + parser.print_help() + print >> sys.stderr, _('List already exists: $listname') + sys.exit(1) + finally: + os.umask(oldmask) + + # Assign domain-specific attributes + mlist.host_name = host_name + mlist.web_page_url = web_page_url + + # And assign the preferred language + mlist.preferred_language = opts.language + mlist.Save() + finally: + mlist.Unlock() + + # Now do the MTA-specific list creation tasks + if mm_cfg.MTA: + modname = 'Mailman.MTA.' + mm_cfg.MTA + __import__(modname) + sys.modules[modname].create(mlist) + + # And send the notice to the list owner + if not opts.quiet: + print _('Hit enter to notify $listname owner...'), + sys.stdin.readline() + siteowner = Utils.get_site_email(mlist.host_name, 'owner') + d = dict( + listname = listname, + password = listpasswd, + admin_url = mlist.GetScriptURL('admin', absolute=True), + listinfo_url = mlist.GetScriptURL('listinfo', absolute=True), + requestaddr = mlist.GetRequestEmail(), + siteowner = siteowner, + ) + text = Utils.maketext('newlist.txt', d, mlist=mlist) + # Set the I18N language to the list's preferred language so the header + # will match the template language. Stashing and restoring the old + # translation context is just (healthy? :) paranoia. + otrans = i18n.get_translation() + i18n.set_language(mlist.preferred_language) + try: + msg = Message.UserNotification( + owner_mail, siteowner, + _('Your new mailing list: $listname'), + text, mlist.preferred_language) + msg.send(mlist) + finally: + i18n.set_translation(otrans) + + + +if __name__ == '__main__': + main() diff --git a/Mailman/bin/rmlist.py b/Mailman/bin/rmlist.py new file mode 100755 index 000000000..fbaf30641 --- /dev/null +++ b/Mailman/bin/rmlist.py @@ -0,0 +1,153 @@ +#! @PYTHON@ +# +# Copyright (C) 1998-2003 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. + +"""Remove the components of a mailing list with impunity - beware! + +This removes (almost) all traces of a mailing list. By default, the lists +archives are not removed, which is very handy for retiring old lists. + +Usage: + rmlist [-a] [-h] listname + +Where: + --archives + -a + Remove the list's archives too, or if the list has already been + deleted, remove any residual archives. + + --help + -h + Print this help message and exit. + +""" + +import os +import sys +import getopt +import shutil + +import paths +from Mailman import mm_cfg +from Mailman import Utils +from Mailman import MailList +from Mailman.i18n import _ + +try: + True, False +except NameError: + True = 1 + False = 0 + + + +def usage(code, msg=''): + if code: + fd = sys.stderr + else: + fd = sys.stdout + print >> fd, _(__doc__) + if msg: + print >> fd, msg + sys.exit(code) + + + +def remove_it(listname, filename, msg): + if os.path.islink(filename): + print _('Removing %(msg)s') + os.unlink(filename) + elif os.path.isdir(filename): + print _('Removing %(msg)s') + shutil.rmtree(filename) + elif os.path.isfile(filename): + os.unlink(filename) + else: + print _('%(listname)s %(msg)s not found as %(filename)s') + + + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], 'ah', + ['archives', 'help']) + except getopt.error, msg: + usage(1, msg) + + if len(args) <> 1: + usage(1) + listname = args[0].lower().strip() + + removeArchives = False + for opt, arg in opts: + if opt in ('-a', '--archives'): + removeArchives = True + elif opt in ('-h', '--help'): + usage(0) + + if not Utils.list_exists(listname): + if not removeArchives: + usage(1, _('No such list (or list already deleted): %(listname)s')) + else: + print _( + 'No such list: %(listname)s. Removing its residual archives.') + + if not removeArchives: + print _('Not removing archives. Reinvoke with -a to remove them.') + + + REMOVABLES = [] + if Utils.list_exists(listname): + mlist = MailList.MailList(listname, lock=0) + + # Do the MTA-specific list deletion tasks + if mm_cfg.MTA: + modname = 'Mailman.MTA.' + mm_cfg.MTA + __import__(modname) + sys.modules[modname].remove(mlist) + + REMOVABLES = [ + (os.path.join('lists', listname), _('list info')), + ] + + # Remove any stale locks associated with the list + for filename in os.listdir(mm_cfg.LOCK_DIR): + fn_listname = filename.split('.')[0] + if fn_listname == listname: + REMOVABLES.append((os.path.join(mm_cfg.LOCK_DIR, filename), + _('stale lock file'))) + + if removeArchives: + REMOVABLES.extend([ + (os.path.join('archives', 'private', listname), + _('private archives')), + (os.path.join('archives', 'private', listname + '.mbox'), + _('private archives')), + (os.path.join('archives', 'public', listname), + _('public archives')), + (os.path.join('archives', 'public', listname + '.mbox'), + _('public archives')), + ]) + + for dirtmpl, msg in REMOVABLES: + dir = os.path.join(mm_cfg.VAR_PREFIX, dirtmpl) + remove_it(listname, dir, msg) + + + +if __name__ == '__main__': + main() |
