[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@18.219.119.163: ~ $
"""Access and/or modify INI files

* Compatiable with ConfigParser
* Preserves order of sections & options
* Preserves comments/blank lines/etc
* More conveninet access to data

Example:

    >>> from StringIO import StringIO
    >>> sio = StringIO('''# configure foo-application
    ... [foo]
    ... bar1 = qualia
    ... bar2 = 1977
    ... [foo-ext]
    ... special = 1''')

    >>> cfg = INIConfig(sio)
    >>> print cfg.foo.bar1
    qualia
    >>> print cfg['foo-ext'].special
    1
    >>> cfg.foo.newopt = 'hi!'
    >>> cfg.baz.enabled = 0

    >>> print cfg
    # configure foo-application
    [foo]
    bar1 = qualia
    bar2 = 1977
    newopt = hi!
    [foo-ext]
    special = 1
    <BLANKLINE>
    [baz]
    enabled = 0

"""

# An ini parser that supports ordered sections/options
# Also supports updates, while preserving structure
# Backward-compatiable with ConfigParser

import re
from ConfigParser import DEFAULTSECT, ParsingError, MissingSectionHeaderError

import config

class LineType(object):
    line = None

    def __init__(self, line=None):
        if line is not None:
            self.line = line.strip('\n')

    # Return the original line for unmodified objects
    # Otherwise construct using the current attribute values
    def __str__(self):
        if self.line is not None:
            return self.line
        else:
            return self.to_string()

    # If an attribute is modified after initialization
    # set line to None since it is no longer accurate.
    def __setattr__(self, name, value):
        if hasattr(self,name):
            self.__dict__['line'] = None
        self.__dict__[name] = value

    def to_string(self):
        raise Exception('This method must be overridden in derived classes')


class SectionLine(LineType):
    regex =  re.compile(r'^\['
                        r'(?P<name>[^]]+)'
                        r'\]\s*'
                        r'((?P<csep>;|#)(?P<comment>.*))?$')

    def __init__(self, name, comment=None, comment_separator=None,
                             comment_offset=-1, line=None):
        super(SectionLine, self).__init__(line)
        self.name = name
        self.comment = comment
        self.comment_separator = comment_separator
        self.comment_offset = comment_offset

    def to_string(self):
        out = '[' + self.name + ']'
        if self.comment is not None:
            # try to preserve indentation of comments
            out = (out+' ').ljust(self.comment_offset)
            out = out + self.comment_separator + self.comment
        return out

    def parse(cls, line):
        m = cls.regex.match(line.rstrip())
        if m is None:
            return None
        return cls(m.group('name'), m.group('comment'),
                   m.group('csep'), m.start('csep'),
                   line)
    parse = classmethod(parse)


class OptionLine(LineType):
    def __init__(self, name, value, separator=' = ', comment=None,
                 comment_separator=None, comment_offset=-1, line=None):
        super(OptionLine, self).__init__(line)
        self.name = name
        self.value = value
        self.separator = separator
        self.comment = comment
        self.comment_separator = comment_separator
        self.comment_offset = comment_offset

    def to_string(self):
        out = '%s%s%s' % (self.name, self.separator, self.value)
        if self.comment is not None:
            # try to preserve indentation of comments
            out = (out+' ').ljust(self.comment_offset)
            out = out + self.comment_separator + self.comment
        return out

    regex = re.compile(r'^(?P<name>[^:=\s[][^:=]*)'
                       r'(?P<sep>[:=]\s*)'
                       r'(?P<value>.*)$')

    def parse(cls, line):
        m = cls.regex.match(line.rstrip())
        if m is None:
            return None

        name = m.group('name').rstrip()
        value = m.group('value')
        sep = m.group('name')[len(name):] + m.group('sep')

        # comments are not detected in the regex because
        # ensuring total compatibility with ConfigParser
        # requires that:
        #     option = value    ;comment   // value=='value'
        #     option = value;1  ;comment   // value=='value;1  ;comment'
        #
        # Doing this in a regex would be complicated.  I
        # think this is a bug.  The whole issue of how to
        # include ';' in the value needs to be addressed.
        # Also, '#' doesn't mark comments in options...

        coff = value.find(';')
        if coff != -1 and value[coff-1].isspace():
            comment = value[coff+1:]
            csep = value[coff]
            value = value[:coff].rstrip()
            coff = m.start('value') + coff
        else:
            comment = None
            csep = None
            coff = -1

        return cls(name, value, sep, comment, csep, coff, line)
    parse = classmethod(parse)


def change_comment_syntax(comment_chars='%;#', allow_rem=False):
    comment_chars = re.sub(r'([\]\-\^])', r'\\\1', comment_chars)
    regex = r'^(?P<csep>[%s]' % comment_chars
    if allow_rem:
        regex += '|[rR][eE][mM]'
    regex += r')(?P<comment>.*)$'
    CommentLine.regex = re.compile(regex)

class CommentLine(LineType):
    regex = re.compile(r'^(?P<csep>[;#]|[rR][eE][mM] +)'
                       r'(?P<comment>.*)$')

    def __init__(self, comment='', separator='#', line=None):
        super(CommentLine, self).__init__(line)
        self.comment = comment
        self.separator = separator

    def to_string(self):
        return self.separator + self.comment

    def parse(cls, line):
        m = cls.regex.match(line.rstrip())
        if m is None:
            return None
        return cls(m.group('comment'), m.group('csep'), line)
    parse = classmethod(parse)


class EmptyLine(LineType):
    # could make this a singleton
    def to_string(self):
        return ''

    value = property(lambda _: '')

    def parse(cls, line):
        if line.strip(): return None
        return cls(line)
    parse = classmethod(parse)


class ContinuationLine(LineType):
    regex = re.compile(r'^\s+(?P<value>.*)$')

    def __init__(self, value, value_offset=None, line=None):
        super(ContinuationLine, self).__init__(line)
        self.value = value
        if value_offset is None:
            value_offset = 8
        self.value_offset = value_offset

    def to_string(self):
        return ' '*self.value_offset + self.value

    def parse(cls, line):
        m = cls.regex.match(line.rstrip())
        if m is None:
            return None
        return cls(m.group('value'), m.start('value'), line)
    parse = classmethod(parse)


class LineContainer(object):
    def __init__(self, d=None):
        self.contents = []
        self.orgvalue = None
        if d:
            if isinstance(d, list): self.extend(d)
            else: self.add(d)

    def add(self, x):
        self.contents.append(x)

    def extend(self, x):
        for i in x: self.add(i)

    def get_name(self):
        return self.contents[0].name

    def set_name(self, data):
        self.contents[0].name = data

    def get_value(self):
        if self.orgvalue is not None:
            return self.orgvalue
        elif len(self.contents) == 1:
            return self.contents[0].value
        else:
            return '\n'.join([('%s' % x.value) for x in self.contents
                              if not isinstance(x, CommentLine)])

    def set_value(self, data):
        self.orgvalue = data
        lines = ('%s' % data).split('\n')

        # If there is an existing ContinuationLine, use its offset
        value_offset = None
        for v in self.contents:
            if isinstance(v, ContinuationLine):
                value_offset = v.value_offset
                break

        # Rebuild contents list, preserving initial OptionLine
        self.contents = self.contents[0:1]
        self.contents[0].value = lines[0]
        del lines[0]
        for line in lines:
            if line.strip():
                self.add(ContinuationLine(line, value_offset))
            else:
                self.add(EmptyLine())

    name = property(get_name, set_name)
    value = property(get_value, set_value)

    def __str__(self):
        s = [x.__str__() for x in self.contents]
        return '\n'.join(s)

    def finditer(self, key):
        for x in self.contents[::-1]:
            if hasattr(x, 'name') and x.name==key:
                yield x

    def find(self, key):
        for x in self.finditer(key):
            return x
        raise KeyError(key)


def _make_xform_property(myattrname, srcattrname=None):
    private_attrname = myattrname + 'value'
    private_srcname = myattrname + 'source'
    if srcattrname is None:
        srcattrname = myattrname

    def getfn(self):
        srcobj = getattr(self, private_srcname)
        if srcobj is not None:
            return getattr(srcobj, srcattrname)
        else:
            return getattr(self, private_attrname)

    def setfn(self, value):
        srcobj = getattr(self, private_srcname)
        if srcobj is not None:
            setattr(srcobj, srcattrname, value)
        else:
            setattr(self, private_attrname, value)

    return property(getfn, setfn)


class INISection(config.ConfigNamespace):
    _lines = None
    _options = None
    _defaults = None
    _optionxformvalue = None
    _optionxformsource = None
    _compat_skip_empty_lines = set()
    def __init__(self, lineobj, defaults = None,
                       optionxformvalue=None, optionxformsource=None):
        self._lines = [lineobj]
        self._defaults = defaults
        self._optionxformvalue = optionxformvalue
        self._optionxformsource = optionxformsource
        self._options = {}

    _optionxform = _make_xform_property('_optionxform')

    def _compat_get(self, key):
        # identical to __getitem__ except that _compat_XXX
        # is checked for backward-compatible handling
        if key == '__name__':
            return self._lines[-1].name
        if self._optionxform: key = self._optionxform(key)
        try:
            value = self._options[key].value
            del_empty = key in self._compat_skip_empty_lines
        except KeyError:
            if self._defaults and key in self._defaults._options:
                value = self._defaults._options[key].value
                del_empty = key in self._defaults._compat_skip_empty_lines
            else:
                raise
        if del_empty:
            value = re.sub('\n+', '\n', value)
        return value

    def _getitem(self, key):
        if key == '__name__':
            return self._lines[-1].name
        if self._optionxform: key = self._optionxform(key)
        try:
            return self._options[key].value
        except KeyError:
            if self._defaults and key in self._defaults._options:
                return self._defaults._options[key].value
            else:
                raise

    def __setitem__(self, key, value):
        if self._optionxform: xkey = self._optionxform(key)
        else: xkey = key
        if xkey in self._compat_skip_empty_lines:
            self._compat_skip_empty_lines.remove(xkey)
        if xkey not in self._options:
            # create a dummy object - value may have multiple lines
            obj = LineContainer(OptionLine(key, ''))
            self._lines[-1].add(obj)
            self._options[xkey] = obj
        # the set_value() function in LineContainer
        # automatically handles multi-line values
        self._options[xkey].value = value

    def __delitem__(self, key):
        if self._optionxform: key = self._optionxform(key)
        if key in self._compat_skip_empty_lines:
            self._compat_skip_empty_lines.remove(key)
        for l in self._lines:
            remaining = []
            for o in l.contents:
                if isinstance(o, LineContainer):
                    n = o.name
                    if self._optionxform: n = self._optionxform(n)
                    if key != n: remaining.append(o)
                else:
                    remaining.append(o)
            l.contents = remaining
        del self._options[key]

    def __iter__(self):
        d = set()
        for l in self._lines:
            for x in l.contents:
                if isinstance(x, LineContainer):
                    if self._optionxform:
                        ans = self._optionxform(x.name)
                    else:
                        ans = x.name
                    if ans not in d:
                        yield ans
                        d.add(ans)
        if self._defaults:
            for x in self._defaults:
                if x not in d:
                    yield x
                    d.add(x)

    def _new_namespace(self, name):
        raise Exception('No sub-sections allowed', name)


def make_comment(line):
    return CommentLine(line.rstrip('\n'))


def readline_iterator(f):
    """iterate over a file by only using the file object's readline method"""

    have_newline = False
    while True:
        line = f.readline()

        if not line:
            if have_newline:
                yield ""
            return

        if line.endswith('\n'):
            have_newline = True
        else:
            have_newline = False

        yield line


def lower(x):
    return x.lower()


class INIConfig(config.ConfigNamespace):
    _data = None
    _sections = None
    _defaults = None
    _optionxformvalue = None
    _optionxformsource = None
    _sectionxformvalue = None
    _sectionxformsource = None
    _parse_exc = None
    _bom = False
    def __init__(self, fp=None, defaults=None, parse_exc=True,
                 optionxformvalue=lower, optionxformsource=None,
                 sectionxformvalue=None, sectionxformsource=None):
        self._data = LineContainer()
        self._parse_exc = parse_exc
        self._optionxformvalue = optionxformvalue
        self._optionxformsource = optionxformsource
        self._sectionxformvalue = sectionxformvalue
        self._sectionxformsource = sectionxformsource
        self._sections = {}
        if defaults is None: defaults = {}
        self._defaults = INISection(LineContainer(), optionxformsource=self)
        for name, value in defaults.iteritems():
            self._defaults[name] = value
        if fp is not None:
            self._readfp(fp)

    _optionxform = _make_xform_property('_optionxform', 'optionxform')
    _sectionxform = _make_xform_property('_sectionxform', 'optionxform')

    def _getitem(self, key):
        if key == DEFAULTSECT:
            return self._defaults
        if self._sectionxform: key = self._sectionxform(key)
        return self._sections[key]

    def __setitem__(self, key, value):
        raise Exception('Values must be inside sections', key, value)

    def __delitem__(self, key):
        if self._sectionxform: key = self._sectionxform(key)
        for line in self._sections[key]._lines:
            self._data.contents.remove(line)
        del self._sections[key]

    def __iter__(self):
        d = set()
        d.add(DEFAULTSECT)
        for x in self._data.contents:
            if isinstance(x, LineContainer):
                if x.name not in d:
                    yield x.name
                    d.add(x.name)

    def _new_namespace(self, name):
        if self._data.contents:
            self._data.add(EmptyLine())
        obj = LineContainer(SectionLine(name))
        self._data.add(obj)
        if self._sectionxform: name = self._sectionxform(name)
        if name in self._sections:
            ns = self._sections[name]
            ns._lines.append(obj)
        else:
            ns = INISection(obj, defaults=self._defaults,
                            optionxformsource=self)
            self._sections[name] = ns
        return ns

    def __str__(self):
        if self._bom:
            fmt = u'\ufeff%s'
        else:
            fmt = '%s'
        return fmt % self._data.__str__()

    __unicode__ = __str__

    _line_types = [EmptyLine, CommentLine,
                   SectionLine, OptionLine,
                   ContinuationLine]

    def _parse(self, line):
        for linetype in self._line_types:
            lineobj = linetype.parse(line)
            if lineobj:
                return lineobj
        else:
            # can't parse line
            return None

    def _readfp(self, fp):
        cur_section = None
        cur_option = None
        cur_section_name = None
        cur_option_name = None
        pending_lines = []
        pending_empty_lines = False
        try:
            fname = fp.name
        except AttributeError:
            fname = '<???>'
        linecount = 0
        exc = None
        line = None

        for line in readline_iterator(fp):
            # Check for BOM on first line
            if linecount == 0 and isinstance(line, unicode):
                if line[0] == u'\ufeff':
                    line = line[1:]
                    self._bom = True

            lineobj = self._parse(line)
            linecount += 1

            if not cur_section and not isinstance(lineobj,
                                (CommentLine, EmptyLine, SectionLine)):
                if self._parse_exc:
                    raise MissingSectionHeaderError(fname, linecount, line)
                else:
                    lineobj = make_comment(line)

            if lineobj is None:
                if self._parse_exc:
                    if exc is None: exc = ParsingError(fname)
                    exc.append(linecount, line)
                lineobj = make_comment(line)

            if isinstance(lineobj, ContinuationLine):
                if cur_option:
                    if pending_lines:
                        cur_option.extend(pending_lines)
                        pending_lines = []
                        if pending_empty_lines:
                            optobj._compat_skip_empty_lines.add(cur_option_name)
                            pending_empty_lines = False
                    cur_option.add(lineobj)
                else:
                    # illegal continuation line - convert to comment
                    if self._parse_exc:
                        if exc is None: exc = ParsingError(fname)
                        exc.append(linecount, line)
                    lineobj = make_comment(line)

            if isinstance(lineobj, OptionLine):
                if pending_lines:
                    cur_section.extend(pending_lines)
                    pending_lines = []
                    pending_empty_lines = False
                cur_option = LineContainer(lineobj)
                cur_section.add(cur_option)
                if self._optionxform:
                    cur_option_name = self._optionxform(cur_option.name)
                else:
                    cur_option_name = cur_option.name
                if cur_section_name == DEFAULTSECT:
                    optobj = self._defaults
                else:
                    optobj = self._sections[cur_section_name]
                optobj._options[cur_option_name] = cur_option

            if isinstance(lineobj, SectionLine):
                self._data.extend(pending_lines)
                pending_lines = []
                pending_empty_lines = False
                cur_section = LineContainer(lineobj)
                self._data.add(cur_section)
                cur_option = None
                cur_option_name = None
                if cur_section.name == DEFAULTSECT:
                    self._defaults._lines.append(cur_section)
                    cur_section_name = DEFAULTSECT
                else:
                    if self._sectionxform:
                        cur_section_name = self._sectionxform(cur_section.name)
                    else:
                        cur_section_name = cur_section.name
                    if cur_section_name not in self._sections:
                        self._sections[cur_section_name] = \
                                INISection(cur_section, defaults=self._defaults,
                                           optionxformsource=self)
                    else:
                        self._sections[cur_section_name]._lines.append(cur_section)

            if isinstance(lineobj, (CommentLine, EmptyLine)):
                pending_lines.append(lineobj)
                if isinstance(lineobj, EmptyLine):
                    pending_empty_lines = True

        self._data.extend(pending_lines)
        if line and line[-1]=='\n':
            self._data.add(EmptyLine())

        if exc:
            raise exc



Filemanager

Name Type Size Permission Actions
.__init__.pyo.40009 File 945 B 0644
.compat.pyo.40009 File 12.54 KB 0644
.config.pyo.40009 File 9.37 KB 0644
.ini.pyo.40009 File 19.94 KB 0644
.utils.pyo.40009 File 1.39 KB 0644
__init__.py File 1.08 KB 0644
__init__.pyc File 945 B 0644
__init__.pyo File 945 B 0644
compat.py File 11.82 KB 0644
compat.pyc File 12.54 KB 0644
compat.pyo File 12.54 KB 0644
config.py File 8.11 KB 0644
config.pyc File 9.37 KB 0644
config.pyo File 9.37 KB 0644
ini.py File 20.17 KB 0644
ini.pyc File 19.94 KB 0644
ini.pyo File 19.94 KB 0644
utils.py File 1.24 KB 0644
utils.pyc File 1.39 KB 0644
utils.pyo File 1.39 KB 0644