vmm
author Pascal Volk <neverseen@users.sourceforge.net>
Tue, 19 Aug 2008 02:40:43 +0000
changeset 48 0d5f58f8b8f5
parent 47 191d5a5adc4a
child 49 9bd033177377
permissions -rwxr-xr-x
* 'VirtualMailManager/Exceptions.py' - Rewrote class VMMException and all derived VMM*Exception classes. Affected files in VirtualMailManager/: + '../vmm' + 'Account.py' + 'Alias.py' + 'Config.py' + 'Domain.py' + 'MailLocation.py' + 'Transport.py' + 'VirtualMailManager.py' * 'VirtualMailManager/Config.py' - Some code cleanups/fixes in: + VMMConfig.load() + VMMConfig.configure() * 'VirtualMailManager/DomainAlias.py' - Added to repository * 'VirtualMailManager/VirtualMailManager.py' - Some code cleanups in: + VirtualMailManager.__chkCfgFile() + VirtualMailManager.__getFileMode() removed + VirtualMailManager.configure() * 'vmm' - Rewrote: + usage() + configure() + __main__ - Implemented show_version() * 'po/de.po' * 'po/vmm.pot' - updated

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Copyright 2007-2008 VEB IT
# See COPYING for distribution information.
# $Id$

"""This is the vmm main script."""

from VirtualMailManager.constants.VERSION import VERSION

__author__ = 'Pascal Volk <p.volk@veb-it.de>'
__version__ = VERSION
__revision__ = 'rev '+'$Rev$'.split()[1]
__date__ = '$Date$'.split()[1]

import locale
import os
import sys
import gettext
from time import strftime, strptime

from VirtualMailManager.VirtualMailManager import VirtualMailManager
from VirtualMailManager.Config import VMMConfig
import VirtualMailManager.Exceptions as VMME
import VirtualMailManager.constants.EXIT as EXIT
import VirtualMailManager.constants.ERROR as ERR


def w_err(code, *args):
    for arg in args:
        sys.stderr.write(arg.encode(ENCODING, 'replace'))
        sys.stderr.write('\n')
    sys.exit(code)

def w_std(*args):
    for arg in args:
        sys.stdout.write(arg.encode(ENCODING, 'replace'))
        sys.stdout.write('\n')

def usage(excode=0, errMsg=None):
    u_head = _("""\
Usage: %s SUBCOMMAND OBJECT ARGS*
  short long
  subcommand               object            args (* = optional)\n""")\
          % __prog__

    u_body = """\
  da    domainadd          domain.tld        transport*
  di    domaininfo         domain.tld        detailed*
  dt    domaintransport    domain.tld        transport force*
  dd    domaindelete       domain.tld        delalias*|deluser*|delall*
  daa   domainaliasadd     aliasdomain.tld   domain.tld
  dai   domainaliasinfo    aliasdomain.tld
  dad   domainaliasdelete  aliasdomain.tld
  ua    useradd            user@domain.tld   password*
  ui    userinfo           user@domain.tld   du*
  un    username           user@domain.tld   'Users Name'
  up    userpassword       user@domain.tld   password*
  ut    usertransport      user@domain.tld   transport
  u0    userdisable        user@domain.tld   smtp*|pop3*|imap*|managesieve*|all*
  u1    userenable         user@domain.tld   smtp*|pop3*|imap*|managesieve*|all*
  ud    userdelete         user@domain.tld
  aa    aliasadd           alias@domain.tld  user@domain.tld
  ai    aliasinfo          alias@domain.tld
  ad    aliasdelete        alias@domain.tld  user@domain.tld*
  gu    getuser            userid
  ld    listdomains                          pattern*
  cf    configure                            section*
  h     help
  v     version
"""
    if excode > 0:
        if errMsg is None:
            w_err(excode, u_head, u_body)
        else:
            w_err(excode, u_head, u_body, '%s: %s\n' % (_('Error'), errMsg))
    else:
        w_std(u_head, u_body)
        sys.exit(excode)

def get_vmm():
    try:
        vmm = VirtualMailManager()
        return vmm
    except (VMME.VMMException, VMME.VMMNotRootException, VMME.VMMPermException,
            VMME.VMMConfigException), e:
        w_err(e.code(), "%s: %s\n" % (_('Error'), e.msg()))

def _getOrder():
    order = ()
    if argv[1] in ['di', 'domaininfo']:
        order = (('domainname', 0), ('gid', 1), ('transport', 0),
                ('domaindir', 0), ('aliasdomains', 0), ('accounts', 0),
                ('aliases', 0))
    elif argv[1] in ['ui', 'userinfo']:
        if argc == 4 or vmm.cfgGetBoolean('maildir', 'diskusage'):
            order = (('address', 0), ('name', 0), ('uid', 1), ('gid', 1),
                    ('transport', 0), ('maildir', 0), ('disk usage', 0),
                    ('smtp', 1), ('pop3', 1), ('imap', 1), ('managesieve', 1))
        else:
            order = (('address', 0), ('name', 0), ('uid', 1), ('gid', 1),
                    ('transport', 0), ('maildir', 0), ('smtp', 1), ('pop3', 1),
                    ('imap', 1), ('managesieve', 1))
    elif argv[1] in ['gu', 'getuser']:
        order = (('uid', 1), ('gid', 1), ('address', 0))
    return order

def _printInfo(info, title):
    msg = '%s %s' % (title, _('information'))
    w_std ('%s\n%s' % (msg, '-'*len(msg)))
    for k,u in _getOrder():
        if u:
            w_std('\t%s: %s' % (k.upper().ljust(15, '.'), info[k]))
        else:
            w_std('\t%s: %s' % (k.title().ljust(15, '.'), info[k]))
    print

def _printList(alist, title):
    msg = '%s %s' % (_('Available'), title)
    print '%s\n%s' % (msg, '-'*len(msg))
    if len(alist) > 0:
        if title != _('alias domains'):
            for val in alist:
                print '\t%s' % val
        else:
            for dom in alist:
                if not dom.startswith('xn--'):
                    print '\t%s' % dom
                else:
                    print '\t%s (%s)' % (dom, vmm.ace2idna(dom))
    else:
        print _('\tNone')
    print

def _printAliases(alias, targets):
    msg = _('Alias information')
    print '%s\n%s' % (msg, '-'*len(msg))
    print _('\tMail for %s goes to:') % alias
    if len(targets) > 0:
        for target in targets:
            print '\t     -> %s' % target
    else:
        print _('\tNone')
    print

def _formatDom(domain, main=True):
    if domain.startswith('xn--'):
        domain = '%s (%s)' % (domain, vmm.ace2idna(domain))
    if main:
        return '\t[+] %s' %  domain
    else:
        return '\t[-]     %s' % domain

def _printDomList(dids, domains):
    if argc < 3:
        msg = _('Available domains')
    else:
        msg = _('Matching domains')
    print '%s\n%s' % (msg, '-'*len(msg))
    if not len(domains):
        print _('\tNone')
    else:
        for id in dids:
            if domains[id][0] is not None:
                print _formatDom(domains[id][0])
            if len(domains[id]) > 1:
                for alias in domains[id][1:]:
                    print _formatDom(alias, main=False)
    print

def configure():
    if need_setup or len(argv) < 3:
        vmm.configure()
    else:
        vmm.configure(argv[2])

def domain_add():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing domain name.'))
    elif argc < 4:
        vmm.domain_add(argv[2].lower())
    else:
        vmm.domain_add(argv[2].lower(), argv[3])

def domain_delete():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing domain name.'))
    elif argc < 4:
        vmm.domain_delete(argv[2].lower())
    else:
        vmm.domain_delete(argv[2].lower(), argv[3])

def domain_info():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing domain name.'))
    elif argc < 4:
        _printInfo(vmm.domain_info(argv[2].lower()), _('Domain'))
    else:
        infos = vmm.domain_info(argv[2].lower(), argv[3])
        _printInfo(infos[0], _('Domain'))
        _printList(infos[1], _('alias domains'))
        _printList(infos[2], _('accounts'))
        _printList(infos[3], _('aliases'))

def domain_transport():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing domain name and new transport.'))
    if argc < 4:
        usage(EXIT.MISSING_ARGS, _(u'Missing new transport.'))
    elif argc < 5:
        vmm.domain_transport(argv[2].lower(), argv[3])
    else:
        vmm.domain_transport(argv[2].lower(), argv[3], argv[4])

def domain_alias_add():
    if argc < 3:
        usage(EXIT.MISSING_ARGS,
                _(u'Missing alias domain name and target domain name.'))
    elif argc < 4:
        usage(EXIT.MISSING_ARGS, _(u'Missing target domain name.'))
    else:
        vmm.domain_alias_add(argv[2].lower(), argv[3].lower())

def domain_alias_info():
    raise NotImplementedError('Sorry not implemented yet. ;-)')
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing alias domain name.'))
    else:
        vmm.domain_alias_delete(argv[2].lower())

def domain_alias_delete():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing alias domain name.'))
    else:
        vmm.domain_alias_delete(argv[2].lower())

def user_add():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
    elif argc < 4:
        password = None
    else:
        password = argv[3]
    vmm.user_add(argv[2].lower(), password)

def user_delete():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
    else:
        vmm.user_delete(argv[2].lower())

def user_info():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
    elif argc < 4:
        _printInfo(vmm.user_info(argv[2].lower()), 'Account')
    else:
        _printInfo(vmm.user_info(argv[2].lower(), True), 'Account')

def user_name():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address and users name.'))
    if argc < 4:
        usage(EXIT.MISSING_ARGS, _('Missing users name.'))
    else:
        vmm.user_name(argv[2].lower(), argv[3])

def user_transport():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address and transport.'))
    if argc <4:
        usage(EXIT.MISSING_ARGS, _(u'Missing transport.'))
    else:
        vmm.user_transport(argv[2].lower(), argv[3])

def user_enable():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
    elif argc < 4:
        vmm.user_enable(argv[2].lower())
    else:
        vmm.user_enable(argv[2].lower(), argv[3].lower())

def user_disable():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
    elif argc < 4:
        vmm.user_disable(argv[2].lower())
    else:
        vmm.user_disable(argv[2].lower(), argv[3].lower())

def user_password():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing e-mail address.'))
    elif argc < 4:
        password = None
    else:
        password = argv[3]
    vmm.user_password(argv[2].lower(), password)

def alias_add():
    if argc < 4:
        usage(EXIT.MISSING_ARGS, _(u'Missing alias address and destination.'))
    else:
        vmm.alias_add(argv[2].lower(), argv[3])

def alias_info():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing alias address'))
    else:
        _printAliases(argv[2], vmm.alias_info(argv[2].lower()))

def alias_delete():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing alias address'))
    elif argc < 4:
        vmm.alias_delete(argv[2].lower())
    else:
        vmm.alias_delete(argv[2].lower(), argv[3].lower())

def user_byID():
    if argc < 3:
        usage(EXIT.MISSING_ARGS, _(u'Missing userid'))
    else:
        _printInfo(vmm.user_byID(argv[2]), u'Account')

def domain_list():
    if argc < 3:
        order, doms = vmm.domain_list()
    else:
        order, doms = vmm.domain_list(argv[2].lower())
    _printDomList(order, doms)

def show_warnings():
    if vmm.hasWarnings():
        print _(u'Warnings:')
        for w in vmm.getWarnings():
            print " * ",w

def show_version():
    w_std("%s, %s %s (%s %s %s)\n" % (__prog__, _('version'), __version__,
            __revision__, _('from'), strftime(locale.nl_langinfo(locale.D_FMT),
                strptime(__date__, '%Y-%m-%d'))))

#def main():
if __name__ == '__main__':
    __prog__ = os.path.basename(sys.argv[0])
    locale.setlocale(locale.LC_ALL, '')
    ENCODING = locale.nl_langinfo(locale.CODESET)
    gettext.install(__prog__, '/usr/local/share/locale', unicode=1)
    argv = [unicode(arg, ENCODING) for arg in sys.argv]
    argc = len(sys.argv)

    if argc < 2:
        usage(EXIT.MISSING_ARGS)

    vmm = get_vmm()
    try:
        need_setup = not vmm.setupIsDone()
        if   argv[1] in ['cf', 'configure'] or need_setup:
            configure()
        elif argv[1] in ['da', 'domainadd']:
            domain_add()
        elif argv[1] in ['di', 'domaininfo']:
            domain_info()
        elif argv[1] in ['dt', 'domaintransport']:
            domain_transport()
        elif argv[1] in ['dd', 'domaindelete']:
            domain_delete()
        elif argv[1] in ['daa', 'domainaliasadd']:
            domain_alias_add()
        elif argv[1] in ['dai', 'domainaliasinfo']:
            domain_alias_info()
        elif argv[1] in ['dad', 'domainaliasdelete']:
            domain_alias_delete()
        elif argv[1] in ['ua', 'useradd']:
            user_add()
        elif argv[1] in ['ui', 'userinfo']:
            user_info()
        elif argv[1] in ['un', 'username']:
            user_name()
        elif argv[1] in ['up', 'userpassword']:
            user_password()
        elif argv[1] in ['ut', 'usertransport']:
            user_transport()
        elif argv[1] in ['u0', 'userdisable']:
            user_disable()
        elif argv[1] in ['u1', 'userenable']:
            user_enable()
        elif argv[1] in ['ud', 'userdelete']:
            user_delete()
        elif argv[1] in ['aa', 'aliasadd']:
            alias_add()
        elif argv[1] in ['ai', 'aliasinfo']:
            alias_info()
        elif argv[1] in ['ad', 'aliasdelete']:
            alias_delete()
        elif argv[1] in ['gu', 'getuser']:
            user_byID()
        elif argv[1] in ['ld', 'listdomains']:
            domain_list()
        elif argv[1] in ['h', 'help']:
            usage()
        elif argv[1] in ['v', 'version']:
            show_version()
        else:
            usage(EXIT.UNKNOWN_COMMAND,
                    u"%s: »%s«" % (_('Unknown subcommand'), argv[1]))
        show_warnings()
    except (EOFError, KeyboardInterrupt):
        w_err(EXIT.USER_INTERRUPT, '\n%s!\n' % _(u'Ouch'))
    except (VMME.VMMConfigException, VMME.VMMException), e:
        w_err(e.code(), "%s: %s" % (_(u'Error'), e.msg()))