--- a/pvl/config/conf.py Sun Jul 12 00:51:08 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-"""
- Generic configuration file output
-"""
-
-import os, os.path, tempfile, shutil
-
-class ConfObject (object) :
- """
- An object that can be written to a ConfFile, as multiple lines of text.
- """
-
- def __init__ (self, comments=None) :
- """
- Initialize with the given list of comments. Comments that are None should be ignore.
- """
-
- # init the comments list
- self.comments = comments or []
-
- def add_comment (self, comment) :
- """
- Add a comment to be rendered in the output.
- """
-
- # add it
- self.comments.append(comment)
-
- def fmt_lines (self) :
- """
- Yield a series of lines to be output in the file
- """
-
- abstract
-
-class File (ConfObject) :
- """
- A single configuration file on the filesystem.
-
- Configuration files are themselves ConfObject's, although this must be implemented in the inheriting class.
- """
-
- 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) :
- """
- Write out this config's stuff into the given file
- """
-
- writer = Writer(file)
- writer.write_obj(self)
-
- def write (self) :
- """
- Write out a new config file with this config's stuff 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)
-
- # close it
- tmp_file.close()
-
- # move the old file out of the way
- if os.path.exists(self.path) :
- 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_line (self, line) :
- """
- Write a single line to the file
- """
-
- self.file.write("%s\n" % (line, ))
-
- def write_lines (self, lines) :
- """
- Write a series of lines into the file
- """
-
- for line in lines :
- self.write_line(line)
-
- def write_obj (self, obj) :
- """
- Write a single object to the file
- """
-
- # just write out all the lines
- self.write_lines(obj.fmt_lines())
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pvl/config/file.py Sun Jul 12 02:14:08 2009 +0300
@@ -0,0 +1,170 @@
+"""
+ Generic configuration file output
+"""
+
+import os, os.path, tempfile, shutil
+
+class Item (object) :
+ """
+ An object that can be represented as a series of lines of text.
+
+ The structure of these objects/lines is not defined, but as a convenience, a method for prepending lines of
+ comments is provided.
+ """
+
+ # the prefix char for comments, must be defined
+ COMMENT_PREFIX = None
+
+ @classmethod
+ def filter_comments (self, comments) :
+ """
+ Return the filtered list of comments
+ """
+
+ return [comment for comment in comments if comment]
+
+ def __init__ (self, comments=()) :
+ """
+ Initialize with the given list of comments, which will be filtered before use.
+ """
+
+ # init the comments list
+ self.comments = self.filter_comments(comments)
+
+ def add_comment (self, comment) :
+ """
+ Add the given comment
+ """
+
+ self.comments += self.filter_comments([comment])
+
+ def iter_comments (self) :
+ """
+ Formats comments for output
+ """
+
+ for comment in self.comments :
+ yield "%s %s" % (self.COMMENT_PREFIX, comment)
+
+ def iter_lines (self, indent='\t') :
+ """
+ Yield a series of lines to be output in the file
+ """
+
+ abstract
+
+ def render_lines (self, encoding=None, newline='\n', **opts) :
+ """
+ Render lines as a series of objects, possibly encoded.
+ """
+
+ for line in self.iter_lines(**opts) :
+ if encoding :
+ line = line.encode(encoding)
+
+ elif encoding is False :
+ line = unicode(line)
+
+ yield line + newline
+
+ def render_unicode (self, **opts) :
+ """
+ Render lines as a single unicode object
+ """
+
+ return u''.join(self.render_lines(encoding=False, **opts))
+
+ def render_str (self, encoding='utf-8', **opts) :
+ """
+ Render lines as a single str object
+ """
+
+ return ''.join(self.render_lines(encoding=encoding, **opts))
+
+ def render_out (self, file, encoding='utf-8', **opts) :
+ """
+ Render lines and write out to given file object
+ """
+
+ for line in self.render_lines(encoding=encoding, **opts) :
+ file.write(line)
+
+class Contents (Item) :
+ """
+ A series of Items
+ """
+
+ def __init__ (self, *items) :
+ self.items = items
+
+ def add_item (self, item) :
+ self.items.append(item)
+
+ def iter_lines (self, **opts) :
+ for item in self.items :
+ for line in item.iter_lines(**opts) :
+ yield line
+
+class File (object) :
+ """
+ A configuration file on the filesystem.
+
+ Configuration files can be written out with some given contents.
+
+
+ XXX: better logic for backup file
+ """
+
+ 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 (self, data) :
+ """
+ Write out a new config file with the given Item data 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 OS 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 the Item out into the file
+ data.render_out(tmp_file)
+
+ # close it
+ tmp_file.close()
+
+ # move the old file out of the way
+ if os.path.exists(self.path) :
+ # XXX: use shutil.move?
+ os.rename(self.path, self.path + self.backup_suffix)
+
+ # move the new file in
+ shutil.move(tmp_path, self.path)
+