Added os.path.join() to a few filesystem related string operations.
[cmless] / bin / misc.py
index 821ef34..289ea6b 100644 (file)
@@ -2,14 +2,13 @@
 # See LICENSE file for copyright and license details.
 
 # Python imports
 # See LICENSE file for copyright and license details.
 
 # Python imports
-import sys, subprocess
+import os, sys, subprocess, configparser
 
 # CMless imports
 
 # CMless imports
-import debug, config
+import debug, config, template
 
 
-# Accepts a string containing a filesystem path to a text file.
-# Returns a string containing the contents of that file.
 def load_file(path):
 def load_file(path):
+    """Open the text file at 'path' and return the contents as a string."""
     try:
         with open(path) as f:
             contents = f.read()
     try:
         with open(path) as f:
             contents = f.read()
@@ -18,9 +17,12 @@ def load_file(path):
         sys.exit("Unable to open " + path + " for reading.")
     return contents
 
         sys.exit("Unable to open " + path + " for reading.")
     return contents
 
-# Accepts a string containing markup'ed text
-# Returns a string containing HTML'ed text
 def process_markup(text):
 def process_markup(text):
+    """Execute external markup processor and return processed 'text'.
+
+    Markup processor is specified by config.markup_processor variable
+    and should accept markup on stdin while returning HTML on stdout.
+    """
     try:
         p = subprocess.Popen(config.markup_processor,
                 stdout=subprocess.PIPE,stdin=subprocess.PIPE)
     try:
         p = subprocess.Popen(config.markup_processor,
                 stdout=subprocess.PIPE,stdin=subprocess.PIPE)
@@ -30,3 +32,48 @@ def process_markup(text):
         sys.exit("Unable to open markup processor: " + config.markup_processor)
     text = p.communicate(text.encode('UTF-8'))[0]
     return(text.decode('UTF-8'))
         sys.exit("Unable to open markup processor: " + config.markup_processor)
     text = p.communicate(text.encode('UTF-8'))[0]
     return(text.decode('UTF-8'))
+
+def strip_page_metadata(content):
+    """Strip metadata from the beginning of 'content' and return whatever remains."""
+    keyword = template.add_delimiter("END_PAGE_METADATA")
+    index = content.find(keyword)
+    if index != -1:
+        return content[index+len(keyword):]
+    else:
+        return content
+
+def lookup_current_metadata(key):
+    """Wrapper for lookup_file_metadata() supplying the current REQUEST_URI as 'file'."""
+    file = os.path.join(config.site_data_prefix + os.environ['REQUEST_URI'] +
+            config.markup_file_extension)
+    return lookup_file_metadata(key,file)
+
+def lookup_file_metadata(key,file):
+    """Read 'key' metadata in 'file' and return corresponding value.
+
+    Assumes key is contained in the [DEFAULT] category.
+    Returns empty string if key is not present.
+    """
+    page_file = load_file(file)
+
+    # Extract just the metadata block so we can pass it to ConfigParser.
+    keyword_begin = template.add_delimiter("BEGIN_PAGE_METADATA")
+    keyword_end = template.add_delimiter("END_PAGE_METADATA")
+    index = page_file.find(keyword_end)
+    if index != -1:
+        page_file = page_file[len(keyword_begin):index]
+    else:
+        # ConfigParser will accept an empty string so use that as fallback.
+        page_file = ""
+
+    page_metadata = configparser.ConfigParser()
+    page_metadata.read_string(page_file)
+
+    if 'DEFAULT' in page_metadata and key in page_metadata['DEFAULT']:
+        return page_metadata['DEFAULT'][key]
+    else:
+        # An empty string is technically a valid value for a key but we will
+        # overload it as also indicating 'key' wasn't present since a key
+        # without a value is functionally equivalent to no key at all for our
+        # purposes.
+        return ""