]> oss.titaniummirror.com Git - webber.git/blobdiff - webber.py
Fix directories key error in get_path_to_root
[webber.git] / webber.py
index 6be571e0ff09ea19d88e0e9e2ef6625b442eaf16..ecd0351379decdc4a7ccc092ddd12057e424bfa6 100644 (file)
--- a/webber.py
+++ b/webber.py
@@ -11,21 +11,21 @@ from config import Holder
 
 __all__ = [
        # Globals
-       "cfg",          # configuration from webber.ini
-       "directories",  # global hash of directories, by rel_path
-       "files",        # global hash of files, by rel_path
-       "functions",    # all exported template functions
+       "cfg",                  # configuration from webber.ini
+       "directories",  # global hash of directories, by rel_path
+       "files",                # global hash of files, by rel_path
+       "functions",    # all exported template functions
 
        # Functions
-       "set_hook",     # decorator for hook-functions
-       "set_macro",    # define macro
+       "set_hook",             # decorator for hook-functions
+       "set_macro",    # define macro
        "set_function", # define functions for the template
        "get_file_for",
        "get_link_from",
        "get_current_file", # because mako-called functions cannot access the
-                       # current File object
+                                       # current File object
        "get_program_directory",
-       "log",          # misc logging functions
+       "log",                  # misc logging functions
        "info",
        "warning",
        "error",
@@ -50,7 +50,18 @@ class Directory(Holder):
 
        def __init__(self, **kw):
                Holder.__init__(self, **kw)
-               directories[kw["rel_path"]] = self
+               kw["rel_path"] = self
+               if self.rel_path == "":
+                       self.rel_path = "."
+               directories[self.rel_path] = self
+               try:
+                       self.load(os.path.join(self.abs_path, "directory.conf"))
+                       #print self
+               except IOError:
+                       pass
+
+       def __repr__(self):
+               return "<Directory %s>" % self.rel_path
 
 
 files = {}
@@ -120,6 +131,9 @@ class File(Holder):
 
                self.contents = "".join(txt)
 
+       def __repr__(self):
+               return "<File %s>" % self.rel_path
+
 
 _get_file_for_cache = {}
 def get_file_for(name):
@@ -139,6 +153,10 @@ def get_file_for(name):
                                #print "  via linktitle:", s
                                _get_file_for_cache[name] = f
                                return f
+                       if f.title == name:
+                               #print "  via title:", s
+                               _get_file_for_cache[name] = f
+                               return f
                except:
                        pass
                # Allow exact match as well
@@ -207,8 +225,8 @@ def relpath(base_path, target):
 
 
 def get_link_from(source, dest):
-       #print "get_link_from", source, dest
-       #print source
+       if dest is None:
+               raise KeyError
        if not isinstance(source, File):
                source = get_file_for(source)
        if not source:
@@ -217,7 +235,7 @@ def get_link_from(source, dest):
        if not isinstance(dest, File):
                dest = get_file_for(dest)
        if not dest:
-               print "NO DEST"
+               warning("unknown link from %s to %s" % (source.rel_path, dest))
                return "."
        rel_path = relpath(directories[source.direc].abs_path, directories[dest.direc].abs_path)
        try:
@@ -229,7 +247,7 @@ def get_link_from(source, dest):
        if rel_path.startswith("./"):
                rel_path = rel_path[2:]
        #print "  from path:", source.out_path
-       #print "  to path:  ", out_path
+       #print "  to path:      ", out_path
        #print "  rel path: ", rel_path
        return rel_path
 
@@ -255,10 +273,10 @@ def get_program_directory():
 #
 #  Logging
 #
-#      1    Error
-#      2    Warning
-#      3    Info
-#      4    Log
+#      1        Error
+#      2        Warning
+#      3        Info
+#      4        Log
 #      5... Debug
 #
 def log(s, level=4):
@@ -288,43 +306,43 @@ def info(s):
 
 # IkiWiki does something like this:
 # At startup:
-#      getopt               modify ARGV
-#      checkconfig          check configuration
-#      refresh              allow plugins to build source files
+#      getopt                           modify ARGV
+#      checkconfig                      check configuration
+#      refresh                          allow plugins to build source files
 # While scanning files:
-#      needsbuild           detect if page needs to be rebuild
-#      filter               arbitrary changes
-#      scan                 collect metadata
+#      needsbuild                       detect if page needs to be rebuild
+#      filter                           arbitrary changes
+#      scan                             collect metadata
 # While rendering files:
-#      filter               arbitrary changes
-#      preprocess           execute macros
-#      linkify              change wikilinks into links
-#      htmlize              turns text into html
-#      sanitize             sanitize html
-#      templatefile         allows changing of the template on a per-file basis
-#      pagetemplate         fill template with page
-#      format               similar to sanitize, but act on whole page body
+#      filter                           arbitrary changes
+#      preprocess                       execute macros
+#      linkify                          change wikilinks into links
+#      htmlize                          turns text into html
+#      sanitize                         sanitize html
+#      templatefile             allows changing of the template on a per-file basis
+#      pagetemplate             fill template with page
+#      format                           similar to sanitize, but act on whole page body
 # At the end:
-#      savestate            plugins can save their state
+#      savestate                        plugins can save their state
 #
 #
 # We do something like this:
 #
 # At startup:
-#      addoptions           allow plugins to add command-line options
-#      checkconfig          check configuration
+#      addoptions                       allow plugins to add command-line options
+#      checkconfig                      check configuration
 #      start
 # While reading files:
-#      read                 ask any reader (plugins!) to read the file
-#      filter               ask anybody to filter the contents
+#      read                             ask any reader (plugins!) to read the file
+#      filter                           ask anybody to filter the contents
 # While scanning files:
-#      scan                 called per file, let plugins act on file data
-#      scan_done            Allows post-processing of scanned data
+#      scan                             called per file, let plugins act on file data
+#      scan_done                        Allows post-processing of scanned data
 # While rendering files:
-#      htmlize              turns text into html-part
-#      linkify              convert link macros to HTML
-#      pagetemplate         ask template engine (plugin!) to generate HTML out
-#                           of template and body part
+#      htmlize                          turns text into html-part
+#      linkify                          convert link macros to HTML
+#      pagetemplate             ask template engine (plugin!) to generate HTML out
+#                                               of template and body part
 # At the end:
 #      finish
 #
@@ -437,17 +455,26 @@ def iso_to_time(val):
        return int(time.mktime(t))
 
 @set_function("format_date")
-def format_date(timestamp):
-       return time.strftime(cfg.date_format, time.localtime(timestamp))
+def format_date(timestamp, format=None):
+       if not format:
+               format = cfg.date_format
+       return time.strftime(format, time.localtime(timestamp))
 
 @set_function("get_time")
-def get_time():
-       return format_date(time.time())
+def get_time(format=None):
+       return format_date(time.time(), format)
 
 @set_function("get_current_file")
 def get_current_file():
        return current_file
 
+@set_function("get_path_to_root")
+def get_path_to_root():
+       rel_path = relpath(directories[current_file.direc].abs_path, directories['.'].abs_path)
+       rel_path = os.path.join(rel_path, os.path.split("")[1])
+       if rel_path[-1] == "/":
+               rel_path = rel_path[:-1]
+       return rel_path
 
 
 
@@ -477,9 +504,9 @@ def read_file(direc, file):
                return_holder=False)
        if not contents:
                return
+       file.contents = contents
 
        log("filtering file %s" % file.rel_path, level=6)
-       file.contents = contents
        res = run_hooks("filter",
                direc=direc,
                file=file)
@@ -511,7 +538,7 @@ def walk_tree(dirpath):
                        full_path = os.path.join(dirpath, s)
                        ok = True
                        if os.path.isdir(full_path):
-                               for e in cfg.exclude_dir:
+                               for e in cfg.exclude_dirs:
                                        if fnmatch.fnmatchcase(s, e):
                                                log("ignoring directory %s" % s, level=7)
                                                ok = False
@@ -554,14 +581,14 @@ def walk_tree(dirpath):
 #
 
 reMacro = re.compile(r'''
-       \[\[\!                  # Begin of macro
+       \[\[\!                                  # Begin of macro
        \s*
-       ([^\s\]]+)              # Macro name
+       ([^\s\]]+)                              # Macro name
        (?:
-               \s+                 # optional space
-        ([^\]]+)            # optional argumens
+               \s+                                     # optional space
+               ([^\]]+)                        # optional argumens
        )?
-       \]\]                    # End of macro
+       \]\]                                    # End of macro
        ''', re.VERBOSE)
 reMacroArgs = re.compile(r'''
        ([-_\w]+)                               # parameter name
@@ -570,9 +597,9 @@ reMacroArgs = re.compile(r'''
                =
                \s*
                (?:
-                       "([^"]*)"       # single-quoted
+                       "([^"]*)"               # single-quoted
                |
-                       (\S+)           # unquoted
+                       (\S+)                   # unquoted
                )
        )?
        ''', re.VERBOSE)
@@ -617,7 +644,7 @@ def scan_files():
 
                direc = directories[file.direc]
 
-               # Output-Filename "berechnen"
+               # "calculate" output file name
                if file.render and file.render == "html":
                        file.out_path = os.path.splitext(s)[0] + ".html"
 
@@ -682,9 +709,8 @@ def render_files():
                if not file.contents:
                        continue
 
-               # TODO: einige Fragmente sollen u.U. in eine andere
-               # Webseite eingebaut werden und sollten daher nicht in
-               # ein HTML-File landen
+               # TODO: make it possible to render also "fragments", e.g.
+               # parts that don't end up immediately in a the HTML file.
                contents = run_hooks("pagetemplate",
                        direc=direc,
                        file=file,
@@ -702,12 +728,13 @@ def render_files():
                except OSError:
                        pass
 
-               # TODO: evtl. überprüfen, ob contents == f.read(), dann nicht schreiben
+               # TODO: check if contents == f.read(). In this case we don't
+               # need to save. Probably overkill.
                log("writing file %s" % fname_out, level=6)
                f = open(fname_out, "w")
                f.write(contents)
                f.close()
-               # TODO: Time-Stamps setzen?
+               os.utime(fname_out, (file.mtime, file.mtime))
 
                #print file.mtime, file.get("ctime","?")
                #print direc.keys()
@@ -769,7 +796,12 @@ def main():
        # link contents of webber.ini into cfg and set some defaults,
        # then let plugins fixup things in cfg.*
        cfg.inheritFrom(options)
-       cfg.setDefault("exclude_dir", ["plugins"])
+       cfg.setDefault("exclude_dirs", [])
+       cfg.setDefault("exclude_files", ["webber.conf", "directory.conf", "*.tmpl"])
+       cfg.setDefault("copy_files", [])
+       cfg.setDefault("input_encoding", "iso-8859-1")
+       cfg.setDefault("output_encoding", "iso-8859-1")
+       cfg.setDefault("template", "default")
        run_hooks("checkconfig")
 
        run_hooks("start")