VMM/Config: moved Config.sections() to class LazyConfig.
No longer import the ENCODING from VirtualMailManager, it's no longer required
in the Config module.
# -*- coding: UTF-8 -*-# Copyright (c) 2007 - 2010, Pascal Volk# See COPYING for distribution information.# package initialization code#importgettextimportosimportreimportlocalefromencodings.idnaimportToASCII,ToUnicodefromVirtualMailManager.constants.ERRORimport \DOMAIN_INVALID,DOMAIN_TOO_LONG,LOCALPART_INVALID,LOCALPART_TOO_LONG, \NOT_EXECUTABLE,NO_SUCH_BINARY,NO_SUCH_DIRECTORYfromVirtualMailManager.constants.VERSIONimport*fromVirtualMailManager.ExceptionsimportVMMException__all__=[# imported modules'os','re','locale',# version information from VERSION'__author__','__date__','__version__',# error codes'ENCODING','ace2idna','check_domainname','check_localpart','exec_ok','expand_path','get_unicode','idn2ascii','is_dir',]# Try to set all of the locales according to the current# environment variables and get the character encoding.try:locale.setlocale(locale.LC_ALL,'')exceptlocale.Error:locale.setlocale(locale.LC_ALL,'C')ENCODING=locale.nl_langinfo(locale.CODESET)RE_ASCII_CHARS=r"^[\x20-\x7E]*$"RE_DOMAIN=r"^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$"RE_LOCALPART=r"[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]"# there may be many domain and e-mail address checksre_obj_domain=re.compile(RE_DOMAIN)re_obj_localpart=re.compile(RE_LOCALPART)gettext.install('vmm','/usr/local/share/locale',unicode=1)defget_unicode(string):"""Converts `string` to `unicode`, if necessary."""ifisinstance(string,unicode):returnstringreturnunicode(string,ENCODING,'replace')defexpand_path(path):"""Expands paths, starting with ``.`` or ``~``, to an absolute path."""ifpath.startswith('.'):returnos.path.abspath(path)ifpath.startswith('~'):returnos.path.expanduser(path)returnpathdefis_dir(path):"""Checks if ``path`` is a directory. Throws a `VMMException` if ``path`` is not a directory. """path=expand_path(path)ifnotos.path.isdir(path):raiseVMMException(_(u'“%s” is not a directory')%get_unicode(path),NO_SUCH_DIRECTORY)returnpathdefexec_ok(binary):"""Checks if the ``binary`` exists and if it is executable. Throws a `VMMException` if the ``binary`` isn't a file or is not executable. """binary=expand_path(binary)ifnotos.path.isfile(binary):raiseVMMException(_(u'“%s” is not a file')%get_unicode(binary),NO_SUCH_BINARY)ifnotos.access(binary,os.X_OK):raiseVMMException(_(u'File is not executable: “%s”')%get_unicode(binary),NOT_EXECUTABLE)returnbinarydefidn2ascii(domainname):"""Converts the idn domain name `domainname` into punycode."""return'.'.join([ToASCII(lbl)forlblindomainname.split('.')iflbl])deface2idna(domainname):"""Converts the domain name `domainname` from ACE according to IDNA."""returnu'.'.join([ToUnicode(lbl)forlblindomainname.split('.')iflbl])defcheck_domainname(domainname):"""Returns the validated domain name `domainname`. It also converts the name of the domain from IDN to ASCII, if necessary. Throws an `VMMException`, if the domain name is too long or doesn't look like a valid domain name (label.label.label). """ifnotre_obj_domain.match(domainname):domainname=idn2ascii(domainname)iflen(domainname)>255:raiseVMMException(_(u'The domain name is too long'),DOMAIN_TOO_LONG)ifnotre_obj_domain.match(domainname):raiseVMMException(_(u'The domain name %r is invalid')%domainname,DOMAIN_INVALID)returndomainnamedefcheck_localpart(localpart):"""Returns the validated local-part *localpart*. Throws a `VMMException` if the local-part is too long or contains invalid characters. """iflen(localpart)>64:raiseVMMException(_(u'The local-part %r is too long')%localpart,LOCALPART_TOO_LONG)invalid_chars=set(re_obj_localpart.findall(localpart))ifinvalid_chars:i_chars=u''.join((u'"%s" '%cforcininvalid_chars))raiseVMMException(_(u"The local-part %(l_part)r contains invalid \characters: %(i_chars)s")%{'l_part':localpart,'i_chars':i_chars},LOCALPART_INVALID)returnlocalpart