<commit_before>#!/usr/bin/env python
#encoding:utf-8
#author:dbr/Ben
#project:tvnamer
#repository:http://github.com/dbr/tvnamer
#license:Creative Commons GNU GPL v2
# http://creativecommons.org/licenses/GPL/2.0/

"""Holds Config singleton
"""

import os
import xml
import xml.etree.ElementTree as ET

from tvnamer_exceptions import InvalidConfigFile, WrongConfigVersion


def _serialiseElement(root, name, elem, etype='option'):
    """Used for config XML saving, currently supports strings, integers
    and lists contains the any of these
    """
    celem = ET.SubElement(root, etype)
    if name is not None:
        celem.set('name', name)

    if isinstance(elem, bool):
        celem.set('type', 'bool')
        celem.text = str(elem)
        return
    elif isinstance(elem, int):
        celem.set('type', 'int')
        celem.text = str(elem)
        return
    elif isinstance(elem, basestring):
        celem.set('type', 'string')
        celem.text = elem
        return
    elif isinstance(elem, list):
        celem.set('type', 'list')
        for subelem in elem:
            _serialiseElement(celem, None, subelem, 'value')
        return
    elif elem is None:
        celem.set('type', 'None')
        celem.text = 'None'
    else:
        raise ValueError("Element %r (type: %s) could not be serialised" % (
            elem,
            type(elem)))


def _deserialiseItem(ctype, citem):
    """Used for config XML loading, currently supports strings, integers
    and lists contains the any of these
    """
    if ctype == 'int':
        return int(citem.text)
    elif ctype == 'string':
        if citem.text is None:
            # Empty string is serialised as None, rather than an empty string
            return ""
        else:
            return citem.text
    elif ctype == 'bool':
        if citem.text == 'True':
            return True
        elif citem.text == 'False':
            return False
        else:
            raise InvalidConfigFile(
                "Boolean value for %s was not 'True' or ', was %r" % (
                    citem.text))
    elif ctype == 'None':
        return None
    elif ctype == 'list':
        ret = []
        for subitem in citem:
            ret.append(_deserialiseItem(subitem.attrib['type'], subitem))
        return ret
    else:
        raise ValueError("Element %r (type: %s) could not be deserialised" % (
            citem,
            ctype))


def _indentTree(elem, level=0):
    """Inline-modification of ElementTree to "pretty-print" the XML
    """
    i = "\n" + "    "*level
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for child in elem:
            _indentTree(child, level+1)
        lastchild = elem[-1]
        if not lastchild.tail or not lastchild.tail.strip():
            lastchild.tail = i
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i


class _ConfigManager(dict):
    """Stores configuration options, deals with optional parsing and saving<commit_msg>Add ability to (de)serialise dictionary in config<commit_after>#!/usr/bin/env python
#encoding:utf-8
#author:dbr/Ben
#project:tvnamer
#repository:http://github.com/dbr/tvnamer
#license:Creative Commons GNU GPL v2
# http://creativecommons.org/licenses/GPL/2.0/

"""Holds Config singleton
"""

import os
import xml
import xml.etree.ElementTree as ET

from tvnamer_exceptions import InvalidConfigFile, WrongConfigVersion


def _serialiseElement(root, name, elem, etype='option'):
    """Used for config XML saving, currently supports strings, integers
    and lists contains the any of these
    """
    celem = ET.SubElement(root, etype)
    if name is not None:
        celem.set('name', name)

    if isinstance(elem, bool):
        celem.set('type', 'bool')
        celem.text = str(elem)
        return
    elif isinstance(elem, int):
        celem.set('type', 'int')
        celem.text = str(elem)
        return
    elif isinstance(elem, basestring):
        celem.set('type', 'string')
        celem.text = elem
        return
    elif isinstance(elem, list):
        celem.set('type', 'list')
        for subelem in elem:
            _serialiseElement(celem, None, subelem, 'value')
        return
    elif isinstance(elem, dict):
        celem.set('type', 'dict')
        for curkey, curvalue in elem.items():
            dicttree = ET.SubElement(celem, 'item')
            dicttree.set('key', curkey)
            dicttree.text = _serialiseElement(dicttree, None, curvalue, etype='value')
    elif elem is None:
        celem.set('type', 'None')
        celem.text = 'None'
    else:
        raise ValueError("Element %r (type: %s) could not be serialised" % (
            elem,
            type(elem)))


def _deserialiseItem(ctype, citem):
    """Used for config XML loading, currently supports strings, integers
    and lists contains the any of these
    """
    if ctype == 'int':
        return int(citem.text)
    elif ctype == 'string':
        if citem.text is None:
            # Empty string is serialised as None, rather than an empty string
            return ""
        else:
            return citem.text
    elif ctype == 'bool':
        if citem.text == 'True':
            return True
        elif citem.text == 'False':
            return False
        else:
            raise InvalidConfigFile(
                "Boolean value for %s was not 'True' or ', was %r" % (
                    citem.text))
    elif ctype == 'None':
        return None
    elif ctype == 'list':
        ret = []
        for subitem in citem:
            ret.append(_deserialiseItem(subitem.attrib['type'], subitem))
        return ret
    elif ctype == 'dict':
        ret = {}
        for curkey in citem:
            thekey = curkey.attrib['key']
            value_item = curkey.find('value')
            thevalue = _deserialiseItem(value_item.attrib['type'], value_item)

            ret[thekey] = thevalue
        return ret
    else:
        raise ValueError("Element %r (type: %s) could not be deserialised" % (
            citem,
            ctype))


def _indentTree(elem, level=0):
    """Inline-modification of ElementTree to "pretty-print" the XML
    """
    i = "\n" + "    "*level
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for child in elem:
            _indentTree(child, level+1)
        lastchild = elem[-1]
        if not lastchild.tail or not lastchild.tail.strip():
            lastchild.tail = i
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i


class _ConfigManager(dict):
    """Stores configuration options, deals with optional parsing and saving
{'fraction_non_alphanumeric': 0.11272984441301273, 'fraction_numerical': 0.0019801980198019802, 'mean_word_length': 2.1013157894736842, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1410622', 'n_tokens_mistral': 2107, 'n_tokens_neox': 2072, 'n_words': 636}