diff options
| author | bwarsaw | 2000-12-07 19:33:52 +0000 |
|---|---|---|
| committer | bwarsaw | 2000-12-07 19:33:52 +0000 |
| commit | 307583d87bc10413f79d34d4eb4d863df7fe6a95 (patch) | |
| tree | 8a2661240f0045314af5fb1be3544d63754001c3 | |
| parent | f80f72d57ce4e6ef145502ef71bcc8f7bed592a1 (diff) | |
| download | mailman-307583d87bc10413f79d34d4eb4d863df7fe6a95.tar.gz mailman-307583d87bc10413f79d34d4eb4d863df7fe6a95.tar.zst mailman-307583d87bc10413f79d34d4eb4d863df7fe6a95.zip | |
| -rwxr-xr-x | bin/add_members | 52 | ||||
| -rw-r--r-- | bin/arch | 21 | ||||
| -rwxr-xr-x | bin/check_db | 116 | ||||
| -rwxr-xr-x | bin/check_perms | 95 | ||||
| -rwxr-xr-x | bin/clone_member | 39 | ||||
| -rw-r--r-- | bin/config_list | 89 | ||||
| -rw-r--r-- | bin/dumpdb | 9 | ||||
| -rwxr-xr-x | bin/find_member | 28 | ||||
| -rw-r--r-- | bin/list_lists | 20 | ||||
| -rwxr-xr-x | bin/list_members | 37 | ||||
| -rwxr-xr-x | bin/mmsitepass | 17 | ||||
| -rw-r--r-- | bin/move_list | 12 | ||||
| -rwxr-xr-x | bin/newlist | 57 | ||||
| -rwxr-xr-x | bin/remove_members | 28 | ||||
| -rwxr-xr-x | bin/rmlist | 30 | ||||
| -rwxr-xr-x | bin/update | 34 | ||||
| -rw-r--r-- | bin/version | 4 |
17 files changed, 378 insertions, 310 deletions
diff --git a/bin/add_members b/bin/add_members index 9f6b186a1..8487546ff 100755 --- a/bin/add_members +++ b/bin/add_members @@ -65,7 +65,6 @@ files can be `-'. import sys import os -import string import getopt import paths @@ -75,25 +74,29 @@ from Mailman import Message from Mailman import Errors from Mailman import mm_cfg from Mailman.Handlers import HandlerAPI +from Mailman.i18n import _ def usage(status, msg=''): + print >> sys.stderr, _(__doc__) if msg: - print msg - print __doc__ % globals() + print >> sys.stderr, msg sys.exit(status) -def ReadFile(filename): - lines = [] - if filename == "-": +def readfile(filename): + if filename == '-': fp = sys.stdin + closep = 0 else: fp = open(filename) - lines = filter(None, map(string.strip, fp.readlines())) - fp.close() + closep = 1 + # strip all the lines of whitespace and discard blank lines + lines = filter(None, [line.strip() for line in fp.readlines()]) + if closep: + fp.close() return lines @@ -109,7 +112,7 @@ def SendExplanation(mlist, users): 'version' : mm_cfg.VERSION, } text = Utils.maketext('convert.txt', d) - subject = 'Big change in %(listname)s@%(listhost)s mailing list' % d + subject = _('Big change in %(listname)s@%(listhost)s mailing list') % d msg = Message.OutgoingMessage(text) msg['From'] = adminaddr msg['Subject'] = subject @@ -129,10 +132,10 @@ def main(): except getopt.error, msg: usage(1, msg) - if not len(args) == 1: + if len(args) <> 1: usage(1) - listname = string.lower(args[0]) + listname = args[0].lower().strip() nfile = None dfile = None send_changes_msg = 0 @@ -163,28 +166,28 @@ def main(): usage(1) if dfile == "-" and nfile == "-": - print "Sorry, can't read both digest *and* normal members from stdin." - sys.exit(1) + usage(1, _('Cannot read both digest and normal members ' + 'from standard input.')) try: ml = MailList.MailList(listname) except Errors.MMUnknownListError: - usage(1, 'You must first create the list by running: newlist %s' % - listname) + usage(1, _('You must first create the list by running: ' + 'newlist %(listname)s')) if send_welcome_msg == -1: send_welcome_msg = ml.send_welcome_msg try: dmembers = [] if dfile: try: - dmembers = ReadFile(dfile) + dmembers = readfile(dfile) except IOError: pass nmembers = [] if nfile: try: - nmembers = ReadFile(nfile) + nmembers = readfile(nfile) except IOError: pass @@ -193,11 +196,13 @@ def main(): if nmembers: nres = ml.ApprovedAddMembers(nmembers, None, 0, send_welcome_msg) - else: nres = {} + else: + nres = {} if dmembers: dres = ml.ApprovedAddMembers(dmembers, None, 1, send_welcome_msg) - else: dres = {} + else: + dres = {} for result in (nres, dres): for name in result.keys(): @@ -208,10 +213,13 @@ def main(): # result[name] is set from sys.exc_info()[:2] e, v = result[name] if e is Errors.MMAlreadyAMember: - print 'Already subscribed (skipping):', name + print >> sys.stderr, \ + _('Already subscribed (skipping):'), name elif issubclass(e, Errors.EmailAddressError): - if name == '': name = '( blank line )' - print "Not a valid email address:", name + if not name: + name = _('( blank line )') + print >> sys.stderr, \ + _('Not a valid email address:'), name if send_changes_msg: SendExplanation(ml, nmembers + dmembers) @@ -22,7 +22,7 @@ Use this command to rebuild the archives for a mailing list. You may want to do this if you edit some messages in an archive, or remove some messages from an archive. -Usage: %(program)s <listname> [<mbox>] [-h] +Usage: %(PROGRAM)s <listname> [<mbox>] [-h] Where <mbox> is the path to a list's complete mbox archive. Usually this will be some path in the archives/private directory. For example: @@ -34,24 +34,25 @@ be some path in the archives/private directory. For example: import sys import os -import string import getopt import paths from Mailman import mm_cfg +from Mailman import Errors + from Mailman.MailList import MailList from Mailman.Archiver.HyperArch import HyperArchive, Article from Mailman.LockFile import LockFile -from Mailman import Errors +from Mailman.i18n import _ -program = sys.argv[0] +PROGRAM = sys.argv[0] def usage(code, msg=''): - print __doc__ % globals() + print >> sys.stderr, _(__doc__) if msg: - print msg + print >> sys.stderr, msg sys.exit(code) @@ -69,8 +70,8 @@ def main(): # grok arguments if len(args) < 1: - usage(1, 'listname is required') - listname = string.lower(args[0]) + usage(1, _('listname is required')) + listname = args[0].lower().strip() if len(args) < 2: mbox = None @@ -87,7 +88,7 @@ def main(): try: mlist = MailList(listname) except Errors.MMListError, e: - usage(2, 'No such list "%s"\n%s' % (listname, e)) + usage(2, _('No such list "%(listname)s"\n%(e)s')) if mbox is None: mbox = os.path.join(mlist.private_archive_file_dir, listname + '.mbox') @@ -111,7 +112,7 @@ def main(): try: fp = open(mbox) except IOError, msg: - usage(3, 'cannot open mbox file %s: %s' % (mbox, msg)) + usage(3, _('Cannot open mbox file %(mbox)s: %(msg)s')) archiver = HyperArchive(mlist) archiver.VERBOSE = 1 diff --git a/bin/check_db b/bin/check_db index 13c46c8e3..e1bee3e55 100755 --- a/bin/check_db +++ b/bin/check_db @@ -16,21 +16,47 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -"""Check the raw config.db for a mailing list. -Also check the config.db.last if the live file is corrupted. +"""Check the databases for mailing lists. -Usage: %(program)s listname +Both the config.db and config.db.last files are checked for corruption. + +Usage: %(PROGRAM)s [options] [listname [listname ...]] + +Options: + + --all + -a + Check all databases. Otherwise only the lists named on the command + line are checked. + + --verbose + -v + Verbose output. + + --help + -h + Print this text and exit. """ import sys import os -import string +import getopt import marshal import paths from Mailman import mm_cfg +from Mailman import Utils +from Mailman.i18n import _ + +PROGRAM = sys.argv[0] -program = sys.argv[0] + + +def usage(code, msg=''): + print >> sys.stderr, _(__doc__) + if msg: + print >> sys.stderr, msg + sys.exit(code) @@ -38,54 +64,76 @@ def testfile(filename): try: fp = open(filename) except IOError, (code, msg): - print filename, 'cannot be opened:\n\t', msg + print _('%(filename)s cannot be opened for reading:\n\t'), msg return 1 else: try: - d = marshal.load(fp) - except (EOFError, ValueError, TypeError), msg: - print filename, 'is corrupted:\n\t', msg - return 1 - else: - print filename, 'is fine' - return 0 - + try: + d = marshal.load(fp) + except (EOFError, ValueError, TypeError), msg: + print _('%(filename)s contains a corrupt marshal:\n\t'), msg + return 1 + else: + return 0 + finally: + fp.close() def main(): - if len(sys.argv) == 2: - listname = string.lower(sys.argv[1]) - else: - print __doc__ % globals() - sys.exit(1) + try: + opts, args = getopt.getopt(sys.argv[1:], 'ahv', + ['all', 'verbose', 'help']) + except getopt.error, msg: + usage(1, msg) + + verbose = 0 + listnames = args - listpath = os.path.join(mm_cfg.LIST_DATA_DIR, listname) - configdb = os.path.join(listpath, 'config.db') - lastdb = os.path.join(listpath, 'config.db.last') + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-v', '--verbose'): + verbose = 1 + elif opt in ('-a', '--all'): + listnames = Utils.list_names() - origbad = testfile(configdb) - backupbad = testfile(lastdb) + listnames = [n.lower().strip() for n in listnames] + if not listnames: + print _('Nothing to do.') + sys.exit(0) - if origbad and not backupbad: - print """ + for listname in listnames: + if not Utils.list_exists(listname): + print _('No list named:'), listname + continue + configdb = os.path.join(mm_cfg.LIST_DATA_DIR, listname, 'config.db') + lastdb = configdb + '.last' + + origbad = testfile(configdb) + lastbad = testfile(lastdb) + + if origbad and not lastbad: + print _("""\ ***** ALERT ***** -The original database file is corrupt, but the backup seems fine. -Consider copying +The original database file for the list `%(listname)s' is corrupt, but the +backup seems fine. Consider copying %(lastdb)s to %(configdb)s -however, you may lose some data.""" % locals() - elif origbad and backupbad: - print """ +however, you may lose some data.""") + elif origbad and backupbad: + print _(""" ***** ALERT ***** -Both the original database file and the backup seem +Both the original database file and the backup for list `%(listname)s' seem corrupted. You will probably need to recover both %(configdb)s and %(lastdb)s from a system backup, or remove the list `%(listname)s' and -re-create it from scratch.""" % locals() - +re-create it from scratch.""") + elif verbose: + print _("The list `%(listname)s' databases seem fine.") + if __name__ == '__main__': diff --git a/bin/check_perms b/bin/check_perms index f8edd50e6..de53f349e 100755 --- a/bin/check_perms +++ b/bin/check_perms @@ -81,7 +81,7 @@ def checkwalk(arg, dirname, names): for name in names: path = os.path.join(dirname, name) if arg.VERBOSE: - print ' checking gid and mode for', path + print _(' checking gid and mode for %(path)s') try: mode, gid = statgidmode(path) except OSError, e: @@ -92,11 +92,11 @@ def checkwalk(arg, dirname, names): groupname = grp.getgrgid(gid)[0] except KeyError: groupname = '<anon gid %d>' % gid - arg.ERRORS = arg.ERRORS + 1 - print path, 'bad gid (has: %s, expected %s)' % ( - groupname, MAILMAN_GRPNAME), + arg.ERRORS += 1 + print _('%(path)s bad gid (has: %(groupname)s, ' + 'expected %(MAILMAN_GRPNAME)s)'), if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chown(path, -1, MAILMAN_GID) else: print @@ -108,10 +108,10 @@ def checkwalk(arg, dirname, names): and os.path.split(path)[1] == 'database'): continue if S_ISDIR(mode) and (mode & DIRPERMS) <> DIRPERMS: - arg.ERRORS = arg.ERRORS + 1 - print 'directory permissions must be at least 02775:', path, + arg.ERRORS += 1 + print _('directory permissions must be at least 02775: %(path)s', if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(path, mode | DIRPERMS) else: print @@ -119,17 +119,18 @@ def checkwalk(arg, dirname, names): def checkall(): # first check PREFIX if STATE.VERBOSE: - print 'checking mode for', mm_cfg.PREFIX, + prefix = mm_cfg.PREFIX + print _('checking mode for %(prefix)s') dirs = {} for d in (mm_cfg.PREFIX, mm_cfg.EXEC_PREFIX, mm_cfg.VAR_PREFIX): dirs[d] = 1 for d in dirs.keys(): mode = statmode(d) if (mode & DIRPERMS) <> DIRPERMS: - STATE.ERRORS = STATE.ERRORS + 1 - print 'directory must be at least 02775:', d, + STATE.ERRORS += 1 + print _('directory must be at least 02775: %(d)s'), if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(d, mode | DIRPERMS) else: print @@ -140,14 +141,14 @@ def checkall(): def checkarchives(): private = mm_cfg.PRIVATE_ARCHIVE_FILE_DIR if STATE.VERBOSE: - print 'checking perms on', private + print _('checking perms on %(private)s') # private archives must not be other readable mode = statmode(private) if mode & S_IROTH: - STATE.ERRORS = STATE.ERRORS + 1 - print private, 'must not be other-readable', + STATE.ERRORS += 1 + print _('%(private)s must not be other-readable'), if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(private, mode & ~S_IROTH) else: print @@ -165,9 +166,9 @@ def checkmboxfile(mboxdir): mode = statmode(mboxfile) if (mode & MBOXPERMS) <> MBOXPERMS: STATE.ERRORS = STATE.ERRORS + 1 - print 'mbox file must be at least 0660', mboxfile + print _('mbox file must be at least 0660:'), mboxfile if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(mboxfile, mode | MBOXPERMS) else: print @@ -188,10 +189,10 @@ def checkarchivedbs(): if e.errno not in (errno.ENOENT, errno.ENOTDIR): raise continue if mode & S_IRWXO: - STATE.ERRORS = STATE.ERRORS + 1 - print dbdir, '"other" perms must be 000', + STATE.ERRORS += 1 + print _('%(dbdir)s "other" perms must be 000'), if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(dbdir, mode & ~S_IRWXO) else: print @@ -199,18 +200,18 @@ def checkarchivedbs(): def checkcgi(): if STATE.VERBOSE: - print 'checking cgi-bin permissions' + print _('checking cgi-bin permissions') exes = os.listdir(mm_cfg.CGI_DIR) for f in exes: path = os.path.join(mm_cfg.CGI_DIR, f) if STATE.VERBOSE: - print ' checking set-gid for', path + print _(' checking set-gid for %(path)s') mode = statmode(path) if mode & S_IXGRP and not mode & S_ISGID: - STATE.ERRORS = STATE.ERRORS + 1 - print path, 'must be set-gid', + STATE.ERRORS += 1 + print _('%(path)s must be set-gid'), if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(path, mode | S_ISGID) else: print @@ -218,53 +219,55 @@ def checkcgi(): def checkmail(): wrapper = os.path.join(mm_cfg.WRAPPER_DIR, 'wrapper') if STATE.VERBOSE: - print 'checking set-gid for', wrapper + print _('checking set-gid for %(wrapper)s') mode = statmode(wrapper) if not mode & S_ISGID: - STATE.ERRORS = STATE.ERRORS + 1 - print wrapper, 'must be set-gid', + STATE.ERRORS += 1 + print _('%(wrapper)s must be set-gid'), if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(wrapper, mode | S_ISGID) def checkadminpw(): adminpw = os.path.join(mm_cfg.DATA_DIR, 'adm.pw') targetmode = S_IFREG | S_IRUSR | S_IWUSR | S_IRGRP if STATE.VERBOSE: - print 'checking permissions on', adminpw + print _('checking permissions on %(adminpw)s') try: mode = statmode(adminpw) except OSError, e: if e.errno <> errno.ENOENT: raise return if mode <> targetmode: - STATE.ERRORS = STATE.ERRORS + 1 - print adminpw, 'permissions must be exactly 0640 (got %s)' % oct(mode) + STATE.ERRORS += 1 + octmode = oct(mode) + print _('%(adminpw)s permissions must be exactly 0640 ' + '(got %(octmode)s)'), if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(adminpw, targetmode) def checkdata(): targetmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP - checkfiles = ['config.db', 'config.db.last', - 'next-digest', 'next-digest-topics'] + checkfiles = ('config.db', 'config.db.last', + 'next-digest', 'next-digest-topics') if STATE.VERBOSE: - print 'checking permissions on list data' + print _('checking permissions on list data') for dir in os.listdir(mm_cfg.LIST_DATA_DIR): for file in checkfiles: path = os.path.join(mm_cfg.LIST_DATA_DIR, dir, file) if STATE.VERBOSE: - print ' checking permissions on:', path + print _(' checking permissions on: %(path)s') try: mode = statmode(path) except OSError, e: if e.errno <> errno.ENOENT: raise continue if (mode & targetmode) <> targetmode: - STATE.ERRORS = STATE.ERRORS + 1 - print 'file permissions must be at least 660:', path, + STATE.ERRORS += 1 + print _('file permissions must be at least 660: %(path)s'), if STATE.FIX: - print '(fixing)' + print _('(fixing)') os.chmod(path, mode | targetmode) else: print @@ -272,9 +275,9 @@ def checkdata(): def usage(code=0, msg=''): - print __doc__ % globals() + print >> sys.stderr, _(__doc__) if msg: - print msg + print >> sys.stderr, msg sys.exit(code) @@ -303,7 +306,7 @@ if __name__ == '__main__': checkadminpw() if not STATE.ERRORS: - print 'No problems found' + print _('No problems found') else: - print 'Problems found:', STATE.ERRORS - print 'Re-run as', MAILMAN_OWNER, '(or root) with -f flag to fix' + print _('Problems found:'), STATE.ERRORS + print _('Re-run as %(MAILMAN_OWNER)s (or root) with -f flag to fix') diff --git a/bin/clone_member b/bin/clone_member index 6f17123f1..2ae066e86 100755 --- a/bin/clone_member +++ b/bin/clone_member @@ -66,38 +66,39 @@ Where: """ import sys -import string import getopt import paths from Mailman import MailList from Mailman import Utils from Mailman import Errors +from Mailman.i18n import _ -def usage(status, msg=''): - print __doc__ % globals() +def usage(code, msg=''): + print >> sys.stderr, _(__doc__) if msg: - print msg - sys.exit(status) + print >> sys.stderr, msg + sys.exit(code) def dolist(mlist, options): + SPACE = ' ' if not options.quiet: - print 'processing mailing list:', mlist.internal_name() + print _('processing mailing list:'), mlist.internal_name() # scan the list owners. TBD: mlist.owner keys should be lowercase? oldowners = mlist.owner[:] oldowners.sort() if options.admintoo: if not options.quiet: - print ' scanning list owners:', string.join(oldowners, ' '), + print _(' scanning list owners:'), SPACE.join(oldowners) newowners = {} foundp = 0 for owner in mlist.owner: - if options.lfromaddr == string.lower(owner): + if options.lfromaddr == owner.lower() foundp = 1 if options.remove: continue @@ -111,9 +112,9 @@ def dolist(mlist, options): if not options.quiet: if newowners <> oldowners: print - print ' new list owners:', string.join(newowners, ' ') + print _(' new list owners:'), SPACE.join(newowners) else: - print '(no change)' + print _('(no change)') # see if the fromaddr is a digest member or regular member if options.lfromaddr in mlist.GetDigestMembers(): @@ -122,7 +123,7 @@ def dolist(mlist, options): digest = 0 else: if not options.quiet: - print ' address "%s" not found' % options.fromaddr + print _(' address not found:'), options.fromaddr return # Get the user's current options and password. TBD: Ugly hack: if a @@ -138,13 +139,13 @@ def dolist(mlist, options): if options.modify: mlist.ApprovedAddMember(options.toaddr, password, digest, 0) if not options.quiet: - print ' clone address added:', options.toaddr + print _(' clone address added:'), options.toaddr except Errors.MMAlreadyAMember: if not options.quiet: - print ' clone address is already a member:', options.toaddr + print _(' clone address is already a member:'), options.toaddr # hack the account flags - ltoaddr = string.lower(options.toaddr) + ltoaddr = options.toaddr.lower() if not flags: try: del mlist.user_options[ltoaddr] @@ -158,7 +159,7 @@ def dolist(mlist, options): if options.remove: if options.modify: mlist.DeleteMember(options.fromaddr, userack=0) - print ' original address removed:', options.fromaddr + print _(' original address removed:'), options.fromaddr @@ -194,7 +195,7 @@ def main(): elif opt in ('-l', '--listname'): if options.listnames is None: options.listnames = [] - options.listnames.append(string.lower(arg)) + options.listnames.append(arg.lower()) # further options and argument processing if not options.modify: @@ -209,8 +210,8 @@ def main(): try: Utils.ValidateEmail(toaddr) except Errors.EmailAddressError: - usage(1, 'Not a valid email address: %s' % toaddr) - lfromaddr = string.lower(fromaddr) + usage(1, _('Not a valid email address: %(toaddr)s') + lfromaddr = fromaddr.lower() options.toaddr = toaddr options.fromaddr = fromaddr options.lfromaddr = lfromaddr @@ -222,7 +223,7 @@ def main(): try: mlist = MailList.MailList(listname) except Errors.MMListError, e: - print 'Error opening list "%s": %s... skipping.' % (listname, e) + print _('Error opening list "%(listname)s", skipping.\n%(e)s') continue try: dolist(mlist, options) diff --git a/bin/config_list b/bin/config_list index bcb2270a5..1f2166644 100644 --- a/bin/config_list +++ b/bin/config_list @@ -63,7 +63,6 @@ The options -o and -i are mutually exclusive. import sys import time -import string import getopt from types import TupleType @@ -72,47 +71,50 @@ from Mailman import mm_cfg from Mailman import MailList from Mailman import Utils from Mailman import Errors +from Mailman.i18n import _ def usage(code, msg=''): - print __doc__ % globals() + msg + print >> sys.stderr, _(__doc__) + if msg: + print >> sys.stderr, msg sys.exit(code) def do_output(listname, outfile): - closep = 0 - stdout = sys.stdout try: if outfile == '-': outfp = sys.stdout + closep = 0 else: outfp = open(outfile, 'w') closep = 1 - sys.stdout = outfp - # open the specified list unlocked, since we're only reading it + # Open the specified list unlocked, since we're only reading it. try: mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: - usage(1, 'No such list "%s"\n%s' % (listname, e)) + usage(1, _('No such list "%(listname)s"\n%(e)s')) # get all the list config info. all this stuff is accessible via the # web interface - print '## "%s" mailing list configuration settings' % listname, - print '-*- python -*-' - print '## captured on', time.ctime(time.time()) - print + when = time.ctime(time.time()) + print >> outfp, _('''\ +## "%(listname)s" mailing list configuration settings -*- python -*- +## captured on %(when)s +''') + config = mlist.GetConfigInfo() - categories = ('general', 'privacy', 'nondigest', 'digest', - 'bounce', 'archive', 'gateway', 'autoreply') + categories = (_('general'), _('privacy'), _('nondigest'), _('digest'), + _('bounce'), _('archive'), _('gateway'), _('autoreply')) for k in categories: info = config[k] - print '##', string.capitalize(k), 'options' - print '#' + print >> outfp, '##', k.capitalize(), _('options') + print >> outfp, '#' desc = Utils.wrap(info[0]) - for line in string.split(desc, '\n'): - print '#', line - print + for line in desc.split('\n'): + print >> outfp, '#', line + print >> outfp for data in info[1:]: if type(data) <> TupleType: continue @@ -122,28 +124,28 @@ def do_output(listname, outfile): continue vtype = data[1] desc = Utils.wrap(data[-1]) - for line in string.split(desc, '\n'): - print '#', line + for line in desc.split('\n'): + print >> outfp, '#', line # munge the value based on its type value = getattr(mlist, varname) if vtype in (mm_cfg.Text, mm_cfg.FileUpload): - print varname, '=', - lines = string.split(string.replace(value, '\r', ''), '\n') + print >> outfp, varname, '=', + lines = value.replace('\r', '').split('\n') if len(lines) == 1: - print repr(value) + print >> outfp, repr(value) else: first = 1 - sys.stdout.write('"""') + outfp.write('"""') for line in lines: if first: first = 0 else: - print - sys.stdout.write(string.replace(line, '"', '\\"')) - print '"""' + print >> outfp + outfp.write(line.replace('"', '\\"')) + print >> outfp, '"""' elif vtype in (mm_cfg.Radio, mm_cfg.Toggle): - print '#' - print '# legal values are:' + print >> outfp, '#' + print >> outfp, '#', _('legal values are:') # TBD: This is disgusting, but it's special cased # everywhere else anyway... if varname == 'subscribe_policy' and \ @@ -152,16 +154,15 @@ def do_output(listname, outfile): else: i = 0 for choice in data[2]: - print '# ', i, '= "%s"' % choice - i = i + 1 - print varname, '=', repr(value) + print >> outfp, '# ', i, '= "%s"' % choice + i += 1 + print >> outfp, varname, '=', repr(value) else: - print varname, '=', repr(value) - print + print >> outfp, varname, '=', repr(value) + print >> outfp finally: if closep: outfp.close() - sys.stdout = stdout @@ -170,22 +171,22 @@ def do_input(listname, infile, checkonly, verbose): try: mlist = MailList.MailList(listname, lock=not checkonly) except Errors.MMListError, e: - usage(1, 'No such list "%s"\n%s' % (listname, e)) + usage(1, _('No such list "%(listname)s"\n%(e)s')) savelist = 0 try: globals = {'mlist': mlist} - # any exception that occurs in execfile() will cause the list to not - # be saved, but any other problems are not save-fatal + # Any exception that occurs in execfile() will cause the list to not + # be saved, but any other problems are not save-fatal. execfile(infile, globals) savelist = 1 for k, v in globals.items(): if k in ('mlist', '__builtins__'): continue if not hasattr(mlist, k): - print 'attribute "%s" ignored' % k + print >> sys.stderr, _('attribute "%(k)s" ignored') continue if verbose: - print 'attribute "%s" changed' % k + print >> sys.stderr, _('attribute "%(k)s" changed') setattr(mlist, k, v) finally: if savelist and not checkonly: @@ -221,14 +222,14 @@ def main(): # sanity check if infile is not None and outfile is not None: - usage(1, 'Only one of -i or -o is allowed') + usage(1, _('Only one of -i or -o is allowed')) if infile is None and outfile is None: - usage(1, 'One of -i or -o is required') + usage(1, _('One of -i or -o is required')) # get the list name if len(args) <> 1: - usage(1, 'List name is required') - listname = string.lower(args[0]) + usage(1, _('List name is required')) + listname = args[0].lower().strip() if outfile: do_output(listname, outfile) diff --git a/bin/dumpdb b/bin/dumpdb index 387948ac7..3c2cfa600 100644 --- a/bin/dumpdb +++ b/bin/dumpdb @@ -20,14 +20,17 @@ These are always marshaled dictionaries. -Usage: %(program)s filename +Usage: %(PROGRAM)s filename """ import sys import marshal import pprint -program = sys.argv[0] +import paths +from Mailman.i18n import _ + +PROGRAM = sys.argv[0] @@ -35,7 +38,7 @@ def main(): try: filename = sys.argv[1] except IndexError: - print __doc__ % globals() + print >> sys.stderr, _(__doc__) sys.exit(1) fp = open(filename) d = marshal.load(fp) diff --git a/bin/find_member b/bin/find_member index b25510506..593428847 100755 --- a/bin/find_member +++ b/bin/find_member @@ -59,12 +59,12 @@ displayed. import sys import re import getopt -import string import paths from Mailman import Utils from Mailman import MailList from Mailman import Errors +from Mailman.i18n import _ AS_MEMBER = 0x01 AS_OWNER = 0x02 @@ -72,9 +72,9 @@ AS_OWNER = 0x02 def usage(code, msg=''): - print __doc__ % globals() + print >> sys.stderr, _(__doc__) if msg: - print msg + print >> sys.stderr, msg sys.exit(code) @@ -90,7 +90,7 @@ def scanlists(options): try: mlist = MailList.MailList(listname, lock=0) except Errors.MMListError: - print 'No such list "%s"' % name + print _('No such list: %(listname)s') continue if options.owners: owners = mlist.owner @@ -102,14 +102,14 @@ def scanlists(options): addr = mlist.GetUserSubscribedAddress(member) entries = matches.get(addr, {}) aswhat = entries.get(listname, 0) - aswhat = aswhat | AS_MEMBER + aswhat |= AS_MEMBER entries[listname] = aswhat matches[addr] = entries for owner in owners: if cre.search(owner): entries = matches.get(addr, {}) aswhat = entries.get(listname, 0) - aswhat = aswhat | AS_OWNER + aswhat |= AS_OWNER entries[listname] = aswhat matches[addr] = entries return matches @@ -126,8 +126,8 @@ def main(): opts, args = getopt.getopt(sys.argv[1:], 'l:x:wh', ['listname=', 'exclude=', 'owners', 'help']) - except getopt.error, e: - usage(1, e) + except getopt.error, msg: + usage(1, msg) options = Options() loptseen = 0 @@ -139,9 +139,9 @@ def main(): if not loptseen: options.listnames = [] loptseen = 1 - options.listnames.append(string.lower(arg)) + options.listnames.append(arg.lower()) elif opt in ('-x', '--exclude'): - excludes.append(string.lower(arg)) + excludes.append(arg.lower()) elif opt in ('-w', '--owners'): options.owners = 1 @@ -152,12 +152,12 @@ def main(): pass if not args: - usage(1, 'search regular expression required') + usage(1, _('Search regular expression required')) options.regexps = args if not options.listnames: - print 'No lists to search' + print _('No lists to search') return matches = scanlists(options) @@ -166,13 +166,13 @@ def main(): for k in addrs: hits = matches[k] lists = hits.keys() - print k, 'found in:' + print k, _('found in:') for name in lists: aswhat = hits[name] if aswhat & AS_MEMBER: print ' ', name if aswhat & AS_OWNER: - print ' ', name, '(as owner)' + print ' ', name, _('(as owner)') diff --git a/bin/list_lists b/bin/list_lists index c24b0b953..33f29dfce 100644 --- a/bin/list_lists +++ b/bin/list_lists @@ -40,21 +40,21 @@ Where: import sys import getopt -import string import paths from Mailman import mm_cfg from Mailman import MailList from Mailman import Utils from Mailman import Errors +from Mailman.i18n import _ program = sys.argv[0] -def usage(status, msg=''): - print __doc__ % globals() +def usage(code, msg=''): + print >> sys.stderr, _(__doc__) if msg: - print msg - sys.exit(status) + print >> sys.stderr, msg + sys.exit(code) @@ -87,20 +87,20 @@ def main(): if advertised and not mlist.advertised: continue if vhost and mm_cfg.VIRTUAL_HOST_OVERVIEW and \ - string.find(vhost, mlist.web_page_url) == -1 and \ - string.find(mlist.web_page_url, vhost) == -1: + vhost.find(mlist.web_page_url) == -1 and \ + mlist.web_page_url.find(vhost) == -1: continue mlists.append(mlist) longest = max(len(mlist.real_name), longest) if not mlists: - print 'No matching mailing lists found' + print _('No matching mailing lists found') return - print len(mlists), 'matching mailing lists found:' + print len(mlists), _('matching mailing lists found:') format = '%%%ds - %%.%ds' % (longest, 77 - longest) for mlist in mlists: - description = mlist.description or '[no description available]' + description = mlist.description or _('[no description available]') print ' ', format % (mlist.real_name, description) diff --git a/bin/list_members b/bin/list_members index c1da95d5e..2de00bd89 100755 --- a/bin/list_members +++ b/bin/list_members @@ -18,7 +18,7 @@ """List all the members of a mailing list. -Usage: %(program)s [-o file] [-r] [-d] [-p] [-h] listname +Usage: %(PROGRAM)s [-o file] [-r] [-d] [-p] [-h] listname Where: @@ -52,20 +52,20 @@ status. """ import sys -import string import getopt import paths from Mailman import MailList from Mailman import Errors +from Mailman.i18n import _ -program = sys.argv[0] +PROGRAM = sys.argv[0] -def usage(status, msg=''): - print __doc__ % globals() +def usage(code, msg=''): + print >> sys.stderr, _(__doc__) if msg: - print msg - sys.exit(status) + print >> sys.stderr, msg + sys.exit(code) @@ -81,7 +81,7 @@ def main(): if len(args) <> 1: usage(1) - listname = string.lower(args[0]) + listname = args[0].lower().strip() outfile = None regular = None digest = None @@ -106,7 +106,7 @@ def main(): try: fp = open(outfile, 'w') except IOError: - print 'Could not open file for writing:', outfile + print _('Could not open file for writing:'), outfile sys.exit(1) else: fp = sys.stdout @@ -114,7 +114,7 @@ def main(): try: mlist = MailList.MailList(listname, lock=0) except Errors.MMListError, e: - print 'No such list "%s"\n%s' % (listname, e) + print _('No such list: %(listname)s') sys.exit(1) if preserve: @@ -124,17 +124,12 @@ def main(): rmembers = mlist.GetMembers() dmembers = mlist.GetDigestMembers() - stdout = sys.stdout - try: - sys.stdout = fp - if regular: - for addr in rmembers: - print addr - if digest: - for addr in dmembers: - print addr - finally: - sys.stdout = stdout + if regular: + for addr in rmembers: + print >> fp, addr + if digest: + for addr in dmembers: + print >> fp, addr if __name__ == '__main__': diff --git a/bin/mmsitepass b/bin/mmsitepass index 27dab419d..7f88ffa65 100755 --- a/bin/mmsitepass +++ b/bin/mmsitepass @@ -38,15 +38,16 @@ import getopt import paths from Mailman import Utils +from Mailman.i18n import _ PROGRAM = sys.argv[0] def usage(code, msg=''): - print __doc__ % globals() + print >> sys.stderr, _(__doc__) if msg: - print msg + print >> sys.stderr, msg sys.exit(code) @@ -65,21 +66,21 @@ def main(): pw1 = args[0] else: try: - pw1 = getpass.getpass("New Password: ") - pw2 = getpass.getpass("Again to confirm password: ") + pw1 = getpass.getpass(_('New Password: ')) + pw2 = getpass.getpass(_('Again to confirm password: ')) if pw1 <> pw2: - print 'Passwords do not match; no changes made.' + print _('Passwords do not match; no changes made.') sys.exit(1) except KeyboardInterrupt: - print "Interrupted..." + print _('Interrupted...') sys.exit(0) # Set the site password by writing it to a local file. Make sure the # permissions don't allow other+read. Utils.SetSiteAdminPassword(pw1) if Utils.CheckSiteAdminPassword(pw1): - print 'Password changed.' + print _('Password changed.') else: - print 'Password change failed.' + print _('Password change failed.') diff --git a/bin/move_list b/bin/move_list index d2d81455a..0873b9b2b 100644 --- a/bin/move_list +++ b/bin/move_list @@ -36,20 +36,20 @@ listname must be a valid mailing list name and is required. import os import sys -import string import getopt import paths from Mailman import Errors from Mailman import MailList from Mailman import mm_cfg +from Mailman.i18n import _ def usage(code, msg=''): - print __doc__ + print >> sys.stderr, _(__doc__) if msg: - print msg + print >> sys.stderr, msg sys.exit(code) @@ -68,14 +68,14 @@ def main(): usage(1) try: - listname = string.lower(args[0]) + listname = args[0].lower().strip() except IndexError: - usage(1, 'You must supply a list name.') + usage(1, _('You must supply a list name')) try: mlist = MailList.MailList(listname) except Errors.MMListError, e: - usage(1, 'No such list "%s"\n%s' % (listname, e)) + usage(1, _('No such list: %(listname)s')) try: mlist.public_archive_file_dir = mm_cfg.PUBLIC_ARCHIVE_FILE_DIR diff --git a/bin/newlist b/bin/newlist index 25bdc9ba4..a07a67edd 100755 --- a/bin/newlist +++ b/bin/newlist @@ -47,7 +47,6 @@ Note that listnames are forced to lowercase. import sys import os -import string import time import getpass import getopt @@ -60,6 +59,7 @@ from Mailman import Errors from Mailman import Message from Mailman.Handlers import HandlerAPI from Mailman.Crypt import crypt +from Mailman.i18n import _ PROGRAM = sys.argv[0] @@ -73,14 +73,16 @@ SENDMAIL_ALIAS_TEMPLATE = ''' ''' QMAIL_ALIAS_TEMPLATE = """ - echo '|preline %(wrapper)s post %(listname)s' >~alias/.qmail-%(listname)s - echo '|preline %(wrapper)s mailowner %(listname)s' >~alias/.qmail-%(listname)s-admin - echo '|preline %(wrapper)s mailcmd %(listname)s' >~alias/.qmail-%(listname)s-request - echo '&%(listname)s-admin' >~alias/.qmail-owner-%(listname)s - echo '&%(listname)s-admin' >~alias/.qmail-%(listname)s-owner - chmod 644 ~alias/.qmail-%(listname)s ~alias/.qmail-%(listname)s-admin - chmod 644 ~alias/.qmail-%(listname)s-request ~alias/.qmail-%(listname)s-owner - chmod 644 ~alias/.qmail-owner-%(listname)s +To create system aliases: + +echo '|preline %(wrapper)s post %(listname)s' >~alias/.qmail-%(listname)s +echo '|preline %(wrapper)s mailowner %(listname)s' >~alias/.qmail-%(listname)s-admin +echo '|preline %(wrapper)s mailcmd %(listname)s' >~alias/.qmail-%(listname)s-request +echo '&%(listname)s-admin' >~alias/.qmail-owner-%(listname)s +echo '&%(listname)s-admin' >~alias/.qmail-%(listname)s-owner +chmod 644 ~alias/.qmail-%(listname)s ~alias/.qmail-%(listname)s-admin +chmod 644 ~alias/.qmail-%(listname)s-request ~alias/.qmail-%(listname)s-owner +chmod 644 ~alias/.qmail-owner-%(listname)s """ # defaults @@ -90,10 +92,9 @@ ALIASTEMPLATE = SENDMAIL_ALIAS_TEMPLATE style = string.lower(mm_cfg.MTA_ALIASES_STYLE) if style == 'qmail': ALIASTEMPLATE = QMAIL_ALIAS_TEMPLATE - STDOUTMSG = 'To create system aliases:' elif style <> 'sendmail': - print "Warning! I don't understand alias style:", mm_cfg.MTA_ALIASES_STYLE - print '(this will print sendmail style...)' + print >> sys.stderr, _("Warning, unknown alias style: %(style)s") + print >> sys.stderr, _('(Using sendmail style instead...)') @@ -109,9 +110,9 @@ def getusername(): def usage(code, msg=''): - print __doc__ + print >> sys.stderr, _(__doc__) if msg: - print msg + print >> sys.stderr, msg sys.exit(code) @@ -136,29 +137,29 @@ def main(): if len(args) > 0: listname = args[0] else: - listname = raw_input("Enter the name of the list: ") - listname = string.lower(listname) + listname = raw_input(_('Enter the name of the list: ')) + listname = listname.lower() if '@' in listname: - usage(1, 'List name must not include "@": ' + listname) + usage(1, _('List name must not include "@": %(listname)s')) if Utils.list_exists(listname): - usage(1, 'List already exists: ' + listname) + usage(1, _('List already exists: %(listname)s')) if len(args) > 1: owner_mail = args[1] else: owner_mail = raw_input( - "Enter the email of the person running the list: ") + _('Enter the email of the person running the list: ')) if len(args) > 2: list_pw = args[2] else: - list_pw = getpass.getpass("Initial %s password: " % listname) + list_pw = getpass.getpass(_('Initial %(listname)s password: ')) # List passwords cannot be empty - list_pw = string.strip(list_pw) + list_pw = list_pw.strip() if not list_pw: - usage(1, 'The list password cannot be empty') + usage(1, _('The list password cannot be empty')) mlist = MailList.MailList() try: @@ -173,9 +174,9 @@ def main(): finally: os.umask(oldmask) except Errors.MMBadEmailError: - usage(1, 'Bad owner email address: ' + owner_mail) + usage(1, _('Bad owner email address: %(owner_mail)s')) except Errors.MMListAlreadyExistsError: - usage(1, 'List already exists: ' + listname) + usage(1, _('List already exists: %(listname)s')) output = ALIASTEMPLATE % { 'listname': listname, @@ -191,13 +192,11 @@ def main(): print output if appendfile: fp = open(appendfile, 'a') - fp.write(output) - fp.write('\n') + print >> fp, output fp.close() if not quiet: - print ("Hit enter to continue with %s owner notification..." - % listname), + print _('Hit enter to notify %(listname)s owner') sys.stdin.readline() # send the notice to the list owner text = Utils.maketext( @@ -212,7 +211,7 @@ def main(): msg = Message.UserNotification( owner_mail, 'mailman-owner@' + mlist.host_name, - 'Your new mailing list: ' + listname, + _('Your new mailing list: %(listname)s'), text) HandlerAPI.DeliverToUser(mlist, msg) finally: diff --git a/bin/remove_members b/bin/remove_members index 988e1f2be..862640b76 100755 --- a/bin/remove_members +++ b/bin/remove_members @@ -43,30 +43,33 @@ Options: """ import sys -import string import getopt import paths from Mailman import MailList from Mailman import Errors +from Mailman.i18n import _ -def usage(status, msg=''): - print __doc__ % globals() +def usage(code, msg=''): + print >> sys.stderr, _(__doc__) if msg: - print msg - sys.exit(status) + print >> sys.stderr, msg + sys.exit(code) def ReadFile(filename): lines = [] if filename == "-": fp = sys.stdin + closep = 0 else: fp = open(filename) - lines = filter(None, map(string.strip, fp.readlines())) - fp.close() + closep = 1 + lines = filter(None, [line.strip() for line in fp.readlines()]) + if closep: + fp.close() return lines @@ -78,10 +81,10 @@ def main(): except getopt.error, msg: usage(1, msg) - if not len(args) >= 1: + if len(args) < 1: usage(1) - listname = string.lower(args[0]) + listname = args[0].lower().strip() addresses = args[1:] filename = None all = 0 @@ -98,14 +101,13 @@ def main(): try: addresses = addresses + ReadFile(filename) except IOError: - print 'Could not open file for reading: %s. Ignoring...' % \ - `filename` + print _('Could not open file for reading: %(filename)s.') try: # open locked mlist = MailList.MailList(listname) except Errors.MMListError, e: - print 'No such list "%s"\n%s' % (listname, e) + print _('No such list: %(listname)s') sys.exit(1) if all: @@ -116,7 +118,7 @@ def main(): try: mlist.DeleteMember(addr) except Errors.MMNoSuchUserError: - print "User `%s' not found." % addr + print _("User `%(addr)s' not found.") finally: # Hmm, should it be all or nothing? mlist.Save() diff --git a/bin/rmlist b/bin/rmlist index fc3d448c1..b60a8dbd5 100755 --- a/bin/rmlist +++ b/bin/rmlist @@ -37,32 +37,32 @@ Where: import os import sys -import string import getopt import paths from Mailman import mm_cfg from Mailman import Utils +from Mailman.i18n import _ -def usage(status, msg=''): - print __doc__ % globals() +def usage(code, msg=''): + print >> sys.stderr, _(__doc__) if msg: - print msg - sys.exit(status) + print >> sys.stderr, msg + sys.exit(code) def remove_it(listname, dir, msg): if os.path.islink(dir): - print 'Removing', msg + print _('Removing %(msg)s') os.unlink(dir) elif os.path.exists(dir): - print 'Removing', msg + print _('Removing %(msg)s') os.system('rm -rf ' + dir) else: - print listname, msg, 'not found as', dir + print _('%(listname)s %(msg)s not found as %(dir)s') @@ -75,10 +75,10 @@ def main(): if len(args) <> 1: usage(1) - listname = string.lower(args[0]) + listname = args[0].lower().strip() if not Utils.list_exists(listname): - usage(1, 'List does not exist: "%s"' % listname) + usage(1, _('No such list: %(listname)s')) removeArchives = 0 for opt, arg in opts: @@ -88,17 +88,17 @@ def main(): usage(0) if not removeArchives: - print 'Not removing archives. Reinvoke with -a to remove them.' + print _('Not removing archives. Reinvoke with -a to remove them.') REMOVABLES = [('lists/%s', 'list info'), ] if removeArchives: REMOVABLES = REMOVABLES + \ - [('archives/private/%s', 'private archives'), - ('archives/private/%s.mbox', 'private archives'), - ('archives/public/%s', 'public archives'), - ('archives/public/%s.mbox', 'public archives'), + [('archives/private/%s', _('private archives')), + ('archives/private/%s.mbox', _('private archives')), + ('archives/public/%s', _('public archives')), + ('archives/public/%s.mbox', _('public archives')), ] for dirtmpl, msg in REMOVABLES: diff --git a/bin/update b/bin/update index 9c275c59b..2223f03dc 100755 --- a/bin/update +++ b/bin/update @@ -23,7 +23,6 @@ some previous version. It knows about versions back to 1.0b4 (?). import sys import os -import string import marshal import paths @@ -31,6 +30,7 @@ from Mailman import mm_cfg from Mailman import Utils from Mailman import MailList from Mailman.LockFile import TimeOutError +from Mailman.i18n import _ FRESH = 0 NOTFRESH = -1 @@ -53,7 +53,7 @@ def calcversions(): fp = open(LMVFILE) data = fp.read() fp.close() - lastversion = string.atoi(data, 16) + lastversion = int(data, 16) except (IOError, ValueError): pass # @@ -80,7 +80,8 @@ def dolist(listname): try: mlist.Lock(0.5) except TimeOutError: - print 'WARNING: could not acquire lock for list:', listname + print >> sys.stderr, _('WARNING: could not acquire lock for list: ' + '%(listname)s') return 1 mbox_dir = makeabs('archives/private/%s.mbox' % (listname)) @@ -101,9 +102,9 @@ def dolist(listname): else: # this shouldn't happen, but hey, just in case if not os.path.isdir(mbox_dir): - print "for some reason", mbox_dir, \ - "exists as a file. This won't work with b6" - print "so I'm renaming it to %s.tmp and proceeding" % (mbox_dir) + print _("""\ +For some reason, %(mbox_dir)s exists as a file. This won't work with +b6, so I'm renaming it to %(mbox_dir)s.tmp and proceeding.""") os.rename(mbox_dir, "%s.tmp" % (mbox_dir)) ou = os.umask(0) os.mkdir(mbox_dir, 02775) @@ -113,20 +114,22 @@ def dolist(listname): # private one existing if os.path.isfile(o_pri_mbox_file) and os.path.isfile(o_pub_mbox_file): if mlist.archive_private: - print """\ -%s has both public and private mbox archives, since this list -currently uses private archiving, I'm installing the private mbox -archive (%s) as the active archive, and renaming - %s + print _("""\ + +%(listname)s has both public and private mbox archives. Since this list +currently uses private archiving, I'm installing the private mbox archive +-- %(o_pri_mbox_file)s -- as the active archive, and renaming + %(o_pub_mbox_file)s to - %s.preb6 + %(o_pub_mbox_file)s.preb6 You can integrate that into the archives if you want by using the 'arch' script. -""" % (mlist._internal_name, o_pri_mbox_file, o_pub_mbox_file, o_pub_mbox_file) +""") % (mlist._internal_name, o_pri_mbox_file, o_pub_mbox_file, + o_pub_mbox_file) os.rename(o_pub_mbox_file, "%s.preb6" % (o_pub_mbox_file)) else: - print """\ + print _("""\ %s has both public and private mbox archives. Since this list currently uses public archiving, I'm installing the public mbox file archive file (%s) as the active one, and renaming @@ -136,7 +139,8 @@ archive file (%s) as the active one, and renaming You can integrate that into the archives if you want by using the 'arch' script. -""" % (mlist._internal_name, o_pub_mbox_file, o_pri_mbox_file, o_pri_mbox_file) +""") % (mlist._internal_name, o_pub_mbox_file, o_pri_mbox_file, + o_pri_mbox_file) os.rename(o_pri_mbox_file, "%s.preb6" % (o_pri_mbox_file)) # # move private archive mbox there if it's around diff --git a/bin/version b/bin/version index 176c87d0e..83fe71920 100644 --- a/bin/version +++ b/bin/version @@ -21,4 +21,6 @@ import paths import Mailman.mm_cfg -print 'Using Mailman version', Mailman.mm_cfg.VERSION +from Mailman.i18n import _ + +print _('Using Mailman version:'), Mailman.mm_cfg.VERSION |
