[Mpuls-commits] r322 - in wasko/trunk: . waskaweb/controllers waskaweb/lib waskaweb/model waskaweb/model/io

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Wed Mar 4 08:25:01 CET 2009


Author: teichmann
Date: 2009-03-04 08:24:55 +0100 (Wed, 04 Mar 2009)
New Revision: 322

Modified:
   wasko/trunk/ChangeLog.txt
   wasko/trunk/waskaweb/controllers/case.py
   wasko/trunk/waskaweb/lib/app_globals.py
   wasko/trunk/waskaweb/lib/helpers.py
   wasko/trunk/waskaweb/lib/xmlhelper.py
   wasko/trunk/waskaweb/model/casedocument.py
   wasko/trunk/waskaweb/model/casexml.py
   wasko/trunk/waskaweb/model/data.py
   wasko/trunk/waskaweb/model/io/document.py
   wasko/trunk/waskaweb/model/io/factories.py
   wasko/trunk/waskaweb/model/nodecomponents.py
Log:
Initial storage of cases to data base.


Modified: wasko/trunk/ChangeLog.txt
===================================================================
--- wasko/trunk/ChangeLog.txt	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/ChangeLog.txt	2009-03-04 07:24:55 UTC (rev 322)
@@ -1,3 +1,29 @@
+2009-03-04	Sascha L. Teichmann	<teichmann at intevation.de>
+
+	This is an intermediate commit suffering from 
+	UnicodeDecodeErrors (Python's unicode support really s*cks).
+
+	* waskaweb/model/nodecomponents.py: Backported default values
+	  support from Offline Client.
+
+	* waskaweb/model/casedocument.py: Cache defaults per widget
+	  after FormEd construction.
+
+	* waskaweb/model/io/factories.py, waskaweb/model/io/document.py, 
+	  waskaweb/model/data.py: Backported relative path loading for 
+	  ExternalChoiceNodes from Offline Client.
+
+	* waskaweb/lib/app_globals.py: Prefetching the external choice
+	  is not longer needed because loading is now handled by 
+	  the external choice lists themself.
+
+	* waskaweb/model/casexml.py: Store cases to database.
+	  Logbook storage still missing. Debug output is left 
+	  in because this is work in progress.
+
+	* waskaweb/lib/helpers.py, waskaweb/lib/xmlhelper.py: Some 
+	  whitespace cleanup
+
 2009-03-03	Torsten Irlaender  <torsten.irlaender at intevation.de> 
 
 	Fixed check for inkonsistency before anonymization

Modified: wasko/trunk/waskaweb/controllers/case.py
===================================================================
--- wasko/trunk/waskaweb/controllers/case.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/controllers/case.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -1,27 +1,27 @@
 # -*- coding: utf-8 -*-
 #
 # Copyright 2007, 2008 Intevation GmbH, Germany, <info at intevation.de>
-# 
-# This file is part of mpuls WASKA (CoMPUter-based case fiLeS - 
+#
+# This file is part of mpuls WASKA (CoMPUter-based case fiLeS -
 # Web-Anwendungs-Server fuer Kompetenzagenturen).
-# 
+#
 # mpuls WASKA is free software: you can redistribute it and/or modify it under
 # the terms of the GNU Affero General Public License as published by the
 # Free Software Foundation, either version 3 of the License, or (at your
 # option) any later version.
-# 
+#
 # mpuls WASKA is distributed in the hope that it will be useful, but WITHOUT
 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 # License for more details.
-# 
+#
 # You should have received a copy of the GNU Affero General Public
 # License along with mpuls WASKA. If not, see <http://www.gnu.org/licenses/>.
-# 
-# mpuls WASKA has been developed on behalf of the 
+#
+# mpuls WASKA has been developed on behalf of the
 # Projekttraeger im Deutschen Zentrum fuer Luft- und Raumfahrt e.V. (PT-DLR)
 # within the programme Kompetenzagenturen (Durchfuehrungsphase) funded by
-# the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and 
+# the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and
 # European Social Fund resources.
 #
 # Authors:
@@ -53,7 +53,7 @@
 
 from waskaweb.lib.helpers import dd_mm_YYYY, HH_MM
 
-from waskaweb.model.repeatgroup    import AidObject, AidList 
+from waskaweb.model.repeatgroup    import AidObject, AidList
 from waskaweb.model.user           import *
 from waskaweb.model.statement      import *
 from waskaweb.model.case           import *
@@ -100,15 +100,15 @@
 u"""Die angegebene Datei konnte nicht als PDF-Fallakte erkannt werden."""
 
 PRINTALL_NOTIFICATION = u'Gesamte Fallakte drucken'
-PRINTALL_NOTIFICATION_TEXT = u'Leider ist die von Ihnen aufgerufene Funktion in der BETA Version dieser Anwendung noch nicht enthalten.' 
+PRINTALL_NOTIFICATION_TEXT = u'Leider ist die von Ihnen aufgerufene Funktion in der BETA Version dieser Anwendung noch nicht enthalten.'
 
-DELETE_CONFIRM = u"""Fallakte löschen?""" 
-DELETE_CONFIRM_TEXT = u"""Wollen Sie wirklich die Fallakte löschen und die Daten unwiederbringlich verlieren?""" 
-MARKDELETE_CONFIRM_TEXT = u"""Wollen Sie wirklich die Fallakte zum Löschen freigeben? Die Fallakte steht Ihnen danach nicht mehr zur Bearbeitung zur Verfügung und wird der Administration zum Löschen vorgelegt.""" 
+DELETE_CONFIRM = u"""Fallakte löschen?"""
+DELETE_CONFIRM_TEXT = u"""Wollen Sie wirklich die Fallakte löschen und die Daten unwiederbringlich verlieren?"""
+MARKDELETE_CONFIRM_TEXT = u"""Wollen Sie wirklich die Fallakte zum Löschen freigeben? Die Fallakte steht Ihnen danach nicht mehr zur Bearbeitung zur Verfügung und wird der Administration zum Löschen vorgelegt."""
 
 ANONYMIZE_CONFIRM = u"""Fallakte anonymisieren?"""
 ANONYMIZE_CONFIRM_TEXT = u"""Wollen Sie wirklich die Fallakte anonymisieren und die personenbezogenen Daten unwiederbringlich verlieren?. Die Fallakte steht danach nicht mehr zur Bearbeitung zur Verfügung. Die anonymisierte Fallakte wird weiterhin in der Auswertung berücksichtigt werden."""
-MARKANONYMIZE_CONFIRM_TEXT = u"""Wollen Sie wirklich die Fallakte zum Anonymisieren freigeben? Die Fallakte steht Ihnen danach nicht mehr zur Bearbeitung zur Verfügung und wird der Administration zur Anonymisierung vorgelegt.""" 
+MARKANONYMIZE_CONFIRM_TEXT = u"""Wollen Sie wirklich die Fallakte zum Anonymisieren freigeben? Die Fallakte steht Ihnen danach nicht mehr zur Bearbeitung zur Verfügung und wird der Administration zur Anonymisierung vorgelegt."""
 
 ANONYMIZE_SUCCESS = u"""Fallakte anonymisiert!"""
 ANONYMIZE_SUCCESS_TEXT = u"""Die personenbezogenen Daten der Fallakte wurden gelöscht und die Fallakte aus der Übersicht entfernt. Bitte klicken Sie auf "OK", um zur Fallaktenübersicht fortzufahren."""
@@ -266,9 +266,9 @@
     def printout(self, ds_id, page_id, form=None):
         ds_id   = self._checkInt(ds_id)
         page_id = self._checkInt(page_id)
-        c.print_version = 1 
+        c.print_version = 1
         if form == "digest":
-            return self.digest(ds_id) 
+            return self.digest(ds_id)
         elif form == "show":
             return self.show(ds_id, page_id)
         else:
@@ -325,7 +325,7 @@
             c.print_version = 1
             statement = PrivacyStatement()
             agency = Agency()
-            c.content = statement.fillout(session_case, agency) 
+            c.content = statement.fillout(session_case, agency)
             return render('statement/default_statement.mako')
 
         # Or do we want to store the new case?
@@ -397,7 +397,7 @@
             redirect_to(controller="/case_overview")
 
         # If we edit page_1 we better update the infofield because the names
-        # may have been edited 
+        # may have been edited
         if ti.name == "page-0":
             try:
                 case_session.last_name     = request.params.get("name")
@@ -412,9 +412,9 @@
         old_errors = case_session.getFormErrors()
         ds_id = request.params["ds"]
         new_errors, page = self.__save(
-            ti.name, 
-            request.params.dict_of_lists(), 
-            old_errors, 
+            ti.name,
+            request.params.dict_of_lists(),
+            old_errors,
             ds_id)
 
         if new_errors:
@@ -432,7 +432,7 @@
             if not nti is None:
                 ti = nti
                 ti.unfold()
-        return self.edit(ds_id, ti.key) 
+        return self.edit(ds_id, ti.key)
 
     def __save(self, pageName, params, old_errors, ds_id):
         # fetch dataset if valid
@@ -559,7 +559,7 @@
         case               = self._loadCase(id)
         c.ds_id            = id
         c.form_navigation  = self._getFormNavigation()
-        c.print_version = 1 
+        c.print_version = 1
         logbook = Logbook()
         logbook.loadById(id)
         c.logbook = logbook
@@ -590,7 +590,7 @@
 
         session_case = session.get('case')
 
-        mode = session_case and session_case.getMode() or "show" 
+        mode = session_case and session_case.getMode() or "show"
         link = lambda ti, extra = "": '"/case/%s/%d/%s%s"' % (mode, id, ti.key, extra)
 
         rf = RequiredFields(g.formedTree)
@@ -610,7 +610,7 @@
         try:
             try:
                 form_result = validator.to_python(request.params)
-                # Load case and do something on phase 
+                # Load case and do something on phase
                 case = factory.loadById(form_result.get('case_id'))
 
                 new_phase, new_phase_symbol = None, None
@@ -691,8 +691,8 @@
         form_defaults['time']  = entry.getTime()
         form_defaults['kind']  = entry.getKindAsInt()
         form_defaults['kind']  = entry.getKindAsInt()
-        form_defaults['short_notice']  = u"Aufbewahrung verlängert" 
-        form_defaults['notice']  = u"Bitte geben Sie hier den Grund für die Verlängerung der Aufbewahrungsfrist ein." 
+        form_defaults['short_notice']  = u"Aufbewahrung verlängert"
+        form_defaults['notice']  = u"Bitte geben Sie hier den Grund für die Verlängerung der Aufbewahrungsfrist ein."
         id                = self._checkInt(id)
         c.ds_id           = id
         c.entry           = entry
@@ -736,7 +736,7 @@
             logbook.addEntry(checker.getLogbookEntry())
             logbook.store(session['USER_AUTHORIZED'].id)
             c.url_ok = "/case/logbook/%s" % str(session['case'].id)
-            c.success_for   = CREATE_LOGBOOK_ENTRY_SUCCESS 
+            c.success_for   = CREATE_LOGBOOK_ENTRY_SUCCESS
             c.success_text  = CREATE_LOGBOOK_ENTRY_SUCCESS_TEXT
             return render('/logbook/dialogs/success_create_logbook_entry.mako')
         except:
@@ -823,7 +823,7 @@
             entry = checker.getLogbookEntry()
             entry.setId(id)
             entry.storeForUser(session['USER_AUTHORIZED'].id)
-            c.success_for  = LOGBOOK_ENTRY_SAVE_SUCCESS 
+            c.success_for  = LOGBOOK_ENTRY_SAVE_SUCCESS
             c.success_text = LOGBOOK_ENTRY_SAVE_SUCCESS_TEXT
             c.url_ok       = "/case/logbook/%s" % str(session['case'].id)
             return render('/logbook/dialogs/success_save_logbook_entry.mako')
@@ -842,7 +842,7 @@
         if confirmed == 1:
             try:
                 Logbook().deleteEntryById(int(id))
-                c.success_for  = LOGBOOK_ENTRY_DELETE_SUCCESS 
+                c.success_for  = LOGBOOK_ENTRY_DELETE_SUCCESS
                 c.success_text = LOGBOOK_ENTRY_DELETE_SUCCESS_TEXT
                 c.url_ok       = "/case/logbook/%s" % str(session['case'].id)
                 return render('/logbook/dialogs/success_delete_logbook_entry.mako')
@@ -946,7 +946,7 @@
                 c.url_ok       = "/case/appointments/%s" % appointment.case_id
                 return render('/casemanagement/dialogs/failed_delete_appointment.mako')
         else:
-            c.context     = "../main.mako" 
+            c.context     = "../main.mako"
             c.confirm_for = DELETE_APPOINT_CONFIRM
             c.question    = DELETE_APPOINT_CONFIRM_TEXT
             c.url_yes     = "/case/deleteAppointment/%s/1" % id
@@ -1044,15 +1044,15 @@
         if confirmed == 1:
             case = load_case(id)
             case.setState(3)
-            c.success_for   =   u'Fallakte gelöscht!' 
-            c.success_text  =   u'Die Fallakte wurde zum Löschen an die Administration weitergeleitet.' 
+            c.success_for   =   u'Fallakte gelöscht!'
+            c.success_text  =   u'Die Fallakte wurde zum Löschen an die Administration weitergeleitet.'
             c.url_ok        =   h.url_for(controller="/case_overview")
             return render('/casemanagement/dialogs/success_delete_cm.mako')
             redirect_to(controller="/case_overview")
         else:
-            c.context = "../main.mako" 
+            c.context = "../main.mako"
             c.confirm_for = DELETE_CONFIRM
-            c.question = MARKDELETE_CONFIRM_TEXT 
+            c.question = MARKDELETE_CONFIRM_TEXT
             c.url_yes = "/case/markForDelete/%s/1" % id
             c.url_no  = "/case_overview/"
             return render('/casemanagement/dialogs/confirm.mako')
@@ -1065,17 +1065,17 @@
         if confirmed == 1:
             case = self._loadCase(id)
             if case.delete():
-                c.success_for   =   u'Fallakte gelöscht!' 
-                c.success_text  =   u'Bitte klicken Sie "OK", um fortzufahren.' 
+                c.success_for   =   u'Fallakte gelöscht!'
+                c.success_text  =   u'Bitte klicken Sie "OK", um fortzufahren.'
                 c.url_ok        =   h.url_for(controller="/case_overview")
                 return render('/casemanagement/dialogs/success_delete.mako')
                 #redirect_to(controller="/case_overview")
             # TODO: Create Errorpage
             return "Error! Could not delete ds."
         else:
-            c.context = "../main.mako" 
-            c.confirm_for = DELETE_CONFIRM 
-            c.question = DELETE_CONFIRM_TEXT 
+            c.context = "../main.mako"
+            c.confirm_for = DELETE_CONFIRM
+            c.question = DELETE_CONFIRM_TEXT
             c.url_yes = "/case/delete/%s/1" % id
             c.url_no  = "/case_overview/"
             return render('/casemanagement/dialogs/confirm_delete.mako')
@@ -1088,15 +1088,15 @@
         if confirmed == 1:
             case = self._loadCase(id)
             case.restore()
-            c.success_for   =   u'Fallakte wiederhergestellt!' 
-            c.success_text  =   u'Bitte klicken Sie "OK", um fortzufahren.' 
+            c.success_for   =   u'Fallakte wiederhergestellt!'
+            c.success_text  =   u'Bitte klicken Sie "OK", um fortzufahren.'
             c.url_ok        =   h.url_for(controller="/case_overview")
             return render('/casemanagement/dialogs/success_restore.mako')
             #redirect_to(controller="/case_overview")
         else:
-            c.context = "../main.mako" 
-            c.confirm_for = RESTORE_CONFIRM 
-            c.question = RESTORE_CONFIRM_TEXT 
+            c.context = "../main.mako"
+            c.confirm_for = RESTORE_CONFIRM
+            c.question = RESTORE_CONFIRM_TEXT
             c.url_yes = "/case/restore/%s/1" % id
             c.url_no  = "/case_overview/"
             return render('/casemanagement/dialogs/confirm_restore.mako')
@@ -1114,9 +1114,9 @@
             c.success_text  =   u'Die Fallakte wurde erfolgreich geöffnet.'
             return render('/casemanagement/dialogs/success_case_close.mako')
         else:
-            c.context = "main.mako" 
-            c.confirm_for = OPEN_CONFIRM 
-            c.question = OPEN_CONFIRM_TEXT 
+            c.context = "main.mako"
+            c.confirm_for = OPEN_CONFIRM
+            c.question = OPEN_CONFIRM_TEXT
             c.url_yes = "/case/open/%s/1" % id
             c.url_no    = h.url_for(controller="/case", action="organisation", id=id)
             return render('/casemanagement/dialogs/confirm_open.mako')
@@ -1134,9 +1134,9 @@
             c.success_text  =   u'Geschlossene Fallakten können Sie in der Fallaktenübersicht durch anklicken des Suchfilters "Geschlossen" einsehen.'
             return render('/casemanagement/dialogs/success_case_close.mako')
         else:
-            c.context = "main.mako" 
+            c.context = "main.mako"
             c.confirm_for = CLOSE_CONFIRM
-            c.question = CLOSE_CONFIRM_TEXT 
+            c.question = CLOSE_CONFIRM_TEXT
             c.url_yes = "/case/close/%s/1" % id
             c.url_no    = h.url_for(controller="/case", action="organisation", id=id)
             return render('/casemanagement/dialogs/confirm_close.mako')
@@ -1151,7 +1151,7 @@
             # Check if the case is in a consistent state (all required fields
             # are filled)
             if not case.getState().phasesAreConsistent() and case.isYoungerThan(INCONSISTENCY_CHECK_AFTER):
-                c.notification_for  = MARKANONYMIZE_INCOMPLETE_PHASE_FAILED 
+                c.notification_for  = MARKANONYMIZE_INCOMPLETE_PHASE_FAILED
                 c.notification_text = MARKANONYMIZE_INCOMPLETE_PHASE_FAILED_TEXT
                 c.url_ok            = h.url_for(controller="/case_overview")
                 return render('/casemanagement/dialogs/failed_markanonymize_phase_incomplete_from_overview.mako')
@@ -1182,7 +1182,7 @@
             # Check if the case is in a consistent state (all required fields
             # are filled)
             if not case.getState().phasesAreConsistent() and case.isYoungerThan(INCONSISTENCY_CHECK_AFTER):
-                c.notification_for  = MARKANONYMIZE_INCOMPLETE_PHASE_FAILED 
+                c.notification_for  = MARKANONYMIZE_INCOMPLETE_PHASE_FAILED
                 c.notification_text = MARKANONYMIZE_INCOMPLETE_PHASE_FAILED_TEXT
                 c.url_ok            = "/case/digest/%s" % id
                 return render('/casemanagement/dialogs/failed_markanonymize_phase_incomplete.mako')

Modified: wasko/trunk/waskaweb/lib/app_globals.py
===================================================================
--- wasko/trunk/waskaweb/lib/app_globals.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/lib/app_globals.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -73,14 +73,6 @@
             print >> sys.stderr, "Could not open Helpfile"
             self.helpData = None
 
-        # prefetch external external choice leaves
-        for ex in self.formedTree.findAllByClass(data.ExternalChoiceListLeaf):
-            fname = ex.getValue()
-            if not fname: continue
-            fname = os.path.join(path, fname)
-            subDoc = openDocument(fname)
-            ex.choice = subDoc.findByClassAndName(data.ChoiceNode)
-
         # data for database connections
 
         host   = config.get('db_host')

Modified: wasko/trunk/waskaweb/lib/helpers.py
===================================================================
--- wasko/trunk/waskaweb/lib/helpers.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/lib/helpers.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -1,25 +1,25 @@
 # Copyright 2007, 2008 Intevation GmbH, Germany, <info at intevation.de>
-# 
-# This file is part of mpuls WASKA (CoMPUter-based case fiLeS - 
+#
+# This file is part of mpuls WASKA (CoMPUter-based case fiLeS -
 # Web-Anwendungs-Server fuer Kompetenzagenturen).
-# 
+#
 # mpuls WASKA is free software: you can redistribute it and/or modify it under
 # the terms of the GNU Affero General Public License as published by the
 # Free Software Foundation, either version 3 of the License, or (at your
 # option) any later version.
-# 
+#
 # mpuls WASKA is distributed in the hope that it will be useful, but WITHOUT
 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 # License for more details.
-# 
+#
 # You should have received a copy of the GNU Affero General Public
 # License along with mpuls WASKA. If not, see <http://www.gnu.org/licenses/>.
-# 
-# mpuls WASKA has been developed on behalf of the 
+#
+# mpuls WASKA has been developed on behalf of the
 # Projekttraeger im Deutschen Zentrum fuer Luft- und Raumfahrt e.V. (PT-DLR)
 # within the programme Kompetenzagenturen (Durchfuehrungsphase) funded by
-# the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and 
+# the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and
 # European Social Fund resources.
 """Helper functions
 
@@ -51,7 +51,7 @@
 PRINTABLE = frozenset(printable)
 
 def get_adele_name(id=None):
-    return EVAL_NAMES.get(str(id), 'Auswertung Nr: %s' % id) 
+    return EVAL_NAMES.get(str(id), 'Auswertung Nr: %s' % id)
 
 def get_adele_description(id):
     return EVAL_DESCRIPTIONS.get(str(id), 'Keine Beschreibung vorhanden')
@@ -79,7 +79,7 @@
 def getUserFullname():
     try:
         user = session['USER_AUTHORIZED']
-        return "%s, %s" % (user.last_name, user.first_name) 
+        return "%s, %s" % (user.last_name, user.first_name)
     except KeyError:
         return ''
 
@@ -93,17 +93,16 @@
 def getLogin():
     try:
         user = session['USER_AUTHORIZED']
-        return user.login 
+        return user.login
     except KeyError:
         return ''
 
 def getUserId():
     try:
         user = session['USER_AUTHORIZED']
-        return user.id 
+        return user.id
     except KeyError:
         return ''
-    
 
 def formatNumber(number):
     retval = locale.format("%.2f",(number),1)
@@ -205,8 +204,8 @@
         if error.page == name:
             return True
     return False
-    
 
+
 def getFormularHeaders(page_id):
     if page_id is None: return u""
     navigation = session.get('navigation.tree')
@@ -258,10 +257,10 @@
     try:
         ti = navigation.getTreeItem(page_id)
     except:
-        return {} 
+        return {}
     errors = session.get('case').getFormErrors()
     try:
-        for key, err in errors.iteritems(): 
+        for key, err in errors.iteritems():
             if err.page == ti.page:
                 errors_on_page[key] = err
     except:
@@ -273,7 +272,7 @@
         return "/case/printout/%s/0/digest" % (ds_id)
     elif print_form == "show":
         return "/case/printout/%s/%s/show" % (ds_id, page_id)
-    else: 
+    else:
         return "#"
 
 def slashSplit(s):
@@ -297,8 +296,8 @@
     except:
         print >> sys.stderr, "Could not fetch KA-name from client certificate"
     return ''
-    
+
 def safe_unicode(s):
     return u''.join([c for c in s if ord(c) > 127 or c in PRINTABLE])
 
-
+# vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

Modified: wasko/trunk/waskaweb/lib/xmlhelper.py
===================================================================
--- wasko/trunk/waskaweb/lib/xmlhelper.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/lib/xmlhelper.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 # (c) 2008 by Intevation GmbH
-# This is Free software under the GPLv3. 
+# This is Free software under the GPLv3.
 # See LICENSE comming with the source of 'mpuls offline'
 # for details.
 #
@@ -25,8 +25,8 @@
 
 def string_iso_time(s):
     return datetime.datetime.strptime(s.replace("-", ""), "%Y%m%dT%H:%M:%S")
-    
 
+
 def decode_int(s):
     s = NO_NUMBER.sub("", s)
     m = INT_NUMBER.match(s)
@@ -64,7 +64,7 @@
 
     def activate_factories(self, tag):
         self.current = self.factories.get(tag)
-        
+
     def startElement(self, name, attrs):
         new_factories = self.factories.get(name)
 

Modified: wasko/trunk/waskaweb/model/casedocument.py
===================================================================
--- wasko/trunk/waskaweb/model/casedocument.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/model/casedocument.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -78,6 +78,7 @@
         self.visit(collector.visitor)
 
         self.buildNameToWidget(collector)
+        self.buildNameToDefault(collector)
         self.buildWidgetsToPages(collector)
         self.buildVarToRules()
         self.buildPhases(collector)
@@ -87,6 +88,11 @@
             (w.getName(), w) 
             for w in collector.widgets if w.getName()])
 
+    def buildNameToDefault(self, collector):
+        self.name2default = dict([
+            (w.getName(), w.findDefault())
+            for w in collector.widgets if w.getName()])
+
     def buildWidgetsToPages(self, collector):
         widgets2pages = {}
         for widget in collector.widgets:

Modified: wasko/trunk/waskaweb/model/casexml.py
===================================================================
--- wasko/trunk/waskaweb/model/casexml.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/model/casexml.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -30,6 +30,8 @@
 
 from waskaweb.lib.uuid import uuid4
 
+from waskaweb.lib.db   import db
+
 from waskaweb.lib.xmlhelper import \
     decode_int,                    \
     decode_date,                   \
@@ -42,7 +44,22 @@
 from xml.sax.saxutils import escape
 
 import sys
+import re
 
+UUID_RE = re.compile(r"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$")
+
+SQL_GET_MASTER_ID = \
+"""SELECT get_masterid_from_uuid(%(relation_name)s, %(uuid)s)"""
+
+SQL_SELECT_ALL_FROM_MASTER = \
+"""SELECT * FROM master_tbl_view WHERE id = %(ds_id)s"""
+
+SQL_CREATE_MASTER_DS = \
+"""SELECT create_master_ds(%(uuid)s)"""
+
+SQL_UPDATE_MASTER = \
+"""UPDATE master_tbl_view SET %s WHERE id = %d"""
+
 VERSION = 2
 
 DECODERS = {
@@ -54,6 +71,9 @@
     data.DateLeaf:     decode_date
 }
 
+def is_uuid(s):
+    return bool(UUID_RE.match(s))
+
 class LogbookEntry(object):
 
     def __init__(self, uuid = None):
@@ -219,7 +239,11 @@
         self.entry = None
 
     def uuid_end(self, name, attrs, value):
-        if self.entry: self.entry.uuid = value.strip()
+        if self.entry: 
+            value = value.strip()
+            if not is_uuid(value):
+                raise ValueError("'%s' is not an UUID" % repr(value))
+            self.entry.uuid = value
 
     def default_start(self, name, attrs):
         pass
@@ -248,17 +272,40 @@
                     "Cannot load files of version %d." % version)
 
     def element_end(self, name, attrs, value):
-        print >> sys.stderr, "looking for '%s'" % repr(name)
 
         try:
             widget = self.formed.widgets[name]
         except KeyError:
             if name == u'uuid_id':
+                value = value.strip()
+                if not is_uuid(value):
+                    raise ValueError("'%s' is not an UUID" % repr(value))
                 self.uuid = value
             return
 
         self.data.append((name, DECODERS.get(widget.__class__, lambda s: s)(value)))
 
+def get_id_for_uuid(cur, relation_name, uuid):
+    cur.execute(SQL_GET_MASTER_ID, {
+        'relation_name': relation_name, 'uuid': uuid })
+    row = cur.next()
+    if not row: return None
+    return row[0]
+
+def create_master(cur, uuid=None):
+    cur.execute(SQL_CREATE_MASTER_DS, { 'uuid': uuid })
+    row = cur.next()
+    if not row: return None
+    return row[0]
+
+def store_changes(cur, changes, ds_id):
+    print >> sys.stderr, "changes: %s" % repr(changes)
+    if not changes: return
+    fields = ['%s = %%(%s)s' % (v, v) for v in changes.iterkeys()]
+    update = SQL_UPDATE_MASTER % (",".join(fields), ds_id)
+    print >> sys.stderr, "%s" % repr(update)
+    cur.execute(update, changes)
+
 def import_xml(f, formed):
 
     master_handler = MasterHandler(formed)
@@ -269,6 +316,7 @@
         'master',
         {},
         (master_handler.element_start, master_handler.element_end))
+
     loader.activate_factories('master') # for backwards compat
 
     logbook_loader = LogbookLoader()
@@ -278,12 +326,110 @@
     parser = make_parser()
     parser.setContentHandler(loader)
     parser.parse(f)
+    logbook = logbook_loader.logbook
 
-    #print >> sys.stderr, repr(master_handler.data)
+    con, cur = None, None
+    try:
+        con = db.getConnection()
+        cur = con.cursor()
+        try:
+            create_case, data = True, None
 
-    logbook = logbook_loader.logbook
+            if master_handler.uuid:
+                print >> sys.stderr, "found uuid '%s'" % repr(master_handler.uuid)
+                ds_id = get_id_for_uuid(cur, 'master', master_handler.uuid)
+                if not ds_id is None:
+                    pass
+                    print >> sys.stderr, "case %d already exists" % ds_id
+                    cur.execute(SQL_SELECT_ALL_FROM_MASTER % { 'ds_id': ds_id })
+                    row = cur.fetchone()
+                    if not row:
+                        raise StandardError("could not load data for id '%s'" % ds_id)
+                    data = dict(zip([n[0] for n in cur.description], row))
+                    create_case = False
+                else:
+                    print >> sys.stderr, "case with uuid '%s' does not exists" % repr(
+                        master_handler.uuid)
+            else:
+                print >> sys.stderr, "case does not have an uuid"
+                #master_handler.uuid = str(uuid4())
 
-    #print >> sys.stderr, repr(logbook.to_xml())
+            print >> sys.stderr, "I was here - 1"
 
+            if data is None:
+                print >> sys.stderr, "preset case with defaults from formed"
+                data = formed.name2default
 
+            print >> sys.stderr, "I was here - 2"
+
+            changed = {}
+
+            def get_data(var):
+                try:
+                    return changed[var]
+                except KeyError:
+                    return data.get(var)
+
+            # now apply the rules
+
+            print >> sys.stderr, "I was here - 3"
+
+            errors = []
+
+            print >> sys.stderr, "len data: %d" % len(master_handler.data)
+
+            for var, value in master_handler.data:
+                print >> sys.stderr, "checking rules for '%s': '%s'" % (
+                    var, repr(value))
+                old_value = get_data(var)
+                print >> sys.stderr, "t1: %s t2: %s" % (
+                    type(old_value), type(value))
+                if old_value == value: continue
+
+                rules = formed.getRulesForVariable(var)
+                okay = True
+                if rules:
+                    for rule in rules:
+                        mark = rule.getMark()
+                        if mark and mark.find("warning:") >= 0: continue
+                        expr = rule.getExpr()
+
+                        isNull, params = False, {}
+                        n_okay = True
+                        for dep in expr.getDependencies():
+                            dep_v = get_data(dep)
+                            if dep_v is None: isNull = True; break
+                            params[dep] = dep_v
+                        if not isNull:
+                            params[var] = value
+                            try:    n_okay = expr.evaluate(params)
+                            except: n_okay = False
+                        if not n_okay: 
+                            errors.append(rule.getDescription())
+                            okay = False
+                if okay:
+                    changed[var] = value
+
+            print >> sys.stderr, "errors: %s" % errors
+            if errors:
+                raise StandardError("rule checking failed")
+
+            print >> sys.stderr, "I was here - 3"
+            if create_case:
+                print >> sys.stderr, "I was here - 4"
+                ds_id = create_master(cur, master_handler.uuid)
+
+            print >> sys.stderr, "I was here - 5"
+            store_changes(cur, changed, ds_id)
+            print >> sys.stderr, "I was here - 6"
+
+            con.commit()
+        except:
+            try: con.rollback()
+            except: pass
+            raise
+
+    finally:
+        db.recycleConnection(con, cur)
+
 # vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 enc=utf-8 :

Modified: wasko/trunk/waskaweb/model/data.py
===================================================================
--- wasko/trunk/waskaweb/model/data.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/model/data.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -1,27 +1,27 @@
 # -*- coding: latin1 -*-
 #
 # Copyright 2007, 2008 Intevation GmbH, Germany, <info at intevation.de>
-# 
-# This file is part of mpuls WASKA (CoMPUter-based case fiLeS - 
+#
+# This file is part of mpuls WASKA (CoMPUter-based case fiLeS -
 # Web-Anwendungs-Server fuer Kompetenzagenturen).
-# 
+#
 # mpuls WASKA is free software: you can redistribute it and/or modify it under
 # the terms of the GNU Affero General Public License as published by the
 # Free Software Foundation, either version 3 of the License, or (at your
 # option) any later version.
-# 
+#
 # mpuls WASKA is distributed in the hope that it will be useful, but WITHOUT
 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 # License for more details.
-# 
+#
 # You should have received a copy of the GNU Affero General Public
 # License along with mpuls WASKA. If not, see <http://www.gnu.org/licenses/>.
-# 
-# mpuls WASKA has been developed on behalf of the 
+#
+# mpuls WASKA has been developed on behalf of the
 # Projekttraeger im Deutschen Zentrum fuer Luft- und Raumfahrt e.V. (PT-DLR)
 # within the programme Kompetenzagenturen (Durchfuehrungsphase) funded by
-# the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and 
+# the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and
 # European Social Fund resources.
 #
 # Authors:
@@ -35,9 +35,10 @@
     VISIT_IGNORE_CHILDREN, \
     VISIT_CONTINUE
 
-from expr           import Expr
+from expr import Expr
 
 import sys
+import os
 
 import waskaweb.model.io.document
 
@@ -53,7 +54,7 @@
                 return VISIT_IGNORE_CHILDREN
             if isinstance(nc, GroupNode) and nc.isRepeat() and nc != self:
                 return VISIT_IGNORE_CHILDREN
-        elif isinstance(nc, Leaf) and not isinstance(nc, 
+        elif isinstance(nc, Leaf) and not isinstance(nc,
             (RuleLeaf, ExternalChoiceListLeaf, InfoLeaf)):
             self.widgets.append(nc)
 
@@ -127,6 +128,24 @@
         Node.__init__(self)
         self.attributes["selected"] = ""
 
+    def firstFindDefault(self):
+        value = None
+        if self.children:
+            for child in self.children:
+                if isinstance(child, ExternalChoiceListLeaf):
+                    found, v = child.find_default()
+                    if found: 
+                        value = v
+                        break
+                elif isinstance(child, BoolLeaf):
+                    if child.getChecked():
+                        v = child.getValue()
+                        if v: value = int(v)
+                        break
+
+        self.found_default = value
+        return Node.firstFindDefault(self)
+
     def getSelected(self):
         return self.getAttribute("selected")
 
@@ -143,24 +162,41 @@
 
     def setChecked(self, checked):
         self.setSelected("checked", checked)
-    
+
 class ExternalChoiceListLeaf(Leaf):
     def __init__(self):
         Leaf.__init__(self)
         self.choice = None
+        self.path   = None
 
+    def setLoadContext(self, path):
+        self.path = os.path.dirname(path)
+
+    def find_default(self):
+        found, value = False, None
+        children = self.getChildren()
+        if children:
+            for child in children:
+                if isinstance(child, BoolLeaf):
+                    if child.getChecked():
+                        v = child.getValue()
+                        if v: value = int(v)
+                        break
+        return found, value    
+
     def getChildren(self):
         if not self.choice:
             fname = self.getValue()
             if fname:
+                if not os.path.isabs(fname) and self.path:
+                    fname = os.path.join(self.path, fname)
                 try: # TODO: This loading code should be else where!
                     import waskaweb.model.io.document
                     document = waskaweb.model.io.document.openDocument(fname)
                     self.choice = document.findByClassAndName(ChoiceNode)
                 except Exception, inst:
-                    print str(inst)
-                    pass
-        if self.choice: 
+                    print >> sys.stderr, repr(inst)
+        if self.choice:
             return self.choice.children
         return None
 
@@ -182,6 +218,12 @@
         self.attributes["cols"] = ""
         self.attributes["rows"] = ""
 
+    def firstFindDefault(self):
+        value = self.getValue()
+        if not value: value = None
+        self.found_default = value
+        return Leaf.firstFindDefault(self)
+
     def getCols(self):
         return self.getAttribute("cols")
 
@@ -200,6 +242,12 @@
         self.attributes["size"] = "40"
         self.attributes["maxlength"] = "60"
 
+    def firstFindDefault(self):
+        value = self.getValue()
+        if not value: value = None
+        self.found_default = value
+        return Leaf.firstFindDefault(self)
+
     def getSize(self):
         return self.getAttribute("size")
 
@@ -218,6 +266,25 @@
         self.attributes["size"]     = "1"
         self.attributes["multiple"] = ""
 
+    def firstFindDefault(self):
+        value = None
+        if self.children:
+            for child in self.children:
+                if isinstance(child, ExternalChoiceListLeaf):
+                    found, v = child.find_default()
+                    if found: 
+                        value = v
+                        break
+                elif isinstance(child, BoolLeaf):
+                    if child.getChecked():
+                        v = child.getValue()
+                        if v: value = int(v)
+                        break
+
+        self.found_default = value
+        return Node.firstFindDefault(self)
+
+
     def getSize(self):
         return self.getAttribute("size")
 
@@ -242,6 +309,19 @@
         self.attributes["minvalue"] = ""
         self.attributes["maxvalue"] = ""
 
+    def firstFindDefault(self):
+        value = self.getValue().strip()
+        if value:
+            try:
+                value = int(value)
+            except ValueError:
+                print >> sys.stderr, "Broken default for '%s'" % self.getName()
+                value = None
+        else:
+            value = None
+        self.found_default = value
+        return Leaf.firstFindDefault(self)
+
     def getMinValue(self):
         return self.getAttribute("minvalue")
 
@@ -258,6 +338,19 @@
     def __init__(self):
         Leaf.__init__(self)
 
+    def firstFindDefault(self):
+        value = self.getValue().strip()
+        if value:
+            try:
+                value = date(*[int(x) for x in value.split("-")])
+            except (TypeError, ValueError):
+                print >> sys.stderr, "Broken default for '%s'" % self.getName()
+                value = None
+        else:
+            value = None
+        self.found_default = value
+        return Leaf.firstFindDefault(self)
+
 class RuleLeaf(Leaf):
     def __init__(self):
         Leaf.__init__(self)

Modified: wasko/trunk/waskaweb/model/io/document.py
===================================================================
--- wasko/trunk/waskaweb/model/io/document.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/model/io/document.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -110,7 +110,7 @@
     BoolLeaf:               BOOL_TAG }
 
 def openDocument(path, documentFactoryCreator = None):
-    builder = SAXBuilder()
+    builder = SAXBuilder(path)
 
     if documentFactoryCreator:
         factories = factoryCreators.copy()

Modified: wasko/trunk/waskaweb/model/io/factories.py
===================================================================
--- wasko/trunk/waskaweb/model/io/factories.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/model/io/factories.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -39,7 +39,12 @@
         self.ncClass      = ncClass
 
     def createFactory(self, name, attrs, ctx):
-        return self.factoryClass(attrs, self.ncClass())
+        obj = self.ncClass()
+        try:
+            getattr(obj, 'setLoadContext')(ctx)
+        except AttributeError:
+            pass
+        return self.factoryClass(attrs, obj)
 
 class NodeComponentFactory(Factory):
 

Modified: wasko/trunk/waskaweb/model/nodecomponents.py
===================================================================
--- wasko/trunk/waskaweb/model/nodecomponents.py	2009-03-03 15:55:00 UTC (rev 321)
+++ wasko/trunk/waskaweb/model/nodecomponents.py	2009-03-04 07:24:55 UTC (rev 322)
@@ -1,27 +1,27 @@
 # -*- coding: latin1 -*-
 #
 # Copyright 2007, 2008 Intevation GmbH, Germany, <info at intevation.de>
-# 
-# This file is part of mpuls WASKA (CoMPUter-based case fiLeS - 
+#
+# This file is part of mpuls WASKA (CoMPUter-based case fiLeS -
 # Web-Anwendungs-Server fuer Kompetenzagenturen).
-# 
+#
 # mpuls WASKA is free software: you can redistribute it and/or modify it under
 # the terms of the GNU Affero General Public License as published by the
 # Free Software Foundation, either version 3 of the License, or (at your
 # option) any later version.
-# 
+#
 # mpuls WASKA is distributed in the hope that it will be useful, but WITHOUT
 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 # License for more details.
-# 
+#
 # You should have received a copy of the GNU Affero General Public
 # License along with mpuls WASKA. If not, see <http://www.gnu.org/licenses/>.
-# 
-# mpuls WASKA has been developed on behalf of the 
+#
+# mpuls WASKA has been developed on behalf of the
 # Projekttraeger im Deutschen Zentrum fuer Luft- und Raumfahrt e.V. (PT-DLR)
 # within the programme Kompetenzagenturen (Durchfuehrungsphase) funded by
-# the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and 
+# the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and
 # European Social Fund resources.
 #
 # Authors:
@@ -32,7 +32,7 @@
 VISIT_CONTINUE        = None
 
 class NodeComponent:
-    
+
     def __init__(self):
         self.parent     = None
         self.attributes = {}
@@ -45,9 +45,19 @@
         self.attributes["alternative"]  = ""
         self.attributes["flags"]        = ""
 
+        self.found_default = None
+        self.findDefault   = self.firstFindDefault
+
+    def firstFindDefault(self):
+        self.findDefault = self.defaultFound
+        return self.found_default
+
+    def defaultFound(self):
+        return self.found_default
+
     def setAttribute(self, key, value, broadcast=True):
         self.attributes[key] = value
-                
+
     def getAttribute(self, key):
         return self.attributes.get(key, None)
 
@@ -74,7 +84,7 @@
 
     def getFormularName(self):
         return self.getAttribute("formularname")
-    
+
     def setName(self, name):
         self.setAttribute("name", name)
 



More information about the Mpuls-commits mailing list