Provide list{addresses,aliases,users,relocated} subcommands
The patch provides the list{addresses,aliases,users,relocated} subcommands to
the UI. All commands actually take the same path in the code and only one
query is run with different parameters for each case.
There are still two shortcomings:
1. With alias domains, the output order is not as one might want it, e.g.
foo@example.org
bar@example.org
foo@example.com
bar@example.com
when it should really be foo@ twice and then bar@ twice. I have not found
a way to modify the SQL accordingly.
2. The SELECT queries for Accounts, Alias and Relocated are hard-coded in
common.py.
# -*- coding: UTF-8 -*-# Copyright (c) 2010 - 2011, Pascal Volk# See COPYING for distribution information.""" VirtualMailManager.cli.handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A derived Handler class with a few changes/additions for cli use."""importosfromVirtualMailManager.errorsimportVMMErrorfromVirtualMailManager.handlerimportHandlerfromVirtualMailManager.cliimportread_passfromVirtualMailManager.cli.configimportCliConfigasCfgfromVirtualMailManager.constantsimportACCOUNT_EXISTS,INVALID_SECTION, \NO_SUCH_ACCOUNT,TYPE_ACCOUNTfromVirtualMailManager.passwordimportrandompw_=lambdamsg:msgclassCliHandler(Handler):"""This class uses a `CliConfig` for configuration stuff, instead of the non-interactive `Config` class. It provides the additional methods cfgSet() and configure(). Additionally it uses `VirtualMailManager.cli.read_pass()` for for the interactive password dialog. """__slots__=()# nothing additional, also no __dict__/__weakref__def__init__(self):"""Creates a new CliHandler instance. Throws a NotRootError if your uid is greater 0. """# Overwrite the parent CTor partly, we use the CliConfig class# and add some command line checks.skip_some_checks=os.sys.argv[1]in('cf','configure','h','help','v','version')super(CliHandler,self).__init__(skip_some_checks)self._cfg=Cfg(self._cfg_fname)self._cfg.load()defcfg_set(self,option,value):"""Set a new value for the given option."""returnself._cfg.set(option,value)defconfigure(self,section=None):"""Starts the interactive configuration. Configures in interactive mode options in the given ``section``. If no section is given (default) all options from all sections will be prompted. """ifsectionisNone:self._cfg.configure(self._cfg.sections())elifself._cfg.has_section(section):self._cfg.configure([section])else:raiseVMMError(_(u"Invalid section: '%s'")%section,INVALID_SECTION)defuser_add(self,emailaddress,password=None):"""Override the parent user_add() - add the interactive password dialog. Returns the generated password, if account.random_password == True. """acc=self._get_account(emailaddress)ifacc:raiseVMMError(_(u"The account '%s' already exists.")%acc.address,ACCOUNT_EXISTS)self._is_other_address(acc.address,TYPE_ACCOUNT)rand_pass=self._cfg.dget('account.random_password')ifpasswordisNone:password=(read_pass,randompw)[rand_pass]()acc.set_password(password)acc.save()self._make_account_dirs(acc)return(None,password)[rand_pass]defuser_password(self,emailaddress,password=None):"""Override the parent user_password() - add the interactive password dialog."""acc=self._get_account(emailaddress)ifnotacc:raiseVMMError(_(u"The account '%s' does not exist.")%acc.address,NO_SUCH_ACCOUNT)ifnotisinstance(password,basestring)ornotpassword:password=read_pass()acc.modify('password',password)del_