VirtualMailManager/ext/Postconf.py
changeset 571 a4aead244f75
parent 465 c0e1fb1b0145
parent 570 28230a8230bf
child 572 3238c58d01ae
equal deleted inserted replaced
465:c0e1fb1b0145 571:a4aead244f75
     1 # -*- coding: UTF-8 -*-
       
     2 # Copyright (c) 2008 - 2010, Pascal Volk
       
     3 # See COPYING for distribution information.
       
     4 
       
     5 """A small - r/o - wrapper class for Postfix' postconf."""
       
     6 
       
     7 from subprocess import Popen, PIPE
       
     8 
       
     9 from __main__ import re, ERR
       
    10 from VirtualMailManager.Exceptions import VMMException
       
    11 
       
    12 RE_PC_PARAMS = """^\w+$"""
       
    13 RE_PC_VARIABLES = r"""\$\b\w+\b"""
       
    14 
       
    15 class Postconf(object):
       
    16     __slots__ = ('__bin', '__val', '__varFinder')
       
    17     def __init__(self, postconf_bin):
       
    18         """Creates a new Postconf instance.
       
    19 
       
    20         Keyword arguments:
       
    21         postconf_bin -- absolute path to the Postfix postconf binary (str)
       
    22         """
       
    23         self.__bin = postconf_bin
       
    24         self.__val = ''
       
    25         self.__varFinder = re.compile(RE_PC_VARIABLES)
       
    26 
       
    27     def read(self, parameter, expand_vars=True):
       
    28         """Returns the parameters value.
       
    29 
       
    30         If expand_vars is True (default), all variables in the value will be
       
    31         expanded:
       
    32         e.g. mydestination -> mail.example.com, localhost.example.com, localhost
       
    33         Otherwise the value may contain one or more variables.
       
    34         e.g. mydestination -> $myhostname, localhost.$mydomain, localhost
       
    35 
       
    36         Keyword arguments:
       
    37         parameter -- the name of a Postfix configuration parameter (str)
       
    38         expand_vars -- default True (bool)
       
    39         """
       
    40         if not re.match(RE_PC_PARAMS, parameter):
       
    41             raise VMMException(_(u'The value ā€œ%sā€ doesn\'t look like a valid\
       
    42  postfix configuration parameter name.') % parameter, ERR.VMM_ERROR)
       
    43         self.__val = self.__read(parameter)
       
    44         if expand_vars:
       
    45             self.__expandVars()
       
    46         return self.__val
       
    47 
       
    48     def __expandVars(self):
       
    49         while True:
       
    50             pvars = set(self.__varFinder.findall(self.__val))
       
    51             pvars_len = len(pvars)
       
    52             if pvars_len < 1:
       
    53                 break
       
    54             if pvars_len > 1:
       
    55                 self.__expandMultiVars(self.__readMulti(pvars))
       
    56                 continue
       
    57             pvars = pvars.pop()
       
    58             self.__val = self.__val.replace(pvars, self.__read(pvars[1:]))
       
    59 
       
    60     def __expandMultiVars(self, old_new):
       
    61         for old, new in old_new.items():
       
    62             self.__val = self.__val.replace('$'+old, new)
       
    63 
       
    64     def __read(self, parameter):
       
    65         out, err = Popen([self.__bin, '-h', parameter], stdout=PIPE,
       
    66                 stderr=PIPE).communicate()
       
    67         if len(err):
       
    68             raise VMMException(err.strip(), ERR.VMM_ERROR)
       
    69         return out.strip()
       
    70 
       
    71     def __readMulti(self, parameters):
       
    72         cmd = [self.__bin]
       
    73         for parameter in parameters:
       
    74             cmd.append(parameter[1:])
       
    75         out, err = Popen(cmd, stdout=PIPE, stderr=PIPE).communicate()
       
    76         if len(err):
       
    77             raise VMMException(err.strip(), ERR.VMM_ERROR)
       
    78         par_val = {}
       
    79         for line in out.splitlines():
       
    80             par, val = line.split(' = ')
       
    81             par_val[par] = val
       
    82         return par_val
       
    83