[Mpuls-commits] r277 - in wasko/trunk: . waskaweb/controllers waskaweb/lib waskaweb/model waskaweb/templates/casemanagement
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Fri Feb 20 16:02:38 CET 2009
Author: teichmann
Date: 2009-02-20 16:02:29 +0100 (Fri, 20 Feb 2009)
New Revision: 277
Modified:
wasko/trunk/ChangeLog.txt
wasko/trunk/waskaweb/controllers/CaseBase.py
wasko/trunk/waskaweb/controllers/case.py
wasko/trunk/waskaweb/lib/base.py
wasko/trunk/waskaweb/lib/db.py
wasko/trunk/waskaweb/lib/helpers.py
wasko/trunk/waskaweb/model/casedocument.py
wasko/trunk/waskaweb/model/data.py
wasko/trunk/waskaweb/model/datapage.py
wasko/trunk/waskaweb/model/expr.py
wasko/trunk/waskaweb/model/navigation.py
wasko/trunk/waskaweb/model/semantic.py
wasko/trunk/waskaweb/templates/casemanagement/formular.mako
Log:
Bring new error system to work.
-- Diesr und die folgenden Zeilen werden ignoriert --
M waskaweb/model/navigation.py
M waskaweb/model/semantic.py
M waskaweb/model/datapage.py
M waskaweb/model/data.py
M waskaweb/model/casedocument.py
M waskaweb/model/expr.py
M waskaweb/controllers/CaseBase.py
M waskaweb/controllers/case.py
M waskaweb/lib/helpers.py
M waskaweb/lib/base.py
M waskaweb/lib/db.py
M waskaweb/templates/casemanagement/formular.mako
M ChangeLog.txt
Modified: wasko/trunk/ChangeLog.txt
===================================================================
--- wasko/trunk/ChangeLog.txt 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/ChangeLog.txt 2009-02-20 15:02:29 UTC (rev 277)
@@ -1,3 +1,39 @@
+2009-02-20 Sascha L. Teichmann <teichmann at intevation.de>
+
+ Bring new error system to work.
+
+ * waskaweb/lib/db.py, waskaweb/lib/base.py: Removed needless import.
+
+ * waskaweb/templates/casemanagement/formular.mako: Use new ErrorRenderer
+ to render errors and warnings on page.
+
+ * waskaweb/lib/helpers.py: New helper function to call ErrorRenderer to
+ display the errors.
+
+ * waskaweb/controllers/case.py: New select_item method for navigation.
+ Removed some 'page in [list]' code.
+
+ * waskaweb/controllers/CaseBase.py: use the select_item method instead
+ of edit/show.
+
+ * waskaweb/model/expr.py: Upstream expression engine from offline client
+ supporting the 'isset' function.
+
+ * waskaweb/model/casedocument.py: Implemented a caching mechanism to
+ allow case wide access to variables not only on page.
+
+ * waskaweb/model/data.py: Enable marks in RuleLeafs.
+
+ * waskaweb/model/datapage.py: Ported some enhancements from data model
+ of the Offline Client. Fixed problems with errors which weren't descripted
+ correctly.
+
+ * waskaweb/model/semantic.py: Upstream version of Offline Client. Enables
+ usage of 'unbekannt' in dates and integers.
+
+ * waskaweb/model/navigation.py: Some more tweaks on its stony way to the
+ much better version of the Offline Client. It is still broken. :-(
+
2009-02-20 Torsten Irlaender <torsten.irlaender at intevation.de>
Changed labeling of "Agentur" to "Einrichtung"
Modified: wasko/trunk/waskaweb/controllers/CaseBase.py
===================================================================
--- wasko/trunk/waskaweb/controllers/CaseBase.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/controllers/CaseBase.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -83,9 +83,9 @@
redirect_to(h.url_for(controller='/case_overview'))
errors = case.getFormErrors()
id = case.id
- mode = case.getMode()
+ #mode = case.getMode()
self.navigation.setErrors([err.page for err in errors.itervalues()])
- select_url = lambda t: '/case/%s/%s/%s' % (mode, id, t.key)
+ select_url = lambda t: '/case/select_item/%s/%s' % (id, t.key)
toggle_url = lambda r: '/navigation/toggle/%s/%s' % (id, r.key)
return self.navigation.render(select_url, toggle_url, selected_key)
Modified: wasko/trunk/waskaweb/controllers/case.py
===================================================================
--- wasko/trunk/waskaweb/controllers/case.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/controllers/case.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -351,6 +351,7 @@
@checkRole('cm_ka')
def edit(self, ds_id, page_id):
+ case_session = session.get('case')
ds_id = self._checkInt(ds_id)
page_id = self._checkInt(page_id)
ti = self.getNavigation().getTreeItem(page_id)
@@ -374,6 +375,19 @@
return render('/casemanagement/formular.mako')
@checkRole(('admin_ka', 'cm_ka', 'pt_dlr'))
+ def select_item(self, ds_id, page_id):
+ try:
+ case_session = session.get('case')
+ except KeyError:
+ raise HTTPNotFound()
+
+ if case_session.getMode() == "show":
+ return self.show(ds_id, page_id)
+
+ return self.edit(ds_id, page_id)
+
+
+ @checkRole(('admin_ka', 'cm_ka', 'pt_dlr'))
def show(self, ds_id, page_id):
ds_id = self._checkInt(ds_id)
page_id = self._checkInt(page_id)
@@ -462,19 +476,6 @@
# Only proceed to next page if the page does not contain errors
if request.params.get('__formular_next') and len(h.getFormularErrors(ti.page)) <= 0:
- # XXX: This ultra ugly!
- if int(ti.key) in [27,28,29,30]:
- try:
- nds = int(case_session.id)
- except:
- print >> sys.stderr, "Case id not found"
- nds = None
- if not nds is None:
- ti.showPath()
- ds_id = ti.realId(int(nds))
- page_id = "14"
- return self.edit(ds_id, page_id)
-
nkey = ti.nextKey()
if not nkey is None:
nti = self.getNavigation().getTreeItem(nkey)
Modified: wasko/trunk/waskaweb/lib/base.py
===================================================================
--- wasko/trunk/waskaweb/lib/base.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/lib/base.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -29,7 +29,6 @@
from pylons import c, cache, config, g, request, response, session
from pylons.controllers import WSGIController
from pylons.controllers.util import abort, etag_cache, redirect_to
-from pylons.decorators import jsonify, validate
from pylons.i18n import _, ungettext, N_
from pylons.templating import render
Modified: wasko/trunk/waskaweb/lib/db.py
===================================================================
--- wasko/trunk/waskaweb/lib/db.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/lib/db.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -32,7 +32,6 @@
import psycopg2 as dbapi
import sys
-import traceback
db = StackedObjectProxy(name="waska.db")
Modified: wasko/trunk/waskaweb/lib/helpers.py
===================================================================
--- wasko/trunk/waskaweb/lib/helpers.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/lib/helpers.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -38,6 +38,11 @@
import datetime
+from waskaweb.lib.renderer import ErrorRenderer
+from waskaweb.lib.filecache import FileCache
+
+from waskaweb.model.data import PageNode
+
VALID_DATE = re.compile(r'^([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{4})$')
VALID_TIME = re.compile(r'^([0-9]{1,2}):([0-9]{2})')
@@ -195,6 +200,25 @@
except:
pass
+def getErrorsAndWarningsOnPage(page_id):
+ case = session.get('case')
+ if not case: return ""
+ navigation = session.get('navigation.tree')
+ if not navigation: return ""
+ tree_item = navigation.getTreeItem(page_id)
+ if not tree_item: return ""
+ page_name = tree_item.page
+ if not page_name: return ""
+ case_id = case.id
+ errors = case.getFormErrors()
+ formed = g.formedTree
+ page = formed.findByClassAndName(PageNode, page_name)
+ if not page: return ""
+ warnings = formed.warningsOnPage(page, case_id)
+ renderer = ErrorRenderer(errors, warnings, FileCache())
+ out = renderer.render(page)
+ return out
+
def getFormularErrors(page_id):
errors_on_page = {}
# Get treeitem
Modified: wasko/trunk/waskaweb/model/casedocument.py
===================================================================
--- wasko/trunk/waskaweb/model/casedocument.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/model/casedocument.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -30,11 +30,18 @@
#
from waskaweb.model.nodecomponents import Document
-from waskaweb.model.data import PageNode
+from waskaweb.model.data import PageNode, WidgetCollector, RuleLeaf
from waskaweb.model.datapage import PageStore, EmptyPageStore
from paste.registry import StackedObjectProxy
+from traceback import print_exc
+
+import re
+import sys
+
+WARNING = re.compile(r"warning\s*:\s*([^\s]+)")
+
page_cache = StackedObjectProxy(name="waska.pagecache")
def enter(cache):
@@ -53,24 +60,83 @@
return self.pages[name]
except KeyError:
nc = formed.findByClassAndName(PageNode, name)
- db_view = "%s_view" % name
+ db_view = "%s_view" % name.replace('-', '_')
page = PageStore(db_view, nc, ds_id)
self.pages[name] = page
return page
class CaseDocument(Document):
+
def __init__(self, root=None):
Document.__init__(self, root)
+ collector = WidgetCollector()
+ self.visit(collector.visitor)
- #def getPageStore(self, name, ds_id=None, proxy=None, no_data=False):
+ widgets2pages = {}
+ for widget in collector.widgets:
+ page = widget
+ while page and not isinstance(page, PageStore):
+ page = page.parent
+ if page:
+ widgets2pages[widget.getName()] = page.getName()
+
+ self.widgets2pages = widgets2pages
+ self.widgets = dict([(w.getName(), w) for w in collector.widgets if w.getName()])
+
def getPageStore(self, name, ds_id=None, no_data=False):
if no_data: # XXX: urcan mode!
- db_view = "%s_view" % name
+ db_view = "%s_view" % name.replace('-', '_')
nc = self.findByClassAndName(PageNode, name)
return EmptyPageStore(db_view, nc, ds_id)
return page_cache.getPageStore(self, name, ds_id)
+ def getPageOfWidget(self, name):
+ return self.widgets2pages[name]
+
+ def getData(self, name, ds_id):
+ page_name = self.widgets2pages.get(name)
+ if not page_name: return None
+ page_store = self.getPageStore(page_name, ds_id)
+ return page_store.getData(name)
+
+ def warningsOnPage(self, page, ds_id):
+ """ Generates a dictionary of warnings that should be displayed
+ on a given page.
+ """
+ # widgets on page
+ used_fields = set([
+ w.getName() for w in page.allWidgets() if w.getName()])
+
+ warnings = {}
+
+ for r in self.findAllByClass(RuleLeaf):
+ mark, expr = r.getMark(), r.getExpr()
+ if not mark or not expr: continue
+ # warnings only
+ mark = WARNING.search(mark)
+ if not mark: continue
+ mark = mark.group(1)
+ # only mark if field is on current page
+ if not mark in used_fields: continue
+
+ try:
+ okay = expr.evaluate(dict([
+ (n, self.getData(n, ds_id)) for n in expr.getDependencies()]))
+ except:
+ print_exc(file=sys.stderr)
+ okay = False
+
+ if not okay:
+ try:
+ t = warnings[mark]
+ except KeyError:
+ t = (self.widgets[mark], [])
+ warnings[mark] = t
+ t[1].append(r.getValue())
+
+ return warnings
+
# vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
Modified: wasko/trunk/waskaweb/model/data.py
===================================================================
--- wasko/trunk/waskaweb/model/data.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/model/data.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -255,6 +255,7 @@
def __init__(self):
Leaf.__init__(self)
self.attributes["expr"] = ""
+ self.attributes["mark"] = ""
self.expr = None
def shallowCopy(self):
@@ -273,4 +274,10 @@
def getExpr(self):
return self.expr
+ def getMark(self):
+ return self.getAttribute("mark")
+
+ def setMark(self, mark):
+ self.setAttribute("mark", mark)
+
# vim:set ts=4 sw=4 si et sta sts=4:
Modified: wasko/trunk/waskaweb/model/datapage.py
===================================================================
--- wasko/trunk/waskaweb/model/datapage.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/model/datapage.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -34,6 +34,7 @@
from waskaweb.lib.db import db
import sys
+import traceback
def convert(x):
if isinstance(x, str): return unicode(x, 'utf-8')
@@ -124,6 +125,7 @@
v[1] = False
except StandardError, err:
+ traceback.print_exc(file=sys.stderr)
print >> sys.stderr, "DB error: %s" % str(err)
def __lazyCheck(self):
@@ -141,6 +143,8 @@
rel = self.relation.replace('-', '_')
stmnt = "SELECT %s FROM %s WHERE id = %%(id)s;" % (
fields, rel)
+
+ #print >> sys.stderr, "select: %s" % stmnt
try:
con, cur = None, None
try:
@@ -155,7 +159,9 @@
zip(self.items, [[convert(item), False] for item in res]))
except StandardError, err:
- print >> sys.stderr, "DB error: %s" % str(err)
+ pass
+ #traceback.print_exc(file=sys.stderr)
+ #print >> sys.stderr, "DB error: %s" % str(err)
def save(self, params, old_errors, document):
@@ -171,13 +177,11 @@
widgets = dict([
(widget.getName(), widget) for widget in nwidgets if widget.getName()])
+ widgets_clone = widgets.copy()
+
# empty parameters will nullify values
delete_vars = []
- # for updating the errors
- #old_errors = session.setdefault("$ERRORS", {})
- # Note: old_errors is now passed as argument
-
# vars that passed lexical and syntactic check
to_be_set = {}
@@ -194,7 +198,10 @@
# Hopefully this one causes no trouble any more
old_errors.pop(k, None)
# the empty array is for the rules
- to_be_set[k] = (checkAndConvert(widget, value), [])
+ nv = checkAndConvert(widget, value)
+ ov = self.getData(k)
+ if nv != ov:
+ to_be_set[k] = (nv, [])
except SematicError, inst:
ei = ErrorItem(pageName, value, widget.getDescription())
ei.addMessage(inst.value)
@@ -207,7 +214,7 @@
dirty = False
# remove variable from dataset which are set to ""
- for wname in list(widgets.iterkeys()) + delete_vars:
+ for wname in widgets.keys() + delete_vars:
dbPage.setData(wname, None)
dirty = True
# an unset value causes no problems.
@@ -216,6 +223,11 @@
# find all rules that depend on variables to be set.
# build up a lookup var-name -> list of rules
for r in document.findAllByClass(RuleLeaf):
+ mark = r.getMark()
+ # warning rules are evaluated at page rendering
+ if mark and mark.find("warning:") >= 0:
+ #print "Ignore warning rule '%s'" % r.getName()
+ continue
expr = r.getExpr()
if not expr: continue
for var in expr.getDependencies():
@@ -246,14 +258,17 @@
vars[k] = v # test it with new value from web
isOkay = expr.evaluate(vars)
except:
- print_exc()
isOkay = False
if not isOkay:
hasNoProblems = False
ie = old_errors.get(k, None)
if ie is None:
- ie = ErrorItem(pageName, v)
- old_errors[k] = ie
+ try:
+ desc = widgets_clone[k].getDescription()
+ except KeyError:
+ desc = ""
+ ie = ErrorItem(pageName, v, desc)
+ old_errors[k] = ie
msg = rule.getValue()
if msg: ie.addMessage(msg)
else: ie.addMessage("There is a problem with '%s'." % k)
Modified: wasko/trunk/waskaweb/model/expr.py
===================================================================
--- wasko/trunk/waskaweb/model/expr.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/model/expr.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -64,6 +64,10 @@
stack = self.stack
stack.append(stack.pop() * stack.pop())
+ def _ISSET(self):
+ stack = self.stack
+ stack.append(stack.pop() is not None)
+
def _MINUS(self):
stack = self.stack
b = stack.pop()
@@ -149,6 +153,9 @@
day = stack.pop()
stack.append(date(year, month, day))
+ def _TODAY(self):
+ self.stack.append(date.today())
+
def _TYPE(self):
stack = self.stack
stack.append(type(stack.pop()))
@@ -212,11 +219,13 @@
'>=': _GE,
'<=': _LE,
'not': _NOT,
+ 'isset': _ISSET,
'or': _OR,
'and': _AND,
'type': _TYPE,
'DUP': _DUP,
'date': _DATE,
+ 'today': _TODAY,
#'=': _ASSIGN,
'?': _QUESTION,
}
@@ -276,7 +285,8 @@
def evaluate(self, vars=None):
if self.prog is None:
self.compile()
- return Expr.EvalContext(vars).evaluate(self.prog)
+ result = Expr.EvalContext(vars).evaluate(self.prog)
+ return result
#def main():
# for arg in sys.argv[1:]:
Modified: wasko/trunk/waskaweb/model/navigation.py
===================================================================
--- wasko/trunk/waskaweb/model/navigation.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/model/navigation.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -135,6 +135,9 @@
current.displayChildren = True
current = current.parent
+ def getPageName(self):
+ return get_page(self)
+
def get_page(nc):
while nc:
if isinstance(nc, PageNode):
Modified: wasko/trunk/waskaweb/model/semantic.py
===================================================================
--- wasko/trunk/waskaweb/model/semantic.py 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/model/semantic.py 2009-02-20 15:02:29 UTC (rev 277)
@@ -36,9 +36,12 @@
from sys import maxint
-from waskaweb.lib.helpers import safe_unicode
+#from waskaweb.lib.helpers import safe_unicode
+def safe_unicode(s):
+ return s
+
UNKNOWN_INT = -9999999
UNKNOWN_DATE = date(1, 1, 1)
Modified: wasko/trunk/waskaweb/templates/casemanagement/formular.mako
===================================================================
--- wasko/trunk/waskaweb/templates/casemanagement/formular.mako 2009-02-20 14:16:00 UTC (rev 276)
+++ wasko/trunk/waskaweb/templates/casemanagement/formular.mako 2009-02-20 15:02:29 UTC (rev 277)
@@ -35,17 +35,8 @@
<li><a href="/case/${session.get('case').getMode()}/${c.ds_id}/${c.page_id}" onclick="return checkModification();">${h.getFormularName(c.page_id)}</a></li>
</%def>
-<%def name="buildFormErrors()">
-% if len(h.getFormularErrors(c.page_id)) > 0:
- <div class="form_errors">
- <h1><a name="error_list">${_('cm_error_header_false_forminput')}</a></h1>
- <ul>
- % for key, error in h.getFormularErrors(c.page_id).iteritems():
- <li><a href="#f_${key}">${error.getName()}</a>: ${"<br>".join(error.getMessages())}</li>
- % endfor
- </ul>
- </div>
-% endif
+<%def name="buildFormErrors()">A
+ ${h.getErrorsAndWarningsOnPage(c.page_id)}
</%def>
<%def name="buildContentHeader()">
More information about the Mpuls-commits
mailing list