From 98c52ea14883f0261fd7a2f2fe8db42d96331ddb Mon Sep 17 00:00:00 2001
From: Barry Warsaw
Date: Mon, 9 Feb 2009 22:19:18 -0500
Subject: Move mailman.Message to mailman.email.Message. Rename
Message.get_sender() to Message.sender (property) and Message.get_senders()
to Message.senders (another property). The semantics of .sender is slightly
different too; it no longer consults config.mailman.use_envelope_sender.
Add absolute_import and unicode_literals to Utils.py, and clean up a few
imports.
---
src/mailman/Message.py | 297 ---------------------------
src/mailman/Utils.py | 14 +-
src/mailman/app/bounces.py | 15 +-
src/mailman/app/membership.py | 4 +-
src/mailman/app/moderator.py | 16 +-
src/mailman/app/notifications.py | 8 +-
src/mailman/app/registrar.py | 2 +-
src/mailman/bin/inject.py | 2 +-
src/mailman/chains/hold.py | 16 +-
src/mailman/commands/cmd_help.py | 2 +-
src/mailman/commands/docs/echo.txt | 2 +-
src/mailman/commands/docs/end.txt | 2 +-
src/mailman/commands/docs/join.txt | 2 +-
src/mailman/commands/join.py | 2 +-
src/mailman/config/schema.cfg | 14 --
src/mailman/docs/message.txt | 5 +-
src/mailman/docs/registration.txt | 24 +--
src/mailman/email/__init__.py | 0
src/mailman/email/message.py | 251 ++++++++++++++++++++++
src/mailman/inject.py | 4 +-
src/mailman/mta/smtp_direct.py | 2 +-
src/mailman/pipeline/acknowledge.py | 8 +-
src/mailman/pipeline/calculate_recipients.py | 3 +-
src/mailman/pipeline/cook_headers.py | 2 +-
src/mailman/pipeline/decorate.py | 2 +-
src/mailman/pipeline/docs/cook-headers.txt | 4 +-
src/mailman/pipeline/file_recipients.py | 3 +-
src/mailman/pipeline/moderate.py | 7 +-
src/mailman/pipeline/replybot.py | 19 +-
src/mailman/pipeline/to_digest.py | 2 +-
src/mailman/queue/__init__.py | 9 +-
src/mailman/queue/command.py | 11 +-
src/mailman/queue/docs/outgoing.txt | 1 -
src/mailman/queue/lmtp.py | 2 +-
src/mailman/queue/maildir.py | 2 +-
src/mailman/rules/moderation.py | 4 +-
src/mailman/tests/test_documentation.py | 2 +-
37 files changed, 352 insertions(+), 413 deletions(-)
delete mode 100644 src/mailman/Message.py
create mode 100644 src/mailman/email/__init__.py
create mode 100644 src/mailman/email/message.py
(limited to 'src')
diff --git a/src/mailman/Message.py b/src/mailman/Message.py
deleted file mode 100644
index ac41a758c..000000000
--- a/src/mailman/Message.py
+++ /dev/null
@@ -1,297 +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 .
-
-"""Standard Mailman message object.
-
-This is a subclass of email.message.Message but provides a slightly extended
-interface which is more convenient for use inside Mailman.
-"""
-
-import re
-import email
-import email.message
-import email.utils
-
-from email.charset import Charset
-from email.header import Header
-from lazr.config import as_boolean
-
-from mailman import Utils
-from mailman.config import config
-
-COMMASPACE = ', '
-
-mo = re.match(r'([\d.]+)', email.__version__)
-VERSION = tuple(int(s) for s in mo.group().split('.'))
-
-
-
-class Message(email.message.Message):
- def __init__(self):
- # We need a version number so that we can optimize __setstate__()
- self.__version__ = VERSION
- email.message.Message.__init__(self)
-
- def __getitem__(self, key):
- value = email.message.Message.__getitem__(self, key)
- if isinstance(value, str):
- return unicode(value, 'ascii')
- return value
-
- def get(self, name, failobj=None):
- value = email.message.Message.get(self, name, failobj)
- if isinstance(value, str):
- return unicode(value, 'ascii')
- return value
-
- def get_all(self, name, failobj=None):
- missing = object()
- all_values = email.message.Message.get_all(self, name, missing)
- if all_values is missing:
- return failobj
- return [(unicode(value, 'ascii') if isinstance(value, str) else value)
- for value in all_values]
-
- # BAW: For debugging w/ bin/dumpdb. Apparently pprint uses repr.
- def __repr__(self):
- return self.__str__()
-
- def __setstate__(self, d):
- # The base class attributes have changed over time. Which could
- # affect Mailman if messages are sitting in the queue at the time of
- # upgrading the email package. We shouldn't burden email with this,
- # so we handle schema updates here.
- self.__dict__ = d
- # We know that email 2.4.3 is up-to-date
- version = d.get('__version__', (0, 0, 0))
- d['__version__'] = VERSION
- if version >= VERSION:
- return
- # Messages grew a _charset attribute between email version 0.97 and 1.1
- if not d.has_key('_charset'):
- self._charset = None
- # Messages grew a _default_type attribute between v2.1 and v2.2
- if not d.has_key('_default_type'):
- # We really have no idea whether this message object is contained
- # inside a multipart/digest or not, so I think this is the best we
- # can do.
- self._default_type = 'text/plain'
- # Header instances used to allow both strings and Charsets in their
- # _chunks, but by email 2.4.3 now it's just Charsets.
- headers = []
- hchanged = 0
- for k, v in self._headers:
- if isinstance(v, Header):
- chunks = []
- cchanged = 0
- for s, charset in v._chunks:
- if isinstance(charset, str):
- charset = Charset(charset)
- cchanged = 1
- chunks.append((s, charset))
- if cchanged:
- v._chunks = chunks
- hchanged = 1
- headers.append((k, v))
- if hchanged:
- self._headers = headers
-
- # I think this method ought to eventually be deprecated
- def get_sender(self):
- """Return the address considered to be the author of the email.
-
- This can return either the From: header, the Sender: header or the
- envelope header (a.k.a. the unixfrom header). The first non-empty
- header value found is returned. However the search order is
- determined by the following:
-
- - If config.mailman.use_envelope_sender is true, then the search order
- is Sender:, From:, unixfrom
-
- - Otherwise, the search order is From:, Sender:, unixfrom
-
- unixfrom should never be empty. The return address is always
- lower cased.
-
- This method differs from get_senders() in that it returns one and only
- one address, and uses a different search order.
- """
- senderfirst = as_boolean(config.mailman.use_envelope_sender)
- if senderfirst:
- headers = ('sender', 'from')
- else:
- headers = ('from', 'sender')
- for h in headers:
- # Use only the first occurrance of Sender: or From:, although it's
- # not likely there will be more than one.
- fieldval = self[h]
- if not fieldval:
- continue
- addrs = email.utils.getaddresses([fieldval])
- try:
- realname, address = addrs[0]
- except IndexError:
- continue
- if address:
- break
- else:
- # We didn't find a non-empty header, so let's fall back to the
- # unixfrom address. This should never be empty, but if it ever
- # is, it's probably a Really Bad Thing. Further, we just assume
- # that if the unixfrom exists, the second field is the address.
- unixfrom = self.get_unixfrom()
- if unixfrom:
- address = unixfrom.split()[1]
- else:
- # TBD: now what?!
- address = ''
- return address.lower()
-
- def get_senders(self):
- """Return a list of addresses representing the author of the email.
-
- The list will contain the following addresses (in order)
- depending on availability:
-
- 1. From:
- 2. unixfrom (From_)
- 3. Reply-To:
- 4. Sender:
-
- The return addresses are always lower cased.
- """
- pairs = []
- for header in config.mailman.sender_headers.split():
- header = header.lower()
- if header == 'from_':
- # get_unixfrom() returns None if there's no envelope
- unix_from = self.get_unixfrom()
- fieldval = (unix_from if unix_from is not None else '')
- try:
- pairs.append(('', fieldval.split()[1]))
- except IndexError:
- # Ignore badly formatted unixfroms
- pass
- else:
- fieldvals = self.get_all(header)
- if fieldvals:
- pairs.extend(email.utils.getaddresses(fieldvals))
- authors = []
- for pair in pairs:
- address = pair[1]
- if address is not None:
- address = address.lower()
- authors.append(address)
- return authors
-
- def get_filename(self, failobj=None):
- """Some MUA have bugs in RFC2231 filename encoding and cause
- Mailman to stop delivery in Scrubber.py (called from ToDigest.py).
- """
- try:
- filename = email.message.Message.get_filename(self, failobj)
- return filename
- except (UnicodeError, LookupError, ValueError):
- return failobj
-
-
-
-class UserNotification(Message):
- """Class for internally crafted messages."""
-
- def __init__(self, recip, sender, subject=None, text=None, lang=None):
- Message.__init__(self)
- charset = 'us-ascii'
- if lang is not None:
- charset = Utils.GetCharSet(lang)
- if text is not None:
- self.set_payload(text.encode(charset), charset)
- if subject is None:
- subject = '(no subject)'
- self['Subject'] = Header(subject.encode(charset), charset,
- header_name='Subject', errors='replace')
- self['From'] = sender
- if isinstance(recip, list):
- self['To'] = COMMASPACE.join(recip)
- self.recips = recip
- else:
- self['To'] = recip
- self.recips = [recip]
-
- def send(self, mlist, **_kws):
- """Sends the message by enqueuing it to the 'virgin' queue.
-
- This is used for all internally crafted messages.
- """
- # Since we're crafting the message from whole cloth, let's make sure
- # this message has a Message-ID.
- if 'message-id' not in self:
- self['Message-ID'] = email.utils.make_msgid()
- # Ditto for Date: as required by RFC 2822.
- if 'date' not in self:
- self['Date'] = email.utils.formatdate(localtime=True)
- # UserNotifications are typically for admin messages, and for messages
- # other than list explosions. Send these out as Precedence: bulk, but
- # don't override an existing Precedence: header.
- if 'precedence' not in self:
- self['Precedence'] = 'bulk'
- self._enqueue(mlist, **_kws)
-
- def _enqueue(self, mlist, **_kws):
- # Not imported at module scope to avoid import loop
- virginq = config.switchboards['virgin']
- # The message metadata better have a 'recip' attribute.
- enqueue_kws = dict(
- recips=self.recips,
- nodecorate=True,
- reduced_list_headers=True,
- )
- if mlist is not None:
- enqueue_kws['listname'] = mlist.fqdn_listname
- enqueue_kws.update(_kws)
- virginq.enqueue(self, **enqueue_kws)
-
-
-
-class OwnerNotification(UserNotification):
- """Like user notifications, but this message goes to the list owners."""
-
- def __init__(self, mlist, subject=None, text=None, tomoderators=True):
- if tomoderators:
- roster = mlist.moderators
- else:
- roster = mlist.owners
- recips = [address.address for address in roster.addresses]
- sender = config.mailman.site_owner
- lang = mlist.preferred_language
- UserNotification.__init__(self, recips, sender, subject, text, lang)
- # Hack the To header to look like it's going to the -owner address
- del self['to']
- self['To'] = mlist.owner_address
- self._sender = sender
-
- def _enqueue(self, mlist, **_kws):
- # Not imported at module scope to avoid import loop
- virginq = config.switchboards['virgin']
- # The message metadata better have a `recip' attribute
- virginq.enqueue(self,
- listname=mlist.fqdn_listname,
- recips=self.recips,
- nodecorate=True,
- reduced_list_headers=True,
- envsender=self._sender,
- **_kws)
diff --git a/src/mailman/Utils.py b/src/mailman/Utils.py
index 9946273c9..b6715616c 100644
--- a/src/mailman/Utils.py
+++ b/src/mailman/Utils.py
@@ -22,6 +22,13 @@ message and address munging, a handy-dandy routine to map a function on all
the mailing lists, and whatever else doesn't belong elsewhere.
"""
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+ ]
+
+
import os
import re
import cgi
@@ -31,10 +38,9 @@ import base64
import random
import logging
import htmlentitydefs
-import email.Header
-import email.Iterators
-from email.Errors import HeaderParseError
+from email.errors import HeaderParseError
+from email.header import decode_header, make_header
from lazr.config import as_boolean
from string import ascii_letters, digits, whitespace
@@ -609,7 +615,7 @@ def uquote(s):
def oneline(s, cset='us-ascii', in_unicode=False):
# Decode header string in one line and convert into specified charset
try:
- h = email.Header.make_header(email.Header.decode_header(s))
+ h = make_header(decode_header(s))
ustr = h.__unicode__()
line = UEMPTYSTRING.join(ustr.splitlines())
if in_unicode:
diff --git a/src/mailman/app/bounces.py b/src/mailman/app/bounces.py
index 875f615a5..aa7f51c77 100644
--- a/src/mailman/app/bounces.py
+++ b/src/mailman/app/bounces.py
@@ -17,7 +17,7 @@
"""Application level bounce handling."""
-from __future__ import unicode_literals
+from __future__ import absolute_import, unicode_literals
__metaclass__ = type
__all__ = [
@@ -29,8 +29,8 @@ import logging
from email.mime.message import MIMEMessage
from email.mime.text import MIMEText
-from mailman import Message
from mailman import Utils
+from mailman.email.message import Message, UserNotification
from mailman.i18n import _
log = logging.getLogger('mailman.config')
@@ -40,7 +40,10 @@ log = logging.getLogger('mailman.config')
def bounce_message(mlist, msg, e=None):
# Bounce a message back to the sender, with an error message if provided
# in the exception argument.
- sender = msg.get_sender()
+ if msg.sender is None:
+ # We can't bounce the message if we don't know who it's supposed to go
+ # to.
+ return
subject = msg.get('subject', _('(no subject)'))
subject = Utils.oneline(subject,
Utils.GetCharSet(mlist.preferred_language))
@@ -49,10 +52,8 @@ def bounce_message(mlist, msg, e=None):
else:
notice = _(e.notice)
# Currently we always craft bounces as MIME messages.
- bmsg = Message.UserNotification(msg.get_sender(),
- mlist.owner_address,
- subject,
- lang=mlist.preferred_language)
+ bmsg = UserNotification(msg.sender, mlist.owner_address, subject,
+ lang=mlist.preferred_language)
# BAW: Be sure you set the type before trying to attach, or you'll get
# a MultipartConversionError.
bmsg.set_type('multipart/mixed')
diff --git a/src/mailman/app/membership.py b/src/mailman/app/membership.py
index 4b9609469..79e2501bd 100644
--- a/src/mailman/app/membership.py
+++ b/src/mailman/app/membership.py
@@ -28,12 +28,12 @@ __all__ = [
from email.utils import formataddr
-from mailman import Message
from mailman import Utils
from mailman import i18n
from mailman.app.notifications import send_goodbye_message
from mailman.config import config
from mailman.core import errors
+from mailman.email.message import Message, OwnerNotification
from mailman.interfaces.member import AlreadySubscribedError, MemberRole
_ = i18n._
@@ -133,5 +133,5 @@ def delete_member(mlist, address, admin_notif=None, userack=None):
{'listname': mlist.real_name,
'member' : formataddr((realname, address)),
}, mlist=mlist)
- msg = Message.OwnerNotification(mlist, subject, text)
+ msg = OwnerNotification(mlist, subject, text)
msg.send(mlist)
diff --git a/src/mailman/app/moderator.py b/src/mailman/app/moderator.py
index b40a34344..1f66e00ac 100644
--- a/src/mailman/app/moderator.py
+++ b/src/mailman/app/moderator.py
@@ -17,7 +17,7 @@
"""Application support for moderators."""
-from __future__ import unicode_literals
+from __future__ import absolute_import, unicode_literals
__metaclass__ = type
__all__ = [
@@ -34,7 +34,6 @@ import logging
from datetime import datetime
from email.utils import formataddr, formatdate, getaddresses, make_msgid
-from mailman import Message
from mailman import Utils
from mailman import i18n
from mailman.app.membership import add_member, delete_member
@@ -42,10 +41,12 @@ from mailman.app.notifications import (
send_admin_subscription_notice, send_welcome_message)
from mailman.config import config
from mailman.core import errors
+from mailman.email.message import Message, UserNotification
from mailman.interfaces import Action
from mailman.interfaces.member import AlreadySubscribedError, DeliveryMode
from mailman.interfaces.requests import RequestType
+
_ = i18n._
vlog = logging.getLogger('mailman.vette')
@@ -87,7 +88,7 @@ def hold_message(mlist, msg, msgdata=None, reason=None):
# the moderation interface.
msgdata['_mod_message_id'] = message_id
msgdata['_mod_fqdn_listname'] = mlist.fqdn_listname
- msgdata['_mod_sender'] = msg.get_sender()
+ msgdata['_mod_sender'] = msg.sender
msgdata['_mod_subject'] = msg.get('subject', _('(no subject)'))
msgdata['_mod_reason'] = reason
msgdata['_mod_hold_date'] = datetime.now().isoformat()
@@ -165,7 +166,7 @@ def handle_message(mlist, id, action,
if member:
language = member.preferred_language
with i18n.using_language(language):
- fmsg = Message.UserNotification(
+ fmsg = UserNotification(
addresses, mlist.bounces_address,
_('Forward of moderated message'),
lang=language)
@@ -212,7 +213,7 @@ def hold_subscription(mlist, address, realname, password, mode, language):
}, mlist=mlist)
# This message should appear to come from the -owner so as
# to avoid any useless bounce processing.
- msg = Message.UserNotification(
+ msg = UserNotification(
mlist.owner_address, mlist.owner_address,
subject, text, mlist.preferred_language)
msg.send(mlist, tomoderators=True)
@@ -284,7 +285,7 @@ def hold_unsubscription(mlist, address):
}, mlist=mlist)
# This message should appear to come from the -owner so as
# to avoid any useless bounce processing.
- msg = Message.UserNotification(
+ msg = UserNotification(
mlist.owner_address, mlist.owner_address,
subject, text, mlist.preferred_language)
msg.send(mlist, tomoderators=True)
@@ -346,6 +347,5 @@ def _refuse(mlist, request, recip, comment, origmsg=None, lang=None):
str(origmsg)
])
subject = _('Request to mailing list "$realname" rejected')
- msg = Message.UserNotification(recip, mlist.bounces_address,
- subject, text, lang)
+ msg = UserNotification(recip, mlist.bounces_address, subject, text, lang)
msg.send(mlist)
diff --git a/src/mailman/app/notifications.py b/src/mailman/app/notifications.py
index 9bef9998b..b1d77dc6f 100644
--- a/src/mailman/app/notifications.py
+++ b/src/mailman/app/notifications.py
@@ -30,10 +30,10 @@ __all__ = [
from email.utils import formataddr
from lazr.config import as_boolean
-from mailman import Message
from mailman import Utils
from mailman import i18n
from mailman.config import config
+from mailman.email.message import Message, OwnerNotification, UserNotification
from mailman.interfaces.member import DeliveryMode
@@ -78,7 +78,7 @@ def send_welcome_message(mlist, address, language, delivery_mode, text=''):
digmode = _(' (Digest mode)')
else:
digmode = ''
- msg = Message.UserNotification(
+ msg = UserNotification(
address, mlist.request_address,
_('Welcome to the "$mlist.real_name" mailing list${digmode}'),
text, language)
@@ -104,7 +104,7 @@ def send_goodbye_message(mlist, address, language):
goodbye = Utils.wrap(mlist.goodbye_msg) + '\n'
else:
goodbye = ''
- msg = Message.UserNotification(
+ msg = UserNotification(
address, mlist.bounces_address,
_('You have been unsubscribed from the $mlist.real_name mailing list'),
goodbye, language)
@@ -132,5 +132,5 @@ def send_admin_subscription_notice(mlist, address, full_name, language):
{'listname' : mlist.real_name,
'member' : formataddr((full_name, address)),
}, mlist=mlist)
- msg = Message.OwnerNotification(mlist, subject, text)
+ msg = OwnerNotification(mlist, subject, text)
msg.send(mlist)
diff --git a/src/mailman/app/registrar.py b/src/mailman/app/registrar.py
index 6a2abeba9..654106668 100644
--- a/src/mailman/app/registrar.py
+++ b/src/mailman/app/registrar.py
@@ -31,9 +31,9 @@ import datetime
from pkg_resources import resource_string
from zope.interface import implements
-from mailman.Message import UserNotification
from mailman.Utils import ValidateEmail
from mailman.config import config
+from mailman.email.message import UserNotification
from mailman.i18n import _
from mailman.interfaces.domain import IDomain
from mailman.interfaces.member import MemberRole
diff --git a/src/mailman/bin/inject.py b/src/mailman/bin/inject.py
index 2bc8a49e3..73f1b9015 100644
--- a/src/mailman/bin/inject.py
+++ b/src/mailman/bin/inject.py
@@ -21,10 +21,10 @@ import sys
from email import message_from_string
from mailman import Utils
-from mailman.Message import Message
from mailman.configuration import config
from mailman.i18n import _
from mailman.inject import inject_text
+from mailman.message import Message
from mailman.options import SingleMailingListOptions
diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py
index 16238a541..162834791 100644
--- a/src/mailman/chains/hold.py
+++ b/src/mailman/chains/hold.py
@@ -33,12 +33,12 @@ from email.utils import formatdate, make_msgid
from zope.interface import implements
from mailman import i18n
-from mailman.Message import UserNotification
from mailman.Utils import maketext, oneline, wrap, GetCharSet
from mailman.app.moderator import hold_message
from mailman.app.replybot import autorespond_to_sender, can_acknowledge
from mailman.chains.base import TerminalChainBase
from mailman.config import config
+from mailman.email.message import UserNotification
from mailman.interfaces.pending import IPendable
@@ -82,8 +82,7 @@ class HoldChain(TerminalChainBase):
# Get the language to send the response in. If the sender is a
# member, then send it in the member's language, otherwise send it in
# the mailing list's preferred language.
- sender = msg.get_sender()
- member = mlist.members.get_member(sender)
+ member = mlist.members.get_member(msg.sender)
language = (member.preferred_language
if member else mlist.preferred_language)
# A substitution dictionary for the email templates.
@@ -96,7 +95,7 @@ class HoldChain(TerminalChainBase):
substitutions = dict(
listname = mlist.fqdn_listname,
subject = original_subject,
- sender = sender,
+ sender = msg.sender,
reason = 'XXX', #reason,
confirmurl = '{0}/{1}'.format(mlist.script_url('confirm'), token),
admindb_url = mlist.script_url('admindb'),
@@ -118,7 +117,7 @@ class HoldChain(TerminalChainBase):
if (not msgdata.get('fromusenet') and
can_acknowledge(msg) and
mlist.respond_to_post_requests and
- autorespond_to_sender(mlist, sender, language)):
+ autorespond_to_sender(mlist, msg.sender, language)):
# We can respond to the sender with a message indicating their
# posting was held.
subject = _(
@@ -127,7 +126,7 @@ class HoldChain(TerminalChainBase):
text = maketext('postheld.txt', substitutions,
lang=send_language, mlist=mlist)
adminaddr = mlist.bounces_address
- nmsg = UserNotification(sender, adminaddr, subject, text,
+ nmsg = UserNotification(msg.sender, adminaddr, subject, text,
send_language)
nmsg.send(mlist)
# Now the message for the list moderators. This one should appear to
@@ -145,7 +144,8 @@ class HoldChain(TerminalChainBase):
substitutions['subject'] = original_subject
# craft the admin notification message and deliver it
subject = _(
- '$mlist.fqdn_listname post from $sender requires approval')
+ '$mlist.fqdn_listname post from $msg.sender requires '
+ 'approval')
nmsg = UserNotification(mlist.owner_address,
mlist.owner_address,
subject, lang=language)
@@ -174,5 +174,5 @@ also appear in the first line of the body of the reply.""")),
# XXX reason
reason = 'n/a'
log.info('HOLD: %s post from %s held, message-id=%s: %s',
- mlist.fqdn_listname, sender,
+ mlist.fqdn_listname, msg.sender,
msg.get('message-id', 'n/a'), reason)
diff --git a/src/mailman/commands/cmd_help.py b/src/mailman/commands/cmd_help.py
index eeee33ca7..30c8dc4d6 100644
--- a/src/mailman/commands/cmd_help.py
+++ b/src/mailman/commands/cmd_help.py
@@ -42,7 +42,7 @@ def process(res, args):
# Since this message is personalized, add some useful information if the
# address requesting help is a member of the list.
msg = res.msg
- for sender in msg.get_senders():
+ for sender in msg.senders:
if mlist.isMember(sender):
memberurl = mlist.GetOptionsURL(sender, absolute=1)
urlhelp = _(
diff --git a/src/mailman/commands/docs/echo.txt b/src/mailman/commands/docs/echo.txt
index 181cc58c8..95b50b523 100644
--- a/src/mailman/commands/docs/echo.txt
+++ b/src/mailman/commands/docs/echo.txt
@@ -20,7 +20,7 @@ The original message is ignored, but the results receive the echoed command.
>>> from mailman.queue.command import Results
>>> results = Results()
- >>> from mailman.Message import Message
+ >>> from mailman.email.message import Message
>>> print command.process(mlist, Message(), {}, ('foo', 'bar'), results)
ContinueProcessing.yes
>>> print unicode(results)
diff --git a/src/mailman/commands/docs/end.txt b/src/mailman/commands/docs/end.txt
index 4f6af26cb..98ca25bda 100644
--- a/src/mailman/commands/docs/end.txt
+++ b/src/mailman/commands/docs/end.txt
@@ -20,7 +20,7 @@ message isn't even looked at.
>>> from mailman.app.lifecycle import create_list
>>> mlist = create_list(u'test@example.com')
- >>> from mailman.Message import Message
+ >>> from mailman.email.message import Message
>>> print command.process(mlist, Message(), {}, (), None)
ContinueProcessing.no
diff --git a/src/mailman/commands/docs/join.txt b/src/mailman/commands/docs/join.txt
index 9b85e816c..471a2a5b6 100644
--- a/src/mailman/commands/docs/join.txt
+++ b/src/mailman/commands/docs/join.txt
@@ -25,7 +25,7 @@ The mail command 'join' subscribes an email address to the mailing list.
No address to join
------------------
- >>> from mailman.Message import Message
+ >>> from mailman.email.message import Message
>>> from mailman.app.lifecycle import create_list
>>> from mailman.queue.command import Results
>>> mlist = create_list(u'alpha@example.com')
diff --git a/src/mailman/commands/join.py b/src/mailman/commands/join.py
index c14f3142b..81a018cff 100644
--- a/src/mailman/commands/join.py
+++ b/src/mailman/commands/join.py
@@ -61,7 +61,7 @@ example:
real_name, address = parseaddr(msg['from'])
# Address could be None or the empty string.
if not address:
- address = msg.get_sender()
+ address = msg.sender
if not address:
print >> results, _(
'$self.name: No valid address found to subscribe')
diff --git a/src/mailman/config/schema.cfg b/src/mailman/config/schema.cfg
index df20a7370..c93d58986 100644
--- a/src/mailman/config/schema.cfg
+++ b/src/mailman/config/schema.cfg
@@ -40,20 +40,6 @@ var_dir: /tmp/mailman
# The default language for this server.
default_language: en
-# When allowing only members to post to a mailing list, how is the sender of
-# the message determined? If this variable is set to Yes, then first the
-# message's envelope sender is used, with a fallback to the sender if there is
-# no envelope sender. Set this variable to No to always use the sender.
-#
-# The envelope sender is set by the SMTP delivery and is thus less easily
-# spoofed than the sender, which is typically just taken from the From: header
-# and thus easily spoofed by the end-user. However, sometimes the envelope
-# sender isn't set correctly and this will manifest itself by postings being
-# held for approval even if they appear to come from a list member. If you
-# are having this problem, set this variable to No, but understand that some
-# spoofed messages may get through.
-use_envelope_sender: no
-
# Membership tests for posting purposes are usually performed by looking at a
# set of headers, passing the test if any of their values match a member of
# the list. Headers are checked in the order given in this variable. The
diff --git a/src/mailman/docs/message.txt b/src/mailman/docs/message.txt
index dab9ddf0e..704842fe4 100644
--- a/src/mailman/docs/message.txt
+++ b/src/mailman/docs/message.txt
@@ -12,13 +12,12 @@ When Mailman needs to send a message to a user, it creates a UserNotification
instance, and then calls the .send() method on this object. This method
requires a mailing list instance.
- >>> mlist = config.db.list_manager.create(u'_xtest@example.com')
- >>> mlist.preferred_language = u'en'
+ >>> mlist = create_list(u'_xtest@example.com')
The UserNotification constructor takes the recipient address, the sender
address, an optional subject, optional body text, and optional language.
- >>> from mailman.Message import UserNotification
+ >>> from mailman.email.message import UserNotification
>>> msg = UserNotification(
... 'aperson@example.com',
... '_xtest@example.com',
diff --git a/src/mailman/docs/registration.txt b/src/mailman/docs/registration.txt
index d243188bc..5f9e0b7fd 100644
--- a/src/mailman/docs/registration.txt
+++ b/src/mailman/docs/registration.txt
@@ -59,30 +59,30 @@ Some amount of sanity checks are performed on the email address, although
honestly, not as much as probably should be done. Still, some patently bad
addresses are rejected outright.
- >>> registrar.register('')
+ >>> registrar.register(u'')
Traceback (most recent call last):
...
- InvalidEmailAddress: ''
- >>> registrar.register('some name@example.com')
+ InvalidEmailAddress: u''
+ >>> registrar.register(u'some name@example.com')
Traceback (most recent call last):
...
- InvalidEmailAddress: 'some name@example.com'
- >>> registrar.register('