pvl/config/conf.py
changeset 8 46d36bc33086
parent 7 0f9cae2d7147
child 9 2156906bfbf1
equal deleted inserted replaced
7:0f9cae2d7147 8:46d36bc33086
     1 """
       
     2     Generic configuration file output
       
     3 """
       
     4 
       
     5 import os, os.path, tempfile, shutil
       
     6 
       
     7 class ConfObject (object) :
       
     8     """
       
     9         An object that can be written to a ConfFile, as multiple lines of text.
       
    10     """
       
    11 
       
    12     def __init__ (self, comments=None) :
       
    13         """
       
    14             Initialize with the given list of comments. Comments that are None should be ignore.
       
    15         """
       
    16         
       
    17         # init the comments list
       
    18         self.comments = comments or []
       
    19 
       
    20     def add_comment (self, comment) :
       
    21         """
       
    22             Add a comment to be rendered in the output.
       
    23         """
       
    24         
       
    25         # add it
       
    26         self.comments.append(comment)
       
    27 
       
    28     def fmt_lines (self) :
       
    29         """
       
    30             Yield a series of lines to be output in the file
       
    31         """
       
    32         
       
    33         abstract
       
    34 
       
    35 class File (ConfObject) :
       
    36     """
       
    37         A single configuration file on the filesystem.
       
    38 
       
    39         Configuration files are themselves ConfObject's, although this must be implemented in the inheriting class.
       
    40     """
       
    41 
       
    42     def __init__ (self, name, path, backup_suffix='.bak', mode=0644) :
       
    43         """
       
    44             Initialize the config file, but don't open it yet
       
    45 
       
    46             @param name the human-readable friendly name for the config file
       
    47             @param path the full filesystem path for the file
       
    48             @param backup_suffix rename the old file by adding this suffix when replacing it
       
    49             @param mode the permission bits for the new file
       
    50         """
       
    51   
       
    52         self.name = name
       
    53         self.path = path
       
    54         self.backup_suffix = backup_suffix
       
    55         self.mode = mode
       
    56     
       
    57     def write_file (self, file) :
       
    58         """
       
    59             Write out this config's stuff into the given file
       
    60         """
       
    61 
       
    62         writer = Writer(file)
       
    63         writer.write_obj(self)
       
    64 
       
    65     def write (self) :
       
    66         """
       
    67             Write out a new config file with this config's stuff using the following procedure:
       
    68 
       
    69                 * lock the real file
       
    70                 * open a new temporary file, and write out the objects into that, closing it
       
    71                 * move the real file out of the way
       
    72                 * move the temporary file into the real file's place
       
    73                 * unlock the real file
       
    74         """
       
    75 
       
    76         # XXX: how to aquire the lock?
       
    77         # XXX: this needs checking over
       
    78 
       
    79         # open the new temporary file
       
    80         # XXX: ensure fd is closed
       
    81         tmp_fd, tmp_path = tempfile.mkstemp(prefix=self.name)
       
    82 
       
    83         # ...as a file
       
    84         tmp_file = os.fdopen(tmp_fd, "w")
       
    85         
       
    86         # fix the permissions
       
    87         os.chmod(tmp_path, self.mode)
       
    88 
       
    89         # write it
       
    90         self.write_file(tmp_file)
       
    91 
       
    92         # close it
       
    93         tmp_file.close()
       
    94         
       
    95         # move the old file out of the way
       
    96         if os.path.exists(self.path) :
       
    97             os.rename(self.path, self.path + self.backup_suffix)
       
    98 
       
    99         # move the new file in
       
   100         shutil.move(tmp_path, self.path)
       
   101 
       
   102 class Writer (object) :
       
   103     """
       
   104         A conf.Writer is used to write out a new conf.File (as a temporary file)
       
   105     """
       
   106 
       
   107     def __init__ (self, file) :
       
   108         """
       
   109             @param file the temporary file object
       
   110         """
       
   111 
       
   112         self.file = file
       
   113     
       
   114     def write_line (self, line) :
       
   115         """
       
   116             Write a single line to the file
       
   117         """
       
   118 
       
   119         self.file.write("%s\n" % (line, ))
       
   120     
       
   121     def write_lines (self, lines) :
       
   122         """
       
   123             Write a series of lines into the file
       
   124         """
       
   125 
       
   126         for line in lines :
       
   127             self.write_line(line)
       
   128 
       
   129     def write_obj (self, obj) :
       
   130         """
       
   131             Write a single object to the file
       
   132         """
       
   133         
       
   134         # just write out all the lines
       
   135         self.write_lines(obj.fmt_lines())
       
   136