summaryrefslogtreecommitdiff
path: root/src/mailman/model
diff options
context:
space:
mode:
authorBarry Warsaw2011-01-01 11:28:29 -0500
committerBarry Warsaw2011-01-01 11:28:29 -0500
commit3f1f5a2826feb9c5fb202ae266ba7f0ff76ebe21 (patch)
tree1bab06750e306942180b18383c06ad2804f98677 /src/mailman/model
parentd0f8e9e03d3c55641165b73a4d8971ec514a9cdc (diff)
downloadmailman-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.py20
-rw-r--r--src/mailman/model/docs/addresses.txt133
-rw-r--r--src/mailman/model/docs/membership.txt18
-rw-r--r--src/mailman/model/docs/registration.txt23
-rw-r--r--src/mailman/model/docs/requests.txt6
-rw-r--r--src/mailman/model/docs/usermanager.txt65
-rw-r--r--src/mailman/model/docs/users.txt50
-rw-r--r--src/mailman/model/member.py2
-rw-r--r--src/mailman/model/roster.py4
-rw-r--r--src/mailman/model/user.py22
-rw-r--r--src/mailman/model/usermanager.py37
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: