summaryrefslogtreecommitdiff
path: root/reconfigure/parsers/ini.py
diff options
context:
space:
mode:
authorAndrew Shadura <andrew@shadura.me>2015-08-20 15:58:26 +0200
committerAndrew Shadura <andrew@shadura.me>2015-08-20 15:58:26 +0200
commitff1408420159488a106492ccd11dd234967029b6 (patch)
tree473420cee1c5229a427ec4cafead1aa6c0a26800 /reconfigure/parsers/ini.py
Imported Upstream version 0.1.29
Diffstat (limited to 'reconfigure/parsers/ini.py')
-rw-r--r--reconfigure/parsers/ini.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/reconfigure/parsers/ini.py b/reconfigure/parsers/ini.py
new file mode 100644
index 0000000..dbd0c7c
--- /dev/null
+++ b/reconfigure/parsers/ini.py
@@ -0,0 +1,70 @@
+from reconfigure.nodes import *
+from reconfigure.parsers import BaseParser
+from iniparse import INIConfig
+from StringIO import StringIO
+
+
+class IniFileParser (BaseParser):
+ """
+ A parser for standard ``.ini`` config files.
+
+ :param sectionless: if ``True``, allows a section-less attributes appear in the beginning of file
+ """
+
+ def __init__(self, sectionless=False, nullsection='__default__'):
+ self.sectionless = sectionless
+ self.nullsection = nullsection
+
+ def _get_comment(self, container):
+ c = container.contents[0].comment
+ return c.strip() if c else None
+
+ def _set_comment(self, container, comment):
+ if comment:
+ container.contents[0].comment = comment
+ container.contents[0].comment_separator = ';'
+
+ def parse(self, content):
+ content = '\n'.join(filter(None, [x.strip() for x in content.splitlines()]))
+ if self.sectionless:
+ content = '[' + self.nullsection + ']\n' + content
+ data = StringIO(content)
+ cp = INIConfig(data, optionxformvalue=lambda x: x)
+
+ root = RootNode()
+ for section in cp:
+ name = section
+ if self.sectionless and section == self.nullsection:
+ name = None
+ section_node = Node(name)
+ section_node.comment = self._get_comment(cp[section]._lines[0])
+ for option in cp[section]:
+ if option in cp[section]._options:
+ node = PropertyNode(option, cp[section][option])
+ node.comment = self._get_comment(cp[section]._options[option])
+ section_node.children.append(node)
+ root.children.append(section_node)
+ return root
+
+ def stringify(self, tree):
+ cp = INIConfig()
+
+ for section in tree.children:
+ if self.sectionless and section.name is None:
+ sectionname = self.nullsection
+ else:
+ sectionname = section.name
+ cp._new_namespace(sectionname)
+ for option in section.children:
+ if not isinstance(option, PropertyNode):
+ raise TypeError('Third level nodes should be PropertyNodes')
+ cp[sectionname][option.name] = option.value
+ if option.comment:
+ self._set_comment(cp[sectionname]._options[option.name], option.comment)
+ if hasattr(cp[sectionname], '_lines'):
+ self._set_comment(cp[sectionname]._lines[0], section.comment)
+
+ data = str(cp) + '\n'
+ if self.sectionless:
+ data = data.replace('[' + self.nullsection + ']\n', '')
+ return data