# -*- coding: UTF-8 -*-# Copyright (c) 2010 - 2013, Pascal Volk# See COPYING for distribution information.""" VirtualMailManager.cli.config ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Adds some interactive stuff to the Config class."""fromconfigparserimportRawConfigParserfromshutilimportcopy2fromstringimportTemplatefromVirtualMailManagerimportENCODINGfromVirtualMailManager.configimportConfig,ConfigValueError,LazyConfigfromVirtualMailManager.errorsimportConfigError,VMMErrorfromVirtualMailManager.cliimportw_err,w_stdfromVirtualMailManager.constantsimportCONF_ERROR,VMM_TOO_MANY_FAILURES_=lambdamsg:msgclassCliConfig(Config):"""Adds the interactive ``configure`` method to the `Config` class and overwrites `LazyConfig.set(), in order to update a single option in the configuration file with a single command line command. """defconfigure(self,sections):"""Interactive method for configuring all options of the given iterable ``sections`` object."""input_tpl=Template(_('Enter new value for option $option ''[$current_value]: '))failures=0w_std(_('Using configuration file: %s\n')%self._cfg_filename)forsectioninsections:w_std(_("* Configuration section: '%s'")%section)foropt,valinself.items(section):failures=0whileTrue:ifisinstance(val,str):val=val.encode(ENCODING,'replace').decode(ENCODING)newval=input(input_tpl.substitute(option=opt,current_value=val))ifnewvalandnewval!=val:try:LazyConfig.set(self,'%s.%s'%(section,opt),newval)breakexcept(ValueError,ConfigValueError,VMMError)aserr:w_err(0,_('Warning: %s')%err)failures+=1iffailures>2:raiseConfigError(_('Too many failures - try ''again later.'),VMM_TOO_MANY_FAILURES)else:breakprint()ifself._modified:self._save_changes()defset(self,option,value):"""Set the value of an option. If the new `value` has been set, the configuration file will be immediately updated. Throws a ``ConfigError`` if `value` couldn't be converted to ``LazyConfigOption.cls`` or ``LazyConfigOption.validate`` fails."""section,option_=self._get_section_option(option)try:val=self._cfg[section][option_].cls(value)ifself._cfg[section][option_].validate:val=self._cfg[section][option_].validate(val)except(ValueError,ConfigValueError)aserr:raiseConfigError(str(err),CONF_ERROR)# Do not write default values also skip identical valuesifnotself._cfg[section][option_].defaultisNone:old_val=self.dget(option)else:old_val=self.pget(option)ifval==old_val:returnifnotRawConfigParser.has_section(self,section):self.add_section(section)RawConfigParser.set(self,section,option_,val)self._save_changes()def_save_changes(self):"""Writes changes to the configuration file."""copy2(self._cfg_filename,self._cfg_filename+'.bak')withopen(self._cfg_filename,'w',encoding='utf-8')asself._cfg_file:self.write(self._cfg_file)del_