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
|
#! /usr/bin/env python
#
# Copyright (C) 1998,1999,2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Send password reminders for all lists to all users.
Any arguments are taken as a list of addresses that become the focus - only
the subscribers on the list are attended to, all other subscribers are
ignored. In addition, if any addresses are specified, a line is printed for
each list where that address is found. (Otherwise operation is silent.)
We accumulate users and their passwords, and use the last list to send a
single message to each user with their complete collection of passwords,
rather than sending a single message for each password.
If mm_cfg.VIRTUAL_HOST_OVERVIEW is true, we further group users by the virtual
host the mailing lists are assigned to. This is so that virtual domains are
treated like real separate machines.
"""
# This puppy should probably do lots of logging.
import sys
import os
import string
import errno
import paths
from Mailman import mm_cfg
from Mailman import MailList
from Mailman import Utils
from Mailman import Message
from Mailman.Handlers import HandlerAPI
# Work around known problems with some RedHat cron daemons
import signal
signal.signal(signal.SIGCHLD, signal.SIG_DFL)
def mail_passwords(mlist, hosts):
"""Send each user their complete list of passwords.
The list can be any random one - it is only used for the message
delivery mechanism. Users are grouped by virtual host.
"""
mailman_owner = mm_cfg.MAILMAN_OWNER
for host, users in hosts.items():
subj = host + ' mailing list memberships reminder'
for addr, data in users.items():
table = []
for l, r, p, u in data:
if len(l) > 39:
table.append("%s\n %-10s\n%s\n" % (l, p, u))
else:
table.append("%-40s %-10s\n%s\n" % (l, p, u))
header = ("%-40s %-10s\n%-40s %-10s"
% ("List", "Password // URL", "----", "--------"))
text = Utils.maketext(
'cronpass.txt',
{'hostname': host,
'useraddr': addr,
'exreq' : r,
'owner' : mailman_owner,
})
# add this to the end so it doesn't get wrapped/filled
text = text + header + '\n' + string.join(table, '\n')
msg = Message.UserNotification(addr, mailman_owner, subj, text)
msg['X-No-Archive'] = 'yes'
HandlerAPI.DeliverToUser(mlist, msg)
def main():
"""Consolidate all the list/url/password info for each user, so we send
the user a single message with the info for all their lists on this
site.
"""
# constrain to specified lists, if any
confined_to = sys.argv[1:]
# Use this list for message delivery only
a_public_list = None
# Group lists by the assigned virtual host, if
# mm_cfg.VIRTUAL_HOST_OVERVIEW is true. Otherwise, there's only one key
# in this dictionary: mm_cfg.DEFAULT_HOST_NAME. Each entry in this
# dictionary is a dictionary of user email addresses
hosts = {}
for listname in Utils.list_names():
if confined_to and listname not in confined_to:
continue
## else:
## print 'Processing list:', listname
mlist = MailList.MailList(listname, lock=0)
if not a_public_list and mlist.advertised:
a_public_list = mlist
if not mlist.send_reminders:
continue
listaddr = mlist.GetListEmail()
listreq = mlist.GetRequestEmail()
umbrella = mlist.umbrella_list
# get host information
if mm_cfg.VIRTUAL_HOST_OVERVIEW:
host = mlist.host_name
else:
host = mm_cfg.DEFAULT_HOST_NAME
#
# each entry in this dictionary is a list of tuples of the following
# form: (listaddr, listreq, password, url)
users = hosts.get(host, {})
badaddrs = []
for addr, passwd in mlist.passwords.items():
url = mlist.GetAbsoluteOptionsURL(addr)
realaddr = mlist.GetUserSubscribedAddress(addr)
if not realaddr:
badaddrs.append(addr)
continue
recip = mlist.GetMemberAdminEmail(realaddr)
userinfo = (listaddr, listreq, passwd, url)
infolist = users.get(recip, [])
infolist.append(userinfo)
users[recip] = infolist
hosts[host] = users
# were there any addresses that are in the password dictionary but are
# not subscribed?
if badaddrs:
mlist.Lock()
try:
for addr in badaddrs:
del mlist.passwords[addr]
mlist.Save()
finally:
mlist.Unlock()
if a_public_list:
mail_passwords(a_public_list, hosts)
if __name__ == '__main__':
main()
|