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('