diff options
| author | Barry Warsaw | 2011-01-01 11:28:29 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2011-01-01 11:28:29 -0500 |
| commit | 3f1f5a2826feb9c5fb202ae266ba7f0ff76ebe21 (patch) | |
| tree | 1bab06750e306942180b18383c06ad2804f98677 /src/mailman/model | |
| parent | d0f8e9e03d3c55641165b73a4d8971ec514a9cdc (diff) | |
| download | mailman-3f1f5a2826feb9c5fb202ae266ba7f0ff76ebe21.tar.gz mailman-3f1f5a2826feb9c5fb202ae266ba7f0ff76ebe21.tar.zst mailman-3f1f5a2826feb9c5fb202ae266ba7f0ff76ebe21.zip | |
Because it was just to damn confusing, rename IAddress.address to
IAddress.email and IAddress.original_address to IAddress.original_email. From
now on we'll use "address" to talk about the IAddress object and "email" to
talk about the textual email address.
Diffstat (limited to 'src/mailman/model')
| -rw-r--r-- | src/mailman/model/address.py | 20 | ||||
| -rw-r--r-- | src/mailman/model/docs/addresses.txt | 133 | ||||
| -rw-r--r-- | src/mailman/model/docs/membership.txt | 18 | ||||
| -rw-r--r-- | src/mailman/model/docs/registration.txt | 23 | ||||
| -rw-r--r-- | src/mailman/model/docs/requests.txt | 6 | ||||
| -rw-r--r-- | src/mailman/model/docs/usermanager.txt | 65 | ||||
| -rw-r--r-- | src/mailman/model/docs/users.txt | 50 | ||||
| -rw-r--r-- | src/mailman/model/member.py | 2 | ||||
| -rw-r--r-- | src/mailman/model/roster.py | 4 | ||||
| -rw-r--r-- | src/mailman/model/user.py | 22 | ||||
| -rw-r--r-- | src/mailman/model/usermanager.py | 37 |
11 files changed, 203 insertions, 177 deletions
diff --git a/src/mailman/model/address.py b/src/mailman/model/address.py index 6209858a8..d2b87e5b6 100644 --- a/src/mailman/model/address.py +++ b/src/mailman/model/address.py @@ -41,7 +41,7 @@ class Address(Model): implements(IAddress) id = Int(primary=True) - address = Unicode() + email = Unicode() _original = Unicode() real_name = Unicode() verified_on = DateTime() @@ -52,15 +52,15 @@ class Address(Model): preferences_id = Int() preferences = Reference(preferences_id, 'Preferences.id') - def __init__(self, address, real_name): + def __init__(self, email, real_name): super(Address, self).__init__() - lower_case = address.lower() - self.address = lower_case + lower_case = email.lower() + self.email = lower_case self.real_name = real_name - self._original = (None if lower_case == address else address) + self._original = (None if lower_case == email else email) def __str__(self): - addr = (self.address if self._original is None else self._original) + addr = (self.email if self._original is None else self._original) return formataddr((self.real_name, addr)) def __repr__(self): @@ -71,7 +71,7 @@ class Address(Model): address_str, verified, id(self)) else: return '<Address: {0} [{1}] key: {2} at {3:#x}>'.format( - address_str, verified, self.address, id(self)) + address_str, verified, self.email, id(self)) def subscribe(self, mailing_list, role): # This member has no preferences by default. @@ -83,7 +83,7 @@ class Address(Model): Member.address == self).one() if member: raise AlreadySubscribedError( - mailing_list.fqdn_listname, self.address, role) + mailing_list.fqdn_listname, self.email, role) member = Member(role=role, mailing_list=mailing_list.fqdn_listname, address=self) @@ -92,5 +92,5 @@ class Address(Model): return member @property - def original_address(self): - return (self.address if self._original is None else self._original) + def original_email(self): + return (self.email if self._original is None else self._original) diff --git a/src/mailman/model/docs/addresses.txt b/src/mailman/model/docs/addresses.txt index aeddb5e31..0ddacb321 100644 --- a/src/mailman/model/docs/addresses.txt +++ b/src/mailman/model/docs/addresses.txt @@ -18,42 +18,45 @@ Creating addresses Addresses are created directly through the user manager, which starts out with no addresses. - >>> sorted(address.address for address in user_manager.addresses) - [] + >>> dump_list(address.email for address in user_manager.addresses) + *Empty* Creating an unlinked email address is straightforward. >>> address_1 = user_manager.create_address('aperson@example.com') - >>> sorted(address.address for address in user_manager.addresses) - [u'aperson@example.com'] + >>> dump_list(address.email for address in user_manager.addresses) + aperson@example.com However, such addresses have no real name. - >>> address_1.real_name - u'' + >>> print address_1.real_name + <BLANKLINE> You can also create an email address object with a real name. >>> address_2 = user_manager.create_address( ... 'bperson@example.com', 'Ben Person') - >>> sorted(address.address for address in user_manager.addresses) - [u'aperson@example.com', u'bperson@example.com'] - >>> sorted(address.real_name for address in user_manager.addresses) - [u'', u'Ben Person'] + >>> dump_list(address.email for address in user_manager.addresses) + aperson@example.com + bperson@example.com + >>> dump_list(address.real_name for address in user_manager.addresses) + <BLANKLINE> + 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...>' + >>> print str(address_2) + Ben Person <bperson@example.com> + >>> print 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 = 'Anne Person' - >>> sorted(address.real_name for address in user_manager.addresses) - [u'Anne Person', u'Ben Person'] + >>> dump_list(address.real_name for address in user_manager.addresses) + Anne Person + Ben Person These addresses are not linked to users, and can be seen by searching the user manager for an associated user. @@ -68,12 +71,16 @@ interface. >>> user_1 = user_manager.create_user( ... '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 user_manager.addresses) - [u'aperson@example.com', u'bperson@example.com', u'cperson@example.com'] - >>> sorted(address.real_name for address in user_manager.addresses) - [u'Anne Person', u'Ben Person', u'Claire Person'] + >>> dump_list(address.email for address in user_1.addresses) + cperson@example.com + >>> dump_list(address.email for address in user_manager.addresses) + aperson@example.com + bperson@example.com + cperson@example.com + >>> dump_list(address.real_name for address in user_manager.addresses) + Anne Person + Ben Person + Claire Person And now you can find the associated user. @@ -91,26 +98,28 @@ Deleting addresses You can remove an unlinked address from the user manager. >>> user_manager.delete_address(address_1) - >>> sorted(address.address for address in user_manager.addresses) - [u'bperson@example.com', u'cperson@example.com'] - >>> sorted(address.real_name for address in user_manager.addresses) - [u'Ben Person', u'Claire Person'] + >>> dump_list(address.email for address in user_manager.addresses) + bperson@example.com + cperson@example.com + >>> dump_list(address.real_name for address in user_manager.addresses) + Ben Person + 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'] + >>> dump_list(address.email for address in user_1.addresses) + cperson@example.com >>> user_1.controls('cperson@example.com') True >>> address_3 = list(user_1.addresses)[0] >>> user_manager.delete_address(address_3) - >>> sorted(address.address for address in user_1.addresses) - [] + >>> dump_list(address.email for address in user_1.addresses) + *Empty* >>> user_1.controls('cperson@example.com') False - >>> sorted(address.address for address in user_manager.addresses) - [u'bperson@example.com'] + >>> dump_list(address.email for address in user_manager.addresses) + bperson@example.com Registration and validation @@ -153,34 +162,36 @@ subscribed, a role is specified. >>> address_5 = user_manager.create_address( ... 'eperson@example.com', 'Elly Person') - >>> mlist = create_list('_xtext@example.com') + >>> mlist = create_list('test@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> + test@example.com as MemberRole.owner> >>> address_5.subscribe(mlist, MemberRole.member) <Member: Elly Person <eperson@example.com> on - _xtext@example.com as MemberRole.member> + test@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) - [] + >>> def memberkey(member): + ... return member.mailing_list, member.address.email, int(member.role) + >>> dump_list(mlist.owners.members, key=memberkey) + <Member: Elly Person <eperson@example.com> on + test@example.com as MemberRole.owner> + >>> dump_list(mlist.moderators.members, key=memberkey) + *Empty* + >>> dump_list(mlist.administrators.members, key=memberkey) + <Member: Elly Person <eperson@example.com> on + test@example.com as MemberRole.owner> + >>> dump_list(mlist.members.members, key=memberkey) + <Member: Elly Person <eperson@example.com> on + test@example.com as MemberRole.member> + >>> dump_list(mlist.regular_members.members, key=memberkey) + <Member: Elly Person <eperson@example.com> on + test@example.com as MemberRole.member> + >>> dump_list(mlist.digest_members.members, key=memberkey) + *Empty* Case-preserved addresses @@ -198,18 +209,18 @@ 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...>' + >>> print str(address_6) + Frank Person <FPERSON@example.com> + >>> print 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. +case-preserved version are available on attributes of the `IAddress` object. - >>> print address_6.address + >>> print address_6.email fperson@example.com - >>> print address_6.original_address + >>> print address_6.original_email FPERSON@example.com Because addresses are case-insensitive for all other purposes, you cannot @@ -231,7 +242,7 @@ create an address that differs only in case. You can get the address using either the lower cased version or case-preserved version. In fact, searching for an address is case insensitive. - >>> print user_manager.get_address('fperson@example.com').address + >>> print user_manager.get_address('fperson@example.com').email fperson@example.com - >>> print user_manager.get_address('FPERSON@example.com').address + >>> print user_manager.get_address('FPERSON@example.com').email fperson@example.com diff --git a/src/mailman/model/docs/membership.txt b/src/mailman/model/docs/membership.txt index ebf1b6ebf..00e79d733 100644 --- a/src/mailman/model/docs/membership.txt +++ b/src/mailman/model/docs/membership.txt @@ -85,7 +85,7 @@ Now, both Anne and Bart are list administrators. >>> from operator import attrgetter >>> def dump_members(roster): ... all_addresses = list(member.address for member in roster) - ... sorted_addresses = sorted(all_addresses, key=attrgetter('address')) + ... sorted_addresses = sorted(all_addresses, key=attrgetter('email')) ... dump_list(sorted_addresses) >>> dump_members(mlist.administrators.members) @@ -121,7 +121,7 @@ It's easy to make the list administrators members of the mailing list too. >>> for address in mlist.administrators.addresses: ... member = address.subscribe(mlist, MemberRole.member) ... members.append(member) - >>> dump_list(members, key=attrgetter('address.address')) + >>> dump_list(members, key=attrgetter('address.email')) <Member: Anne Person <aperson@example.com> on test@example.com as MemberRole.member> <Member: Bart Person <bperson@example.com> on @@ -211,9 +211,9 @@ There is also a roster containing all the subscribers of a mailing list, regardless of their role. >>> def sortkey(member): - ... return (member.address.address, int(member.role)) + ... return (member.address.email, int(member.role)) >>> for member in sorted(mlist.subscribers.members, key=sortkey): - ... print member.address.address, member.role + ... print member.address.email, member.role aperson@example.com MemberRole.member aperson@example.com MemberRole.owner bperson@example.com MemberRole.member @@ -242,8 +242,8 @@ postings from that member are handled. By default, owners and moderators are automatically accepted for posting to the mailing list. >>> for member in sorted(mlist.administrators.members, - ... key=attrgetter('address.address')): - ... print member.address.address, member.role, member.moderation_action + ... key=attrgetter('address.email')): + ... print member.address.email, member.role, member.moderation_action aperson@example.com MemberRole.owner Action.accept bperson@example.com MemberRole.moderator Action.accept @@ -251,8 +251,8 @@ By default, members have a *deferred* action which specifies that the posting should go through the normal moderation checks. >>> for member in sorted(mlist.members.members, - ... key=attrgetter('address.address')): - ... print member.address.address, member.role, member.moderation_action + ... key=attrgetter('address.email')): + ... print member.address.email, member.role, member.moderation_action aperson@example.com MemberRole.member Action.defer bperson@example.com MemberRole.member Action.defer cperson@example.com MemberRole.member Action.defer @@ -260,5 +260,5 @@ should go through the normal moderation checks. Postings by nonmembers are held for moderator approval by default. >>> for member in mlist.nonmembers.members: - ... print member.address.address, member.role, member.moderation_action + ... print member.address.email, member.role, member.moderation_action fperson@example.com MemberRole.nonmember Action.hold diff --git a/src/mailman/model/docs/registration.txt b/src/mailman/model/docs/registration.txt index 050a4d0f3..e92c63f52 100644 --- a/src/mailman/model/docs/registration.txt +++ b/src/mailman/model/docs/registration.txt @@ -100,7 +100,7 @@ But this address is waiting for confirmation. >>> pendingdb = getUtility(IPendings) >>> dump_msgdata(pendingdb.confirm(token, expunge=False)) - address : aperson@example.com + email : aperson@example.com list_name: alpha@example.com real_name: Anne Person type : registration @@ -178,8 +178,8 @@ token and uses that to confirm the pending registration. >>> registrar.confirm(token) True -Now, there is an ``IAddress`` in the database matching the address, as well as -an ``IUser`` linked to this address. The ``IAddress`` is verified. +Now, there is an `IAddress` in the database matching the address, as well as +an `IUser` linked to this address. The `IAddress` is verified. >>> found_address = user_manager.get_address('aperson@example.com') >>> found_address @@ -187,7 +187,7 @@ an ``IUser`` linked to this address. The ``IAddress`` is verified. >>> found_user = user_manager.get_user('aperson@example.com') >>> found_user <User "Anne Person" at ...> - >>> found_user.controls(found_address.address) + >>> found_user.controls(found_address.email) True >>> from datetime import datetime >>> isinstance(found_address.verified_on, datetime) @@ -247,8 +247,7 @@ Discarding ========== A confirmation token can also be discarded, say if the user changes his or her -mind about registering. When discarded, no ``IAddress`` or ``IUser`` is -created. +mind about registering. When discarded, no `IAddress` or `IUser` is created. :: >>> token = registrar.register(mlist, 'eperson@example.com', 'Elly Person') @@ -282,8 +281,8 @@ can be used. >>> address.verified_on = datetime.now() >>> from operator import attrgetter - >>> sorted((addr for addr in dperson.addresses), key=attrgetter('address')) - [<Address: Dave Person <dperson@example.com> [verified] at ...>] + >>> dump_list(repr(address) for address in dperson.addresses) + <Address: Dave Person <dperson@example.com> [verified] at ...> >>> dperson.register('david.person@example.com', 'David Person') <Address: David Person <david.person@example.com> [not verified] at ...> >>> token = registrar.register(mlist, 'david.person@example.com') @@ -299,9 +298,9 @@ can be used. True >>> user <User "Dave Person" at ...> - >>> sorted((addr for addr in user.addresses), key=attrgetter('address')) - [<Address: David Person <david.person@example.com> [verified] at ...>, - <Address: Dave Person <dperson@example.com> [verified] at ...>] + >>> dump_list(repr(address) for address in user.addresses) + <Address: Dave Person <dperson@example.com> [verified] at ...> + <Address: David Person <david.person@example.com> [verified] at ...> Corner cases @@ -313,7 +312,7 @@ confirm method will just return False. >>> registrar.confirm(bytes('no token')) False -Likewise, if you try to confirm, through the ``IUserRegistrar`` interface, a +Likewise, if you try to confirm, through the `IUserRegistrar` interface, a token that doesn't match a registration event, you will get ``None``. However, the pending event matched with that token will still be removed. diff --git a/src/mailman/model/docs/requests.txt b/src/mailman/model/docs/requests.txt index 6cca8f602..94c81e1dc 100644 --- a/src/mailman/model/docs/requests.txt +++ b/src/mailman/model/docs/requests.txt @@ -56,8 +56,8 @@ The list's requests database starts out empty. >>> requests.count 0 - >>> list(requests.held_requests) - [] + >>> dump_list(requests.held_requests) + *Empty* At the lowest level, the requests database is very simple. Holding a request requires a request type (as an enum value), a key, and an optional dictionary @@ -697,7 +697,7 @@ Frank Person is now a member of the mailing list. >>> from zope.component import getUtility >>> user_manager = getUtility(IUserManager) - >>> user = user_manager.get_user(member.address.address) + >>> user = user_manager.get_user(member.address.email) >>> print user.real_name Frank Person >>> print user.password diff --git a/src/mailman/model/docs/usermanager.txt b/src/mailman/model/docs/usermanager.txt index a6bd4fed2..7b333248c 100644 --- a/src/mailman/model/docs/usermanager.txt +++ b/src/mailman/model/docs/usermanager.txt @@ -24,10 +24,10 @@ have a password. >>> verifyObject(IUser, user) True - >>> sorted(address.address for address in user.addresses) - [] - >>> user.real_name - u'' + >>> dump_list(address.email for address in user.addresses) + *Empty* + >>> print user.real_name + <BLANKLINE> >>> print user.password None @@ -39,52 +39,59 @@ The user has preferences, but none of them will be specified. A user can be assigned a real name. >>> user.real_name = 'Anne Person' - >>> sorted(user.real_name for user in user_manager.users) - [u'Anne Person'] + >>> dump_list(user.real_name for user in user_manager.users) + Anne Person A user can be assigned a password. >>> user.password = 'secret' - >>> sorted(user.password for user in user_manager.users) - [u'secret'] + >>> dump_list(user.password for user in user_manager.users) + secret You can also create a user with an address to start out with. >>> user_2 = user_manager.create_user('bperson@example.com') >>> verifyObject(IUser, user_2) True - >>> sorted(address.address for address in user_2.addresses) - [u'bperson@example.com'] - >>> sorted(user.real_name for user in user_manager.users) - [u'', u'Anne Person'] + >>> dump_list(address.email for address in user_2.addresses) + bperson@example.com + >>> dump_list(user.real_name for user in user_manager.users) + <BLANKLINE> + Anne Person As above, you can assign a real name to such users. >>> user_2.real_name = 'Ben Person' - >>> sorted(user.real_name for user in user_manager.users) - [u'Anne Person', u'Ben Person'] + >>> dump_list(user.real_name for user in user_manager.users) + Anne Person + Ben Person You can also create a user with just a real name. >>> user_3 = user_manager.create_user(real_name='Claire Person') >>> verifyObject(IUser, user_3) True - >>> sorted(address.address for address in user.addresses) - [] - >>> sorted(user.real_name for user in user_manager.users) - [u'Anne Person', u'Ben Person', u'Claire Person'] + >>> dump_list(address.email for address in user.addresses) + *Empty* + >>> dump_list(user.real_name for user in user_manager.users) + Anne Person + Ben Person + Claire Person Finally, you can create a user with both an address and a real name. >>> user_4 = user_manager.create_user('dperson@example.com', 'Dan Person') >>> verifyObject(IUser, user_3) True - >>> sorted(address.address for address in user_4.addresses) - [u'dperson@example.com'] - >>> sorted(address.real_name for address in user_4.addresses) - [u'Dan Person'] - >>> sorted(user.real_name for user in user_manager.users) - [u'Anne Person', u'Ben Person', u'Claire Person', u'Dan Person'] + >>> dump_list(address.email for address in user_4.addresses) + dperson@example.com + >>> dump_list(address.real_name for address in user_4.addresses) + Dan Person + >>> dump_list(user.real_name for user in user_manager.users) + Anne Person + Ben Person + Claire Person + Dan Person Deleting users @@ -94,8 +101,10 @@ You delete users by going through the user manager. The deleted user is no longer available through the user manager iterator. >>> user_manager.delete_user(user) - >>> sorted(user.real_name for user in user_manager.users) - [u'Ben Person', u'Claire Person', u'Dan Person'] + >>> dump_list(user.real_name for user in user_manager.users) + Ben Person + Claire Person + Dan Person Finding users @@ -107,7 +116,7 @@ that the ``.get_user()`` method takes a string email address, not an ``IAddress`` object. >>> address = list(user_4.addresses)[0] - >>> found_user = user_manager.get_user(address.address) + >>> found_user = user_manager.get_user(address.email) >>> found_user <User "Dan Person" at ...> >>> found_user is user_4 @@ -119,5 +128,5 @@ with it, you will get ``None`` back. >>> print user_manager.get_user('zperson@example.com') None >>> user_4.unlink(address) - >>> print user_manager.get_user(address.address) + >>> print user_manager.get_user(address.email) None diff --git a/src/mailman/model/docs/users.txt b/src/mailman/model/docs/users.txt index b36c250f9..bbfef8391 100644 --- a/src/mailman/model/docs/users.txt +++ b/src/mailman/model/docs/users.txt @@ -21,19 +21,19 @@ Users may have a real name and a password. >>> user_1 = user_manager.create_user() >>> user_1.password = 'my password' >>> user_1.real_name = 'Zoe Person' - >>> sorted(user.real_name for user in user_manager.users) - [u'Zoe Person'] - >>> sorted(user.password for user in user_manager.users) - [u'my password'] + >>> dump_list(user.real_name for user in user_manager.users) + Zoe Person + >>> dump_list(user.password for user in user_manager.users) + my password The password and real name can be changed at any time. >>> user_1.real_name = 'Zoe X. Person' >>> user_1.password = 'another password' - >>> sorted(user.real_name for user in user_manager.users) - [u'Zoe X. Person'] - >>> sorted(user.password for user in user_manager.users) - [u'another password'] + >>> dump_list(user.real_name for user in user_manager.users) + Zoe X. Person + >>> dump_list(user.password for user in user_manager.users) + another password Users addresses @@ -50,19 +50,25 @@ address on a user object. <Address: Zoe Person <zperson@example.com> [not verified] at 0x...> >>> user_1.register('zperson@example.org') <Address: zperson@example.org [not verified] at 0x...> - >>> sorted(address.address for address in user_1.addresses) - [u'zperson@example.com', u'zperson@example.org'] - >>> sorted(address.real_name for address in user_1.addresses) - [u'', u'Zoe Person'] + >>> dump_list(address.email for address in user_1.addresses) + zperson@example.com + zperson@example.org + >>> dump_list(address.real_name for address in user_1.addresses) + <BLANKLINE> + Zoe Person You can also create the address separately and then link it to the user. >>> address_1 = user_manager.create_address('zperson@example.net') >>> user_1.link(address_1) - >>> sorted(address.address for address in user_1.addresses) - [u'zperson@example.com', u'zperson@example.net', u'zperson@example.org'] - >>> sorted(address.real_name for address in user_1.addresses) - [u'', u'', u'Zoe Person'] + >>> dump_list(address.email for address in user_1.addresses) + zperson@example.com + zperson@example.net + zperson@example.org + >>> dump_list(address.real_name for address in user_1.addresses) + <BLANKLINE> + <BLANKLINE> + Zoe Person But don't try to link an address to more than one user. @@ -74,7 +80,7 @@ But don't try to link an address to more than one user. You can also ask whether a given user controls a given address. - >>> user_1.controls(address_1.address) + >>> user_1.controls(address_1.email) True >>> user_1.controls('bperson@example.com') False @@ -163,8 +169,10 @@ membership role. :: >>> user_1.link(address_1) - >>> sorted(address.address for address in user_1.addresses) - [u'zperson@example.com', u'zperson@example.net', u'zperson@example.org'] + >>> dump_list(address.email for address in user_1.addresses) + zperson@example.com + zperson@example.net + zperson@example.org >>> com = user_manager.get_address('zperson@example.com') >>> org = user_manager.get_address('zperson@example.org') >>> net = user_manager.get_address('zperson@example.net') @@ -194,10 +202,10 @@ membership role. >>> len(members) 4 >>> def sortkey(member): - ... return (member.address.address, member.mailing_list, + ... return (member.address.email, member.mailing_list, ... int(member.role)) >>> for member in sorted(members, key=sortkey): - ... print member.address.address, member.mailing_list, member.role + ... print member.address.email, member.mailing_list, member.role zperson@example.com xtest_1@example.com MemberRole.member zperson@example.net xtest_3@example.com MemberRole.moderator zperson@example.org xtest_2@example.com MemberRole.member diff --git a/src/mailman/model/member.py b/src/mailman/model/member.py index 5dde5c629..8723a3ca4 100644 --- a/src/mailman/model/member.py +++ b/src/mailman/model/member.py @@ -110,7 +110,7 @@ class Member(Model): @property def options_url(self): # XXX Um, this is definitely wrong - return 'http://example.com/' + self.address.address + return 'http://example.com/' + self.address.email def unsubscribe(self): config.db.store.remove(self.preferences) diff --git a/src/mailman/model/roster.py b/src/mailman/model/roster.py index 89ef98531..2b098ff54 100644 --- a/src/mailman/model/roster.py +++ b/src/mailman/model/roster.py @@ -99,7 +99,7 @@ class AbstractRoster: Member, Member.mailing_list == self._mlist.fqdn_listname, Member.role == self.role, - Address.address == address, + Address.email == address, Member.address_id == Address.id) if results.count() == 0: return None @@ -169,7 +169,7 @@ class AdministratorRoster(AbstractRoster): Member.mailing_list == self._mlist.fqdn_listname, Or(Member.role == MemberRole.moderator, Member.role == MemberRole.owner), - Address.address == address, + Address.email == address, Member.address_id == Address.id) if results.count() == 0: return None diff --git a/src/mailman/model/user.py b/src/mailman/model/user.py index 327a3b184..9aa751ea1 100644 --- a/src/mailman/model/user.py +++ b/src/mailman/model/user.py @@ -66,28 +66,28 @@ class User(Model): raise AddressNotLinkedError(address) address.user = None - def controls(self, address): + def controls(self, email): """See `IUser`.""" - found = config.db.store.find(Address, address=address) + found = config.db.store.find(Address, email=email) if found.count() == 0: return False assert found.count() == 1, 'Unexpected count' return found[0].user is self - def register(self, address, real_name=None): + def register(self, email, real_name=None): """See `IUser`.""" # First, see if the address already exists - addrobj = config.db.store.find(Address, address=address).one() - if addrobj is None: + address = config.db.store.find(Address, email=email).one() + if address is None: if real_name is None: real_name = '' - addrobj = Address(address=address, real_name=real_name) - addrobj.preferences = Preferences() + address = Address(email=email, real_name=real_name) + address.preferences = Preferences() # Link the address to the user if it is not already linked. - if addrobj.user is not None: - raise AddressAlreadyLinkedError(addrobj) - addrobj.user = self - return addrobj + if address.user is not None: + raise AddressAlreadyLinkedError(address) + address.user = self + return address @property def memberships(self): diff --git a/src/mailman/model/usermanager.py b/src/mailman/model/usermanager.py index da12ba33c..11e9ad24e 100644 --- a/src/mailman/model/usermanager.py +++ b/src/mailman/model/usermanager.py @@ -39,13 +39,12 @@ from mailman.model.user import User class UserManager: implements(IUserManager) - def create_user(self, address=None, real_name=None): + def create_user(self, email=None, real_name=None): user = User() user.real_name = ('' if real_name is None else real_name) - if address: - addrobj = Address(address, user.real_name) - addrobj.preferences = Preferences() - user.link(addrobj) + if email: + address = self.create_address(email, real_name) + user.link(address) user.preferences = Preferences() config.db.store.add(user) return user @@ -53,13 +52,8 @@ class UserManager: def delete_user(self, user): config.db.store.remove(user) - @property - def users(self): - for user in config.db.store.find(User): - yield user - - def get_user(self, address): - addresses = config.db.store.find(Address, address=address.lower()) + def get_user(self, email): + addresses = config.db.store.find(Address, email=email.lower()) if addresses.count() == 0: return None elif addresses.count() == 1: @@ -67,17 +61,22 @@ class UserManager: else: raise AssertionError('Unexpected query count') - def create_address(self, address, real_name=None): - addresses = config.db.store.find(Address, address=address.lower()) + @property + def users(self): + for user in config.db.store.find(User): + yield user + + def create_address(self, email, real_name=None): + addresses = config.db.store.find(Address, email=email.lower()) if addresses.count() == 1: found = addresses[0] - raise ExistingAddressError(found.original_address) + raise ExistingAddressError(found.original_email) assert addresses.count() == 0, 'Unexpected results' if real_name is None: real_name = '' - # It's okay not to lower case the 'address' argument because the + # It's okay not to lower case the 'email' argument because the # constructor will do the right thing. - address = Address(address, real_name) + address = Address(email, real_name) address.preferences = Preferences() config.db.store.add(address) return address @@ -89,8 +88,8 @@ class UserManager: address.user.unlink(address) config.db.store.remove(address) - def get_address(self, address): - addresses = config.db.store.find(Address, address=address.lower()) + def get_address(self, email): + addresses = config.db.store.find(Address, email=email.lower()) if addresses.count() == 0: return None elif addresses.count() == 1: |
