1.1 --- a/moinformat/output/common.py Sun Aug 05 18:07:02 2018 +0200
1.2 +++ b/moinformat/output/common.py Sun Aug 05 18:13:36 2018 +0200
1.3 @@ -19,6 +19,8 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 +import codecs
1.8 +
1.9 class Output:
1.10
1.11 "A common output context abstraction."
1.12 @@ -48,12 +50,57 @@
1.13
1.14 self.output.append(self.encode(text))
1.15
1.16 + # Serialisation methods.
1.17 +
1.18 def to_string(self):
1.19
1.20 "Return the output as a plain string."
1.21
1.22 return "".join(self.output)
1.23
1.24 + # Serialisation methods.
1.25 +
1.26 + def can_write(self):
1.27 +
1.28 + "Return whether this context supports page writing."
1.29 +
1.30 + return False
1.31 +
1.32 + def writefile(self, text, filename, encoding=None):
1.33 +
1.34 + """
1.35 + Write 'text' to the file having the given 'filename'. If the
1.36 + optional 'encoding' is specified, override the general encoding.
1.37 +
1.38 + Subclasses need to override this method for it to have an effect.
1.39 + """
1.40 +
1.41 + pass
1.42 +
1.43 + def writepage(self, text, pagename, encoding=None):
1.44 +
1.45 + """
1.46 + Write 'text' to the file having the given 'pagename' and optional
1.47 + 'encoding'.
1.48 + """
1.49 +
1.50 + return self.writefile(text, self.to_filename(pagename), encoding)
1.51 +
1.52 + # Output methods.
1.53 +
1.54 + def writepath(self, text, filename, encoding=None):
1.55 +
1.56 + """
1.57 + Write 'text' to the file having the given 'filename'. If the
1.58 + optional 'encoding' is specified, override the general encoding.
1.59 + """
1.60 +
1.61 + f = codecs.open(filename, "w", encoding=encoding or self.encoding)
1.62 + try:
1.63 + f.write(text)
1.64 + finally:
1.65 + f.close()
1.66 +
1.67 def encode(s, encoding):
1.68
1.69 "Encode 's' using 'encoding' if Unicode."
2.1 --- a/moinformat/output/directory.py Sun Aug 05 18:07:02 2018 +0200
2.2 +++ b/moinformat/output/directory.py Sun Aug 05 18:13:36 2018 +0200
2.3 @@ -21,6 +21,8 @@
2.4
2.5 from moinformat.output.common import Output
2.6 from moinformat.utils.directory import Directory
2.7 +from os import makedirs, rename
2.8 +from os.path import exists, isdir, isfile, join, split
2.9
2.10 class DirectoryOutput(Output, Directory):
2.11
2.12 @@ -38,6 +40,85 @@
2.13 Output.__init__(self, parameters)
2.14 Directory.__init__(self, parameters["filename"])
2.15
2.16 + if not exists(self.filename):
2.17 + makedirs(self.filename)
2.18 +
2.19 + self.index_name = parameters and parameters.get("index_name") or "index"
2.20 +
2.21 + # Name translation methods.
2.22 +
2.23 + def to_filename(self, pagename):
2.24 +
2.25 + "Return the filename corresponding to 'pagename'."
2.26 +
2.27 + return pagename
2.28 +
2.29 + def to_pagename(self, filename):
2.30 +
2.31 + "Return the pagename corresponding to 'filename'."
2.32 +
2.33 + # Take the leafname as the pagename from an arbitrary filename.
2.34 +
2.35 + return split(filename)[-1]
2.36 +
2.37 + # Serialisation methods.
2.38 +
2.39 + def can_write(self):
2.40 +
2.41 + "Return whether this context supports page writing."
2.42 +
2.43 + return True
2.44 +
2.45 + def writefile(self, text, filename, encoding=None):
2.46 +
2.47 + """
2.48 + Write 'text' to the file having the given 'filename'. If the
2.49 + optional 'encoding' is specified, override the general encoding.
2.50 + """
2.51 +
2.52 + return self.writepath(text, self.get_filename(filename), encoding)
2.53 +
2.54 + def writepage(self, text, pagename, encoding=None):
2.55 +
2.56 + """
2.57 + Write 'text' to the file having the given 'pagename' and optional
2.58 + 'encoding'. If 'parent' is specified and a true value, it indicates that
2.59 + the page is a parent of other pages.
2.60 + """
2.61 +
2.62 + filename = self.to_filename(pagename)
2.63 + parent = split(filename)[0]
2.64 +
2.65 + # The page may have a parent.
2.66 +
2.67 + if parent and parent != filename:
2.68 + dirpath = self.get_filename(parent)
2.69 +
2.70 + # Relocate any file for the parent to an index file within a page
2.71 + # directory.
2.72 +
2.73 + if isfile(dirpath):
2.74 + parent_tmp = "%s.tmp" % dirpath
2.75 + rename(dirpath, parent_tmp)
2.76 + makedirs(dirpath)
2.77 + rename(parent_tmp, join(dirpath, self.index_name))
2.78 +
2.79 + # Or make a directory for the parent.
2.80 +
2.81 + elif not exists(dirpath):
2.82 + makedirs(dirpath)
2.83 +
2.84 + # Obtain a complete filename for the content.
2.85 +
2.86 + pathname = self.get_filename(filename)
2.87 +
2.88 + # Write to an index filename within any existing directory.
2.89 +
2.90 + if isdir(pathname):
2.91 + pathname = join(pathname, self.index_name)
2.92 +
2.93 + self.writefile(text, pathname, encoding)
2.94 +
2.95 output = DirectoryOutput
2.96
2.97 # vim: tabstop=4 expandtab shiftwidth=4