diff -r 000000000000 -r 257003279747 conf.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conf.py Thu Apr 02 17:47:43 2009 +0300 @@ -0,0 +1,114 @@ +""" + Generic configuration file output +""" + +import os, tempfile, shutil + +class Object (object) : + """ + An object that can be written to a ConfFile, as multiple lines of text. + """ + + def fmt_lines (self) : + """ + Yield a series of lines to be output in the file + """ + + abstract + +class File (object) : + """ + A single configuration file on the filesystem. + + Configuration files are + """ + + def __init__ (self, name, path, backup_suffix='.bak', mode=0644) : + """ + Initialize the config file, but don't open it yet + + @param name the human-readable friendly name for the config file + @param path the full filesystem path for the file + @param backup_suffix rename the old file by adding this suffix when replacing it + @param mode the permission bits for the new file + """ + + self.name = name + self.path = path + self.backup_suffix = backup_suffix + self.mode = mode + + def write_file (self, file, objects) : + """ + Write out the given config objects into the given file + """ + + writer = Writer(file) + writer.write_objs(objects) + + def write (self, objects) : + """ + Write out a new config file with the given series of objects using the following procedure: + * lock the real file + * open a new temporary file, and write out the objects into that, closing it + * move the real file out of the way + * move the temporary file into the real file's place + * unlock the real file + """ + + # XXX: how to aquire the lock? + # XXX: this needs checking over + + # open the new temporary file + # XXX: ensure fd is closed + tmp_fd, tmp_path = tempfile.mkstemp(prefix=self.name) + + # ...as a file + tmp_file = os.fdopen(tmp_fd, "w") + + # fix the permissions + os.chmod(tmp_path, self.mode) + + # write it + self.write_file(tmp_file, objects) + + # close it + tmp_file.close() + del writer + del tmp_file + + # move the old file out of the way + os.rename(self.path, self.path + self.backup_suffix) + + # move the new file in + shutil.move(tmp_path, self.path) + +class Writer (object) : + """ + A conf.Writer is used to write out a new conf.File (as a temporary file) + """ + + def __init__ (self, file) : + """ + @param file the temporary file object + """ + + self.file = file + + def write_obj (self, obj) : + """ + Write a single object to the file + """ + + # just write out all the lines + self.file.writelines(obj.fmt_lines()) + + def write_objs (self, objs) : + """ + Write a series of objects to the file + """ + + # just write each in turn + for obj in objs : + self.write_obj(obj) +