Changeset 764


Ignore:
Timestamp:
03/01/11 21:31:04 (8 years ago)
Author:
aspidites
Message:

Patch by Aspidites

+ modified the Settings API slightly to allow for the specification

of both settings filenames as well as the paths to those named
files

  • Documentation doesn't yet reflect these changes + fixed bug that prevented settings file from being saved + a Section's options() method now shows the options as well as their values
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/active/character_customization/game/parpg/settings.py

    r761 r764  
    2727import os 
    2828 
     29#TODO: prevent new sections from being created if an option hasn't been defined 
     30#TODO: update documentation for Settings' __init__, read, and write methods 
    2931class Section(object): 
    3032    """ An object that represents a section in a settings file. 
    3133 
    3234        Options can be added to a section by simply assigning a value to an  
    33             attribute: 
    34                 section.foo = baz 
    35             would produce: 
    36                 [section] 
    37                 foo = baz 
    38             in the settings file. Options that do not exist on assignment 
    39             are created dynamcially. 
     35        attribute: 
     36            section.foo = baz 
     37        would produce: 
     38            [section] 
     39            foo = baz 
     40        in the settings file. Options that do not exist on assignment 
     41        are created dynamcially. 
    4042    """ 
    4143    def __init__(self, name): 
     
    4345 
    4446            @param name: name of the section. In the INI file, sections are surrounded 
    45                 by brackets ([name]) 
     47                         by brackets ([name]) 
    4648            @type name: string 
    4749        """ 
     
    5658            @type value: int, float, string, boolean, or list 
    5759        """ 
    58         # needed so that the leading space in FontGlyphs isn't accidentally  
    59         # striped 
    6060        if (value.startswith("\"") and value.endswith("\"") or 
    6161            value.startswith("\'") and value.endswith("\'")): 
    6262            # remove quotation marks and evaluate as a string 
    6363            value = value[1:-1] 
    64         if value.startswith('[') and value.endswith(']'): 
     64        elif value.startswith('[') and value.endswith(']'): 
    6565            value = [item.strip() for item in value[1:-1].split(',')] 
    6666        elif value.lower() == 'true': 
     
    9292            options.pop('name') 
    9393 
    94         return options.keys() 
    95  
    96 #TODO: remember config filenames/paths 
    97 #TODO: remove hard-coded settings filename/path 
     94        return options 
     95 
    9896class Settings(object): 
    9997    """ An object that represents a settings file, its sectons, 
    10098        and the options defined within those sections. 
    10199    """ 
    102     def __init__(self, *filenames): 
     100    def __init__(self, **kwargs): 
    103101        """ initializes a new settings object. 
    104102 
    105             @param filenames: Either a string representing a filename or a list 
    106                 of such strings. If a single string is given, settings  
    107                 sections and options are simply read from it. If a list is given, 
    108                 each file is parsed sequentially with the next file's options 
    109                 taking precedence over the previous one's. Consider: 
    110                     files = ['foo.cfg' ,'bar.cfg'] 
    111                     config = Config(files) 
    112                 First, foo.cfg is read, then, if similar options in bar.cfg exist,  
    113                 they overwrite the ones previously set by foo.cfg. 
    114             @type filenames: either a string or list 
     103            @param paths: Either a string representing a path to a settings  
     104                          file or a list of such strings. If a single  
     105                          string is given, settings sections and options are  
     106                          simply read from it. If a list is given, each file  
     107                          is parsed sequentially with the next file's  
     108                          options taking precedence over the previous one's.  
     109                          Consider: 
     110                              files = ['foo.cfg' ,'bar.cfg'] 
     111                              config = Config(files) 
     112                          First, foo.cfg is read, then, if similar options  
     113                          in bar.cfg exist, they overwrite the ones  
     114                          previously set by foo.cfg. 
     115            @type paths: either a string or list 
    115116            @ivar config_file: Python object representing the settings 
    116                 file. Its purpose is to preserve the order of each section and  
    117                 its options on read and write. 
     117                               file. Its purpose is to preserve the order of  
     118                               each section and its options on read and write. 
    118119            @type config_file: list 
    119120        """ 
    120121 
    121122        self.config_file = '' 
    122  
    123         if hasattr(filenames, 'split'): 
    124             self.read(filenames) 
    125         else: 
    126             for filename in filenames: 
    127                 self.read(filename) 
     123        self.paths = kwargs.get('paths', None) 
     124        self.filename = kwargs.get('filename', 'settings.ini') 
     125 
     126        if self.paths is not None: 
     127            self.read(self.paths) 
     128        else: 
     129            self.paths = '.' 
    128130 
    129131    def __getattr__(self, name): 
     
    144146        return getattr(self, name) 
    145147 
    146     def read(self, filename): 
     148    def read(self, paths, filename=None): 
    147149        """ Reads a settings file and populates the settings object  
    148150            with its sections and options. 
    149151 
    150             @param filename: name of file to be parsed. 
    151             @type filename: string 
    152         """ 
    153         section = None 
    154         try: 
    155             self.config_file = open(filename, 'r').readlines() 
    156         except IOError: 
    157             pass 
    158  
    159         for line in self.config_file: 
    160             if line.startswith('#') or line.strip() == '': 
    161                 continue 
    162             elif line.startswith('[') and line.endswith(']\n'): 
    163                 getattr(self, line[1:-2]) 
    164                 section = line[1:-2] 
    165             else: 
    166                 option, value = [item.strip() for item in line.split('=', 1)] 
    167                 setattr(getattr(self, section), option, value) 
    168  
    169     def write(self, filename): 
     152            @param path: name of file to be parsed. 
     153            @type path: string 
     154        """ 
     155        if filename is not None: 
     156            self.filename = filename 
     157 
     158        if hasattr(paths, 'split'): 
     159            self.paths = [paths] 
     160        else: 
     161            self.paths = paths 
     162 
     163        for path in self.paths: 
     164            location = os.path.join(path, self.filename) 
     165            section = None 
     166            try: 
     167                self.config_file = open(location, 'r').readlines() 
     168            except IOError: 
     169                pass 
     170 
     171            for line in self.config_file: 
     172                if line.startswith('#') or line.strip() == '': 
     173                    continue 
     174                elif line.startswith('[') and line.endswith(']\n'): 
     175                    getattr(self, line[1:-2]) 
     176                    section = line[1:-2] 
     177                else: 
     178                    option, value = [item.strip()  
     179                                     for item in line.split('=', 1)] 
     180                    setattr(getattr(self, section), option, value) 
     181 
     182    def write(self, path=None, filename=None): 
    170183        """ Writes a settings file based on the settings object's  
    171184            sections and options 
    172185 
    173             @param filename: name of file to save to 
    174             @type filename: string 
    175         """ 
     186            @param path: Name of file to save to. By default, this is  
     187                             last file that was read when the Setings object 
     188                             was created. 
     189            @type path: string 
     190        """ 
     191        if path is None: 
     192            path = self.paths[-1] 
     193 
     194        if filename is None: 
     195            filename = self.filename 
     196 
    176197        for section in self.sections(): 
    177198            if '[{0}]\n'.format(section) not in self.config_file: 
     
    183204                start_of_section = (self.config_file 
    184205                                        .index('[{0}]\n'.format(section)) + 1) 
     206 
    185207                for option, value in getattr(self,  
    186208                                             section).options().iteritems(): 
     
    201223                        self.config_file.insert(start_of_section, template) 
    202224 
    203         with open(filename, 'w') as out_stream: 
     225        location = os.path.join(path, filename) 
     226        with open(location, 'w') as out_stream: 
    204227            for line in self.config_file: 
    205228                out_stream.write(line) 
     
    209232        sections = self.__dict__.keys() 
    210233        sections.pop(sections.index('config_file')) 
     234        sections.pop(sections.index('paths')) 
     235        sections.pop(sections.index('filename')) 
    211236        return sections 
Note: See TracChangeset for help on using the changeset viewer.