1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
# Copyright (C) 2007-2008 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.
"""Application support for membership management."""
from __future__ import with_statement
from email.utils import formataddr
from Mailman import Errors
from Mailman import Message
from Mailman import Utils
from Mailman import i18n
from Mailman.configuration import config
from Mailman.interfaces import DeliveryMode, MemberRole
_ = i18n._
__i18n_templates__ = True
def add_member(mlist, address, realname, password, delivery_mode, language,
ack=None, admin_notif=None, text=''):
"""Add a member right now.
The member's subscription must be approved by what ever policy the
list enforces.
ack is a flag that specifies whether the user should get an
acknowledgement of their being subscribed. Default is to use the
list's default flag value.
admin_notif is a flag that specifies whether the list owner should get
an acknowledgement of this subscription. Default is to use the list's
default flag value.
"""
# Set up default flag values
if ack is None:
ack = mlist.send_welcome_msg
if admin_notif is None:
admin_notif = mlist.admin_notify_mchanges
# Let's be extra cautious.
Utils.ValidateEmail(address)
if mlist.members.get_member(address) is not None:
raise Errors.AlreadySubscribedError(address)
# Check for banned address here too for admin mass subscribes and
# confirmations.
pattern = Utils.get_pattern(address, mlist.ban_list)
if pattern:
raise Errors.MembershipIsBanned(pattern)
# Do the actual addition. First, see if there's already a user linked
# with the given address.
user = config.db.user_manager.get_user(address)
if user is None:
# A user linked to this address does not yet exist. Is the address
# itself known but just not linked to a user?
address_obj = config.db.user_manager.get_address(address)
if address_obj is None:
# Nope, we don't even know about this address, so create both the
# user and address now.
user = config.db.user_manager.create_user(address, realname)
# Do it this way so we don't have to flush the previous change.
address_obj = list(user.addresses)[0]
else:
# The address object exists, but it's not linked to a user.
# Create the user and link it now.
user = config.db.user_manager.create_user()
user.real_name = (realname if realname else address_obj.real_name)
user.link(address_obj)
# Since created the user, then the member, and set preferences on the
# appropriate object.
user.password = password
user.preferences.preferred_language = language
member = address_obj.subscribe(mlist, MemberRole.member)
member.preferences.delivery_mode = delivery_mode
else:
# The user exists and is linked to the address.
for address_obj in user.addresses:
if address_obj.address == address:
break
else:
raise AssertionError(
'User should have had linked address: %s', address)
# Create the member and set the appropriate preferences.
member = address_obj.subscribe(mlist, MemberRole.member)
member.preferences.preferred_language = language
member.preferences.delivery_mode = delivery_mode
## mlist.setMemberOption(email, config.Moderate,
## mlist.default_member_moderation)
# Send notifications.
if ack:
send_welcome_message(mlist, address, language, delivery_mode, text)
if admin_notif:
with i18n.using_language(mlist.preferred_language):
subject = _('$mlist.real_name subscription notification')
if isinstance(realname, unicode):
realname = realname.encode(Utils.GetCharSet(language), 'replace')
text = Utils.maketext(
'adminsubscribeack.txt',
{'listname' : mlist.real_name,
'member' : formataddr((realname, address)),
}, mlist=mlist)
msg = Message.OwnerNotification(mlist, subject, text)
msg.send(mlist)
def send_welcome_message(mlist, address, language, delivery_mode, text=''):
if mlist.welcome_msg:
welcome = Utils.wrap(mlist.welcome_msg) + '\n'
else:
welcome = ''
# Find the IMember object which is subscribed to the mailing list, because
# 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.
text += Utils.maketext(
'subscribeack.txt', {
'real_name' : mlist.real_name,
'posting_address' : mlist.fqdn_listname,
'listinfo_url' : mlist.script_url('listinfo'),
'optionsurl' : options_url,
'request_address' : mlist.request_address,
'welcome' : welcome,
}, lang=language, mlist=mlist)
if delivery_mode is not DeliveryMode.regular:
digmode = _(' (Digest mode)')
else:
digmode = ''
msg = Message.UserNotification(
address, mlist.request_address,
_('Welcome to the "$mlist.real_name" mailing list${digmode}'),
text, language)
msg['X-No-Archive'] = 'yes'
msg.send(mlist, verp=config.VERP_PERSONALIZED_DELIVERIES)
def delete_member(mlist, address, admin_notif=None, userack=None):
if userack is None:
userack = mlist.send_goodbye_msg
if admin_notif is None:
admin_notif = mlist.admin_notify_mchanges
# Delete a member, for which we know the approval has been made
member = mlist.members.get_member(address)
language = member.preferred_language
member.unsubscribe()
# And send an acknowledgement to the user...
if userack:
send_goodbye_message(mlist, address, language)
# ...and to the administrator.
if admin_notif:
user = config.db.user_manager.get_user(address)
realname = user.real_name
subject = _('$mlist.real_name unsubscription notification')
text = Utils.maketext(
'adminunsubscribeack.txt',
{'listname': mlist.real_name,
'member' : formataddr((realname, address)),
}, mlist=mlist)
msg = Message.OwnerNotification(mlist, subject, text)
msg.send(mlist)
def send_goodbye_message(mlist, address, language):
if mlist.goodbye_msg:
goodbye = Utils.wrap(mlist.goodbye_msg) + '\n'
else:
goodbye = ''
msg = Message.UserNotification(
address, mlist.bounces_address,
_('You have been unsubscribed from the $mlist.real_name mailing list'),
goodbye, language)
msg.send(mlist, verp=config.VERP_PERSONALIZED_DELIVERIES)
|