summaryrefslogtreecommitdiff
path: root/src/mailman/model/docs/mailinglist.rst
blob: 53ba99575da3337b8451d67c8e02b67d9154cee6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
=============
Mailing lists
=============

.. XXX 2010-06-18 BAW: This documentation needs a lot more detail.

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`_.

    >>> 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.

    >>> for member in mlist.members.members:
    ...     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 mlist.owners.members:
    ...     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 roster.members:
    ...     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 roster.members:
    ...     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.
::

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

    >>> mlist.subscribe(user)
    <Member: Dave Person <dperson@example.com> on aardvark@example.com
             as MemberRole.member>
    >>> for member in mlist.members.members:
    ...     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>

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

    >>> for member in mlist.members.members:
    ...     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 not allowed to subscribe more than once to the mailing list.

    >>> mlist.subscribe(user)
    Traceback (most recent call last):
    ...
    AlreadySubscribedError: <User "Dave Person" (1) at ...>
    is already a MemberRole.member of mailing list aardvark@example.com

However, they are allowed to 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>

A user cannot subscribe to a mailing list without a preferred address.

    >>> user = user_manager.create_user('eperson@example.com', 'Elly Person')
    >>> address = list(user.addresses)[0]
    >>> address.verified_on = now()
    >>> mlist.subscribe(user)
    Traceback (most recent call last):
    ...
    MissingPreferredAddressError: User must have a preferred address:
    <User "Elly Person" (2) at ...>


.. _`RFC 2369`: http://www.faqs.org/rfcs/rfc2369.html