Apply 21_newlist_help.patch
[mspang/vmailman.git] / bin / newlist
1 #! @PYTHON@
2 #
3 # Copyright (C) 1998-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 """Create a new, unpopulated mailing list.
20
21 Usage: %(PROGRAM)s [options] [listname [listadmin-addr [admin-password]]]
22
23 Options:
24
25     -l language
26     --language=language
27         Make the list's preferred language `language', which must be a two
28         letter language code.
29
30     -u urlhost
31     --urlhost=urlhost
32         Gives the list's web interface host name.
33
34     -e emailhost
35     --emailhost=emailhost
36         Gives the list's email domain name.
37
38     -q/--quiet
39         Normally the administrator is notified by email (after a prompt) that
40         their list has been created.  This option suppresses the prompt and
41         notification.
42
43     -h/--help
44         Print this help text and exit.
45
46 You can specify as many of the arguments as you want on the command line:
47 you will be prompted for the missing ones.
48
49 Every Mailman list has two parameters which define the default host name for
50 outgoing email, and the default URL for all web interfaces.  When you
51 configured Mailman, certain defaults were calculated, but if you are running
52 multiple virtual Mailman sites, then the defaults may not be appropriate for
53 the list you are creating.
54
55 You also specify the domain to create your new list in by typing the command
56 like so:
57
58     newlist --urlhost=www.mydom.ain mylist
59
60 where `www.mydom.ain' should be the base hostname for the URL to this virtual
61 hosts's lists.  E.g. with this setting people will view the general list
62 overviews at http://www.mydom.ain/mailman/listinfo.  Also, www.mydom.ain
63 should be a key in the VIRTUAL_HOSTS mapping in mm_cfg.py/Defaults.py if
64 the email hostname to be automatically determined.
65
66 If you want the email hostname to be different from the one looked up by the
67 VIRTUAL_HOSTS or if urlhost is not registered in VIRTUAL_HOSTS, you can specify
68 `emailhost' like so:
69
70     newlist --urlhost=www.mydom.ain --emailhost=mydom.ain mylist
71
72 where `mydom.ain' is the mail domain name. If you don't specify emailhost but
73 urlhost is not in the virtual host list, then mm_cfg.DEFAULT_EMAIL_HOST will
74 be used for the email interface.
75
76 For backward compatibility, you can also specify the domain to create your
77 new list in by spelling the listname like so:
78
79     mylist@www.mydom.ain
80
81 where www.mydom.ain is used for `urlhost' but it will also be used for
82 `emailhost' if it is not found in the virtual host table. Note that
83 '--urlhost' and '--emailhost' have precedence to this notation.
84
85 If you spell the list name as just `mylist', then the email hostname will be
86 taken from DEFAULT_EMAIL_HOST and the url will be taken from DEFAULT_URL (as
87 defined in your Defaults.py file or overridden by settings in mm_cfg.py).
88
89 Note that listnames are forced to lowercase.
90
91 The list admin address need to be a fully-qualified address, like
92 owner@example.com, not just owner.
93 """
94
95 import sys
96 import os
97 import getpass
98 import getopt
99 import sha
100 import grp
101
102 import paths
103 from Mailman import mm_cfg
104 from Mailman import MailList
105 from Mailman import Utils
106 from Mailman import Errors
107 from Mailman import Message
108 from Mailman import i18n
109
110 _ = i18n._
111
112 PROGRAM = sys.argv[0]
113
114
115 \f
116 def usage(code, msg=''):
117     if code:
118         fd = sys.stderr
119     else:
120         fd = sys.stdout
121     print >> fd, _(__doc__)
122     if msg:
123         print >> fd, msg
124     sys.exit(code)
125
126
127 \f
128 def main():
129     gid = grp.getgrnam(mm_cfg.MAILMAN_GROUP)[2]
130     if os.getgid() != gid and gid not in os.getgroups():
131         os.setgid(gid)
132     try:
133         opts, args = getopt.getopt(sys.argv[1:], 'hql:u:e:',
134                                    ['help', 'quiet', 'language=',
135                                     'urlhost=', 'emailhost='])
136     except getopt.error, msg:
137         usage(1, msg)
138
139     lang = mm_cfg.DEFAULT_SERVER_LANGUAGE
140     quiet = 0
141     urlhost = None
142     emailhost = None
143     for opt, arg in opts:
144         if opt in ('-h', '--help'):
145             usage(0)
146         if opt in ('-q', '--quiet'):
147             quiet = 1
148         if opt in ('-l', '--language'):
149             lang = arg
150         if opt in ('-u', '--urlhost'):
151             urlhost = arg
152         if opt in ('-e', '--emailhost'):
153             emailhost = arg
154
155     # Is the language known?
156     if lang not in mm_cfg.LC_DESCRIPTIONS.keys():
157         usage(1, _('Unknown language: %(lang)s'))
158
159     if len(args) > 0:
160         listname = args[0]
161     else:
162         listname = raw_input(_('Enter the name of the list: '))
163     listname = listname.lower()
164
165     if '@' in listname:
166         # note that --urlhost and --emailhost have precedence
167         listname, domain = listname.split('@', 1)
168         urlhost = urlhost or domain
169         emailhost = emailhost or mm_cfg.VIRTUAL_HOSTS.get(domain, domain)
170
171     urlhost = urlhost or mm_cfg.DEFAULT_URL_HOST
172     host_name = emailhost or \
173                 mm_cfg.VIRTUAL_HOSTS.get(urlhost, mm_cfg.DEFAULT_EMAIL_HOST)
174     web_page_url = mm_cfg.DEFAULT_URL_PATTERN % urlhost
175
176     if Utils.list_exists(listname):
177         usage(1, _('List already exists: %(listname)s'))
178
179     if len(args) > 1:
180         owner_mail = args[1]
181     else:
182         owner_mail = raw_input(
183             _('Enter the email of the person running the list: '))
184
185     if len(args) > 2:
186         listpasswd = args[2]
187     else:
188         listpasswd = getpass.getpass(_('Initial %(listname)s password: '))
189     # List passwords cannot be empty
190     listpasswd = listpasswd.strip()
191     if not listpasswd:
192         usage(1, _('The list password cannot be empty'))
193
194     mlist = MailList.MailList()
195     try:
196         pw = sha.new(listpasswd).hexdigest()
197         # Guarantee that all newly created files have the proper permission.
198         # proper group ownership should be assured by the autoconf script
199         # enforcing that all directories have the group sticky bit set
200         oldmask = os.umask(002)
201         try:
202             try:
203                 mlist.Create(listname, owner_mail, pw)
204             finally:
205                 os.umask(oldmask)
206         except Errors.BadListNameError, s:
207             usage(1, _('Illegal list name: %(s)s'))
208         except Errors.EmailAddressError, s:
209             usage(1, _('Bad owner email address: %(s)s.  Owner addresses need to be fully-qualified names, like "owner@example.com", not just "owner".'))
210         except Errors.MMListAlreadyExistsError:
211             usage(1, _('List already exists: %(listname)s'))
212
213         # Assign domain-specific attributes
214         mlist.host_name = host_name
215         mlist.web_page_url = web_page_url
216
217         # And assign the preferred language
218         mlist.preferred_language = lang
219
220         mlist.Save()
221     finally:
222         mlist.Unlock()
223
224     # Now do the MTA-specific list creation tasks
225     if mm_cfg.MTA:
226         modname = 'Mailman.MTA.' + mm_cfg.MTA
227         __import__(modname)
228         sys.modules[modname].create(mlist)
229
230     # And send the notice to the list owner
231     if not quiet:
232         print _('Hit enter to notify %(listname)s owner...'),
233         sys.stdin.readline()
234         siteowner = Utils.get_site_email(mlist.host_name, 'owner')
235         text = Utils.maketext(
236             'newlist.txt',
237             {'listname'    : listname,
238              'password'    : listpasswd,
239              'admin_url'   : mlist.GetScriptURL('admin', absolute=1),
240              'listinfo_url': mlist.GetScriptURL('listinfo', absolute=1),
241              'requestaddr' : mlist.GetRequestEmail(),
242              'siteowner'   : siteowner,
243              }, mlist=mlist)
244         # Set the I18N language to the list's preferred language so the header
245         # will match the template language.  Stashing and restoring the old
246         # translation context is just (healthy? :) paranoia.
247         otrans = i18n.get_translation()
248         i18n.set_language(mlist.preferred_language)
249         try:
250             msg = Message.UserNotification(
251                 owner_mail, siteowner,
252                 _('Your new mailing list: %(listname)s'),
253                 text, mlist.preferred_language)
254             msg.send(mlist)
255         finally:
256             i18n.set_translation(otrans)
257
258
259 \f
260 if __name__ == '__main__':
261     main()