diff options
| author | Barry Warsaw | 2007-06-18 10:50:23 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2007-06-18 10:50:23 -0400 |
| commit | 511a33778c4195c4abca7c58aa6917e6a77059b6 (patch) | |
| tree | 5bffc7a5793a8247310294ac86931741e73b1fc5 /Mailman/docs | |
| parent | f0e3b3934d5d458cadd814eeae07277b58650180 (diff) | |
| download | mailman-511a33778c4195c4abca7c58aa6917e6a77059b6.tar.gz mailman-511a33778c4195c4abca7c58aa6917e6a77059b6.tar.zst mailman-511a33778c4195c4abca7c58aa6917e6a77059b6.zip | |
Remove both the model and interface for RosterSets. These are no longer used
or necessary in the current data model.
Convert the test_handlers.py Python test to an acknowledge.txt doctest, and
make the Acknowledge.py handler work with the new data model. There are a few
XXX comments left in here due to the fact that the web stuff is a total hack
in the current branch currently.
Added IMailingListWeb methods and properties to the MailingList model class:
web_host and script_url().
Work out how IMembers will expose the lookup-order based preferences. By
getting the attribute IMember.preferences you can see exactly the preferences
overridden by this member. To use the lookup order, use
IMember.delivery_mode, IMember.acknowledge_posts, etc. IOW, the IMember
interface now provides the properties directly and access through this
mechanism supports lookup order with definitive preference values.
Also added IMember.unsubscribe() which does the obvious, and
IMember.options_url() which is a total hack for providing a url (but not the
ultimately right one) for the user's option page.
Refactor the model's roster classes. Also added IRoster.get_member() method
with efficient queries to return the right results. Make
AdministratorRoster.members more efficient due to a better query.
Update the membership.txt doctest to eliminate a chance ordering effect, and
also to test finding members with .get_member(). The clean up section uses
the new .unsubscribe() method.
Diffstat (limited to 'Mailman/docs')
| -rw-r--r-- | Mailman/docs/acknowledge.txt | 176 | ||||
| -rw-r--r-- | Mailman/docs/membership.txt | 67 |
2 files changed, 238 insertions, 5 deletions
diff --git a/Mailman/docs/acknowledge.txt b/Mailman/docs/acknowledge.txt new file mode 100644 index 000000000..6c7e3c28f --- /dev/null +++ b/Mailman/docs/acknowledge.txt @@ -0,0 +1,176 @@ +Message acknowledgment +====================== + +When a user posts a message to a mailing list, and that user has chosen to +receive acknowledgments of their postings, Mailman will sent them such an +acknowledgment. + + >>> from email import message_from_string + >>> from Mailman.Message import Message + >>> from Mailman.Handlers.Acknowledge import process + >>> from Mailman.configuration import config + >>> from Mailman.database import flush + >>> mlist = config.list_manager.create('_xtest@example.com') + >>> mlist.real_name = 'XTest' + >>> # XXX This will almost certainly change once we've worked out the web + >>> # space layout for mailing lists now. + >>> mlist._data.web_page_url = 'http://lists.example.com/' + >>> flush() + + >>> # Ensure that the virgin queue is empty, since we'll be checking this + >>> # for new auto-response messages. + >>> from Mailman.Queue.sbcache import get_switchboard + >>> virginq = get_switchboard(config.VIRGINQUEUE_DIR) + >>> virginq.files() + [] + +Subscribe a user to the mailing list. + + >>> from Mailman.constants import MemberRole + >>> user_1 = config.user_manager.create_user('aperson@example.com') + >>> address_1 = list(user_1.addresses)[0] + >>> address_1.subscribe(mlist, MemberRole.member) + <Member: aperson@example.com on _xtest@example.com as MemberRole.member> + >>> flush() + + +Non-member posts +---------------- + +Non-members can't get acknowledgments of their posts to the mailing list. + + >>> msg = message_from_string("""\ + ... From: bperson@example.com + ... + ... """, Message) + >>> process(mlist, msg, {}) + >>> virginq.files() + [] + +We can also specify the original sender in the message's metadata. If that +person is also not a member, no acknowledgment will be sent either. + + >>> msg = message_from_string("""\ + ... From: bperson@example.com + ... + ... """, Message) + >>> process(mlist, msg, dict(original_sender='cperson@example.com')) + >>> virginq.files() + [] + + +No acknowledgment requested +--------------------------- + +Unless the user has requested acknowledgments, they will not get one. + + >>> msg = message_from_string("""\ + ... From: aperson@example.com + ... + ... """, Message) + >>> process(mlist, msg, {}) + >>> virginq.files() + [] + +Similarly if the original sender is specified in the message metadata, and +that sender is a member but not one who has requested acknowledgments, none +will be sent. + + >>> user_2 = config.user_manager.create_user('dperson@example.com') + >>> address_2 = list(user_2.addresses)[0] + >>> address_2.subscribe(mlist, MemberRole.member) + <Member: dperson@example.com on _xtest@example.com as MemberRole.member> + >>> flush() + + >>> process(mlist, msg, dict(original_sender='dperson@example.com')) + >>> virginq.files() + [] + + +Requested acknowledgments +------------------------- + +If the member requests acknowledgments, Mailman will send them one when they +post to the mailing list. + + >>> user_1.preferences.acknowledge_posts = True + >>> flush() + +The receipt will include the original message's subject in the response body, + + >>> msg = message_from_string("""\ + ... From: aperson@example.com + ... Subject: Something witty and insightful + ... + ... """, Message) + >>> process(mlist, msg, {}) + + >>> len(virginq.files()) + 1 + >>> qmsg, qdata = virginq.dequeue(virginq.files()[0]) + >>> virginq.files() + [] + >>> # Print only some of the meta data. The rest is uninteresting. + >>> qdata['listname'] + '_xtest@example.com' + >>> qdata['recips'] + ['aperson@example.com'] + >>> print qmsg.as_string() + MIME-Version: 1.0 + Content-Type: text/plain; charset="us-ascii" + Content-Transfer-Encoding: 7bit + Subject: XTest post acknowledgment + From: _xtest-bounces@example.com + To: aperson@example.com + Message-ID: ... + Date: ... + Precedence: bulk + <BLANKLINE> + Your message entitled + <BLANKLINE> + Something witty and insightful + <BLANKLINE> + was successfully received by the XTest mailing list. + <BLANKLINE> + List info page: http://lists.example.com/listinfo/_xtest@example.com + Your preferences: http://example.com/aperson@example.com + <BLANKLINE> + +If there is no subject, then the receipt will use a generic message. + + >>> msg = message_from_string("""\ + ... From: aperson@example.com + ... + ... """, Message) + >>> process(mlist, msg, {}) + + >>> len(virginq.files()) + 1 + >>> qmsg, qdata = virginq.dequeue(virginq.files()[0]) + >>> virginq.files() + [] + >>> # Print only some of the meta data. The rest is uninteresting. + >>> qdata['listname'] + '_xtest@example.com' + >>> qdata['recips'] + ['aperson@example.com'] + >>> print qmsg.as_string() + MIME-Version: 1.0 + Content-Type: text/plain; charset="us-ascii" + Content-Transfer-Encoding: 7bit + Subject: XTest post acknowledgment + From: _xtest-bounces@example.com + To: aperson@example.com + Message-ID: ... + Date: ... + Precedence: bulk + <BLANKLINE> + Your message entitled + <BLANKLINE> + (no subject) + <BLANKLINE> + was successfully received by the XTest mailing list. + <BLANKLINE> + List info page: http://lists.example.com/listinfo/_xtest@example.com + Your preferences: http://example.com/aperson@example.com + <BLANKLINE> diff --git a/Mailman/docs/membership.txt b/Mailman/docs/membership.txt index 36b1508a8..9b6465d4a 100644 --- a/Mailman/docs/membership.txt +++ b/Mailman/docs/membership.txt @@ -168,12 +168,15 @@ Claire will be a regular delivery member but not a digest member. It's easy to make the list administrators members of the mailing list too. + >>> members = [] >>> for address in mlist.administrators.addresses: - ... address.subscribe(mlist, MemberRole.member) - <Member: Ben Person <bperson@example.com> on - _xtest@example.com as MemberRole.member> - <Member: Anne Person <aperson@example.com> on - _xtest@example.com as MemberRole.member> + ... member = address.subscribe(mlist, MemberRole.member) + ... members.append(member) + >>> sorted(members, key=lambda m: m.address.address) + [<Member: Anne Person <aperson@example.com> on + _xtest@example.com as MemberRole.member>, + <Member: Ben Person <bperson@example.com> on + _xtest@example.com as MemberRole.member>] >>> flush() >>> sorted(address.address for address in mlist.members.addresses) ['aperson@example.com', 'bperson@example.com', 'cperson@example.com'] @@ -181,3 +184,57 @@ It's easy to make the list administrators members of the mailing list too. ['aperson@example.com', 'bperson@example.com', 'cperson@example.com'] >>> sorted(address.address for address in mlist.digest_members.addresses) [] + + +Finding members +--------------- + +You can find the IMember object that is a member of a roster for a given text +email address by using an IRoster's .get_member() method. + + >>> mlist.owners.get_member('aperson@example.com') + <Member: Anne Person <aperson@example.com> on + _xtest@example.com as MemberRole.owner> + >>> mlist.administrators.get_member('aperson@example.com') + <Member: Anne Person <aperson@example.com> on + _xtest@example.com as MemberRole.owner> + >>> mlist.members.get_member('aperson@example.com') + <Member: Anne Person <aperson@example.com> on + _xtest@example.com as MemberRole.member> + +However, if the address is not subscribed with the appropriate role, then None +is returned. + + >>> print mlist.administrators.get_member('zperson@example.com') + None + >>> print mlist.moderators.get_member('aperson@example.com') + None + >>> print mlist.members.get_member('zperson@example.com') + None + + +Clean up +-------- + + >>> for member in mlist.members.members: + ... member.unsubscribe() + >>> for admin in mlist.administrators.members: + ... admin.unsubscribe() + >>> flush() + >>> list(mlist.members.members) + [] + >>> list(mlist.administrators.members) + [] + >>> for user in config.user_manager.users: + ... config.user_manager.delete_user(user) + >>> for address in config.user_manager.addresses: + ... config.user_manager.delete_address(address) + >>> for mlist in config.list_manager.mailing_lists: + ... config.list_manager.delete(mlist) + >>> flush() + >>> list(config.user_manager.users) + [] + >>> list(config.user_manager.addresses) + [] + >>> list(config.list_manager.mailing_lists) + [] |
