- from PLD
[packages/mailman.git] / subscribe_list
1 #! /usr/bin/python
2 #
3 # Copyright (C) 1998,1999,2000,2001,2002 by the Free Software Foundation, Inc.
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software 
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 #
19 # argv[1] should be the name of the list.
20 # argv[2] should be the list of non-digested users.
21 # argv[3] should be the list of digested users.
22
23 # Make sure that the list of email addresses doesn't contain any comments,
24 # like majordomo may throw in.  For now, you just have to remove them manually.
25
26 """Add members to a list from the command line.
27
28 Usage:
29     subscribe_list [options] listname [listname ...]
30
31 Options:
32
33     --regular-member=addr1
34     -r addr1
35         Add addr1 as a regular (non-digest) member.
36
37     --digest-member=addr1
38     -d addr1
39         Add add1 as a digest member.
40
41     --welcome-msg=<y|n>
42     -w <y|n>
43         Set whether or not to send the list members a welcome message,
44         overriding whatever the list's `send_welcome_msg' setting is.
45
46     --admin-notify=<y|n>
47     -a <y|n>
48         Set whether or not to send the list administrators a notification on
49         the success/failure of these subscriptions, overriding whatever the
50         list's `admin_notify_mchanges' setting is.
51
52     --help
53     -h
54         Print this help message and exit.
55
56     listname
57         The name of the Mailman list you are adding members to.  It must
58         already exist.
59
60 You must supply at least one of -n and -d options.  At most one of the
61 files can be `-'.
62 """
63
64 import sys
65 import os
66 import getopt
67 from cStringIO import StringIO
68
69 import paths
70 # Import this /after/ paths so that the sys.path is properly hacked
71 from email.Utils import parseaddr
72
73 from Mailman import MailList
74 from Mailman import Utils
75 from Mailman import Message
76 from Mailman import Errors
77 from Mailman import mm_cfg
78 from Mailman import i18n
79
80 _ = i18n._
81
82
83 \f
84 def usage(status, msg=''):
85     print >> sys.stderr, _(__doc__)
86     if msg:
87         print >> sys.stderr, msg
88     sys.exit(status)
89
90
91 \f
92 class Tee:
93     def __init__(self, outfp):
94         self.__outfp = outfp
95
96     def write(self, msg):
97         sys.stdout.write(msg)
98         self.__outfp.write(msg)
99
100
101 class UserDesc: pass
102
103
104 \f
105 def add(mlist, member, digest, ack, outfp):
106     tee = Tee(outfp)
107
108     mlist_name = mlist.internal_name()
109     
110     userdesc = UserDesc()
111     userdesc.fullname, userdesc.address = parseaddr(member)
112     userdesc.digest = digest
113
114     try:
115         mlist.ApprovedAddMember(userdesc, ack, 0)
116     except Errors.MMAlreadyAMember:
117         print >> tee, _('Already a member of %(mlist_name)s: %(member)s')
118     except Errors.MMBadEmailError:
119         if userdesc.address == '':
120             print >> tee, _('Bad/Invalid email address: blank line')
121         else:
122             print >> tee, _('Bad/Invalid email address: %(member)s')
123     except MMHostileAddress:
124         print >> tee, _('Hostile address (illegal characters): %(member)s')
125     else:
126         print >> tee, _('Subscribed: %(member)s to %(mlist_name)s')
127
128
129 \f
130 def main():
131     try:
132         opts, args = getopt.getopt(sys.argv[1:],
133                                    'a:r:d:w:h',
134                                    ['admin-notify=',
135                                     'regular-member=',
136                                     'digest-member=',
137                                     'welcome-msg=',
138                                     'help'])
139     except getopt.error, msg:
140         usage(1, msg)
141
142     if len(args) < 1:
143         usage(1, args)
144
145     listnames = args
146
147     send_welcome_msg = None
148     admin_notif = None
149     member_address = None
150     digest_member = 0
151     for opt, arg in opts:
152         if opt in ('-h', '--help'):
153             usage(0)
154         elif opt in ('-d', '--digest-member'):
155             member_address = arg
156             digest_member = 1
157         elif opt in ('-r', '--regular-member'):
158             member_address = arg
159             digest_member = 0
160         elif opt in ('-w', '--welcome-msg'):
161             if arg.lower()[0] == 'y':
162                 send_welcome_msg = 1
163             elif arg.lower()[0] == 'n':
164                 send_welcome_msg = 0
165             else:
166                 usage(1, _('Bad argument to -w/--welcome-msg: %(arg)s'))
167         elif opt in ('-a', '--admin-notify'):
168             if arg.lower()[0] == 'y':
169                 admin_notif = 1
170             elif arg.lower()[0] == 'n':
171                 admin_notif = 0
172             else:
173                 usage(1, _('Bad argument to -a/--admin-notify: %(arg)s'))
174                 
175     if member_address is None:
176         usage(1)
177
178     listnames = [n.lower().strip() for n in listnames]
179     if not listnames:
180         print _('Nothing to do.')
181         sys.exit(0)
182
183     for listname in listnames:
184         try:
185             mlist = MailList.MailList(listname)
186         except Errors.MMUnknownListError:
187             usage(1, _('No such list: %(listname)s'))
188
189         # Set up defaults
190         if send_welcome_msg is None:
191             send_welcome_msg = mlist.send_welcome_msg
192             if admin_notif is None:
193                 admin_notif = mlist.admin_notify_mchanges
194
195         otrans = i18n.get_translation()
196         # Read the regular and digest member files
197         try:
198             s = StringIO()
199             i18n.set_language(mlist.preferred_language)
200
201             add(mlist, member_address, digest_member, send_welcome_msg, s)
202
203             if admin_notif:
204                 realname = mlist.real_name
205                 subject = _('%(realname)s subscription notification')
206                 msg = Message.UserNotification(
207                     mlist.owner, Utils.get_site_email(), subject, s.getvalue(),
208                     mlist.preferred_language)
209                 msg.send(mlist)
210
211             mlist.Save()
212         finally:
213             mlist.Unlock()
214             i18n.set_translation(otrans)
215
216 \f
217 if __name__ == '__main__':
218     main()