#! /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.

"""Create a new, unpopulated mailing list.

Usage: %(PROGRAM)s [options] listname listadmin-addr admin-password

Options:

    -q
    --quiet
        Normally the administrator is notified by email (after a prompt) that
        their list has been created.  This option suppresses that
        notification.

    -o file
    --output=file
        Append the alias setting recommendations to file, in addition to
        printing them to standard output.

    -h/--help
        Print this help text and exit.

You can specify as many of the arguments as you want on the command line. 
The optional <immediate> argument, if present, means to send out the notice 
immediately.  Otherwise, the script hangs pending input, to give time for
the person creating the list to customize it before sending the admin an
email notice about the existence of the new list.

Note that listnames are forced to lowercase.
"""

import sys
import os
import string
import time
import getpass
import getopt

import paths
from Mailman import mm_cfg
from Mailman import MailList
from Mailman import Utils
from Mailman import Errors
from Mailman import Message
from Mailman.Handlers import HandlerAPI
from Mailman.Crypt import crypt

PROGRAM = sys.argv[0]

SENDMAIL_ALIAS_TEMPLATE = '''
## %(listname)s mailing list
## created: %(date)s %(user)s
%(list)s "|%(wrapper)s post %(listname)s"
%(admin)s "|%(wrapper)s mailowner %(listname)s"
%(request)s "|%(wrapper)s mailcmd %(listname)s"
%(owner2)s %(listname)s-admin
'''

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
"""

# defaults
STDOUTMSG = 'Entry for aliases file:'
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...)'



def getusername():
    username = os.environ.get('USER') or os.environ.get('LOGNAME')
    if not username:
        import pwd
        username = pwd.getpwuid(os.getuid())[0]
    if not username:
        username = '<unknown>'
    return username



def usage(code, msg=''):
    print __doc__
    if msg:
        print msg
    sys.exit(code)



def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'ho:q',
                                   ['help', 'output=', 'quiet'])
    except getopt.error, msg:
        usage(1, msg)

    appendfile = None
    quiet = 0
    for opt, arg in opts:
        if opt in ('-o', '--output'):
            appendfile = arg
        if opt in ('-h', '--help'):
            usage(0)
        if opt in ('-q', '--quiet'):
            quiet = 1

    if len(args) > 0:
	listname = args[0]
    else:
	listname = raw_input("Enter the name of the list: ")
    listname = string.lower(listname)

    if '@' in listname:
        usage(1, 'List name must not include "@": ' + listname)

    if Utils.list_exists(listname):
        usage(1, 'List already exists: ' + listname)

    if len(args) > 1:
	owner_mail = args[1]
    else:
	owner_mail = raw_input(
	    "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 passwords cannot be empty
    list_pw = string.strip(list_pw)
    if not list_pw:
        usage(1, 'The list password cannot be empty')

    mlist = MailList.MailList()
    try:
        pw = crypt(list_pw , Utils.GetRandomSeed())
        # guarantee that all newly created files have the proper permission.
        # proper group ownership should be assured by the autoconf script
        # enforcing that all directories have the group sticky bit set
        oldmask = os.umask(002)
        try:
            try:
                mlist.Create(listname, owner_mail, pw)
            finally:
                os.umask(oldmask)
        except Errors.MMBadEmailError:
            usage(1, 'Bad owner email address: ' + owner_mail)
        except Errors.MMListAlreadyExistsError:
            usage(1, 'List already exists: ' + listname)

        output = ALIASTEMPLATE % {
            'listname': listname,
            'list'    : "%-24s" % (listname + ":"),
            'wrapper' : '%s/wrapper' % mm_cfg.WRAPPER_DIR,
            'admin'   : "%-24s" % ("%s-admin:" % listname),
            'request' : "%-24s" % ("%s-request:" % listname),
            'owner2'  : "%-24s" % ("%s-owner:" % listname),
            'date'    : time.strftime('%d-%b-%Y', time.localtime(time.time())),
            'user'    : getusername(),
            }
        print STDOUTMSG
        print output
        if appendfile:
            fp = open(appendfile, 'a')
            fp.write(output)
            fp.write('\n')
            fp.close()

        if not quiet:
            print ("Hit enter to continue with %s owner notification..."
                   % listname),
            sys.stdin.readline()
            # send the notice to the list owner
            text = Utils.maketext(
                'newlist.txt',
                {'listname'    : listname,
                 'password'    : list_pw, 
                 'admin_url'   : mlist.GetScriptURL('admin', absolute=1), 
                 'listinfo_url': mlist.GetScriptURL('listinfo', absolute=1),
                 'requestaddr' : "%s-request@%s" % (listname, mlist.host_name),
                 'hostname'    : mlist.host_name,
                 })
            msg = Message.UserNotification(
                owner_mail,
                'mailman-owner@' + mlist.host_name,
                'Your new mailing list: ' + listname,
                text)
            HandlerAPI.DeliverToUser(mlist, msg)
    finally:
        mlist.Unlock()


if __name__ == '__main__':
    main()
