diff options
Diffstat (limited to 'src/mailman/docs/addresses.txt')
| -rw-r--r-- | src/mailman/docs/addresses.txt | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/src/mailman/docs/addresses.txt b/src/mailman/docs/addresses.txt new file mode 100644 index 000000000..9eccb2673 --- /dev/null +++ b/src/mailman/docs/addresses.txt @@ -0,0 +1,231 @@ +Email addresses +=============== + +Addresses represent a text email address, along with some meta data about +those addresses, such as their registration date, and whether and when they've +been validated. Addresses may be linked to the users that Mailman knows +about. Addresses are subscribed to mailing lists though members. + + >>> usermgr = config.db.user_manager + + +Creating addresses +------------------ + +Addresses are created directly through the user manager, which starts out with +no addresses. + + >>> sorted(address.address for address in usermgr.addresses) + [] + +Creating an unlinked email address is straightforward. + + >>> address_1 = usermgr.create_address(u'aperson@example.com') + >>> sorted(address.address for address in usermgr.addresses) + [u'aperson@example.com'] + +However, such addresses have no real name. + + >>> address_1.real_name + u'' + +You can also create an email address object with a real name. + + >>> address_2 = usermgr.create_address( + ... u'bperson@example.com', u'Ben Person') + >>> sorted(address.address for address in usermgr.addresses) + [u'aperson@example.com', u'bperson@example.com'] + >>> sorted(address.real_name for address in usermgr.addresses) + [u'', u'Ben Person'] + +The str() of the address is the RFC 2822 preferred originator format, while +the repr() carries more information. + + >>> str(address_2) + 'Ben Person <bperson@example.com>' + >>> repr(address_2) + '<Address: Ben Person <bperson@example.com> [not verified] at 0x...>' + +You can assign real names to existing addresses. + + >>> address_1.real_name = u'Anne Person' + >>> sorted(address.real_name for address in usermgr.addresses) + [u'Anne Person', u'Ben Person'] + +These addresses are not linked to users, and can be seen by searching the user +manager for an associated user. + + >>> print usermgr.get_user(u'aperson@example.com') + None + >>> print usermgr.get_user(u'bperson@example.com') + None + +You can create email addresses that are linked to users by using a different +interface. + + >>> user_1 = usermgr.create_user(u'cperson@example.com', u'Claire Person') + >>> sorted(address.address for address in user_1.addresses) + [u'cperson@example.com'] + >>> sorted(address.address for address in usermgr.addresses) + [u'aperson@example.com', u'bperson@example.com', u'cperson@example.com'] + >>> sorted(address.real_name for address in usermgr.addresses) + [u'Anne Person', u'Ben Person', u'Claire Person'] + +And now you can find the associated user. + + >>> print usermgr.get_user(u'aperson@example.com') + None + >>> print usermgr.get_user(u'bperson@example.com') + None + >>> usermgr.get_user(u'cperson@example.com') + <User "Claire Person" at ...> + + +Deleting addresses +------------------ + +You can remove an unlinked address from the user manager. + + >>> usermgr.delete_address(address_1) + >>> sorted(address.address for address in usermgr.addresses) + [u'bperson@example.com', u'cperson@example.com'] + >>> sorted(address.real_name for address in usermgr.addresses) + [u'Ben Person', u'Claire Person'] + +Deleting a linked address does not delete the user, but it does unlink the +address from the user. + + >>> sorted(address.address for address in user_1.addresses) + [u'cperson@example.com'] + >>> user_1.controls(u'cperson@example.com') + True + >>> address_3 = list(user_1.addresses)[0] + >>> usermgr.delete_address(address_3) + >>> sorted(address.address for address in user_1.addresses) + [] + >>> user_1.controls(u'cperson@example.com') + False + >>> sorted(address.address for address in usermgr.addresses) + [u'bperson@example.com'] + + +Registration and validation +--------------------------- + +Addresses have two dates, the date the address was registered on and the date +the address was validated on. Neither date is set by default. + + >>> address_4 = usermgr.create_address( + ... u'dperson@example.com', u'Dan Person') + >>> print address_4.registered_on + None + >>> print address_4.verified_on + None + +The registered date takes a Python datetime object. + + >>> from datetime import datetime + >>> address_4.registered_on = datetime(2007, 5, 8, 22, 54, 1) + >>> print address_4.registered_on + 2007-05-08 22:54:01 + >>> print address_4.verified_on + None + +And of course, you can also set the validation date. + + >>> address_4.verified_on = datetime(2007, 5, 13, 22, 54, 1) + >>> print address_4.registered_on + 2007-05-08 22:54:01 + >>> print address_4.verified_on + 2007-05-13 22:54:01 + + +Subscriptions +------------- + +Addresses get subscribed to mailing lists, not users. When the address is +subscribed, a role is specified. + + >>> address_5 = usermgr.create_address( + ... u'eperson@example.com', u'Elly Person') + >>> mlist = config.db.list_manager.create(u'_xtext@example.com') + >>> from mailman.interfaces.member import MemberRole + >>> address_5.subscribe(mlist, MemberRole.owner) + <Member: Elly Person <eperson@example.com> on + _xtext@example.com as MemberRole.owner> + >>> address_5.subscribe(mlist, MemberRole.member) + <Member: Elly Person <eperson@example.com> on + _xtext@example.com as MemberRole.member> + +Now Elly is both an owner and a member of the mailing list. + + >>> sorted(mlist.owners.members) + [<Member: Elly Person <eperson@example.com> on + _xtext@example.com as MemberRole.owner>] + >>> sorted(mlist.moderators.members) + [] + >>> sorted(mlist.administrators.members) + [<Member: Elly Person <eperson@example.com> on + _xtext@example.com as MemberRole.owner>] + >>> sorted(mlist.members.members) + [<Member: Elly Person <eperson@example.com> on + _xtext@example.com as MemberRole.member>] + >>> sorted(mlist.regular_members.members) + [<Member: Elly Person <eperson@example.com> on + _xtext@example.com as MemberRole.member>] + >>> sorted(mlist.digest_members.members) + [] + + +Case-preserved addresses +------------------------ + +Technically speaking, email addresses are case sensitive in the local part. +Mailman preserves the case of addresses and uses the case preserved version +when sending the user a message, but it treats addresses that are different in +case equivalently in all other situations. + + >>> address_6 = usermgr.create_address( + ... u'FPERSON@example.com', u'Frank Person') + +The str() of such an address prints the RFC 2822 preferred originator format +with the original case-preserved address. The repr() contains all the gory +details. + + >>> str(address_6) + 'Frank Person <FPERSON@example.com>' + >>> repr(address_6) + '<Address: Frank Person <FPERSON@example.com> [not verified] + key: fperson@example.com at 0x...>' + +Both the case-insensitive version of the address and the original +case-preserved version are available on attributes of the IAddress object. + + >>> address_6.address + u'fperson@example.com' + >>> address_6.original_address + u'FPERSON@example.com' + +Because addresses are case-insensitive for all other purposes, you cannot +create an address that differs only in case. + + >>> usermgr.create_address(u'fperson@example.com') + Traceback (most recent call last): + ... + ExistingAddressError: FPERSON@example.com + >>> usermgr.create_address(u'fperson@EXAMPLE.COM') + Traceback (most recent call last): + ... + ExistingAddressError: FPERSON@example.com + >>> usermgr.create_address(u'FPERSON@example.com') + Traceback (most recent call last): + ... + ExistingAddressError: FPERSON@example.com + +You can get the address using either the lower cased version or case-preserved +version. In fact, searching for an address is case insensitive. + + >>> usermgr.get_address(u'fperson@example.com').address + u'fperson@example.com' + >>> usermgr.get_address(u'FPERSON@example.com').address + u'fperson@example.com' |
