Mailing lists

The mailing list is a core object in Mailman. It is uniquely identified in the system by its list-id which is derived from its posting address, i.e. the email address you would send a message to in order to post a message to the mailing list. The list id is defined in RFC 2369.

>>> from mailman.app.lifecycle import create_list
>>> mlist = create_list('aardvark@example.com')
>>> print(mlist.list_id)
aardvark.example.com
>>> print(mlist.fqdn_listname)
aardvark@example.com

The mailing list also has convenient attributes for accessing the list’s short name (i.e. local part) and host name.

>>> print(mlist.list_name)
aardvark
>>> print(mlist.mail_host)
example.com

Rosters

Mailing list membership is represented by rosters. Each mailing list has several rosters of members, representing the subscribers to the mailing list, the owners, the moderators, and so on. The rosters are defined by a membership role.

Addresses can be explicitly subscribed to a mailing list. By default, a subscription puts the address in the member role, meaning that address will receive a copy of any message sent to the mailing list.

>>> from mailman.interfaces.usermanager import IUserManager
>>> from zope.component import getUtility
>>> user_manager = getUtility(IUserManager)

>>> aperson = user_manager.create_address('aperson@example.com')
>>> bperson = user_manager.create_address('bperson@example.com')
>>> mlist.subscribe(aperson)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
>>> mlist.subscribe(bperson)
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>

Both addresses appear on the roster of members.

>>> from operator import attrgetter
>>> sort_key = attrgetter('address.email')
>>> for member in sorted(mlist.members.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>

By explicitly specifying the role of the subscription, an address can be added to the owner and moderator rosters.

>>> from mailman.interfaces.member import MemberRole
>>> mlist.subscribe(aperson, MemberRole.owner)
<Member: aperson@example.com on aardvark@example.com as MemberRole.owner>
>>> cperson = user_manager.create_address('cperson@example.com')
>>> mlist.subscribe(cperson, MemberRole.owner)
<Member: cperson@example.com on aardvark@example.com as MemberRole.owner>
>>> mlist.subscribe(cperson, MemberRole.moderator)
<Member: cperson@example.com on aardvark@example.com
         as MemberRole.moderator>

A Person is now both a member and an owner of the mailing list. C Person is an owner and a moderator.

>>> for member in sorted(mlist.owners.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.owner>
<Member: cperson@example.com on aardvark@example.com as MemberRole.owner>

>>> for member in mlist.moderators.members:
...     print(member)
<Member: cperson@example.com on aardvark@example.com
         as MemberRole.moderator>

All rosters can also be accessed indirectly.

>>> roster = mlist.get_roster(MemberRole.member)
>>> for member in sorted(roster.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>

>>> roster = mlist.get_roster(MemberRole.owner)
>>> for member in sorted(roster.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.owner>
<Member: cperson@example.com on aardvark@example.com as MemberRole.owner>

>>> roster = mlist.get_roster(MemberRole.moderator)
>>> for member in roster.members:
...     print(member)
<Member: cperson@example.com on aardvark@example.com
         as MemberRole.moderator>

Subscribing users

An alternative way of subscribing to a mailing list is as a user with a preferred address. This way the user can change their subscription address just by changing their preferred address.

The user must have a preferred address.

>>> from mailman.utilities.datetime import now
>>> user = user_manager.create_user('dperson@example.com', 'Dave Person')
>>> address = list(user.addresses)[0]
>>> address.verified_on = now()
>>> user.preferred_address = address

The preferred address is used in the subscription.

>>> mlist.subscribe(user)
<Member: Dave Person <dperson@example.com> on aardvark@example.com
         as MemberRole.member>
>>> for member in sorted(mlist.members.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>
<Member: Dave Person <dperson@example.com> on aardvark@example.com
         as MemberRole.member>

If the user’s preferred address changes, their subscribed email address also changes automatically.

>>> new_address = user.register('dave.person@example.com')
>>> new_address.verified_on = now()
>>> user.preferred_address = new_address

>>> for member in sorted(mlist.members.members, key=sort_key):
...     print(member)
<Member: aperson@example.com on aardvark@example.com as MemberRole.member>
<Member: bperson@example.com on aardvark@example.com as MemberRole.member>
<Member: dave.person@example.com on aardvark@example.com
         as MemberRole.member>

A user is allowed to explicitly subscribe again with a specific address, even if this address is their preferred address.

>>> mlist.subscribe(user.preferred_address)
<Member: dave.person@example.com
         on aardvark@example.com as MemberRole.member>

MailingList Attributes

This defines all the attributes of a MailingList.

interface mailman.interfaces.mailinglist.IMailingList[source]

A mailing list.

acceptable_aliases = <zope.interface.interface.Attribute object at 0x7f8c8d084af0 mailman.interfaces.mailinglist.IMailingList.acceptable_aliases>
admin_immed_notify = <zope.interface.interface.Attribute object at 0x7f8c8d0c68b0 mailman.interfaces.mailinglist.IMailingList.admin_immed_notify>
admin_notify_mchanges = <zope.interface.interface.Attribute object at 0x7f8c8d0c6640 mailman.interfaces.mailinglist.IMailingList.admin_notify_mchanges>
administrators = <zope.interface.interface.Attribute object at 0x7f8c8d046f70 mailman.interfaces.mailinglist.IMailingList.administrators>
administrivia = <zope.interface.interface.Attribute object at 0x7f8c8d084be0 mailman.interfaces.mailinglist.IMailingList.administrivia>
advertised = <zope.interface.interface.Attribute object at 0x7f8c8cfd6b20 mailman.interfaces.mailinglist.IMailingList.advertised>
allow_list_posts = <zope.interface.interface.Attribute object at 0x7f8c8cfd6970 mailman.interfaces.mailinglist.IMailingList.allow_list_posts>
anonymous_list = <zope.interface.interface.Attribute object at 0x7f8c8cfd6ca0 mailman.interfaces.mailinglist.IMailingList.anonymous_list>
archive_policy = <zope.interface.interface.Attribute object at 0x7f8c8d01b400 mailman.interfaces.mailinglist.IMailingList.archive_policy>
archive_rendering_mode = <zope.interface.interface.Attribute object at 0x7f8c8d0c6cd0 mailman.interfaces.mailinglist.IMailingList.archive_rendering_mode>
autorespond_owner = <zope.interface.interface.Attribute object at 0x7f8c8d0106a0 mailman.interfaces.mailinglist.IMailingList.autorespond_owner>
autorespond_postings = <zope.interface.interface.Attribute object at 0x7f8c8d010100 mailman.interfaces.mailinglist.IMailingList.autorespond_postings>
autorespond_requests = <zope.interface.interface.Attribute object at 0x7f8c8d010190 mailman.interfaces.mailinglist.IMailingList.autorespond_requests>
autoresponse_grace_period = <zope.interface.interface.Attribute object at 0x7f8c8d010640 mailman.interfaces.mailinglist.IMailingList.autoresponse_grace_period>
autoresponse_owner_text = <zope.interface.interface.Attribute object at 0x7f8c8d010610 mailman.interfaces.mailinglist.IMailingList.autoresponse_owner_text>
autoresponse_postings_text = <zope.interface.interface.Attribute object at 0x7f8c8d010070 mailman.interfaces.mailinglist.IMailingList.autoresponse_postings_text>
autoresponse_request_text = <zope.interface.interface.Attribute object at 0x7f8c8d0100a0 mailman.interfaces.mailinglist.IMailingList.autoresponse_request_text>
bounce_info_stale_after = <zope.interface.interface.Attribute object at 0x7f8c8d084820 mailman.interfaces.mailinglist.IMailingList.bounce_info_stale_after>
bounce_notify_owner_on_bounce_increment = <zope.interface.interface.Attribute object at 0x7f8c8d0847c0 mailman.interfaces.mailinglist.IMailingList.bounce_notify_owner_on_bounce_increment>
bounce_notify_owner_on_disable = <zope.interface.interface.Attribute object at 0x7f8c8d084760 mailman.interfaces.mailinglist.IMailingList.bounce_notify_owner_on_disable>
bounce_notify_owner_on_removal = <zope.interface.interface.Attribute object at 0x7f8c8d084700 mailman.interfaces.mailinglist.IMailingList.bounce_notify_owner_on_removal>
bounce_score_threshold = <zope.interface.interface.Attribute object at 0x7f8c8d084640 mailman.interfaces.mailinglist.IMailingList.bounce_score_threshold>
bounce_you_are_disabled_warnings = <zope.interface.interface.Attribute object at 0x7f8c8d0c6a60 mailman.interfaces.mailinglist.IMailingList.bounce_you_are_disabled_warnings>
bounce_you_are_disabled_warnings_interval = <zope.interface.interface.Attribute object at 0x7f8c8d0c6520 mailman.interfaces.mailinglist.IMailingList.bounce_you_are_disabled_warnings_interval>
bounces_address = <zope.interface.interface.Attribute object at 0x7f8c8cfd6610 mailman.interfaces.mailinglist.IMailingList.bounces_address>
collapse_alternatives = <zope.interface.interface.Attribute object at 0x7f8c8d084e80 mailman.interfaces.mailinglist.IMailingList.collapse_alternatives>
confirm_address(cookie='')

The address used for various forms of email confirmation.

convert_html_to_plaintext = <zope.interface.interface.Attribute object at 0x7f8c8d084d60 mailman.interfaces.mailinglist.IMailingList.convert_html_to_plaintext>
created_at = <zope.interface.interface.Attribute object at 0x7f8c8cfeed60 mailman.interfaces.mailinglist.IMailingList.created_at>
data_path = <zope.interface.interface.Attribute object at 0x7f8c8d084a60 mailman.interfaces.mailinglist.IMailingList.data_path>
default_member_action = <zope.interface.interface.Attribute object at 0x7f8c8d084d90 mailman.interfaces.mailinglist.IMailingList.default_member_action>
default_nonmember_action = <zope.interface.interface.Attribute object at 0x7f8c8d084850 mailman.interfaces.mailinglist.IMailingList.default_nonmember_action>
description = <zope.interface.interface.Attribute object at 0x7f8c8cfd6220 mailman.interfaces.mailinglist.IMailingList.description>
digest_last_sent_at = <zope.interface.interface.Attribute object at 0x7f8c8d010370 mailman.interfaces.mailinglist.IMailingList.digest_last_sent_at>
digest_members = <zope.interface.interface.Attribute object at 0x7f8c8d01b730 mailman.interfaces.mailinglist.IMailingList.digest_members>
digest_send_periodic = <zope.interface.interface.Attribute object at 0x7f8c8d010430 mailman.interfaces.mailinglist.IMailingList.digest_send_periodic>
digest_size_threshold = <zope.interface.interface.Attribute object at 0x7f8c8d4accd0 mailman.interfaces.mailinglist.IMailingList.digest_size_threshold>
digest_volume_frequency = <zope.interface.interface.Attribute object at 0x7f8c8d0103d0 mailman.interfaces.mailinglist.IMailingList.digest_volume_frequency>
digests_enabled = <zope.interface.interface.Attribute object at 0x7f8c8d457c40 mailman.interfaces.mailinglist.IMailingList.digests_enabled>
display_name = <zope.interface.interface.Attribute object at 0x7f8c8cfd61f0 mailman.interfaces.mailinglist.IMailingList.display_name>
dmarc_mitigate_action = <zope.interface.interface.Attribute object at 0x7f8c8d046790 mailman.interfaces.mailinglist.IMailingList.dmarc_mitigate_action>
dmarc_mitigate_unconditionally = <zope.interface.interface.Attribute object at 0x7f8c8d0468b0 mailman.interfaces.mailinglist.IMailingList.dmarc_mitigate_unconditionally>
dmarc_moderation_notice = <zope.interface.interface.Attribute object at 0x7f8c8d0468e0 mailman.interfaces.mailinglist.IMailingList.dmarc_moderation_notice>
dmarc_wrapped_message_text = <zope.interface.interface.Attribute object at 0x7f8c8d046c70 mailman.interfaces.mailinglist.IMailingList.dmarc_wrapped_message_text>
domain = <zope.interface.interface.Attribute object at 0x7f8c8cfd61c0 mailman.interfaces.mailinglist.IMailingList.domain>
filter_action = <zope.interface.interface.Attribute object at 0x7f8c8d084c40 mailman.interfaces.mailinglist.IMailingList.filter_action>
filter_content = <zope.interface.interface.Attribute object at 0x7f8c8d084cd0 mailman.interfaces.mailinglist.IMailingList.filter_content>
filter_extensions = <zope.interface.interface.Attribute object at 0x7f8c8d084fd0 mailman.interfaces.mailinglist.IMailingList.filter_extensions>
filter_types = <zope.interface.interface.Attribute object at 0x7f8c8d084df0 mailman.interfaces.mailinglist.IMailingList.filter_types>
forward_unrecognized_bounces_to = <zope.interface.interface.Attribute object at 0x7f8c8d0c6490 mailman.interfaces.mailinglist.IMailingList.forward_unrecognized_bounces_to>
fqdn_listname = <zope.interface.interface.Attribute object at 0x7f8c8cfd6160 mailman.interfaces.mailinglist.IMailingList.fqdn_listname>
gateway_to_mail = <zope.interface.interface.Attribute object at 0x7f8c8d0c68e0 mailman.interfaces.mailinglist.IMailingList.gateway_to_mail>
gateway_to_news = <zope.interface.interface.Attribute object at 0x7f8c8d0c6970 mailman.interfaces.mailinglist.IMailingList.gateway_to_news>
get_roster(role)

Return the appropriate roster for the given role.

Parameters:role (MemberRole) – The requested roster’s role.
Returns:The requested roster.
Return type:Roster
include_rfc2369_headers = <zope.interface.interface.Attribute object at 0x7f8c8cfd6c70 mailman.interfaces.mailinglist.IMailingList.include_rfc2369_headers>
info = <zope.interface.interface.Attribute object at 0x7f8c8cfd6280 mailman.interfaces.mailinglist.IMailingList.info>
is_subscribed(subscriber, role=<MemberRole.member: 1>)

Is the given address or user subscribed to the mailing list?

Parameters:
  • subscriber (IUser or IAddress) – The address or user to check.
  • role (MemberRole) – The role being checked (e.g. a member, owner, or moderator of a mailing list).
Returns:

A flag indicating whether the subscriber is already subscribed to the mailing list or not.

join_address = <zope.interface.interface.Attribute object at 0x7f8c8d046d30 mailman.interfaces.mailinglist.IMailingList.join_address>
last_digest_recipients = <zope.interface.interface.Attribute object at 0x7f8c8d0102b0 mailman.interfaces.mailinglist.IMailingList.last_digest_recipients>
last_post_at = <zope.interface.interface.Attribute object at 0x7f8c8d01b3d0 mailman.interfaces.mailinglist.IMailingList.last_post_at>
leave_address = <zope.interface.interface.Attribute object at 0x7f8c8d046be0 mailman.interfaces.mailinglist.IMailingList.leave_address>
linked_newsgroup = <zope.interface.interface.Attribute object at 0x7f8c8d0c6b50 mailman.interfaces.mailinglist.IMailingList.linked_newsgroup>
list_id = <zope.interface.interface.Attribute object at 0x7f8c8cfd6100 mailman.interfaces.mailinglist.IMailingList.list_id>
list_name = <zope.interface.interface.Attribute object at 0x7f8c8d03ba90 mailman.interfaces.mailinglist.IMailingList.list_name>
mail_host = <zope.interface.interface.Attribute object at 0x7f8c8cfd6a00 mailman.interfaces.mailinglist.IMailingList.mail_host>
member_roster_visibility = <zope.interface.interface.Attribute object at 0x7f8c8d438340 mailman.interfaces.mailinglist.IMailingList.member_roster_visibility>
members = <zope.interface.interface.Attribute object at 0x7f8c8d01b580 mailman.interfaces.mailinglist.IMailingList.members>
moderators = <zope.interface.interface.Attribute object at 0x7f8c8d046fd0 mailman.interfaces.mailinglist.IMailingList.moderators>
newsgroup_moderation = <zope.interface.interface.Attribute object at 0x7f8c8d0c6e80 mailman.interfaces.mailinglist.IMailingList.newsgroup_moderation>
next_digest_number = <zope.interface.interface.Attribute object at 0x7f8c8d0101f0 mailman.interfaces.mailinglist.IMailingList.next_digest_number>
nntp_prefix_subject_too = <zope.interface.interface.Attribute object at 0x7f8c8d0c6f10 mailman.interfaces.mailinglist.IMailingList.nntp_prefix_subject_too>
no_reply_address = <zope.interface.interface.Attribute object at 0x7f8c8cfd6af0 mailman.interfaces.mailinglist.IMailingList.no_reply_address>
nonmembers = <zope.interface.interface.Attribute object at 0x7f8c8d01b820 mailman.interfaces.mailinglist.IMailingList.nonmembers>
owner_address = <zope.interface.interface.Attribute object at 0x7f8c8cfd6a30 mailman.interfaces.mailinglist.IMailingList.owner_address>
owner_chain = <zope.interface.interface.Attribute object at 0x7f8c8d0849d0 mailman.interfaces.mailinglist.IMailingList.owner_chain>
owner_pipeline = <zope.interface.interface.Attribute object at 0x7f8c8d084940 mailman.interfaces.mailinglist.IMailingList.owner_pipeline>
owners = <zope.interface.interface.Attribute object at 0x7f8c8d046b20 mailman.interfaces.mailinglist.IMailingList.owners>
pass_extensions = <zope.interface.interface.Attribute object at 0x7f8c8d084f70 mailman.interfaces.mailinglist.IMailingList.pass_extensions>
pass_types = <zope.interface.interface.Attribute object at 0x7f8c8d084ee0 mailman.interfaces.mailinglist.IMailingList.pass_types>
personalize = <zope.interface.interface.Attribute object at 0x7f8c8d01b2e0 mailman.interfaces.mailinglist.IMailingList.personalize>
post_id = <zope.interface.interface.Attribute object at 0x7f8c8d01b370 mailman.interfaces.mailinglist.IMailingList.post_id>
posting_address = <zope.interface.interface.Attribute object at 0x7f8c8cfd6b50 mailman.interfaces.mailinglist.IMailingList.posting_address>
posting_chain = <zope.interface.interface.Attribute object at 0x7f8c8d084a30 mailman.interfaces.mailinglist.IMailingList.posting_chain>
posting_pipeline = <zope.interface.interface.Attribute object at 0x7f8c8d084d30 mailman.interfaces.mailinglist.IMailingList.posting_pipeline>
preferred_language = <zope.interface.interface.Attribute object at 0x7f8c8cfd62e0 mailman.interfaces.mailinglist.IMailingList.preferred_language>
process_bounces = <zope.interface.interface.Attribute object at 0x7f8c8d0c6880 mailman.interfaces.mailinglist.IMailingList.process_bounces>
regular_members = <zope.interface.interface.Attribute object at 0x7f8c8d01b5e0 mailman.interfaces.mailinglist.IMailingList.regular_members>
reply_goes_to_list = <zope.interface.interface.Attribute object at 0x7f8c8d438820 mailman.interfaces.mailinglist.IMailingList.reply_goes_to_list>
request_address = <zope.interface.interface.Attribute object at 0x7f8c8cfd69d0 mailman.interfaces.mailinglist.IMailingList.request_address>
require_explicit_destination = <zope.interface.interface.Attribute object at 0x7f8c8d084b80 mailman.interfaces.mailinglist.IMailingList.require_explicit_destination>
send_goodbye_message = <zope.interface.interface.Attribute object at 0x7f8c8d0c6610 mailman.interfaces.mailinglist.IMailingList.send_goodbye_message>
send_one_last_digest_to(address, delivery_mode)

Make sure to send one last digest to an address.

This is used when a person transitions from digest delivery to regular delivery and wants to make sure they don’t miss anything. By indicating that they’d like to receive one last digest, they will ensure continuity in receiving mailing lists posts.

Parameters:
  • address (IAddress) – The address of the person receiving one last digest.
  • delivery_mode (DeliveryMode) – The type of digest to receive.
send_welcome_message = <zope.interface.interface.Attribute object at 0x7f8c8d0c6730 mailman.interfaces.mailinglist.IMailingList.send_welcome_message>
subject_prefix = <zope.interface.interface.Attribute object at 0x7f8c8cfd66d0 mailman.interfaces.mailinglist.IMailingList.subject_prefix>
subscribe(subscriber, role=<MemberRole.member: 1>)

Subscribe the given address or user to the mailing list.

Parameters:
  • subscriber (IUser or IAddress) – The address or user to subscribe to the mailing list. The user’s preferred address receives deliveries, if she has one, otherwise no address for the user appears in the rosters.
  • role (MemberRole) – The role being subscribed to (e.g. a member, owner, or moderator of a mailing list).
Returns:

The member object representing the subscription.

Return type:

IMember

Raises:
  • AlreadySubscribedError – If the address or user is already subscribed to the mailing list with the given role. Note however that it is possible to subscribe an address to a mailing list with a particular role, and also subscribe a user with a matching preferred address that is explicitly subscribed with the same role.
  • InvalidEmailAddressError – If the address being subscribed is the list’s posting address.
subscribe_address = <zope.interface.interface.Attribute object at 0x7f8c8d046a30 mailman.interfaces.mailinglist.IMailingList.subscribe_address>
subscribers = <zope.interface.interface.Attribute object at 0x7f8c8d01b4c0 mailman.interfaces.mailinglist.IMailingList.subscribers>
subscription_policy = <zope.interface.interface.Attribute object at 0x7f8c8d01bb50 mailman.interfaces.mailinglist.IMailingList.subscription_policy>
unsubscribe_address = <zope.interface.interface.Attribute object at 0x7f8c8d0467c0 mailman.interfaces.mailinglist.IMailingList.unsubscribe_address>
unsubscription_policy = <zope.interface.interface.Attribute object at 0x7f8c8d01ba00 mailman.interfaces.mailinglist.IMailingList.unsubscription_policy>
usenet_watermark = <zope.interface.interface.Attribute object at 0x7f8c8d0c6e50 mailman.interfaces.mailinglist.IMailingList.usenet_watermark>
volume = <zope.interface.interface.Attribute object at 0x7f8c8d010280 mailman.interfaces.mailinglist.IMailingList.volume>