configreader.py :  » Network » Torrent-Swapper » swapper » Utility » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Network » Torrent Swapper 
Torrent Swapper » swapper » Utility » configreader.py
import sys
import wx
import os

from cStringIO import StringIO

from ConfigParser import ConfigParser,MissingSectionHeaderError,NoSectionError,ParsingError,DEFAULTSECT

from BitTornado.bencode import bencode,bdecode

################################################################
#
# Class: ConfigReader
#
# Extension of ConfigParser that supports various types of
# config values.  Values are converted to strings when writing
# and back into their respective types when reading.
#
################################################################
class ConfigReader(ConfigParser):
    def __init__(self, filename, section, defaults = None):
        if defaults is None:
            defaults = {}
            
        ConfigParser.__init__(self)
        self.defaults = defaults

        self.defaultvalues = { "string"  : "",
                               "int"     : 0,
                               "float"   : 0.0,
                               "boolean" : False,
                               "color"   : wx.Colour(0, 0, 0),
                               "bencode-list" : [],
                               "bencode-string": "",
                               "bencode-fontinfo": {'name': None,
                                                    'size': None,
                                                    'style': None,
                                                    'weight': None }
                              }

        self.filename = filename
        self.section = section
        
        # If the directory for this file doesn't exist,
        # try creating it now
        dirname = os.path.dirname(self.filename)
        if not os.access(dirname, os.F_OK):
            os.makedirs(dirname)
        
        try:
            self.read(self.filename)
        except MissingSectionHeaderError:
            # Old file didn't have the section header
            # (add it in manually)
            oldfile = open(self.filename, "r")
            oldconfig = oldfile.readlines()
            oldfile.close()

            newfile = open(self.filename, "w")
            newfile.write("[" + self.section + "]\n")
            newfile.writelines(oldconfig)
            newfile.close()
            
            self.read(self.filename)
        except ParsingError:
            # A more severe exception occured
            # Try to do whatever is possible to repair
            #
            # If this fails, then there's trouble
            self.tryRepair()
            self.read(self.filename)
        
    def testConfig(self, goodconfig, newline, passes = 0):
        if newline:
            testconfig = goodconfig + newline + "\n"
            
            # Write out to a StringIO object
            newfile = StringIO(testconfig)
            try:
                testparser = ConfigParser()
                testparser.readfp(newfile)
                
                # Line looks ok, add it to the config file
                return testconfig
            except MissingSectionHeaderError:
                if passes > 0:
                    # Something is odd here... just return the version that works
                    return goodconfig
                else:
                    return self.testConfig(goodconfig + "[" + self.section + "]\n", newline, passes = 1)
            except ParsingError:
                # Ignore the line, don't add it to the config file
                return goodconfig
    
    # Try to repair a damaged config file
    # (i.e.: one w/ parsing errors, etc.)
    def tryRepair(self):
        oldconfig = ""
        
        try:
            oldfile = open(self.filename, "r")
            oldconfig = oldfile.readlines()
            oldfile.close()
        except:
            # Can't read the original file at all
            #
            # try to write a blank file with just the section header
            newfile = open(self.filename, "w")
            newfile.write("[" + self.section + "]\n")
            newfile.close()
            return
            
        goodconfig = ""
        
        for line in oldconfig:
            # Strip off any leading or trailing spaces
            newline = line.strip()

            # If the line looks ok, try writing it
            goodconfig = self.testConfig(goodconfig, newline)

        newfile = open(self.filename, "w")
        newfile.writelines(goodconfig)
        newfile.close()
            
    def setSection(self, section):
        self.section = section

    def ValueToString(self, value, typex):
        if typex == "boolean":
            if value:
                text = "1"
            else:
                text = "0"
        elif typex == "color":
            red = str(value.Red())
            while len(red) < 3:
                red = "0" + red

            green = str(value.Green())            
            while len(green) < 3:
                green = "0" + green
                
            blue = str(value.Blue())            
            while len(blue) < 3:
                blue = "0" + blue

            text = str(red) + str(green) + str(blue)
        elif typex.startswith("bencode"):
            text = bencode(value)
        else:
            if type(value) is unicode:
                text = value
            else:
                text = str(value)
        
        return text

    def StringToValue(self, value, type):
        # Assume that the value is already in the proper form
        # if it's not a string
        # (the case for some defaults)
        if value is not None:
            if not isinstance(value, unicode) and not isinstance(value, str):
                return value

        try:
            if type == "boolean":
                if value == "1":
                    value = True
                else:
                    value = False
            elif type == "int":
                value = int(value)
            elif type == "float":
                value = float(value)
            elif type == "color":
                red = int(value[0:3])
                green = int(value[3:6])
                blue = int(value[6:9])
                value = wx.Colour(red, green, blue)
            elif type.startswith("bencode"):
                value = bdecode(value)
        except:           
            value = None
            
        if value is None:
            value = self.defaultvalues[type]
        
        return value

    def ReadDefault(self, param, type = "string", section = None):
        if section is None:
            section = self.section

        if param is None or param == "":
            return ""

        param = param.lower()
        value = self.defaults.get(param, None)
            
        value = self.StringToValue(value, type)
            
        return value
        
    def Read(self, param, type = "string", section = None):
        if section is None:
            section = self.section
            
        if param is None or param == "":
            return ""

#        value = None

        try:
            value = self.get(section, param)
            value = value.strip("\"")
#            value = value.strip("'")
        except:
            param = param.lower()
            value = self.defaults.get(param, None)
#            sys.stderr.write("Error while reading parameter: (" + str(param) + ")\n")
#            data = StringIO()
#            print_exc(file = data)
#            sys.stderr.write(data.getvalue())
            pass

        value = self.StringToValue(value, type)
           
        return value
        
    def Exists(self, param, section = None):
        if section is None:
            section = self.section
            
        return self.has_option(section, param)
        
    def Items(self, section = None):
        if section is None:
            section = self.section
        
        try:
            items = self.items(section)
            for i in range(len(items)):
                (key, value) = items[i]
                value = value.strip("\"")
#                value = value.strip("'")
                items[i] = (key, value)
            return items
        except:
            self.add_section(section)
        return []

    def GetOptions(self, section = None):
        if section is None:
            section = self.section
        try:
            options = self.options(section)
        except NoSectionError:
            options = []
        return options

    def Write(self, param, value, type = "string", section = None):
        if section is None:
            section = self.section
            
        if param is None or param == "":            
            return False
        
        param = param.lower()
            
        if not self.has_section(section):
            self.add_section(section)
               
        text = self.ValueToString(value, type)

        while 1:
            try:
                oldtext = self.Read(param)
                
                self.set(section, param, text)
    
                # Return True if we actually changed something            
                if oldtext != text:
                    return True
                
                break
            except NoSectionError:
                self.add_section(section)
            except:
#                sys.stderr.write("Error while writing parameter: (" + str(param) + ") with value: (" + str(text) + ")\n")
#                data = StringIO()
#                print_exc(file = data)
#                sys.stderr.write(data.getvalue())
                break
        
        return False
    
    def DeleteEntry(self, param, section = None):
        if section is None:
            section = self.section
               
        try:
            return self.remove_option(section, param)
        except:
            return False
        
    def DeleteGroup(self, section = None):
        if section is None:
            section = self.section

        try:
            return self.remove_section(section)
        except:
            return False
        
    def Flush(self):        
        self.write(open(self.filename, "w"))

    def _read(self, fp, fpname):
        cursect = None                            # None, or a dictionary
        optname = None
        lineno = 0
        e = None                                  # None, or an exception
        firstline = True            
        while True:
            line = fp.readline()
            if not line:
                break
            lineno = lineno + 1
            if firstline:
                # Skip BOM
                if line[:3] == '\xef\xbb\xbf':
                    line = line[3:]
                    self.encoding = 'utf_8'
                else:
                    self.encoding = sys.getfilesystemencoding()
                firstline = False
            # comment or blank line?
            if line.strip() == '' or line[0] in '#;':
                continue
            if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR":
                # no leading whitespace
                continue
            # continuation line?
            if line[0].isspace() and cursect is not None and optname:
                value = line.strip()
                if value:
                    cursect[optname] = "%s\n%s" % (cursect[optname], value.decode(self.encoding))
            # a section header or option header?
            else:
                # is it a section header?
                mo = self.SECTCRE.match(line)
                if mo:
                    sectname = mo.group('header')
                    if sectname in self._sections:
                        cursect = self._sections[sectname]
                    elif sectname == DEFAULTSECT:
                        cursect = self._defaults
                    else:
                        cursect = {'__name__': sectname}
                        self._sections[sectname] = cursect
                    # So sections can't start with a continuation line
                    optname = None
                # no section header in the file?
                elif cursect is None:
                    raise MissingSectionHeaderError(fpname, lineno, line)
                # an option line?
                else:
                    mo = self.OPTCRE.match(line)
                    if mo:
                        optname, vi, optval = mo.group('option', 'vi', 'value')
                        if vi in ('=', ':') and ';' in optval:
                            # ';' is a comment delimiter only if it follows
                            # a spacing character
                            pos = optval.find(';')
                            if pos != -1 and optval[pos-1].isspace():
                                optval = optval[:pos]
                        optval = optval.strip()
                        # allow empty values
                        if optval == '""':
                            optval = ''
                        optname = self.optionxform(optname.rstrip())
                        cursect[optname] = optval.decode(self.encoding)
                    else:
                        # a non-fatal parsing error occurred.  set up the
                        # exception but keep going. the exception will be
                        # raised at the end of the file and will contain a
                        # list of all bogus lines
                        if not e:
                            e = ParsingError(fpname)
                        e.append(lineno, repr(line))
        # if any parsing errors occurred, raise an exception
        if e:
            raise e
        
    def write(self, fp):
        fp.writelines('\xef\xbb\xbf')
        if self._defaults:
            fp.write("[%s]\n" % DEFAULTSECT)
            for (key, value) in self._defaults.items():
                if type(value) is not str and type(value) is not unicode:
                    value = str(value)
                fp.write((key + " = " + value + "\n").encode('utf_8'))
            fp.write("\n")
        for section in self._sections:
            fp.write("[%s]\n" % section)
            for (key, value) in self._sections[section].items():
                if key != "__name__":
                    if type(value) is not str and type(value) is not unicode:
                        value = str(value)
                    try:
                        fp.write((key + " = " + value + "\n").encode('utf_8'))
                    # for unicode bencod-list items (already UTF-8 encoded)
                    except UnicodeDecodeError:
                        fp.write((key + " = " + value + "\n"))
            fp.write("\n")






www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.