source: cows_wps/trunk/cows_wps/utils/case_sensitive_ordered_config_parser.py @ 7525

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows_wps/trunk/cows_wps/utils/case_sensitive_ordered_config_parser.py@7575
Revision 7525, 4.7 KB checked in by astephen, 9 years ago (diff)

Added bin/create_policy_file.py
To allow auto-generation of policy.xml NDG-security file.

Line 
1"""
2case_sensitive_ordered_config_parser.py
3=======================================
4
5Holds a sub-class of ConfigParser that includes an additional dictionary
6called _option_orders. This includes keys of section_name and each holds
7a list of option keys in the order they are found in the config file.
8Also retains case in config file contents.
9
10"""
11
12from ConfigParser import *
13
14import logging
15log = logging.getLogger(__name__)
16
17
18class CaseSensitiveConfigParser(ConfigParser):
19    "Sub-class allowing case sensitive keys."
20    # Fix parser to be case sensitive
21    optionxform = str
22
23
24class CaseSensitiveOrderedConfigParser(ConfigParser):
25    """
26    Sub-class of ConfigParser that includes an additional dictionary
27    called _option_orders. This includes keys of section_name and each holds
28    a list of option keys in the order they are found in the config file.
29
30    Also retains Case in config file contents.
31    """
32
33    # Fix parser to be case sensitive
34    optionxform = str
35    _option_orders = {}
36
37    # Now re-write _read() to include a new instance object called self._option_orders
38    # that is a dictionary holding {option_name: [opt1, opt2, opt3...optn]}
39    def _read(self, fp, fpname):
40        """Parse a sectioned setup file.
41
42        The sections in setup file contains a title line at the top,
43        indicated by a name in square brackets (`[]'), plus key/value
44        options lines, indicated by `name: value' format lines.
45        Continuations are represented by an embedded newline then
46        leading whitespace.  Blank lines, lines beginning with a '#',
47        and just about everything else are ignored.
48        """
49        cursect = None                            # None, or a dictionary
50        optname = None
51        lineno = 0
52        e = None                                  # None, or an exception
53        while True:
54            line = fp.readline()
55            if not line:
56                break
57            lineno = lineno + 1
58            # comment or blank line?
59            if line.strip() == '' or line[0] in '#;':
60                continue
61            if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
62                # no leading whitespace
63                continue
64            # continuation line?
65            if line[0].isspace() and cursect is not None and optname:
66                value = line.strip()
67                if value:
68                    cursect[optname] = "%s\n%s" % (cursect[optname], value)
69            # a section header or option header?
70            else:
71                # is it a section header?
72                mo = self.SECTCRE.match(line)
73                if mo:
74                    sectname = mo.group('header')
75                    if sectname in self._sections:
76                        cursect = self._sections[sectname]
77                    elif sectname == DEFAULTSECT:
78                        cursect = self._defaults
79                    else:
80                        cursect = {'__name__': sectname}
81                        self._sections[sectname] = cursect
82                        self._option_orders[sectname] = []
83                    # So sections can't start with a continuation line
84                    optname = None
85                # no section header in the file?
86                elif cursect is None:
87                    raise MissingSectionHeaderError(fpname, lineno, line)
88                # an option line?
89                else:
90                    mo = self.OPTCRE.match(line)
91                    if mo:
92                        optname, vi, optval = mo.group('option', 'vi', 'value')
93                        if vi in ('=', ':') and ';' in optval:
94                            # ';' is a comment delimiter only if it follows
95                            # a spacing character
96                            pos = optval.find(';')
97                            if pos != -1 and optval[pos-1].isspace():
98                                optval = optval[:pos]
99                        optval = optval.strip()
100                        # allow empty values
101                        if optval == '""':
102                            optval = ''
103                        optname = self.optionxform(optname.rstrip())
104                        cursect[optname] = optval
105                        self._option_orders[cursect["__name__"]].append(optname)
106                    else:
107                        # a non-fatal parsing error occurred.  set up the
108                        # exception but keep going. the exception will be
109                        # raised at the end of the file and will contain a
110                        # list of all bogus lines
111                        if not e:
112                            e = ParsingError(fpname)
113                        e.append(lineno, repr(line))
114        # if any parsing errors occurred, raise an exception
115        if e:
116            raise e
Note: See TracBrowser for help on using the repository browser.