Revision: 737
Author:   keith.dart
Date:     Fri Aug  2 04:22:04 2013
Log:      Updates to webui modules to matche new API.
http://code.google.com/p/pycopia/source/detail?r=737
Modified:
  /trunk/QA/pycopia/QA/webui/testcases.py
  /trunk/QA/pycopia/QA/webui/testsuites.py
  /trunk/WWW/pycopia/webtools/core/views.py
  /trunk/WWW/pycopia/webtools/debugger/views.py
  /trunk/storage/pycopia/db/webhelpers.py
  /trunk/storage/pycopia/db/webservice.py
  /trunk/storage/pycopia/db/webui/confedit.py
  /trunk/storage/pycopia/db/webui/countryset.py
  /trunk/storage/pycopia/db/webui/db.py
  /trunk/storage/pycopia/db/webui/eqedit.py
=======================================
--- /trunk/QA/pycopia/QA/webui/testcases.py	Mon Jul 11 01:27:14 2011
+++ /trunk/QA/pycopia/QA/webui/testcases.py	Fri Aug  2 04:22:04 2013
@@ -1,7 +1,7 @@
  #!/usr/bin/python2.6
  # -*- coding: us-ascii -*-
  # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
-#
+#
  # $Id$
  #
  #    Copyright (C) 2009 Keith Dart <
ke...@dartworks.biz>
@@ -27,6 +27,7 @@
  from pycopia.WWW import framework
  from pycopia.WWW.middleware import auth
+from pycopia.WWW import HTML5
  from pycopia.aid import IF
  from pycopia.db import types
@@ -44,9 +45,9 @@
  TINY_MCE_EDIT_INIT="""
-    tinyMCE.init({
-        mode : "textareas",
-        theme : "advanced",
+    tinyMCE.init({
+        mode : "textareas",
+        theme : "advanced",
          editor_selector : "TEXT",
           
theme_advanced_buttons1 : "bold,italic,underline,separator,strikethrough,justifyleft,justifycenter,justifyright,justifyfull,bullist,numlist,undo,redo,|,formatselect,fontselect,fontsizeselect",
          theme_advanced_buttons2 : "",
@@ -59,12 +60,9 @@
  def testcase_edit_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
-    doc.stylesheet = request.get_url("css", name="qawebui.css")
-    doc.add_javascript2head(url=request.get_url("js", name="MochiKit.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="proxy.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="db.js"))
-    doc.add_javascript2head(url=request.get_url("js",  
name="tiny_mce/tiny_mce.js"))
+    doc = HTML5.new_document()
+    doc.stylesheet = request.resolver.get_url("css", name="qawebui.css")
+    doc.scripts =  
[ "MochiKit.js", "proxy.js", "db.js", "tiny_mce/tiny_mce.js"]
      doc.add_javascript2head(text=TINY_MCE_EDIT_INIT)
      for name, val in kwargs.items():
          setattr(doc, name, val)
@@ -73,19 +71,17 @@
  def testcase_view_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
-    doc.stylesheet = request.get_url("css", name="qawebui.css")
-    doc.add_javascript2head(url=request.get_url("js", name="MochiKit.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="proxy.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="db.js"))
+    doc = HTML5.new_document()
+    doc.stylesheet = request.resolver.get_url("css", name="qawebui.css")
+    doc.scripts = [ "MochiKit.js", "proxy.js", "db.js"]
      for name, val in kwargs.items():
          setattr(doc, name, val)
      build_framing(request, doc, "Test Case")
      return doc
  #def testcase_delete_constructor(request, **kwargs):
-#    doc = framework.get_acceptable_document(request)
-#    doc.stylesheet = request.get_url("css", name="qawebui.css")
+#    doc = HTML5.new_document()
+#    doc.stylesheet = request.resolver.get_url("css", name="qawebui.css")
  #    for name, val in kwargs.items():
  #        setattr(doc, name, val)
  #    build_framing(request, doc, "Delete Test Case")
@@ -93,8 +89,8 @@
  def testcase_run_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
-    doc.stylesheet = request.get_url("css", name="qawebui.css")
+    doc = HTML5.new_document()
+    doc.stylesheet = request.resolver.get_url("css", name="qawebui.css")
      for name, val in kwargs.items():
          setattr(doc, name, val)
      build_framing(request, doc, "Run Test Case")
@@ -102,11 +98,9 @@
  def testcase_list_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
-    doc.stylesheet = request.get_url("css", name="qawebui.css")
-    doc.add_javascript2head(url=request.get_url("js", name="MochiKit.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="proxy.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="db.js"))
+    doc = HTML5.new_document()
+    doc.stylesheet = request.resolver.get_url("css", name="qawebui.css")
+    doc.scripts = [ "MochiKit.js", "proxy.js", "db.js"]
      for name, val in kwargs.items():
          setattr(doc, name, val)
      build_framing(request, doc, "Test Cases")
@@ -114,14 +108,11 @@
  def testcase_create_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
-    doc.stylesheet = request.get_url("css", name="qawebui.css")
+    doc = HTML5.new_document()
+    doc.stylesheet = request.resolver.get_url("css", name="qawebui.css")
      for name, val in kwargs.items():
          setattr(doc, name, val)
-    doc.add_javascript2head(url=request.get_url("js", name="MochiKit.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="proxy.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="db.js"))
-    doc.add_javascript2head(url=request.get_url("js",  
name="tiny_mce/tiny_mce.js"))
+    doc.scripts =  
[ "MochiKit.js", "proxy.js", "db.js", "tiny_mce/tiny_mce.js"]
      doc.add_javascript2head(text=TINY_MCE_EDIT_INIT)
      build_framing(request, doc, "New Test Case")
      return doc
@@ -135,7 +126,7 @@
           IF(request.path.count("/") > 2, NM("A", {"href":".."}, "Up")),  
NM("_", None),
      ))
      nav.append(NM("P", {"class_": "title"}, title))
-    nav.append(NM("P", None,
+    nav.append(NM("P", None,
              NM("A", {"href": "/auth/logout"}, "logout")))
      doc.add_section("messages", id="messages")
@@ -153,7 +144,7 @@
      sect.add_header(3, "Implementation")
      if dbrow.automated:
          if dbrow.testimplementation:
-            sect.new_para("Implemented in: '%s'%s." %  
(dbrow.testimplementation,
+            sect.new_para("Implemented in: '%s'%s." %  
(dbrow.testimplementation,
                      IF(dbrow.interactive, " (user interactive test)", "")))
          else:
              sect.new_para("Test is automated but has no implementation!",  
class_="error")
@@ -167,7 +158,7 @@
          sect.add_header(3, colname.capitalize())
          sect.append(NM("ASIS", None, getattr(dbrow, colname))) # these  
entries stored as XHTML markup already.
-#        form = doc.add_form(action=request.get_url(testcase_edit,  
tcid=
dbrow.id))
+#        form =  
doc.add_form(action=request.resolver.get_url(testcase_edit, tcid=
dbrow.id))
  #        BR = form.get_new_element("Br")
  #        outerfs = form.add_fieldset(modelclass.__name__)
  #        for colname in  
('name', 'purpose', 'passcriteria', 'startcondition', 'endcondition',
@@ -191,10 +182,10 @@
          doc = resp.doc
          NM = doc.nodemaker
          doc.new_para(
-                NM("Fragments", None,
-                    NM("A", {"href": request.get_url(testcase_run,  
tcid=
dbrow.id)}, resp.get_icon("go")),
-                    NM("A", {"href": request.get_url(testcase_edit,  
tcid=
dbrow.id)}, resp.get_icon("edit")),
-                    NM("A", {"href": "javascript:doDeleteRow(%r, %r);" %  
("TestCase", 
dbrow.id)},
+                NM("Fragments", None,
+                    NM("A", {"href":  
request.resolver.get_url(testcase_run, tcid=
dbrow.id)},  
resp.get_icon("go")),
+                    NM("A", {"href":  
request.resolver.get_url(testcase_edit, tcid=
dbrow.id)},  
resp.get_icon("edit")),
+                    NM("A", {"href": "javascript:doDeleteRow(%r, %r);" %  
("TestCase", 
dbrow.id)},
                          resp.get_icon("delete")),
                  )
          )
@@ -225,7 +216,7 @@
              resp = self.get_page(request, dbrow, err)
              return resp.finalize()
          else:
-            return  
framework.HttpResponseRedirect(request.get_url(testcase_list))
+            return  
framework.HttpResponseRedirect(request.resolver.get_url(testcase_list))
      def get_page(self, request, dbrow, error=None):
          title = "Edit test case %r." % (
dbrow.name,)
@@ -234,7 +225,7 @@
          resp.new_para(title)
          if error is not None:
              resp.new_para(error, class_="error")
-        form = resp.add_form(action=request.get_url(testcase_edit,  
tcid=
dbrow.id))
+        form =  
resp.add_form(action=request.resolver.get_url(testcase_edit, tcid=
dbrow.id))
          BR = form.get_new_element("Br")
          outerfs = form.add_fieldset(modelclass.__name__)
          for colname in  
('name', 'purpose', 'passcriteria', 'startcondition', 'endcondition',
@@ -262,7 +253,7 @@
          resp = framework.ResponseDocument(request,  
testcase_run_constructor, title=title)
          render_testcase(resp.doc, dbrow)
          if not dbrow.automated:
-            form = resp.doc.add_form(action=request.get_url(testcase_run,  
tcid=
dbrow.id))
+            form =  
resp.doc.add_form(action=request.resolver.get_url(testcase_run,  
tcid=
dbrow.id))
              BR = form.get_new_element("Br")
              outerfs = form.add_fieldset("Run the test.")
              outerfs.add_textinput("build", "Build")
@@ -280,7 +271,7 @@
              resp.doc.new_para("""
              This is an automated test. Running automated tests from the
              web interface is not yet supported.
-            """,
+            """,
              class_="error")
          return resp.finalize()
@@ -299,7 +290,7 @@
          tester = models.User.get_by_username(webhelpers.dbsession,  
username)
          build=webhelpers.resolve_build(data.get("build"))
-        rr = models.create(models.TestResult,
+        rr = models.create(models.TestResult,
                  objecttype=webhelpers.RUNNER,
                  testcase=None,
                   
environment=webhelpers.resolve_environment(data.get("environment")),
@@ -316,7 +307,7 @@
                  valid=True,
              )
          webhelpers.dbsession.add(rr)
-        tr = models.create(models.TestResult,
+        tr = models.create(models.TestResult,
                  objecttype=webhelpers.TEST,
                  testcase=dbrow,
                  environment=None,
@@ -342,7 +333,7 @@
              resp.doc.new_para(err, class_="error")
              resp.doc.new_para("There was an error recording this test.  
Please try again.")
              return resp.finalize()
-        return  
framework.HttpResponseRedirect(request.get_url(testcase_list))
+        return  
framework.HttpResponseRedirect(request.resolver.get_url(testcase_list))
  class TestcaseCreator(framework.RequestHandler):
@@ -354,7 +345,7 @@
          resp.new_para(title)
          if error is not None:
              resp.new_para(error, class_="error")
-        form = resp.add_form(action=request.get_url(testcase_create))
+        form =  
resp.add_form(action=request.resolver.get_url(testcase_create))
          outerfs = form.add_fieldset(modelclass.__name__)
          BR = form.get_new_element("Br")
          for colname in  
('name', 'purpose', 'passcriteria', 'startcondition', 'endcondition',
@@ -394,7 +385,7 @@
              resp = self.get_page(request, err)
              return resp.finalize()
          else:
-            return  
framework.HttpResponseRedirect(request.get_url(testcase_list))
+            return  
framework.HttpResponseRedirect(request.resolver.get_url(testcase_list))
@@ -404,7 +395,7 @@
          resp = framework.ResponseDocument(request,  
testcase_list_constructor, title="Test cases")
          tableclass = models.TestCase
          NM = resp.nodemaker
-        resp.new_para(NM("A", {"href": request.get_url(testcase_create)},
+        resp.new_para(NM("A", {"href":  
request.resolver.get_url(testcase_create)},
                  resp.get_icon("add")))
          cycler = itertools.cycle(["row1", "row2"])
          tbl = resp.doc.add_table(width="100%")
@@ -414,18 +405,18 @@
          for dbrow in webhelpers.query(tableclass, {}):
              row = tbl.new_row(id="rowid_%s" % 
dbrow.id,  
class_=cycler.next())
              col = row.new_column(
-                NM("Fragments", {},
-                    NM("A", {"href": "run/%s" % (
dbrow.id,)},
+                NM("Fragments", {},
+                    NM("A", {"href": "run/%s" % (
dbrow.id,)},
                          resp.get_small_icon("go")),
-                    NM("A", {"href": "edit/%s" % (
dbrow.id,)},
+                    NM("A", {"href": "edit/%s" % (
dbrow.id,)},
                          resp.get_small_icon("edit")),
-                    NM("A", {"href": "javascript:doDeleteRow(%r, %r);" %  
(tableclass.__name__, 
dbrow.id)},
+                    NM("A", {"href": "javascript:doDeleteRow(%r, %r);" %  
(tableclass.__name__, 
dbrow.id)},
                          resp.get_small_icon("delete")),
                  )
              )
              firstname = colnames[0]
              row.new_column(
-                NM("A", {"href": request.get_url(testcase_view,  
tcid=
dbrow.id)},
+                NM("A", {"href": request.resolver.get_url(testcase_view,  
tcid=
dbrow.id)},
                          getattr(dbrow, firstname))
              )
              for colname in colnames[1:]:
@@ -446,11 +437,8 @@
  def main_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
-    doc.stylesheet = request.get_url("css", name="qawebui.css")
-#    doc.add_javascript2head(url=request.get_url("js", name="MochiKit.js"))
-#    doc.add_javascript2head(url=request.get_url("js", name="proxy.js"))
-#    doc.add_javascript2head(url=request.get_url("js", name="db.js"))
+    doc = HTML5.new_document()
+    doc.stylesheet = request.resolver.get_url("css", name="qawebui.css")
      for name, val in kwargs.items():
          setattr(doc, name, val)
      build_framing(request, doc, "Test Management")
@@ -465,11 +453,11 @@
          resp.new_para("Test Management.")
          resp.doc.append(
            NM("UL", None,
-            NM("LI", None,
-                    NM("A", {"href":  
request.get_url(testcase_list)}, "Test cases."),
+            NM("LI", None,
+                    NM("A", {"href":  
request.resolver.get_url(testcase_list)}, "Test cases."),
              ),
-#            NM("LI", None,
-#                    NM("A", {"href":  
request.get_url(testresults_list)}, "Latest test results."),
+#            NM("LI", None,
+#                    NM("A", {"href":  
request.resolver.get_url(testresults_list)}, "Latest test results."),
  #            ),
            )
          )
=======================================
--- /trunk/QA/pycopia/QA/webui/testsuites.py	Mon Oct 17 09:58:56 2011
+++ /trunk/QA/pycopia/QA/webui/testsuites.py	Fri Aug  2 04:22:04 2013
@@ -21,19 +21,21 @@
  """
  from pycopia.WWW import framework
+from pycopia.WWW import HTML5
  from pycopia.WWW.middleware import auth
  def ts_page_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
-    doc.stylesheet = request.get_url("css", name="common.css")
-    doc.stylesheet = request.get_url("css", name="ui.css")
-    doc.stylesheet = request.get_url("css", name="db.css")
-    doc.add_javascript2head(url=request.get_url("js", name="MochiKit.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="proxy.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="ui.js"))
-    doc.add_javascript2head(url=request.get_url("js", name="db.js"))
-    doc.add_javascript2head(url=request.get_url("js",  
name="testsuites.js"))
+    doc = HTML5.new_document()
+    res = request.resolver
+    doc.stylesheet = res.get_url("css", name="common.css")
+    doc.stylesheet = res.get_url("css", name="ui.css")
+    doc.stylesheet = res.get_url("css", name="db.css")
+    doc.add_javascript2head(url=res.get_url("js", name="MochiKit.js"))
+    doc.add_javascript2head(url=res.get_url("js", name="proxy.js"))
+    doc.add_javascript2head(url=res.get_url("js", name="ui.js"))
+    doc.add_javascript2head(url=res.get_url("js", name="db.js"))
+    doc.add_javascript2head(url=res.get_url("js", name="testsuites.js"))
      for name, val in kwargs.items():
          setattr(doc, name, val)
      nav = doc.add_section("navigation")
=======================================
--- /trunk/WWW/pycopia/webtools/core/views.py	Tue Feb 24 01:26:47 2009
+++ /trunk/WWW/pycopia/webtools/core/views.py	Fri Aug  2 04:22:04 2013
@@ -1,6 +1,6 @@
  #!/usr/bin/python
  # vim:ts=4:sw=4:softtabstop=4:smarttab:expandtab
-#
+#
  #    Copyright (C) 2007  Keith Dart <
ke...@dartworks.biz>
  #
  #    This library is free software; you can redistribute it and/or
@@ -21,6 +21,7 @@
  from pycopia.WWW import framework
  from pycopia.WWW import XHTML
  from pycopia.aid import partial
+from pycopia.WWW import HTML5
  from pycopia import ezmail
@@ -29,7 +30,7 @@
  """
  def doc_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
+    doc = HTML5.new_document()
      for name, val in kwargs.items():
          setattr(doc, name, val)
      container = doc.add_section("container")
@@ -57,8 +58,8 @@
  def main(request):
-    resp = framework.ResponseDocument(request, doc_constructor,
-                title="Web Tools",
+    resp = framework.ResponseDocument(request, doc_constructor,
+                title="Web Tools",
                  stylesheet=request.get_url("css", name="default.css"))
      resp.doc.header.add_header(1, "Web Utilities and Tools")
      resp.doc.nav.append(resp.anchor2("/", "Home"))
@@ -67,7 +68,7 @@
  def headers(request):
-    resp = framework.ResponseDocument(request, doc_constructor,
+    resp = framework.ResponseDocument(request, doc_constructor,
               title="Request Headers",
               stylesheet=request.get_url("css", name="headers.css"))
      resp.doc.nav.append(resp.anchor2("/", "Home"))
@@ -97,7 +98,7 @@
          body["Content-Disposition"] = 'inline'
          msg = ezmail.AutoMessage(str(rpt), mimetype=rpt.MIMETYPE,  
charset=rpt.encoding)
          msg["Content-Disposition"] = 'attachment; filename=headers.html'
-        ezmail.mail([body, msg], To=recipients,
+        ezmail.mail([body, msg], To=recipients,
                    subject="Webtool header request from %s." %  
(request.environ.get("REMOTE_ADDR", "<unknown>"),))
      get_header_table(resp.doc.content, request.environ)
=======================================
--- /trunk/WWW/pycopia/webtools/debugger/views.py	Tue Jul 24 00:13:52 2007
+++ /trunk/WWW/pycopia/webtools/debugger/views.py	Fri Aug  2 04:22:04 2013
@@ -8,8 +8,825 @@
  Web-interactive Python debugger.
  """
-# TODO implement. ;-)
-def main(request):
-    pass
+import sys, os
+import linecache
+import bdb
+import re
+
+try:
+    from repr import Repr
+except ImportError:
+    from reprlib import Repr
+
+# Create a custom safe Repr instance and increase its maxstring.
+# The default of 30 truncates error messages too easily.
+_repr = Repr()
+_repr.maxstring = 200
+_repr.maxother = 50
+_saferepr = _repr.repr
+
+DebuggerQuit = bdb.BdbQuit
+
+def find_function(funcname, filename):
+    cre = re.compile(r'def\s+%s\s*[(]' % funcname)
+    try:
+        fp = open(filename)
+    except IOError:
+        return None
+    # consumer of this info expects the first line to be 1
+    lineno = 1
+    answer = None
+    while 1:
+        line = fp.readline()
+        if line == '':
+            break
+        if cre.match(line):
+            answer = funcname, filename, lineno
+            break
+        lineno = lineno + 1
+    fp.close()
+    return answer
+
+def lookupmodule(filename):
+    """Helper function for break/clear parsing."""
+    root, ext = os.path.splitext(filename)
+    if ext == '':
+        filename = filename + '.py'
+    if os.path.isabs(filename):
+        return filename
+    for dirname in sys.path:
+        while os.path.islink(dirname):
+            dirname = os.readlink(dirname)
+        fullname = os.path.join(dirname, filename)
+        if os.path.exists(fullname):
+            return fullname
+    return None
+
+def checkline(filename, lineno, ui):
+    """Return line number of first line at or after input
+    argument such that if the input points to a 'def', the
+    returned line number is the first
+    non-blank/non-comment line to follow.  If the input
+    points to a blank or comment line, return 0.  At end
+    of file, also return 0."""
+
+    line = linecache.getline(filename, lineno)
+    if not line:
+        ui.Print('*** End of file')
+        return 0
+    line = line.strip()
+    # Don't allow setting breakpoint at a blank line
+    if (not line or (line[0] == '#') or
+         (line[:3] == '"""') or line[:3] == "'''"):
+        ui.Print('*** Blank or comment')
+        return 0
+    # When a file is read in and a breakpoint is at
+    # the 'def' statement, the system stops there at
+    # code parse time.  We don't want that, so all breakpoints
+    # set at 'def' statements are moved one line onward
+    if line[:3] == 'def':
+        instr = ''
+        brackets = 0
+        while 1:
+            skipone = 0
+            for c in line:
+                if instr:
+                    if skipone:
+                        skipone = 0
+                    elif c == '\\':
+                        skipone = 1
+                    elif c == instr:
+                        instr = ''
+                elif c == '#':
+                    break
+                elif c in ('"',"'"):
+                    instr = c
+                elif c in ('(','{','['):
+                    brackets = brackets + 1
+                elif c in (')','}',']'):
+                    brackets = brackets - 1
+            lineno = lineno+1
+            line = linecache.getline(filename, lineno)
+            if not line:
+                ui.Print('*** end of file')
+                return 0
+            line = line.strip()
+            if not line: continue   # Blank line
+            if brackets <= 0 and line[0] not in ('#','"',"'"):
+                break
+    return lineno
+
+
+
+class Debugger(bdb.Bdb):
+    def reset(self):
+        bdb.Bdb.reset(self) # old style class
+        self.forget()
+        self._ui = WebUI()
+
+    def _expansions(self, c):
+        if c == "S": # current frame over total frames in backtrace
+            return "%s/%s" % (self.curindex+1, len(self.stack))
+
+    def forget(self):
+        self.lineno = None
+        self.stack = []
+        self.curindex = 0
+        self.curframe = None
+
+    def setup(self, f, t):
+        self.forget()
+        self.stack, self.curindex = self.get_stack(f, t)
+        self.curframe = self.stack[self.curindex][0]
+
+    # Override Bdb methods
+
+    def set_trace(self, frame=None, start=0):
+        """Start debugging from `frame`, or `start` frames back from
+        caller's frame.
+        If frame is not specified, debugging starts from caller's frame.
+        """
+        if frame is None:
+            frame = sys._getframe().f_back
+        self.reset()
+        if start:
+            start = int(start)
+            while start > 0 and frame:
+                frame = frame.f_back
+                start -= 1
+        while frame:
+            frame.f_trace = self.trace_dispatch
+            self.botframe = frame
+            frame = frame.f_back
+        self.set_step()
+        sys.settrace(self.trace_dispatch)
+
+    def user_call(self, frame, argument_list):
+        """This method is called when there is the remote possibility
+        that we ever need to stop in this function."""
+        if self.stop_here(frame):
+            self._ui.printf('%g--Call--%N')
+            self.interaction(frame, None)
+
+    def user_line(self, frame):
+        """This function is called when we stop or break at this line."""
+        self.interaction(frame, None)
+
+    def user_return(self, frame, return_value):
+        """This function is called when a return trap is set here."""
+        frame.f_locals['__return__'] = return_value
+        self._ui.printf('%g--Return--%N')
+        self.interaction(frame, None)
+
+    def user_exception(self, frame, exc_tuple):
+        """This function is called if an exception occurs,
+        but only if we are to stop at or just below this level."""
+        exc_type, exc_value, exc_traceback = exc_tuple
+        frame.f_locals['__exception__'] = exc_type, exc_value
+        if type(exc_type) == type(''):
+            exc_type_name = exc_type
+        else:
+            exc_type_name = exc_type.__name__
+        self.print_exc(exc_type_name, exc_value)
+        self.interaction(frame, exc_traceback)
+
+    # General interaction function
+    def interaction(self, frame, traceback):
+        self.setup(frame, traceback)
+        self.print_stack_entry(self.stack[self.curindex])
+        if self._parser is None:
+            cmd = DebuggerCommands(self._ui)
+            cmd._setup(self, "%GDebug%N:%S> ")
+            parser = DebuggerParser(cmd)
+            self._parser = parser
+        self._parser.interact()
+        self.forget()
+
+    def execline(self, line):
+        locals = self.curframe.f_locals
+        globals = self.curframe.f_globals
+        try:
+            code = compile(line + '\n', '<stdin>', 'single')
+        except:
+            t, v = sys.exc_info()[:2]
+            self._ui.printf('*** Could not compile: %%r%s%%N: %s' % (t, v))
+        else:
+            try:
+                exec(code, globals, locals)
+            except:
+                t, v = sys.exc_info()[:2]
+                self._ui.printf('*** %%r%s%%N: %s' % (t, v))
+
+    def go_up(self):
+        if self.curindex == 0:
+            return '*** Oldest frame'
+        self.curindex = self.curindex - 1
+        self.curframe = self.stack[self.curindex][0]
+        self.print_stack_entry(self.stack[self.curindex])
+        self.lineno = None
+        return None
+
+    def go_down(self):
+        if self.curindex + 1 == len(self.stack):
+            return '*** Newest frame'
+        self.curindex = self.curindex + 1
+        self.curframe = self.stack[self.curindex][0]
+        self.print_stack_entry(self.stack[self.curindex])
+        self.lineno = None
+        return None
+
+    def getval(self, arg):
+        return eval(arg, self.curframe.f_globals, self.curframe.f_locals)
+
+    def retval(self):
+        if '__return__' in self.curframe.f_locals:
+            return self.curframe.f_locals['__return__']
+        else:
+            return None
+
+    def defaultFile(self):
+        """Produce a reasonable default."""
+        filename = self.curframe.f_code.co_filename
+        return filename
+
+    def lineinfo(self, identifier):
+        failed = (None, None, None)
+        # Input is identifier, may be in single quotes
+        idstring = identifier.split("'")
+        if len(idstring) == 1:
+            # not in single quotes
+            id = idstring[0].strip()
+        elif len(idstring) == 3:
+            # quoted
+            id = idstring[1].strip()
+        else:
+            return failed
+        if id == '':
+            return failed
+        parts = id.split('.')
+        # Protection for derived debuggers
+        if parts[0] == 'self':
+            del parts[0]
+            if len(parts) == 0:
+                return failed
+        # Best first guess at file to look at
+        fname = self.defaultFile()
+        if len(parts) == 1:
+            item = parts[0]
+        else:
+            # More than one part.
+            # First is module, second is method/class
+            f = lookupmodule(parts[0])
+            if f:
+                fname = f
+            item = parts[1]
+        answer = find_function(item, fname)
+        return answer or failed
+
+    # Print a traceback starting at the top stack frame.
+    # The most recently entered frame is printed last;
+    # this is different from dbx and gdb, but consistent with
+    # the Python interpreter's stack trace.
+    # It is also consistent with the up/down commands (which are
+    # compatible with dbx and gdb: up moves towards 'main()'
+    # and down moves towards the most recent stack frame).
+
+    def print_stack_trace(self):
+        try:
+            for frame_lineno in self.stack:
+                self.print_stack_entry(frame_lineno)
+        except KeyboardInterrupt:
+            pass
+
+    def print_stack_entry(self, frame_lineno):
+        frame, lineno = frame_lineno
+        if frame is self.curframe:
+            self._ui.Print(self._ui.format('%I>%N'), None)
+        else:
+            self._ui.Print(' ', None)
+        self._ui.Print(self.format_stack_entry(frame_lineno))
+        self.lineno = None
+
+    def format_stack_entry(self, frame_lineno):
+        frame, lineno = frame_lineno
+        filename = self.canonic(frame.f_code.co_filename)
+        s = []
+        s.append(self._ui.format("%%y%s%%N(%%Y%r%%N) in " % (filename,  
lineno)))
+        if frame.f_code.co_name:
+            s.append(frame.f_code.co_name)
+        else:
+            s.append("<lambda>")
+        if '__args__' in frame.f_locals:
+            args = frame.f_locals['__args__']
+            s.append(_saferepr(args))
+        else:
+            s.append('()')
+        if '__return__' in frame.f_locals:
+            rv = frame.f_locals['__return__']
+            s.append(self._ui.format('%I->%N'))
+            s.append(_saferepr(rv))
+        line = linecache.getline(filename, lineno)
+        if line:
+            s.append("\n  ")
+            s.append(line.strip())
+        return "".join(s)
+
+    def print_exc(self, ex, val):
+        uif = self._ui.format
+        self._ui.Print(uif('%R'), ex, uif('%N:'), str(val))
+
+
+
+
+class DebuggerCommands(CLI.BaseCommands):
+
+    def _setup(self, obj, prompt=None):
+        self._dbg = obj # the debugger object
+        self._obj = obj # for base class
+        if prompt:
+            self._environ["PS1"] = str(prompt)
+        self._reset_scopes()
+
+    def finalize(self):
+        self._dbg.set_quit()
+
+    def default_command(self, argv):
+        line = " ".join(argv)
+        self._dbg.execline(line)
+
+    def execute(self, argv):
+        """execute <statement>
+    Execute <statement> in current frame context."""
+        line = " ".join(argv[1:])
+        self._dbg.execline(line)
+
+    def brk(self, argv):
+        """brk [-t] [breakpoint] ([file:]lineno | function) [, condition]
+    With a line number argument, set a break there in the current
+    file.  With a function name, set a break at first executable line
+    of that function.  Without argument, list all breaks.  If a second
+    argument is present, it is a string specifying an expression
+    which must evaluate to true before the breakpoint is honored.
+
+    The line number may be prefixed with a filename and a colon,
+    to specify a breakpoint in another file (probably one that
+    hasn't been loaded yet).  The file is searched for on sys.path;
+    the .py suffix may be omitted."""
+        temporary = False
+        opts, longopts, args = self.getopt(argv, "t")
+        for opt, arg in opts:
+            if opt == "-t":
+                temporary = True
+
+        if not args:
+            if self._dbg.breaks:  # There's at least one
+                self._print("Num Type         Disp Enb   Where")
+                for bp in bdb.Breakpoint.bpbynumber:
+                    if bp:
+                        bp.bpprint()
+            return
+        # parse arguments; comma has lowest precedence
+        # and cannot occur in filename
+        arg = " ".join(args)
+        filename = None
+        lineno = None
+        cond = None
+        comma = arg.find(',')
+        if comma > 0:
+            # parse stuff after comma: "condition"
+            cond = arg[comma+1:].lstrip()
+            arg = arg[:comma].rstrip()
+        # parse stuff before comma: [filename:]lineno | function
+        colon = arg.rfind(':')
+        if colon >= 0:
+            filename = arg[:colon].rstrip()
+            f = lookupmodule(filename)
+            if not f:
+                self._print('*** ', repr(filename), 'not found from  
sys.path')
+                return
+            else:
+                filename = f
+            arg = arg[colon+1:].lstrip()
+            try:
+                lineno = int(arg)
+            except ValueError as msg:
+                self._print('*** Bad lineno:', arg)
+                return
+        else:
+            # no colon; can be lineno or function
+            try:
+                lineno = int(arg)
+            except ValueError:
+                try:
+                    func = eval(arg,
+                                self._dbg.curframe.f_globals,
+                                self._dbg.curframe.f_locals)
+                except:
+                    func = arg
+                try:
+                    if hasattr(func, 'im_func'):
+                        func = func.im_func
+                    code = func.func_code
+                    lineno = code.co_firstlineno
+                    filename = code.co_filename
+                except:
+                    # last thing to try
+                    (ok, filename, ln) = self._dbg.lineinfo(arg)
+                    if not ok:
+                        self._print('*** The specified object', repr(arg))
+                        self._print('is not a function or was not found  
along sys.path.')
+                        return
+                    lineno = int(ln)
+        if not filename:
+            filename = self._dbg.defaultFile()
+        # Check for reasonable breakpoint
+        line = checkline(filename, lineno, self._ui)
+        if line:
+            # now set the break point
+            err = self._dbg.set_break(filename, line, temporary, cond)
+            if err:
+                self._print('***', err)
+            else:
+                bp = self._dbg.get_breaks(filename, line)[-1]
+                self._print("Breakpoint %d at %s:%d" % (bp.number,  
bp.file, bp.line))
+
+    def enable(self, argv):
+        """enable bpnumber [bpnumber ...]
+    Enables the breakpoints given as a space separated list of
+    bp numbers."""
+        for i in argv[1:]:
+            try:
+                i = int(i)
+            except ValueError:
+                self._print('Breakpoint index %r is not a number' % i)
+                continue
+            if not (0 <= i < len(bdb.Breakpoint.bpbynumber)):
+                self._print('No breakpoint numbered', i)
+                continue
+            bp = bdb.Breakpoint.bpbynumber[i]
+            if bp:
+                bp.enable()
+
+    def disable(self, argv):
+        """disable bpnumber [bpnumber ...]
+    Disables the breakpoints given as a space separated list of
+    bp numbers."""
+        for i in argv[1:]:
+            try:
+                i = int(i)
+            except ValueError:
+                self._print('Breakpoint index %r is not a number' % i)
+                continue
+            if not (0 <= i < len(bdb.Breakpoint.bpbynumber)):
+                self._print('No breakpoint numbered', i)
+                continue
+            bp = bdb.Breakpoint.bpbynumber[i]
+            if bp:
+                bp.disable()
+
+    def condition(self, argv):
+        """condition bpnumber str_condition
+    str_condition is a string specifying an expression which
+    must evaluate to true before the breakpoint is honored.
+    If str_condition is absent, any existing condition is removed;
+    i.e., the breakpoint is made unconditional."""
+        bpnum = int(argv[1].strip())
+        try:
+            cond = argv[2]
+        except:
+            cond = None
+        bp = bdb.Breakpoint.bpbynumber[bpnum]
+        if bp:
+            bp.cond = cond
+            if not cond:
+                self._print('Breakpoint', bpnum, 'is now unconditional.')
+
+    def ignore(self, argv):
+        """ignore bpnumber count
+    Sets the ignore count for the given breakpoint number.  A breakpoint
+    becomes active when the ignore count is zero.  When non-zero, the
+    count is decremented each time the breakpoint is reached and the
+    breakpoint is not disabled and any associated condition evaluates
+    to true."""
+        bpnum = int(argv[1].strip())
+        try:
+            count = int(argv[2].strip())
+        except:
+            count = 0
+        bp = bdb.Breakpoint.bpbynumber[bpnum]
+        if bp:
+            bp.ignore = count
+            if count > 0:
+                reply = 'Will ignore next '
+                if count > 1:
+                    reply = reply + '%d crossings' % count
+                else:
+                    reply = reply + '1 crossing'
+                self._print(reply + ' of breakpoint %d.' % bpnum)
+            else:
+                self._print( 'Will stop next time breakpoint', bpnum, 'is  
reached.')
+
+    def clear(self, argv):
+        """clear ...
+    Three possibilities, tried in this order:
+    clear -> clear all breaks, ask for confirmation
+    clear file:lineno -> clear all breaks at file:lineno
+    clear bpno bpno ... -> clear breakpoints by number
+
+    With a space separated list of breakpoint numbers, clear
+    those breakpoints.  Without argument, clear all breaks (but
+    first ask confirmation).  With a filename:lineno argument,
+    clear all breaks at that line in that file.
+
+    Note that the argument is different from previous versions of
+    the debugger (in python distributions 1.5.1 and before) where
+    a linenumber was used instead of either filename:lineno or
+    breakpoint numbers."""
+        if len(argv) == 1:
+            reply = self._ui.yes_no('Clear all breaks? ')
+            if reply:
+                self._dbg.clear_all_breaks()
+            return
+        arg = " ".join(argv[1:])
+        if ':' in arg:
+            # Make sure it works for "clear C:\foo\bar.py:12"
+            i = arg.rfind(':')
+            filename = arg[:i]
+            arg = arg[i+1:]
+            try:
+                lineno = int(arg)
+            except:
+                err = "Invalid line number (%s)" % arg
+            else:
+                err = self._dbg.clear_break(filename, lineno)
+            if err:
+                self._print('***', err)
+            return
+        numberlist = arg.split()
+        for i in numberlist:
+            err = self._dbg.clear_bpbynumber(i)
+            if err:
+                self._print('***', err)
+            else:
+                self._print('Deleted breakpoint %s ' % (i,))
+
+    def where(self, argv): # backtrace
+        """where
+    Print a stack trace, with the most recent frame at the bottom.
+    An arrow indicates the "current frame", which determines the
+    context of most commands.  'bt' is an alias for this command."""
+        self._dbg.print_stack_trace()
+
+    def up(self, argv):
+        """up
+    Move the current frame one level up in the stack trace
+    (to a newer frame)."""
+        res = self._dbg.go_up()
+        if res:
+            self._print(res)
+        self._reset_namespace()
+
+    def down(self, argv):
+        """down
+    Move the current frame one level down in the stack trace
+    (to an older frame)."""
+        res = self._dbg.go_down()
+        if res:
+            self._print(res)
+        self._reset_namespace()
+
+    def step(self, argv):
+        """step
+    Execute the current line, stop at the first possible occasion
+    (either in a function that is called or in the current function)."""
+        self._dbg.set_step()
+        raise CLI.CommandExit
+
+    def next(self, argv):
+        """next
+    Continue execution until the next line in the current function
+    is reached or it returns."""
+        self._dbg.set_next(self._dbg.curframe)
+        raise CLI.CommandExit
+
+    def returns(self, argv):
+        """returns
+    Continue execution until the current function returns."""
+        self._dbg.set_return(self._dbg.curframe)
+        raise CLI.CommandExit
+
+    def cont(self, arg):
+        """cont
+    Continue execution, only stop when a breakpoint is encountered."""
+        self._dbg.set_continue()
+        if self._dbg.breaks:
+            raise CLI.CommandExit
+        else:
+            self._dbg._parser = None
+            raise CLI.CommandQuit
+
+    def jump(self, argv):
+        """jump lineno
+    Set the next line that will be executed."""
+        if self._dbg.curindex + 1 != len(self._dbg.stack):
+            self._print("*** You can only jump within the bottom frame")
+            return
+        try:
+            arg = int(argv[1])
+        except ValueError:
+            self._print("*** The 'jump' command requires a line number.")
+        else:
+            try:
+                # Do the jump, fix up our copy of the stack, and display  
the
+                # new position
+                self._dbg.curframe.f_lineno = arg
+                self._dbg.stack[self._dbg.curindex] =  
self._dbg.stack[self._dbg.curindex][0], arg
+                 
self._dbg.print_stack_entry(self._dbg.stack[self._dbg.curindex])
+            except ValueError as e:
+                self._print('*** Jump failed:', e)
+            else:
+                self._reset_namespace()
+
+    def quit(self, argv):
+        """quit or exit - Quit from the debugger.
+    The program being executed is aborted."""
+        super(DebuggerCommands, self).quit(argv)
+
+    def args(self, argv):
+        """args
+    Print the arguments of the current function."""
+        f = self._dbg.curframe
+        co = f.f_code
+        dict = f.f_locals
+        n = co.co_argcount
+        if co.co_flags & 4: n = n+1
+        if co.co_flags & 8: n = n+1
+        for i in range(n):
+            name = co.co_varnames[i]
+            self._print(name, '=', None)
+            if name in dict:
+                self._print(dict[name])
+            else:
+                self._print("*** undefined ***")
+
+    def retval(self, argv):
+        """retval
+    Show return value."""
+        val = self._dbg.retval()
+        if val is not None:
+            self._print(val)
+
+    def show(self, argv):
+        """show [<name>...]
+    Shows the current frame's object and values. If parameter names are  
given
+    then show only those local names."""
+        f = self._dbg.curframe
+        if len(argv) > 1:
+            for name in argv[1:]:
+                try:
+                    self._print("%25.25s = %s" % \
+                                (name, _saferepr(f.f_locals[name])))
+                except KeyError:
+                    self._print("%r not found." % (name,))
+        else:
+            self._ui.printf("%%I%s%%N (" % (f.f_code.co_name  
or "<lambda>",))
+            co = f.f_code
+            n = co.co_argcount
+            if co.co_flags & 4:
+                n += 1
+            if co.co_flags & 8:
+                n += 1
+            local = f.f_locals
+            for name in co.co_varnames[:n]:
+                val = local.get(name, "*** no formal ***")
+                self._print("%15.15s = %s," % (name, _saferepr(val)))
+            self._print("  )")
+            s = []
+            for name in co.co_varnames[n:]:
+                val = local.get(name, "*** undefined ***")
+                s.append("%25.25s = %s" % (name, _saferepr(val)))
+            if s:
+                self._print("  Compiled locals:")
+                self._print("\n".join(s))
+            # find and print local variables that were not defined when
+            # compiled. These must have been "stuffed" by other code.
+            extra = []
+            varnames = list(co.co_varnames) # to get list methods
+            for name, val in local.items():
+                try:
+                    i = varnames.index(name)
+                except ValueError:
+                    extra.append("%25.25s = %s" % (name, _saferepr(val)))
+            if extra:
+                self._print("  Extra locals:")
+                self._print("\n".join(extra))
+
+    def Print(self, argv):
+        """Print <expression>
+    Print the value of the expression."""
+        try:
+            self._print(repr(self._dbg.getval(" ".join(argv[1:]))))
+        except:
+            ex, val = sys.exc_info()[:2]
+            self._print("***", ex, val)
+
+    def list(self, argv):
+        """list [first [,last]]
+    List source code for the current file.
+    Without arguments, list 20 lines around the current line
+    or continue the previous listing.
+    With one argument, list 20 lines centered at that line.
+    With two arguments, list the given range;
+    if the second argument is less than the first, it is a count."""
+
+        last = None
+        if len(argv) >= 2:
+            first = max(1, int(argv[1]) - 10)
+            if len(argv) >= 3:
+                last = int(argv[2])
+                if last < first:
+                    # Assume it's a count
+                    last = first + last
+        elif self._dbg.lineno is None:
+            first = max(1, self._dbg.curframe.f_lineno - 10)
+        else:
+            first = self._dbg.lineno + 1
+        if last is None:
+            last = first + 20
+        filename = self._dbg.curframe.f_code.co_filename
+        self._print_source(filename, first, last)
+
+
+    def whatis(self, argv):
+        """whatis arg
+    Prints the type of the argument."""
+        arg = " ".join(argv[1:])
+        try:
+            value = eval(arg, self._dbg.curframe.f_globals,  
self._dbg.curframe.f_locals)
+        except:
+            t, v = sys.exc_info()[:2]
+            if type(t) == type(''):
+                exc_type_name = t
+            else: exc_type_name = t.__name__
+            self._print('***', exc_type_name + ':', repr(v))
+            return
+        # Is it a function?
+        try:
+            code = value.func_code
+        except:
+            pass
+        else:
+            self._print('Function', code.co_name)
+            return
+        # Is it an instance method?
+        try:
+            code = value.im_func.func_code
+        except:
+            pass
+        else:
+            self._print('Method', code.co_name)
+            return
+        # None of the above...
+        self._print(type(value))
+
+    def search(self, argv):
+        """search <pattern>
+    Search the source file for the regular expression pattern."""
+        patt = re.compile(" ".join(argv[1:]))
+        filename = self._dbg.curframe.f_code.co_filename
+        if self._dbg.lineno is None:
+            start = 0
+        else:
+            start = max(0,  self._dbg.lineno - 9)
+        lines = linecache.getlines(filename)[start:]
+        for lineno, line in enumerate(lines):
+            #line = linecache.getline(filename, lineno)
+            mo = patt.search(line)
+            if mo:
+                self._print_source(filename, lineno+start-10,  
lineno+start+10)
+                return
+        else:
+            self._print("Pattern not found.")
+
+    def _print_source(self, filename, first, last):
+        breaklist = self._dbg.get_file_breaks(filename)
+        try:
+            for lineno in range(first, last+1):
+                line = linecache.getline(filename, lineno)
+                if not line:
+                    self._ui.printf('%Y[EOF]%N')
+                    break
+                else:
+                    s = []
+                    s.append("%5.5s%s" % (lineno,  
self._ui.format(" %RB%N") if (lineno in breaklist) else "  "))
+                    if lineno == self._dbg.curframe.f_lineno:
+                        s.append(self._ui.format("%I->%N "))
+                    else:
+                        s.append("   ")
+                    self._print("".join(s), line.rstrip())
+                    self._dbg.lineno = lineno
+        except KeyboardInterrupt:
+            pass
+
=======================================
--- /trunk/storage/pycopia/db/webhelpers.py	Mon Mar  4 15:29:59 2013
+++ /trunk/storage/pycopia/db/webhelpers.py	Fri Aug  2 04:22:04 2013
@@ -58,7 +58,7 @@
  # decorator for top-level handlers that sets up DB session.
  def setup_dbsession(handler):
      def newhandler(request, *args, **kwargs):
-        with models.DatabaseContext(request) as dbsession:
+        with models.DatabaseContext() as dbsession:
              with GlobalDatabaseContext(dbsession):
                  return handler(request, *args, **kwargs)
      return newhandler
=======================================
--- /trunk/storage/pycopia/db/webservice.py	Wed Aug 29 05:42:55 2012
+++ /trunk/storage/pycopia/db/webservice.py	Fri Aug  2 04:22:04 2013
@@ -33,6 +33,7 @@
  #from pycopia.dictlib import AttrDict
  from pycopia.WWW import json
  from pycopia.WWW import framework
+from pycopia.WWW import HTML5
  from pycopia.WWW.middleware import auth
  from sqlalchemy.exc import DataError, IntegrityError
@@ -238,7 +239,7 @@
  ##### Code below here will eventually disappear.
  def doc_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
+    doc = HTML5.new_document()
      doc.stylesheets = ["common.css", "ui.css", "db.css"]
      doc.scripts =  
["MochiKit.js", "proxy.js", "ui.js", "sorttable.js", "db.js"]
      for name, val in kwargs.items():
=======================================
--- /trunk/storage/pycopia/db/webui/confedit.py	Fri Jun 15 11:02:32 2012
+++ /trunk/storage/pycopia/db/webui/confedit.py	Fri Aug  2 04:22:04 2013
@@ -26,14 +26,16 @@
  from pycopia.db import webhelpers
  from pycopia.WWW import framework
+from pycopia.WWW import HTML5
  from pycopia.WWW import json
  from pycopia.WWW.middleware import auth
  def config_page_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
-    doc.stylesheet = request.get_url("css", name="tableedit.css")
+    doc = HTML5.new_document()
+    res = request.resolver
+    doc.stylesheet = res.get_url("css", name="tableedit.css")
      doc.scripts =  
["MochiKit.js", "proxy.js", "ui.js", "db.js", "config.js"]
      for name, val in kwargs.items():
          setattr(doc, name, val)
=======================================
--- /trunk/storage/pycopia/db/webui/countryset.py	Mon Oct 17 09:58:56 2011
+++ /trunk/storage/pycopia/db/webui/countryset.py	Fri Aug  2 04:22:04 2013
@@ -16,7 +16,7 @@
  """
  Supply server-side components of the countryset editor. A country set is
-an arbitrary set of countries selected from a list.
+an arbitrary set of countries selected from a list.
  This also serves as an example of dynamic web applications using the
  Pycopia framework.
@@ -25,11 +25,12 @@
  from pycopia.WWW import framework
+from pycopia.WWW import HTML5
  from pycopia.WWW.middleware import auth
  def cs_page_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
+    doc = HTML5.new_document()
      doc.stylesheets = ["common.css", "ui.css", "db.css"]
      doc.scripts =  
["MochiKit.js", "proxy.js", "ui.js", "db.js", "countryset.js"]
      for name, val in kwargs.items():
=======================================
--- /trunk/storage/pycopia/db/webui/db.py	Wed Oct 12 17:26:18 2011
+++ /trunk/storage/pycopia/db/webui/db.py	Fri Aug  2 04:22:04 2013
@@ -19,12 +19,13 @@
  """
  from pycopia.WWW import framework
+from pycopia.WWW import HTML5
  from pycopia.WWW.middleware import auth
  CHARSET = "utf-8"
  def dbedit_page_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
+    doc = HTML5.new_document()
      doc.stylesheets = ["common.css", "ui.css", "db.css"]
      doc.scripts =  
[ "MochiKit.js", "proxy.js", "ui.js", "db.js", "dbedit.js"]
      for name, val in kwargs.items():
@@ -38,7 +39,7 @@
  def metadata_page_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
+    doc = HTML5.new_document()
      doc.stylesheets = ["common.css", "ui.css", "db.css"]
      doc.scripts =  
[ "MochiKit.js", "proxy.js", "ui.js", "db.js", "dbmetaapp.js"]
      for name, val in kwargs.items():
=======================================
--- /trunk/storage/pycopia/db/webui/eqedit.py	Mon Jul 11 01:23:15 2011
+++ /trunk/storage/pycopia/db/webui/eqedit.py	Fri Aug  2 04:22:04 2013
@@ -26,6 +26,7 @@
  from pycopia.WWW import framework
+from pycopia.WWW import HTML5
  from pycopia.WWW import json
  from pycopia.WWW.middleware import auth
@@ -35,7 +36,7 @@
  def eqedit_constructor(request, **kwargs):
-    doc = framework.get_acceptable_document(request)
+    doc = HTML5.new_document()
      for name, val in kwargs.items():
          setattr(doc, name, val)
      doc.title = "Equipment Editor"
@@ -78,8 +79,7 @@
              q = q.limit(end)
      return q.all()
-_exported = [get_equipment_list]
-dispatcher = json.JSONDispatcher(_exported)
+dispatcher = json.JSONDispatcher([get_equipment_list])
  dispatcher =  
auth.need_authentication(webhelpers.setup_dbsession(dispatcher))