summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mailman/Utils.py132
-rw-r--r--mailman/app/lifecycle.py2
-rw-r--r--mailman/archiving/pipermail.py2
-rw-r--r--mailman/bin/bounces.py61
-rw-r--r--mailman/bin/confirm.py63
-rw-r--r--mailman/bin/join.py63
-rw-r--r--mailman/bin/leave.py62
-rw-r--r--mailman/bin/owner.py68
-rw-r--r--mailman/bin/post.py71
-rw-r--r--mailman/bin/request.py65
-rw-r--r--mailman/bin/update.py5
-rw-r--r--mailman/config/config.py7
-rw-r--r--mailman/database/listmanager.py7
-rw-r--r--mailman/database/mailinglist.py6
-rw-r--r--mailman/database/messagestore.py5
-rw-r--r--mailman/docs/lifecycle.txt5
-rw-r--r--mailman/i18n.py4
-rw-r--r--mailman/pipeline/scrubber.py20
-rw-r--r--mailman/queue/__init__.py5
19 files changed, 25 insertions, 628 deletions
diff --git a/mailman/Utils.py b/mailman/Utils.py
index 10e201638..9946273c9 100644
--- a/mailman/Utils.py
+++ b/mailman/Utils.py
@@ -65,30 +65,6 @@ log = logging.getLogger('mailman.error')
-def list_exists(fqdn_listname):
- """Return true iff list `fqdn_listname' exists."""
- return config.db.list_manager.get(fqdn_listname) is not None
-
-
-def list_names():
- """Return the fqdn names of all lists in default list directory."""
- return ['%s@%s' % (listname, hostname)
- for listname, hostname in config.db.list_manager.get_list_names()]
-
-
-def split_listname(listname):
- if AT in listname:
- return listname.split(AT, 1)
- return listname, config.DEFAULT_EMAIL_HOST
-
-
-def fqdn_listname(listname, hostname=None):
- if hostname is None:
- return AT.join(split_listname(listname))
- return AT.join((listname, hostname))
-
-
-
# a much more naive implementation than say, Emacs's fill-paragraph!
def wrap(text, column=70, honor_leading_ws=True):
"""Wrap and fill the text to the specified column.
@@ -562,20 +538,6 @@ def GetRequestURI(fallback=None, escape=True):
-def makedirs(path, mode=02775):
- try:
- omask = os.umask(0)
- try:
- os.makedirs(path, mode)
- finally:
- os.umask(omask)
- except OSError, e:
- # Ignore the exceptions if the directory already exists
- if e.errno <> errno.EEXIST:
- raise
-
-
-
# XXX Replace this with direct calls. For now, existing uses of GetCharSet()
# are too numerous to change.
def GetCharSet(lang):
@@ -607,100 +569,6 @@ def midnight(date=None):
-# Utilities to convert from simplified $identifier substitutions to/from
-# standard Python $(identifier)s substititions. The "Guido rules" for the
-# former are:
-# $$ -> $
-# $identifier -> $(identifier)s
-# ${identifier} -> $(identifier)s
-
-def to_dollar(s):
- """Convert from %-strings to $-strings."""
- s = s.replace('$', '$$').replace('%%', '%')
- parts = cre.split(s)
- for i in range(1, len(parts), 2):
- if parts[i+1] and parts[i+1][0] in IDENTCHARS:
- parts[i] = '${' + parts[i] + '}'
- else:
- parts[i] = '$' + parts[i]
- return EMPTYSTRING.join(parts)
-
-
-def to_percent(s):
- """Convert from $-strings to %-strings."""
- s = s.replace('%', '%%').replace('$$', '$')
- parts = dre.split(s)
- for i in range(1, len(parts), 4):
- if parts[i] is not None:
- parts[i] = '$'
- elif parts[i+1] is not None:
- parts[i+1] = '%(' + parts[i+1] + ')s'
- else:
- parts[i+2] = '%(' + parts[i+2] + ')s'
- return EMPTYSTRING.join(filter(None, parts))
-
-
-def dollar_identifiers(s):
- """Return the set (dictionary) of identifiers found in a $-string."""
- d = {}
- for name in filter(None, [b or c or None for a, b, c in dre.findall(s)]):
- d[name] = True
- return d
-
-
-def percent_identifiers(s):
- """Return the set (dictionary) of identifiers found in a %-string."""
- d = {}
- for name in cre.findall(s):
- d[name] = True
- return d
-
-
-
-# Utilities to canonicalize a string, which means un-HTML-ifying the string to
-# produce a Unicode string or an 8-bit string if all the characters are ASCII.
-def canonstr(s, lang=None):
- newparts = []
- parts = re.split(r'&(?P<ref>[^;]+);', s)
- def appchr(i):
- if i < 256:
- newparts.append(chr(i))
- else:
- newparts.append(unichr(i))
- while True:
- newparts.append(parts.pop(0))
- if not parts:
- break
- ref = parts.pop(0)
- if ref.startswith('#'):
- try:
- appchr(int(ref[1:]))
- except ValueError:
- # Non-convertable, stick with what we got
- newparts.append('&'+ref+';')
- else:
- c = htmlentitydefs.entitydefs.get(ref, '?')
- if c.startswith('#') and c.endswith(';'):
- appchr(int(ref[1:-1]))
- else:
- newparts.append(c)
- newstr = EMPTYSTRING.join(newparts)
- if isinstance(newstr, unicode):
- return newstr
- # We want the default fallback to be iso-8859-1 even if the language is
- # English (us-ascii). This seems like a practical compromise so that
- # non-ASCII characters in names can be used in English lists w/o having to
- # change the global charset for English from us-ascii (which I
- # superstitiously think may have unintended consequences).
- if lang is None:
- charset = 'iso-8859-1'
- else:
- charset = GetCharSet(lang)
- if charset == 'us-ascii':
- charset = 'iso-8859-1'
- return unicode(newstr, charset, 'replace')
-
-
# The opposite of canonstr() -- sorta. I.e. it attempts to encode s in the
# charset of the given language, which is the character set that the page will
# be rendered in, and failing that, replaces non-ASCII characters with their
diff --git a/mailman/app/lifecycle.py b/mailman/app/lifecycle.py
index c57d7e1fc..eec00dc86 100644
--- a/mailman/app/lifecycle.py
+++ b/mailman/app/lifecycle.py
@@ -47,7 +47,7 @@ def create_list(fqdn_listname, owners=None):
if owners is None:
owners = []
ValidateEmail(fqdn_listname)
- listname, domain = Utils.split_listname(fqdn_listname)
+ listname, domain = fqdn_listname.split('@', 1)
if domain not in config.domains:
raise errors.BadDomainSpecificationError(domain)
mlist = config.db.list_manager.create(fqdn_listname)
diff --git a/mailman/archiving/pipermail.py b/mailman/archiving/pipermail.py
index 4ee2e8dff..377f4ab53 100644
--- a/mailman/archiving/pipermail.py
+++ b/mailman/archiving/pipermail.py
@@ -31,10 +31,10 @@ from cStringIO import StringIO
from zope.interface import implements
from zope.interface.interface import adapter_hooks
-from mailman.Utils import makedirs
from mailman.config import config
from mailman.interfaces.archiver import IArchiver, IPipermailMailingList
from mailman.interfaces.mailinglist import IMailingList
+from mailman.utilities.filesystem import makedirs
from mailman.utilities.string import expand
from mailman.Archiver.HyperArch import HyperArchive
diff --git a/mailman/bin/bounces.py b/mailman/bin/bounces.py
deleted file mode 100644
index e5e4e16b6..000000000
--- a/mailman/bin/bounces.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright (C) 2001-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Process VERP'd bounces.
-
-Called by the wrapper, stdin is the mail message, and argv[1] is the name
-of the target mailing list.
-
-Errors are redirected to logs/error.
-"""
-
-import sys
-import logging
-
-from mailman import Utils
-from mailman import loginit
-from mailman.configuration import config
-from mailman.i18n import _
-from mailman.queue import Switchboard
-
-
-
-def main():
- # Setup logging to stderr stream and error log.
- loginit.initialize(propagate=True)
- log = logging.getLogger('mailman.error')
- try:
- listname = sys.argv[1]
- except IndexError:
- log.error(_('bounces script got no listname.'))
- sys.exit(1)
- # Make sure the list exists
- if not Utils.list_exists(listname):
- log.error(_('bounces script, list not found: $listname'))
- sys.exit(1)
- # Immediately queue the message for the bounces qrunner to process. The
- # advantage to this approach is that messages should never get lost --
- # some MTAs have a hard limit to the time a filter prog can run. Postfix
- # is a good example; if the limit is hit, the proc is SIGKILL'd giving us
- # no chance to save the message.
- bounceq = Switchboard(config.BOUNCEQUEUE_DIR)
- bounceq.enqueue(sys.stdin.read(), listname=listname, _plaintext=True)
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/mailman/bin/confirm.py b/mailman/bin/confirm.py
deleted file mode 100644
index c3f1d49f6..000000000
--- a/mailman/bin/confirm.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2002-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Simple confirm via VERP-ish sender.
-
-Called by the wrapper, stdin is the mail message, and argv[1] is the name
-of the target mailing list.
-
-Errors are redirected to logs/error.
-"""
-
-import sys
-import logging
-
-from mailman import Utils
-from mailman import loginit
-from mailman.configuration import config
-from mailman.i18n import _
-from mailman.queue import Switchboard
-
-
-
-def main():
- config.load()
- # Setup logging to stderr stream and error log.
- loginit.initialize(propagate=True)
- log = logging.getLogger('mailman.error')
- try:
- listname = sys.argv[1]
- except IndexError:
- log.error(_('confirm script got no listname.'))
- sys.exit(1)
- # Make sure the list exists
- if not Utils.list_exists(listname):
- log.error(_('confirm script, list not found: $listname'))
- sys.exit(1)
- # Immediately queue the message for the bounce/cmd qrunner to process.
- # The advantage to this approach is that messages should never get lost --
- # some MTAs have a hard limit to the time a filter prog can run. Postfix
- # is a good example; if the limit is hit, the proc is SIGKILL'd giving us
- # no chance to save the message.
- cmdq = Switchboard(config.CMDQUEUE_DIR)
- cmdq.enqueue(sys.stdin.read(), listname=listname,
- toconfirm=True, _plaintext=True)
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/mailman/bin/join.py b/mailman/bin/join.py
deleted file mode 100644
index 29ae4c752..000000000
--- a/mailman/bin/join.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (C) 2001-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Simple join-a-list email address.
-
-Called by the wrapper, stdin is the mail message, and argv[1] is the name
-of the target mailing list.
-
-Errors are redirected to logs/error.
-"""
-
-import sys
-import logging
-
-from mailman import Utils
-from mailman import loginit
-from mailman.configuration import config
-from mailman.i18n import _
-from mailman.queue import Switchboard
-
-
-
-def main():
- config.load()
- # Setup logging to stderr stream and error log.
- loginit.initialize(propagate=True)
- log = logging.getLogger('mailman.error')
- try:
- listname = sys.argv[1]
- except IndexError:
- log.error(_('join script got no listname.'))
- sys.exit(1)
- # Make sure the list exists
- if not Utils.list_exists(listname):
- log.error(_('join script, list not found: $listname'))
- sys.exit(1)
- # Immediately queue the message for the bounce/cmd qrunner to process.
- # The advantage to this approach is that messages should never get lost --
- # some MTAs have a hard limit to the time a filter prog can run. Postfix
- # is a good example; if the limit is hit, the proc is SIGKILL'd giving us
- # no chance to save the message.
- cmdq = Switchboard(config.CMDQUEUE_DIR)
- cmdq.enqueue(sys.stdin.read(), listname=listname,
- tojoin=True, _plaintext=True)
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/mailman/bin/leave.py b/mailman/bin/leave.py
deleted file mode 100644
index 64f4f01c5..000000000
--- a/mailman/bin/leave.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2001-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Simple leave-a-list email address.
-
-Called by the wrapper, stdin is the mail message, and argv[1] is the name
-of the target mailing list.
-
-Errors are redirected to logs/error.
-"""
-
-import sys
-import logging
-
-from mailman import Utils
-from mailman import loginit
-from mailman.configuration import config
-from mailman.i18n import _
-from mailman.queue import Switchboard
-
-
-
-def main():
- # Setup logging to stderr stream and error log.
- loginit.initialize(propagate=True)
- log = logging.getLogger('mailman.error')
- try:
- listname = sys.argv[1]
- except IndexError:
- log.error(_('leave script got no listname.'))
- sys.exit(1)
- # Make sure the list exists
- if not Utils.list_exists(listname):
- log.error(_('leave script, list not found: $listname'))
- sys.exit(1)
- # Immediately queue the message for the bounce/cmd qrunner to process.
- # The advantage to this approach is that messages should never get lost --
- # some MTAs have a hard limit to the time a filter prog can run. Postfix
- # is a good example; if the limit is hit, the proc is SIGKILL'd giving us
- # no chance to save the message.
- cmdq = Switchboard(config.CMDQUEUE_DIR)
- cmdq.enqueue(sys.stdin.read(), listname=listname,
- toleave=True, _plaintext=True)
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/mailman/bin/owner.py b/mailman/bin/owner.py
deleted file mode 100644
index e7c40b7e5..000000000
--- a/mailman/bin/owner.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (C) 1998-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Send a message to the mailing list owner.
-
-All messages to a list's -owner address should be piped through this script.
-The -owner address is defined to be delivered directly to the list owners plus
-the list moderators, with no intervention for bounce processing.
-
-Stdin is the mail message, and argv[1] is the name of the target mailing list.
-
-Errors are redirected to logs/error.
-"""
-
-import sys
-import logging
-
-from mailman import Utils
-from mailman import loginit
-from mailman.configuration import config
-from mailman.i18n import _
-from mailman.queue import Switchboard
-
-
-
-def main():
- config.load()
- # Setup logging to stderr stream and error log.
- loginit.initialize(propagate=True)
- log = logging.getLogger('mailman.error')
- try:
- listname = sys.argv[1]
- except IndexError:
- log.error(_('owner script got no listname.'))
- sys.exit(1)
- # Make sure the list exists
- if not Utils.list_exists(listname):
- log.error(_('owner script, list not found: $listname'))
- sys.exit(1)
- # Queue the message for the owners. We will send them through the
- # incoming queue because we need some processing done on the message. The
- # processing is minimal though, so craft our own pipeline, expressly for
- # the purpose of delivering to the list owners.
- inq = Switchboard(config.INQUEUE_DIR)
- inq.enqueue(sys.stdin.read(),
- listname=listname,
- _plaintext=True,
- pipeline=config.OWNER_PIPELINE,
- toowner=True)
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/mailman/bin/post.py b/mailman/bin/post.py
deleted file mode 100644
index 8511d52dc..000000000
--- a/mailman/bin/post.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (C) 1998-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Accept posts to a list and handle them properly.
-
-The main advertised address for a list should be filtered to this program,
-through the mail wrapper. E.g. for list `test@yourdomain.com', the `test'
-alias would deliver to this script.
-
-Stdin is the mail message, and argv[1] is the name of the target mailing list.
-
-Errors are redirected to logs/error.
-"""
-
-import sys
-import logging
-
-from mailman import Utils
-from mailman import loginit
-from mailman.configuration import config
-from mailman.i18n import _
-from mailman.queue import Switchboard
-
-
-
-def main():
- config.load()
- # Setup logging to stderr stream and error log.
- loginit.initialize(propagate=True)
- log = logging.getLogger('mailman.error')
- # XXX If you've configured your list or aliases so poorly as to get either
- # of these first two errors, there's little that can be done to save your
- # messages. They will be lost. Minimal testing of new lists should avoid
- # either of these problems.
- try:
- listname = sys.argv[1]
- except IndexError:
- log.error(_('post script got no listname.'))
- sys.exit(1)
- # Make sure the list exists
- if not Utils.list_exists(listname):
- log.error(_('post script, list not found: $listname'))
- sys.exit(1)
- # Immediately queue the message for the incoming qrunner to process. The
- # advantage to this approach is that messages should never get lost --
- # some MTAs have a hard limit to the time a filter prog can run. Postfix
- # is a good example; if the limit is hit, the proc is SIGKILL'd giving us
- # no chance to save the message.
- inq = Switchboard(config.INQUEUE_DIR)
- inq.enqueue(sys.stdin.read(),
- listname=listname,
- tolist=True, _plaintext=True)
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/mailman/bin/request.py b/mailman/bin/request.py
deleted file mode 100644
index af62b4f51..000000000
--- a/mailman/bin/request.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright (C) 1998-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Process emailed commands.
-
-Called by the wrapper, stdin is the mail message, and argv[1] is the name
-of the target mailing list.
-
-Errors are redirected to logs/error.
-"""
-
-import sys
-import logging
-
-from mailman import Utils
-from mailman import loginit
-from mailman.configuration import config
-from mailman.i18n import _
-from mailman.queue import Switchboard
-
-
-
-def main():
- config.load()
- # Setup logging to stderr stream and error log.
- loginit.initialize(propagate=True)
- log = logging.getLogger('mailman.error')
- try:
- listname = sys.argv[1]
- except IndexError:
- log.error(_('request script got no listname.'))
- sys.exit(1)
- # Make sure the list exists
- if not Utils.list_exists(listname):
- log.error(_('request script, list not found: $listname'))
- sys.exit(1)
- # Immediately queue the message for the bounce/cmd qrunner to process.
- # The advantage to this approach is that messages should never get lost --
- # some MTAs have a hard limit to the time a filter prog can run. Postfix
- # is a good example; if the limit is hit, the proc is SIGKILL'd giving us
- # no chance to save the message.
- cmdq = Switchboard(config.CMDQUEUE_DIR)
- cmdq.enqueue(sys.stdin.read(),
- listname=listname,
- torequest=True,
- _plaintext=True)
-
-
-
-if __name__ == '__main__':
- main()
diff --git a/mailman/bin/update.py b/mailman/bin/update.py
index d26548aa0..34ea6cda3 100644
--- a/mailman/bin/update.py
+++ b/mailman/bin/update.py
@@ -39,6 +39,7 @@ from mailman.Queue.Switchboard import Switchboard
from mailman.configuration import config
from mailman.i18n import _
from mailman.initialize import initialize
+from mailman.utilities.filesystem import makedirs
FRESH = 0
@@ -251,7 +252,7 @@ def dolist(listname):
o_html_dir = makeabs('public_html/archives/%s' % (listname))
# Make the mbox directory if it's not there.
if not os.path.exists(mbox_dir):
- Utils.makedirs(mbox_dir)
+ makedirs(mbox_dir)
else:
# This shouldn't happen, but hey, just in case
if not os.path.isdir(mbox_dir):
@@ -259,7 +260,7 @@ def dolist(listname):
For some reason, $mbox_dir exists as a file. This won't work with b6, so I'm
renaming it to ${mbox_dir}.tmp and proceeding.""")
os.rename(mbox_dir, "%s.tmp" % (mbox_dir))
- Utils.makedirs(mbox_dir)
+ makedirs(mbox_dir)
# Move any existing mboxes around, but watch out for both a public and a
# private one existing
if os.path.isfile(o_pri_mbox_file) and os.path.isfile(o_pub_mbox_file):
diff --git a/mailman/config/config.py b/mailman/config/config.py
index 189917999..fa359a6f5 100644
--- a/mailman/config/config.py
+++ b/mailman/config/config.py
@@ -39,6 +39,7 @@ from mailman.core import errors
from mailman.domain import Domain
from mailman.languages import LanguageManager
from mailman.styles.manager import StyleManager
+from mailman.utilities.filesystem import makedirs
SPACE = ' '
@@ -169,11 +170,7 @@ class Configuration(object):
def ensure_directories_exist(self):
"""Create all path directories if they do not exist."""
for variable, directory in self.paths.items():
- try:
- os.makedirs(directory, 02775)
- except OSError, e:
- if e.errno <> errno.EEXIST:
- raise
+ makedirs(directory)
@property
def qrunner_configs(self):
diff --git a/mailman/database/listmanager.py b/mailman/database/listmanager.py
index 346580eb9..790a2509a 100644
--- a/mailman/database/listmanager.py
+++ b/mailman/database/listmanager.py
@@ -29,7 +29,6 @@ import datetime
from zope.interface import implements
-from mailman.Utils import split_listname, fqdn_listname
from mailman.config import config
from mailman.database.mailinglist import MailingList
from mailman.interfaces.listmanager import IListManager, ListAlreadyExistsError
@@ -43,7 +42,7 @@ class ListManager(object):
def create(self, fqdn_listname):
"""See `IListManager`."""
- listname, hostname = split_listname(fqdn_listname)
+ listname, hostname = fqdn_listname.split('@', 1)
mlist = config.db.store.find(
MailingList,
MailingList.list_name == listname,
@@ -57,7 +56,7 @@ class ListManager(object):
def get(self, fqdn_listname):
"""See `IListManager`."""
- listname, hostname = split_listname(fqdn_listname)
+ listname, hostname = fqdn_listname.split('@', 1)
mlist = config.db.store.find(MailingList,
list_name=listname,
host_name=hostname).one()
@@ -80,4 +79,4 @@ class ListManager(object):
def names(self):
"""See `IListManager`."""
for mlist in config.db.store.find(MailingList):
- yield fqdn_listname(mlist.list_name, mlist.host_name)
+ yield '{0}@{1}'.format(mlist.list_name, mlist.host_name)
diff --git a/mailman/database/mailinglist.py b/mailman/database/mailinglist.py
index fb45afe96..8803a5fa4 100644
--- a/mailman/database/mailinglist.py
+++ b/mailman/database/mailinglist.py
@@ -32,12 +32,12 @@ from storm.locals import *
from urlparse import urljoin
from zope.interface import implements
-from mailman.Utils import fqdn_listname, makedirs, split_listname
from mailman.config import config
from mailman.database import roster
from mailman.database.model import Model
from mailman.database.types import Enum
from mailman.interfaces.mailinglist import IMailingList, Personalization
+from mailman.utilities.filesystem import makedirs
from mailman.utilities.string import expand
@@ -175,7 +175,7 @@ class MailingList(Model):
def __init__(self, fqdn_listname):
super(MailingList, self).__init__()
- listname, hostname = split_listname(fqdn_listname)
+ listname, hostname = fqdn_listname.split('@', 1)
self.list_name = listname
self.host_name = hostname
# For the pending database
@@ -203,7 +203,7 @@ class MailingList(Model):
@property
def fqdn_listname(self):
"""See `IMailingList`."""
- return fqdn_listname(self.list_name, self.host_name)
+ return '{0}@{1}'.format(self.list_name, self.host_name)
@property
def web_host(self):
diff --git a/mailman/database/messagestore.py b/mailman/database/messagestore.py
index d16fc93c4..a129f47ec 100644
--- a/mailman/database/messagestore.py
+++ b/mailman/database/messagestore.py
@@ -33,10 +33,11 @@ import cPickle as pickle
from zope.interface import implements
-from mailman import Utils
from mailman.config import config
from mailman.database.message import Message
from mailman.interfaces.messages import IMessageStore
+from mailman.utilities.filesystem import makedirs
+
# It could be very bad if you have already stored files and you change this
# value. We'd need a script to reshuffle and resplit.
@@ -95,7 +96,7 @@ class MessageStore:
except IOError as error:
if error.errno <> errno.ENOENT:
raise
- os.makedirs(os.path.dirname(path))
+ makedirs(os.path.dirname(path))
return hash32
def _get_message(self, row):
diff --git a/mailman/docs/lifecycle.txt b/mailman/docs/lifecycle.txt
index 8a98bf0f5..c6c0c0671 100644
--- a/mailman/docs/lifecycle.txt
+++ b/mailman/docs/lifecycle.txt
@@ -123,11 +123,10 @@ Removing a list
Removing a mailing list deletes the list, all its subscribers, and any related
artifacts.
- >>> from mailman import Utils
>>> from mailman.app.lifecycle import remove_list
>>> remove_list(mlist_2.fqdn_listname, mlist_2, True)
- >>> Utils.list_exists(u'test_2@example.com')
- False
+ >>> print config.db.list_manager.get('test_2@example.com')
+ None
We should now be able to completely recreate the mailing list.
diff --git a/mailman/i18n.py b/mailman/i18n.py
index d5e54ded2..12a06dc02 100644
--- a/mailman/i18n.py
+++ b/mailman/i18n.py
@@ -92,9 +92,11 @@ class using_language(object):
self._old_translation = _translation
set_language(self._language)
- def __exit__(self, exc_type, exc_val, exc_tb):
+ def __exit__(self, *exc_info):
global _translation
_translation = self._old_translation
+ # Do not suppress exceptions.
+ return False
# Set up the global translation based on environment variables. Mostly used
diff --git a/mailman/pipeline/scrubber.py b/mailman/pipeline/scrubber.py
index fa9c8577f..3ee68612f 100644
--- a/mailman/pipeline/scrubber.py
+++ b/mailman/pipeline/scrubber.py
@@ -48,6 +48,7 @@ from mailman.core.errors import DiscardMessage
from mailman.core.plugins import get_plugin
from mailman.i18n import _
from mailman.interfaces.handler import IHandler
+from mailman.utilities.filesystem import makedirs
# Path characters for common platforms
@@ -378,25 +379,6 @@ URL: $url
-def makedirs(dir):
- # Create all the directories to store this attachment in and try to make
- # sure that the permissions of the directories are set correctly.
- try:
- os.makedirs(dir, 02775)
- except OSError, e:
- if e.errno == errno.EEXIST:
- return
- # Some systems such as FreeBSD ignore mkdir's mode, so walk the just
- # created directories and try to set the mode, ignoring any OSErrors that
- # occur here.
- for dirpath, dirnames, filenames in os.walk(dir):
- try:
- os.chmod(dirpath, 02775)
- except OSError:
- pass
-
-
-
def save_attachment(mlist, msg, dir, filter_html=True):
fsdir = os.path.join(config.PRIVATE_ARCHIVE_FILE_DIR,
mlist.fqdn_listname, dir)
diff --git a/mailman/queue/__init__.py b/mailman/queue/__init__.py
index cb2225b13..6094bda9e 100644
--- a/mailman/queue/__init__.py
+++ b/mailman/queue/__init__.py
@@ -50,13 +50,14 @@ from lazr.config import as_boolean, as_timedelta
from zope.interface import implements
from mailman import Message
-from mailman import Utils
from mailman import i18n
from mailman.config import config
from mailman.interfaces.runner import IRunner
from mailman.interfaces.switchboard import ISwitchboard
+from mailman.utilities.filesystem import makedirs
from mailman.utilities.string import expand
+
# 20 bytes of all bits set, maximum hashlib.sha.digest() value
shamax = 0xffffffffffffffffffffffffffffffffffffffffL
@@ -108,7 +109,7 @@ class Switchboard:
'Not a power of 2: {0}'.format(numslices))
self.queue_directory = queue_directory
# Create the directory if it doesn't yet exist.
- Utils.makedirs(self.queue_directory, 0770)
+ makedirs(self.queue_directory, 0770)
# Fast track for no slices
self._lower = None
self._upper = None