Introduce a `warn' output operation.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 23 May 2014 17:20:46 +0000 (18:20 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 24 May 2014 21:58:53 +0000 (22:58 +0100)
Mostly warnings are just written to standard error.  The HTML output
driver captures warnings and displays them in an obvious box.

cgi.py
chpwd.css
cmd-cgi.py
output.py
wrapper.fhtml

diff --git a/cgi.py b/cgi.py
index 69b9038..227d33b 100644 (file)
--- a/cgi.py
+++ b/cgi.py
@@ -105,6 +105,7 @@ class HTTPOutput (O.FileOutput):
     """Constructor: initialize `headerp' flag."""
     super(HTTPOutput, me).__init__(*args, **kw)
     me.headerp = False
+    me.warnings = []
 
   def write(me, msg):
     """Output protocol: print a header if we've not written one already."""
@@ -126,6 +127,15 @@ class HTTPOutput (O.FileOutput):
     if METHOD == 'HEAD':
       HEADER_DONE()
 
+  def warn(me, msg):
+    """
+    Report a warning message.
+
+    The warning is stashed in a list where it can be retrieved using
+    `warnings'.
+    """
+    me.warnings.append(msg)
+
 def cookie(name, value, **kw):
   """
   Return a HTTP `Set-Cookie' header.
@@ -272,7 +282,8 @@ def page(template, header = {}, title = 'Chopwood', **kw):
   header = dict(header, content_type = 'text/html')
   OUT.header(**header)
   format_tmpl(TMPL['wrapper.fhtml'],
-              title = title, payload = TMPL[template], **kw)
+              title = title, warnings = OUT.warnings,
+              payload = TMPL[template], **kw)
 
 ###--------------------------------------------------------------------------
 ### Error reporting.
index 64b98be..4b2a062 100644 (file)
--- a/chpwd.css
+++ b/chpwd.css
@@ -54,6 +54,13 @@ div.credits {
         font-style: italic;
 }
 
+div.warn {
+       border: thin solid;
+       padding: 0ex 1em 2ex 1em;
+       margin: 2ex 1em;
+       background: red;
+}
+
 /*----- Form layout -------------------------------------------------------*/
 
 /* Common form validation styling. */
index 104dd6a..f6bbe94 100644 (file)
@@ -112,6 +112,17 @@ def cmd_fail_cgi(partial = False):
 <p>This is some normal output which will be rudely interrupted.""")
   raise Exception, 'You asked for this.'
 
+@CGI.subcommand(
+  'warn', ['cgi-noauth'],
+  'Raise an exception, to test the error reporting machinery.')
+def cmd_warn_cgi():
+  OUT.header(content_type = 'text/html')
+  OUT.warn("Here's a very important warning.")
+  CGI.format_tmpl(CGI.TMPL['wrapper.fhtml'],
+                  title = "Warning test", warnings = OUT.warnings,
+                  payload = "<h1>Chopwood: warning test</h1>\n"
+                  "<p>There ought to be a warning below.\n")
+
 ###--------------------------------------------------------------------------
 ### Static content.
 
index b849985..8dd967f 100644 (file)
--- a/output.py
+++ b/output.py
@@ -26,6 +26,7 @@
 from __future__ import with_statement
 
 import contextlib as CTX
+import os as OS
 from cStringIO import StringIO
 import sys as SYS
 
@@ -77,7 +78,7 @@ class BasicOutputDriver (object):
 
   def __init__(me):
     """Trivial constructor."""
-    pass
+    me.warnings = []
 
   def writeln(me, msg):
     """Write MSG, as a complete line."""
@@ -87,6 +88,10 @@ class BasicOutputDriver (object):
     """Write MSG to the output, with any necessary decoration."""
     me._write(str(msg))
 
+  def warn(me, msg):
+    """Write MSG as a warning message."""
+    SYS.stderr.write('%s: %s\n' % (OS.path.basename(SYS.argv[0]), msg))
+
   def close(me):
     """Wrap up when everything that needs saying has been said."""
     pass
@@ -194,10 +199,13 @@ class DelegatingOutput (BasicOutputDriver):
   def writeln(me, msg): me._fluid.target.writeln(msg)
   def close(me): me._fluid.target.close()
   def header(me, **kw): me._fluid.target.header(**kw)
+  def warn(me, msg): me._fluid.target.warn(msg)
 
   ## Delegating properties.
   @property
   def headerp(me): return me._fluid.target.headerp
+  @property
+  def warnings(me): return me._fluid.target.warnings
 
 ## The selected output driver.  Set this with `output_to'.
 OUT = DelegatingOutput()
index 18cc77f..854fa34 100644 (file)
 
 ~={payload}@?~
 
+~={warnings}{~
+<div class=warn>
+<h2>Warnings</h2>
+<ul>
+~@{<li>~:H~%~}~
+</ul>
+</div>~2%~}~
+
 <div class=credits>
   <a href="~={static}H/about.html">Chopwood</a>, version ~={version}H:
   copyright &copy; 2012 Mark Wooding