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 |
|