summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Mailman/Handlers/Hold.py3
-rw-r--r--Mailman/app/membership.py6
-rw-r--r--Mailman/database/model/pending.py48
-rw-r--r--Mailman/database/model/requests.py8
-rw-r--r--Mailman/docs/hold.txt12
-rw-r--r--Mailman/docs/pending.txt16
-rw-r--r--Mailman/docs/registration.txt48
-rw-r--r--Mailman/docs/requests.txt106
8 files changed, 129 insertions, 118 deletions
diff --git a/Mailman/Handlers/Hold.py b/Mailman/Handlers/Hold.py
index 2e6eeb4ad..bef1fa24f 100644
--- a/Mailman/Handlers/Hold.py
+++ b/Mailman/Handlers/Hold.py
@@ -253,8 +253,7 @@ def hold_for_approval(mlist, msg, msgdata, exc):
#
# This message should appear to come from <list>-admin so as to handle any
# bounce processing that might be needed.
- pendable = HeldMessagePendable(type=HeldMessagePendable.PEND_KEY,
- id=str(id))
+ pendable = HeldMessagePendable(type=HeldMessagePendable.PEND_KEY, id=id)
token = config.db.pendings.add(pendable)
# Get the language to send the response in. If the sender is a member,
# then send it in the member's language, otherwise send it in the mailing
diff --git a/Mailman/app/membership.py b/Mailman/app/membership.py
index e950f790a..56ad59ca5 100644
--- a/Mailman/app/membership.py
+++ b/Mailman/app/membership.py
@@ -107,7 +107,7 @@ def add_member(mlist, address, realname, password, delivery_mode, language,
with i18n.using_language(mlist.preferred_language):
subject = _('$mlist.real_name subscription notification')
if isinstance(realname, unicode):
- realname = name.encode(Utils.GetCharSet(language), 'replace')
+ realname = realname.encode(Utils.GetCharSet(language), 'replace')
text = Utils.maketext(
'adminsubscribeack.txt',
{'listname' : mlist.real_name,
@@ -124,9 +124,7 @@ def send_welcome_message(mlist, address, language, delivery_mode, text=''):
else:
welcome = ''
# Find the IMember object which is subscribed to the mailing list, because
- # from there, we can get the member's options url. XXX we have to flush
- # the database here otherwise the get_member() call returns None.
- from Mailman.database import flush; flush()
+ # from there, we can get the member's options url.
member = mlist.members.get_member(address)
options_url = member.options_url
# Get the text from the template.
diff --git a/Mailman/database/model/pending.py b/Mailman/database/model/pending.py
index be180d7f2..3f3e2caa0 100644
--- a/Mailman/database/model/pending.py
+++ b/Mailman/database/model/pending.py
@@ -17,6 +17,7 @@
"""Implementations of the IPendable and IPending interfaces."""
+import sys
import time
import random
import hashlib
@@ -29,7 +30,7 @@ from zope.interface.verify import verifyObject
from Mailman.configuration import config
from Mailman.database import Model
from Mailman.interfaces import (
- IPendings, IPendable, IPendedKeyValue, IPended)
+ IPendable, IPended, IPendedKeyValue, IPendings)
@@ -45,6 +46,7 @@ class PendedKeyValue(Model):
id = Int(primary=True)
key = Unicode()
value = Unicode()
+ pended_id = Int()
class Pended(Model):
@@ -59,7 +61,7 @@ class Pended(Model):
id = Int(primary=True)
token = RawStr()
expiration_date = DateTime()
- key_values = ReferenceSet(id, PendedKeyValue.id)
+ key_values = ReferenceSet(id, PendedKeyValue.pended_id)
@@ -104,13 +106,20 @@ class Pendings(object):
key = unicode(key, 'utf-8')
if isinstance(value, str):
value = unicode(value, 'utf-8')
+ elif type(value) is int:
+ value = u'__builtin__.int\1%s' % value
+ elif type(value) is float:
+ value = u'__builtin__.float\1%s' % value
+ elif type(value) is bool:
+ value = u'__builtin__.bool\1%s' % value
keyval = PendedKeyValue(key=key, value=value)
pending.key_values.add(keyval)
config.db.store.add(pending)
return token
def confirm(self, token, expunge=True):
- pendings = config.db.store.find(Pended, token=token)
+ store = config.db.store
+ pendings = store.find(Pended, token=token)
if pendings.count() == 0:
return None
assert pendings.count() == 1, (
@@ -118,27 +127,32 @@ class Pendings(object):
pending = pendings[0]
pendable = UnpendedPendable()
# Find all PendedKeyValue entries that are associated with the pending
- # object's ID.
- q = PendedKeyValue.query.filter(
- PendedKeyValue.c.pended_id == Pended.c.id).filter(
- Pended.c.id == pending.id)
- for keyvalue in q.all():
- pendable[keyvalue.key] = keyvalue.value
+ # object's ID. Watch out for type conversions.
+ for keyvalue in store.find(PendedKeyValue,
+ PendedKeyValue.pended_id == pending.id):
+ if keyvalue.value is not None and '\1' in keyvalue.value:
+ typename, value = keyvalue.value.split('\1', 1)
+ package, classname = typename.rsplit('.', 1)
+ __import__(package)
+ module = sys.modules[package]
+ pendable[keyvalue.key] = getattr(module, classname)(value)
+ else:
+ pendable[keyvalue.key] = keyvalue.value
if expunge:
- keyvalue.delete()
+ store.remove(keyvalue)
if expunge:
- pending.delete()
+ store.remove(pending)
return pendable
def evict(self):
+ store = config.db.store
now = datetime.datetime.now()
- for pending in Pended.query.filter_by().all():
+ for pending in store.find(Pended):
if pending.expiration_date < now:
# Find all PendedKeyValue entries that are associated with the
# pending object's ID.
- q = PendedKeyValue.query.filter(
- PendedKeyValue.c.pended_id == Pended.c.id).filter(
- Pended.c.id == pending.id)
+ q = store.find(PendedKeyValue,
+ PendedKeyValue.pended_id == pending.id)
for keyvalue in q:
- keyvalue.delete()
- pending.delete()
+ store.remove(keyvalue)
+ store.remove(pending)
diff --git a/Mailman/database/model/requests.py b/Mailman/database/model/requests.py
index 0817388e3..64fff7c48 100644
--- a/Mailman/database/model/requests.py
+++ b/Mailman/database/model/requests.py
@@ -99,12 +99,12 @@ class ListRequests:
return result.key, data
def delete_request(self, request_id):
- result = _Request.get(request_id)
- if result is None:
+ request = config.db.store.get(_Request, request_id)
+ if request is None:
raise KeyError(request_id)
# Throw away the pended data.
- config.db.pendings.confirm(result.data_hash)
- result.delete()
+ config.db.pendings.confirm(request.data_hash)
+ config.db.store.remove(request)
diff --git a/Mailman/docs/hold.txt b/Mailman/docs/hold.txt
index 33c542d31..56a10206f 100644
--- a/Mailman/docs/hold.txt
+++ b/Mailman/docs/hold.txt
@@ -145,7 +145,7 @@ Suspicious headers are a way for Mailman to hold messages that match a
particular regular expression. This mostly historical feature is fairly
confusing to users, and the list attribute that controls this is misnamed.
- >>> mlist.bounce_matching_headers = 'From: .*person@(blah.)?example.com'
+ >>> mlist.bounce_matching_headers = u'From: .*person@(blah.)?example.com'
>>> msg = message_from_string("""\
... From: aperson@example.com
... To: _xtest@example.com
@@ -288,9 +288,9 @@ one to the original author.
of the body of the reply.
--...
>>> sorted(qdata.items())
- [('_parsemsg', False), ('listname', '_xtest@example.com'),
+ [('_parsemsg', False), ('listname', u'_xtest@example.com'),
('nodecorate', True), ('received_time', ...),
- ('recips', ['_xtest-owner@example.com']),
+ ('recips', [u'_xtest-owner@example.com']),
('reduced_list_headers', True),
('tomoderators', 1), ('version', 3)]
>>> qmsg, qdata = qfiles['aperson@example.com']
@@ -323,9 +323,9 @@ one to the original author.
<BLANKLINE>
<BLANKLINE>
>>> sorted(qdata.items())
- [('_parsemsg', False), ('listname', '_xtest@example.com'),
+ [('_parsemsg', False), ('listname', u'_xtest@example.com'),
('nodecorate', True), ('received_time', ...),
- ('recips', ['aperson@example.com']),
+ ('recips', [u'aperson@example.com']),
('reduced_list_headers', True), ('version', 3)]
In addition, the pending database is holding the original messages, waiting
@@ -344,7 +344,7 @@ first item is a type code and the second item is a message id.
... break
>>> data = config.db.pendings.confirm(cookie)
>>> sorted(data.items())
- [('id', '...'), ('type', 'held message')]
+ [(u'id', ...), (u'type', u'held message')]
The message itself is held in the message store.
diff --git a/Mailman/docs/pending.txt b/Mailman/docs/pending.txt
index be0050c0c..566cc2de6 100644
--- a/Mailman/docs/pending.txt
+++ b/Mailman/docs/pending.txt
@@ -44,11 +44,11 @@ returned.
None
>>> pendable = pendingdb.confirm(token)
>>> sorted(pendable.items())
- [('address', 'aperson@example.com'),
- ('language', 'en'),
- ('password', 'xyz'),
- ('realname', 'Anne Person'),
- ('type', 'subscription')]
+ [(u'address', u'aperson@example.com'),
+ (u'language', u'en'),
+ (u'password', u'xyz'),
+ (u'realname', u'Anne Person'),
+ (u'type', u'subscription')]
After confirmation, the token is no longer in the database.
@@ -68,10 +68,10 @@ expunge it.
>>> token_3 = pendingdb.add(event_3)
>>> pendable = pendingdb.confirm(token_1, expunge=False)
>>> pendable.items()
- [('type', 'one')]
+ [(u'type', u'one')]
>>> pendable = pendingdb.confirm(token_1, expunge=True)
>>> pendable.items()
- [('type', 'one')]
+ [(u'type', u'one')]
>>> pendable = pendingdb.confirm(token_1)
>>> print pendable
None
@@ -92,4 +92,4 @@ Every once in a while the pending database is cleared of old records.
None
>>> pendable = pendingdb.confirm(token_2)
>>> pendable.items()
- [('type', 'two')]
+ [(u'type', u'two')]
diff --git a/Mailman/docs/registration.txt b/Mailman/docs/registration.txt
index 1db60722e..9f699b966 100644
--- a/Mailman/docs/registration.txt
+++ b/Mailman/docs/registration.txt
@@ -120,9 +120,9 @@ But this address is waiting for confirmation.
>>> pendingdb = config.db.pendings
>>> sorted(pendingdb.confirm(token, expunge=False).items())
- [('address', 'aperson@example.com'),
- ('real_name', 'Anne Person'),
- ('type', 'registration')]
+ [(u'address', u'aperson@example.com'),
+ (u'real_name', u'Anne Person'),
+ (u'type', u'registration')]
Verification by email
@@ -174,7 +174,7 @@ message is sent to the user in order to verify the registered address.
[('_parsemsg', False),
('nodecorate', True),
('received_time', ...),
- ('recips', ['aperson@example.com']),
+ ('recips', [u'aperson@example.com']),
('reduced_list_headers', True),
('version', 3)]
@@ -206,10 +206,10 @@ extracts the token and uses that to confirm the pending registration.
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 = usermgr.get_address('aperson@example.com')
+ >>> found_address = usermgr.get_address(u'aperson@example.com')
>>> found_address
<Address: Anne Person <aperson@example.com> [verified] at ...>
- >>> found_user = usermgr.get_user('aperson@example.com')
+ >>> found_user = usermgr.get_user(u'aperson@example.com')
>>> found_user
<User "Anne Person" at ...>
>>> found_user.controls(found_address.address)
@@ -225,7 +225,7 @@ Non-standard registrations
If you try to confirm a registration token twice, of course only the first one
will work. The second one is ignored.
- >>> token = registrar.register('bperson@example.com')
+ >>> token = registrar.register(u'bperson@example.com')
>>> check_token(token)
ok
>>> filebase = switchboard.files[0]
@@ -243,25 +243,25 @@ If an address is in the system, but that address is not linked to a user yet
and the address is not yet validated, then no user is created until the
confirmation step is completed.
- >>> usermgr.create_address('cperson@example.com')
+ >>> usermgr.create_address(u'cperson@example.com')
<Address: cperson@example.com [not verified] at ...>
- >>> token = registrar.register('cperson@example.com', 'Claire Person')
- >>> print usermgr.get_user('cperson@example.com')
+ >>> token = registrar.register(u'cperson@example.com', u'Claire Person')
+ >>> print usermgr.get_user(u'cperson@example.com')
None
>>> filebase = switchboard.files[0]
>>> qmsg, qdata = switchboard.dequeue(filebase)
>>> switchboard.finish(filebase)
>>> registrar.confirm(token)
True
- >>> usermgr.get_user('cperson@example.com')
+ >>> usermgr.get_user(u'cperson@example.com')
<User "Claire Person" at ...>
- >>> usermgr.get_address('cperson@example.com')
+ >>> usermgr.get_address(u'cperson@example.com')
<Address: cperson@example.com [verified] at ...>
If an address being registered has already been verified, linked or not to a
user, then registration sends no confirmation.
- >>> print registrar.register('cperson@example.com')
+ >>> print registrar.register(u'cperson@example.com')
None
>>> len(switchboard.files)
0
@@ -269,15 +269,15 @@ user, then registration sends no confirmation.
But if the already verified address is not linked to a user, then a user is
created now and they are linked, with no confirmation necessary.
- >>> address = usermgr.create_address('dperson@example.com', 'Dave Person')
+ >>> address = usermgr.create_address(u'dperson@example.com', u'Dave Person')
>>> address.verified_on = datetime.now()
- >>> print usermgr.get_user('dperson@example.com')
+ >>> print usermgr.get_user(u'dperson@example.com')
None
- >>> print registrar.register('dperson@example.com')
+ >>> print registrar.register(u'dperson@example.com')
None
>>> len(switchboard.files)
0
- >>> usermgr.get_user('dperson@example.com')
+ >>> usermgr.get_user(u'dperson@example.com')
<User "Dave Person" at ...>
@@ -287,15 +287,15 @@ 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.
- >>> token = registrar.register('eperson@example.com', 'Elly Person')
+ >>> token = registrar.register(u'eperson@example.com', u'Elly Person')
>>> check_token(token)
ok
>>> registrar.discard(token)
>>> print pendingdb.confirm(token)
None
- >>> print usermgr.get_address('eperson@example.com')
+ >>> print usermgr.get_address(u'eperson@example.com')
None
- >>> print usermgr.get_user('eperson@example.com')
+ >>> print usermgr.get_user(u'eperson@example.com')
None
@@ -306,21 +306,21 @@ When a new address for an existing user is registered, there isn't too much
different except that the new address will still need to be verified before it
can be used.
- >>> dperson = usermgr.get_user('dperson@example.com')
+ >>> dperson = usermgr.get_user(u'dperson@example.com')
>>> dperson
<User "Dave Person" at ...>
>>> from operator import attrgetter
>>> sorted((addr for addr in dperson.addresses), key=attrgetter('address'))
[<Address: Dave Person <dperson@example.com> [verified] at ...>]
- >>> dperson.register('david.person@example.com', 'David Person')
+ >>> dperson.register(u'david.person@example.com', u'David Person')
<Address: David Person <david.person@example.com> [not verified] at ...>
- >>> token = registrar.register('david.person@example.com')
+ >>> token = registrar.register(u'david.person@example.com')
>>> filebase = switchboard.files[0]
>>> qmsg, qdata = switchboard.dequeue(filebase)
>>> switchboard.finish(filebase)
>>> registrar.confirm(token)
True
- >>> user = usermgr.get_user('david.person@example.com')
+ >>> user = usermgr.get_user(u'david.person@example.com')
>>> user is dperson
True
>>> user
diff --git a/Mailman/docs/requests.txt b/Mailman/docs/requests.txt
index 3ef272c9e..7a395ce94 100644
--- a/Mailman/docs/requests.txt
+++ b/Mailman/docs/requests.txt
@@ -108,7 +108,7 @@ We can hold requests with additional data.
2 RequestType.subscription hold_2 None
3 RequestType.unsubscription hold_3 None
4 RequestType.held_message hold_4 None
- 5 RequestType.held_message hold_5 [('bar', 'no'), ('foo', 'yes')]
+ 5 RequestType.held_message hold_5 [(u'bar', u'no'), (u'foo', u'yes')]
Getting requests
@@ -132,9 +132,9 @@ However, if we ask for a request that had data, we'd get it back now.
>>> key, data = requests.get_request(5)
>>> key
- 'hold_5'
+ u'hold_5'
>>> sorted(data.items())
- [('bar', 'no'), ('foo', 'yes')]
+ [(u'bar', u'no'), (u'foo', u'yes')]
If we ask for a request that is not in the database, we get None back.
@@ -151,14 +151,14 @@ over by type.
>>> requests.count_of(RequestType.held_message)
3
>>> for request in requests.of_type(RequestType.held_message):
- ... assert request.type is RequestType.held_message
+ ... assert request.request_type is RequestType.held_message
... key, data = requests.get_request(request.id)
... if data is not None:
... data = sorted(data.items())
... print request.id, key, data
1 hold_1 None
4 hold_4 None
- 5 hold_5 [('bar', 'no'), ('foo', 'yes')]
+ 5 hold_5 [(u'bar', u'no'), (u'foo', u'yes')]
Deleting requests
@@ -209,9 +209,9 @@ Holding messages
For this section, we need a mailing list and at least one message.
- >>> mlist = config.db.list_manager.create('alist@example.com')
- >>> mlist.preferred_language = 'en'
- >>> mlist.real_name = 'A Test List'
+ >>> mlist = config.db.list_manager.create(u'alist@example.com')
+ >>> mlist.preferred_language = u'en'
+ >>> mlist.real_name = u'A Test List'
>>> msg = message_from_string(u"""\
... From: aperson@example.org
... To: alist@example.com
@@ -234,7 +234,7 @@ We can also hold a message with some additional metadata.
>>> msgdata = dict(sender='aperson@example.com',
... approved=True,
... received_time=123.45)
- >>> id_2 = moderator.hold_message(mlist, msg, msgdata, 'Feeling ornery')
+ >>> id_2 = moderator.hold_message(mlist, msg, msgdata, u'Feeling ornery')
>>> requests.get_request(id_2) is not None
True
@@ -288,10 +288,10 @@ The message can be rejected, meaning it is bounced back to the sender.
<BLANKLINE>
>>> sorted(qdata.items())
[('_parsemsg', False),
- ('listname', 'alist@example.com'),
+ ('listname', u'alist@example.com'),
('nodecorate', True),
('received_time', ...),
- ('recips', ['aperson@example.org']),
+ ('recips', [u'aperson@example.org']),
('reduced_list_headers', True),
('version', 3)]
@@ -316,8 +316,8 @@ indicates that the message has been approved.
<BLANKLINE>
>>> sorted(qdata.items())
[('_parsemsg', False),
- ('adminapproved', True), ('approved', True),
- ('received_time', ...), ('sender', 'aperson@example.com'),
+ ('adminapproved', True), (u'approved', True),
+ (u'received_time', 123.45), (u'sender', u'aperson@example.com'),
('version', 3)]
In addition to any of the above dispositions, the message can also be
@@ -338,7 +338,7 @@ is deleted.
... """)
>>> id_4 = moderator.hold_message(mlist, msg, {}, 'Needs approval')
>>> moderator.handle_message(mlist, id_4, Action.discard)
- >>> msgs = config.db.message_store.get_messages_by_message_id('<12345>')
+ >>> msgs = config.db.message_store.get_messages_by_message_id(u'<12345>')
>>> list(msgs)
[]
@@ -347,7 +347,7 @@ the message store after disposition.
>>> id_4 = moderator.hold_message(mlist, msg, {}, 'Needs approval')
>>> moderator.handle_message(mlist, id_4, Action.discard, preserve=True)
- >>> msgs = config.db.message_store.get_messages_by_message_id('<12345>')
+ >>> msgs = config.db.message_store.get_messages_by_message_id(u'<12345>')
>>> msgs = list(msgs)
>>> len(msgs)
1
@@ -368,7 +368,7 @@ moderators.
>>> id_4 = moderator.hold_message(mlist, msg, {}, 'Needs approval')
>>> moderator.handle_message(mlist, id_4, Action.discard,
- ... forward=['zperson@example.com'])
+ ... forward=[u'zperson@example.com'])
>>> qmsg, qdata = dequeue()
>>> print qmsg.as_string()
Subject: Forward of moderated message
@@ -390,9 +390,9 @@ moderators.
Here's something important about our mailing list.
<BLANKLINE>
>>> sorted(qdata.items())
- [('_parsemsg', False), ('listname', 'alist@example.com'),
+ [('_parsemsg', False), ('listname', u'alist@example.com'),
('nodecorate', True), ('received_time', ...),
- ('recips', ['zperson@example.com']),
+ ('recips', [u'zperson@example.com']),
('reduced_list_headers', True), ('version', 3)]
@@ -408,8 +408,8 @@ chosing and their preferred language.
>>> from Mailman.interfaces import DeliveryMode
>>> mlist.admin_immed_notify = False
>>> id_3 = moderator.hold_subscription(mlist,
- ... 'bperson@example.org', 'Ben Person',
- ... '{NONE}abcxyz', DeliveryMode.regular, 'en')
+ ... u'bperson@example.org', u'Ben Person',
+ ... u'{NONE}abcxyz', DeliveryMode.regular, u'en')
>>> requests.get_request(id_3) is not None
True
@@ -427,10 +427,10 @@ queue when the message is held.
>>> mlist.admin_immed_notify = True
>>> # XXX This will almost certainly change once we've worked out the web
>>> # space layout for mailing lists now.
- >>> mlist.web_page_url = 'http://www.example.com/'
+ >>> mlist.web_page_url = u'http://www.example.com/'
>>> id_4 = moderator.hold_subscription(mlist,
- ... 'cperson@example.org', 'Claire Person',
- ... '{NONE}zyxcba', DeliveryMode.regular, 'en')
+ ... u'cperson@example.org', u'Claire Person',
+ ... u'{NONE}zyxcba', DeliveryMode.regular, u'en')
>>> requests.get_request(id_4) is not None
True
>>> qmsg, qdata = dequeue()
@@ -460,10 +460,10 @@ queue when the message is held.
<BLANKLINE>
>>> sorted(qdata.items())
[('_parsemsg', False),
- ('listname', 'alist@example.com'),
+ ('listname', u'alist@example.com'),
('nodecorate', True),
('received_time', ...),
- ('recips', ['alist-owner@example.com']),
+ ('recips', [u'alist-owner@example.com']),
('reduced_list_headers', True), ('tomoderators', True), ('version', 3)]
Once held, the moderator can select one of several dispositions. The most
@@ -513,10 +513,10 @@ subscriber.
alist-owner@example.com
<BLANKLINE>
>>> sorted(qdata.items())
- [('_parsemsg', False), ('listname', 'alist@example.com'),
+ [('_parsemsg', False), ('listname', u'alist@example.com'),
('nodecorate', True),
('received_time', ...),
- ('recips', ['cperson@example.org']),
+ ('recips', [u'cperson@example.org']),
('reduced_list_headers', True), ('version', 3)]
The subscription can also be accepted. This subscribes the address to the
@@ -524,8 +524,8 @@ mailing list.
>>> mlist.send_welcome_msg = True
>>> id_4 = moderator.hold_subscription(mlist,
- ... 'fperson@example.org', 'Frank Person',
- ... '{NONE}abcxyz', DeliveryMode.regular, 'en')
+ ... u'fperson@example.org', u'Frank Person',
+ ... u'{NONE}abcxyz', DeliveryMode.regular, u'en')
A message will be sent to the moderators telling them about the held
subscription and the fact that they may need to approve it.
@@ -556,9 +556,9 @@ subscription and the fact that they may need to approve it.
to process the request.
<BLANKLINE>
>>> sorted(qdata.items())
- [('_parsemsg', False), ('listname', 'alist@example.com'),
+ [('_parsemsg', False), ('listname', u'alist@example.com'),
('nodecorate', True), ('received_time', ...),
- ('recips', ['alist-owner@example.com']),
+ ('recips', [u'alist-owner@example.com']),
('reduced_list_headers', True), ('tomoderators', True), ('version', 3)]
Accept the subscription request.
@@ -626,9 +626,9 @@ The welcome message is sent to the person who just subscribed.
options page that will send your current password to you.
<BLANKLINE>
>>> sorted(welcome_qdata.items())
- [('_parsemsg', False), ('listname', 'alist@example.com'),
+ [('_parsemsg', False), ('listname', u'alist@example.com'),
('nodecorate', True), ('received_time', ...),
- ('recips', ['fperson@example.org']),
+ ('recips', [u'fperson@example.org']),
('reduced_list_headers', True), ('verp', False), ('version', 3)]
The admin message is sent to the moderators.
@@ -649,25 +649,25 @@ The admin message is sent to the moderators.
<BLANKLINE>
>>> sorted(admin_qdata.items())
[('_parsemsg', False), ('envsender', 'changeme@example.com'),
- ('listname', 'alist@example.com'),
+ ('listname', u'alist@example.com'),
('nodecorate', True), ('received_time', ...),
('recips', []), ('reduced_list_headers', True), ('version', 3)]
Frank Person is now a member of the mailing list.
- >>> member = mlist.members.get_member('fperson@example.org')
+ >>> member = mlist.members.get_member(u'fperson@example.org')
>>> member
<Member: Frank Person <fperson@example.org>
on alist@example.com as MemberRole.member>
>>> member.preferred_language
- 'en'
+ u'en'
>>> print member.delivery_mode
DeliveryMode.regular
>>> user = config.db.user_manager.get_user(member.address.address)
>>> user.real_name
- 'Frank Person'
+ u'Frank Person'
>>> user.password
- '{NONE}abcxyz'
+ u'{NONE}abcxyz'
Holding unsubscription requests
@@ -679,21 +679,21 @@ unsubscription holds can send the list's moderators an immediate notification.
>>> mlist.admin_immed_notify = False
>>> from Mailman.interfaces import MemberRole
- >>> user_1 = config.db.user_manager.create_user('gperson@example.com')
+ >>> user_1 = config.db.user_manager.create_user(u'gperson@example.com')
>>> address_1 = list(user_1.addresses)[0]
>>> address_1.subscribe(mlist, MemberRole.member)
<Member: gperson@example.com on alist@example.com as MemberRole.member>
- >>> user_2 = config.db.user_manager.create_user('hperson@example.com')
+ >>> user_2 = config.db.user_manager.create_user(u'hperson@example.com')
>>> address_2 = list(user_2.addresses)[0]
>>> address_2.subscribe(mlist, MemberRole.member)
<Member: hperson@example.com on alist@example.com as MemberRole.member>
- >>> id_5 = moderator.hold_unsubscription(mlist, 'gperson@example.com')
+ >>> id_5 = moderator.hold_unsubscription(mlist, u'gperson@example.com')
>>> requests.get_request(id_5) is not None
True
>>> virginq.files
[]
>>> mlist.admin_immed_notify = True
- >>> id_6 = moderator.hold_unsubscription(mlist, 'hperson@example.com')
+ >>> id_6 = moderator.hold_unsubscription(mlist, u'hperson@example.com')
>>> qmsg, qdata = dequeue()
>>> print qmsg.as_string()
MIME-Version: 1.0
@@ -720,9 +720,9 @@ unsubscription holds can send the list's moderators an immediate notification.
<BLANKLINE>
>>> sorted(qdata.items())
[('_parsemsg', False),
- ('listname', 'alist@example.com'), ('nodecorate', True),
+ ('listname', u'alist@example.com'), ('nodecorate', True),
('received_time', ...),
- ('recips', ['alist-owner@example.com']),
+ ('recips', [u'alist-owner@example.com']),
('reduced_list_headers', True), ('tomoderators', True), ('version', 3)]
There are now two addresses with held unsubscription requests. As above, one
@@ -738,7 +738,7 @@ subscribed.
>>> moderator.handle_unsubscription(mlist, id_5, Action.discard)
>>> print requests.get_request(id_5)
None
- >>> mlist.members.get_member('gperson@example.com')
+ >>> mlist.members.get_member(u'gperson@example.com')
<Member: gperson@example.com on alist@example.com as MemberRole.member>
The request can be rejected, in which case a message is sent to the member,
@@ -776,22 +776,22 @@ and the person remains a member of the mailing list.
<BLANKLINE>
>>> sorted(qdata.items())
[('_parsemsg', False),
- ('listname', 'alist@example.com'),
+ ('listname', u'alist@example.com'),
('nodecorate', True), ('received_time', ...),
('recips', [u'hperson@example.com']),
('reduced_list_headers', True), ('version', 3)]
- >>> mlist.members.get_member('hperson@example.com')
+ >>> mlist.members.get_member(u'hperson@example.com')
<Member: hperson@example.com on alist@example.com as MemberRole.member>
The unsubscription request can also be accepted. This removes the member from
the mailing list.
>>> mlist.send_goodbye_msg = True
- >>> mlist.goodbye_msg = 'So long!'
+ >>> mlist.goodbye_msg = u'So long!'
>>> mlist.admin_immed_notify = False
- >>> id_7 = moderator.hold_unsubscription(mlist, 'gperson@example.com')
+ >>> id_7 = moderator.hold_unsubscription(mlist, u'gperson@example.com')
>>> moderator.handle_unsubscription(mlist, id_7, Action.accept)
- >>> print mlist.members.get_member('gperson@example.com')
+ >>> print mlist.members.get_member(u'gperson@example.com')
None
There are now two messages in the virgin queue, one to the member who was just
@@ -829,9 +829,9 @@ The goodbye message...
<BLANKLINE>
>>> sorted(goodbye_qdata.items())
[('_parsemsg', False),
- ('listname', 'alist@example.com'),
+ ('listname', u'alist@example.com'),
('nodecorate', True), ('received_time', ...),
- ('recips', ['gperson@example.com']),
+ ('recips', [u'gperson@example.com']),
('reduced_list_headers', True), ('verp', False), ('version', 3)]
...and the admin message.
@@ -851,6 +851,6 @@ The goodbye message...
<BLANKLINE>
>>> sorted(admin_qdata.items())
[('_parsemsg', False), ('envsender', 'changeme@example.com'),
- ('listname', 'alist@example.com'),
+ ('listname', u'alist@example.com'),
('nodecorate', True), ('received_time', ...),
('recips', []), ('reduced_list_headers', True), ('version', 3)]