summaryrefslogtreecommitdiff
path: root/mailman/app/lifecycle.py
diff options
context:
space:
mode:
authorBarry Warsaw2008-02-27 01:26:18 -0500
committerBarry Warsaw2008-02-27 01:26:18 -0500
commita1c73f6c305c7f74987d99855ba59d8fa823c253 (patch)
tree65696889450862357c9e05c8e9a589f1bdc074ac /mailman/app/lifecycle.py
parent3f31f8cce369529d177cfb5a7c66346ec1e12130 (diff)
downloadmailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.tar.gz
mailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.tar.zst
mailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.zip
Diffstat (limited to 'mailman/app/lifecycle.py')
-rw-r--r--mailman/app/lifecycle.py117
1 files changed, 117 insertions, 0 deletions
diff --git a/mailman/app/lifecycle.py b/mailman/app/lifecycle.py
new file mode 100644
index 000000000..7d8dbb3cf
--- /dev/null
+++ b/mailman/app/lifecycle.py
@@ -0,0 +1,117 @@
+# Copyright (C) 2007-2008 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.
+
+"""Application level list creation."""
+
+import os
+import sys
+import shutil
+import logging
+
+from mailman import Errors
+from mailman import Utils
+from mailman.Utils import ValidateEmail
+from mailman.app.plugins import get_plugin
+from mailman.app.styles import style_manager
+from mailman.configuration import config
+from mailman.interfaces import MemberRole
+
+__all__ = [
+ 'create_list',
+ 'remove_list',
+ ]
+
+
+log = logging.getLogger('mailman.error')
+
+
+
+def create_list(fqdn_listname, owners=None):
+ """Create the named list and apply styles."""
+ if owners is None:
+ owners = []
+ ValidateEmail(fqdn_listname)
+ listname, domain = Utils.split_listname(fqdn_listname)
+ if domain not in config.domains:
+ raise Errors.BadDomainSpecificationError(domain)
+ mlist = config.db.list_manager.create(fqdn_listname)
+ for style in style_manager.lookup(mlist):
+ # XXX FIXME. When we get rid of the wrapper object, this hack won't
+ # be necessary. Until then, setattr on the MailList instance won't
+ # set the database column values, so pass the underlying database
+ # object to .apply() instead.
+ style.apply(mlist)
+ # Coordinate with the MTA, which should be defined by plugins.
+ # XXX FIXME
+## mta_plugin = get_plugin('mailman.mta')
+## mta_plugin().create(mlist)
+ # Create any owners that don't yet exist, and subscribe all addresses as
+ # owners of the mailing list.
+ usermgr = config.db.user_manager
+ for owner_address in owners:
+ addr = usermgr.get_address(owner_address)
+ if addr is None:
+ # XXX Make this use an IRegistrar instead, but that requires
+ # sussing out the IDomain stuff. For now, fake it.
+ user = usermgr.create_user(owner_address)
+ addr = list(user.addresses)[0]
+ addr.subscribe(mlist, MemberRole.owner)
+ return mlist
+
+
+
+def remove_list(fqdn_listname, mailing_list=None, archives=True):
+ """Remove the list and all associated artifacts and subscriptions."""
+ removeables = []
+ # mailing_list will be None when only residual archives are being removed.
+ if mailing_list:
+ # Remove all subscriptions, regardless of role.
+ for member in mailing_list.subscribers.members:
+ member.unsubscribe()
+ # Delete the mailing list from the database.
+ config.db.list_manager.delete(mailing_list)
+ # Do the MTA-specific list deletion tasks
+ if config.MTA:
+ modname = 'mailman.MTA.' + config.MTA
+ __import__(modname)
+ sys.modules[modname].remove(mailing_list)
+ # Remove the list directory.
+ removeables.append(os.path.join(config.LIST_DATA_DIR, fqdn_listname))
+ # Remove any stale locks associated with the list.
+ for filename in os.listdir(config.LOCK_DIR):
+ fn_listname = filename.split('.')[0]
+ if fn_listname == fqdn_listname:
+ removeables.append(os.path.join(config.LOCK_DIR, filename))
+ if archives:
+ private_dir = config.PRIVATE_ARCHIVE_FILE_DIR
+ public_dir = config.PUBLIC_ARCHIVE_FILE_DIR
+ removeables.extend([
+ os.path.join(private_dir, fqdn_listname),
+ os.path.join(private_dir, fqdn_listname + '.mbox'),
+ os.path.join(public_dir, fqdn_listname),
+ os.path.join(public_dir, fqdn_listname + '.mbox'),
+ ])
+ # Now that we know what files and directories to delete, delete them.
+ for target in removeables:
+ if os.path.islink(target):
+ os.unlink(target)
+ elif os.path.isdir(target):
+ shutil.rmtree(target)
+ elif os.path.isfile(target):
+ os.unlink(target)
+ else:
+ log.error('Could not delete list artifact: $target')