[Mpuls-commits] r711 - in waska/trunk: . waskaweb/controllers waskaweb/lib waskaweb/public/styles waskaweb/templates

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Fri Nov 27 14:10:04 CET 2009


Author: torsten
Date: 2009-11-27 14:10:03 +0100 (Fri, 27 Nov 2009)
New Revision: 711

Modified:
   waska/trunk/ChangeLog.txt
   waska/trunk/production_wsgi.ini
   waska/trunk/waskaweb/controllers/evaluate.py
   waska/trunk/waskaweb/lib/app_globals.py
   waska/trunk/waskaweb/lib/helpers.py
   waska/trunk/waskaweb/lib/validators.py
   waska/trunk/waskaweb/public/styles/all.css
   waska/trunk/waskaweb/templates/main.mako
Log:
Implemented first version of new evaluations in WASKA


Modified: waska/trunk/ChangeLog.txt
===================================================================
--- waska/trunk/ChangeLog.txt	2009-11-27 07:36:03 UTC (rev 710)
+++ waska/trunk/ChangeLog.txt	2009-11-27 13:10:03 UTC (rev 711)
@@ -1,3 +1,15 @@
+2009-11-27 	Torsten Irlaender  <torsten.irlaender at intevation.de>
+
+	Implemented new evaluations based on libmpuls
+
+	* production_wsgi.ini,
+	  waskaweb/controllers/evaluate.py,
+	  waskaweb/lib/helpers.py,
+	  waskaweb/lib/validators.py,
+	  waskaweb/lib/app_globals.py,
+	  waskaweb/public/styles/all.css,
+	  waskaweb/templates/main.mako: Added new evaluations 
+
 2009-11-26 	Torsten Irlaender  <torsten.irlaender at intevation.de>
 
 	* waskaweb/lib/renderer.py: If formfields are disabled. Render

Modified: waska/trunk/production_wsgi.ini
===================================================================
--- waska/trunk/production_wsgi.ini	2009-11-27 07:36:03 UTC (rev 710)
+++ waska/trunk/production_wsgi.ini	2009-11-27 13:10:03 UTC (rev 711)
@@ -49,6 +49,11 @@
 #beaker.cache.data_dir = %(here)s/data/cache
 #beaker.session.data_dir = %(here)s/data/sessions
 
+# You can provide a user specific configuration for the mpuls server.
+# In this file you can configure various things like the database connection,
+# enable or disable modules etc.
+#mpuls_config=%(here)s/myconfig.json
+
 # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
 # Debug mode will enable the interactive debugging tool, allowing ANYONE to
 # execute malicious code after an exception is raised.

Modified: waska/trunk/waskaweb/controllers/evaluate.py
===================================================================
--- waska/trunk/waskaweb/controllers/evaluate.py	2009-11-27 07:36:03 UTC (rev 710)
+++ waska/trunk/waskaweb/controllers/evaluate.py	2009-11-27 13:10:03 UTC (rev 711)
@@ -1,488 +1,283 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright 2007, 2008 Intevation GmbH, Germany, <info at intevation.de>
-# 
-# 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 
-# 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 
-# European Social Fund resources.
-#
-# Authors:
-# Torsten Irländer <torsten.irlaender at intevation.de>
-# Sascha L. Teichmann <teichmann at intevation.de>
-#
+import os
 import logging
-import paste
 import formencode
-from sets import Set
-from datetime import datetime
-from waskaweb.lib.sql_helper import range_compress 
+import traceback
+import pylons
+
+from pylons import session, g, c
+from waskaweb.lib.validators import EvaluationFormValidator
 from waskaweb.lib.base import *
-from waskaweb.lib.evaluation import *
-from waskaweb.lib.evaluation_new import Evaluation as NewEvaluation, EvaluationExportXML
-from waskaweb.lib.adelexml import AdeleXML
-from waskaweb.lib.basicevaluation import BasicEvaluation
-from waskaweb.lib.evaluation_new import *
-from waskaweb.lib.search import CaseSearch
-from waskaweb.lib.validators import SearchCaseForm 
-from waskaweb.controllers.case_overview import parseSearchOptions 
-from waskaweb.model.case import CaseBundle 
-from waskaweb.model.agency import AgencyBundle, AgencyOverview 
+from waskaweb.lib.db import db
+from waskaweb.lib.helpers import format_date, get_phasesuccessors 
+from libmpuls.evaluation.config import EvaluationConfig
+from libmpuls.evaluation.evaluation import EvaluationSet
+from libmpuls.evaluation.export import EvaluationExportXML, EvaluationExportCSV, EvaluationExportHTML
 
 log = logging.getLogger(__name__)
 
-import sys
-import traceback
+def get_configfile(id):
+    for enabled_eval in g.mpuls_config.get('evaluations', 'enabled'):
+        if enabled_eval.get('id') == str(id):
+            filename = enabled_eval.get('config')
+            path = os.path.join(
+                pylons.config.get('pylons.paths').get('static_files'), 
+                'xml',
+                filename)
+            return path
+    return None
 
-from waskaweb.lib.security import checkRole
-from paste.httpexceptions  import HTTPNotFound
+def get_search_options(soptions=None, id=None):
+    options = {}
+    options['id'] = id
+    if soptions:
+        options['start_date'] = soptions.get('start_date') or datetime.date(2009,9,1)
+        options['end_date'] = soptions.get('end_date') or datetime.date.today() 
 
-SEARCH_STR = "state:1;state:2;state:4;state:5;own:%s"
+        phase = [int(p) for p in soptions.get('phase')]
+        if len(phase) == 1 and -1 in phase:
+            options['start_date_field'] = g.mpuls_config.get('evaluations', 'default-start-date-field')
+            options['end_date_field'] = g.mpuls_config.get('evaluations', 'default-end-date-field')
+        else:
+            options['start_date_field'] = g.mpuls_config.get('agency-fields-mapping', 'date_phase%s_start' % min(phase))
+            options['end_date_field'] = g.mpuls_config.get('agency-fields-mapping', 'date_phase%s_end' % max(phase))
 
-class EvaluateController(BaseController):
+        options['phase'] = max(phase)
+        options['sqlwhere'] = soptions.get('sqlwhere') or None 
+        options['sql'] =  soptions.get('sql') or None
+    else:
+        # set default evaluation options.
+        options['phase'] = 1
+        options['start_date'] = g.mpuls_config.get('search', 'default-start-date')
+        options['end_date'] = g.mpuls_config.get('search', 'default-end-date')
+        options['start_date_field'] = g.mpuls_config.get('evaluations', 'default-start-date-field')
+        options['end_date_field'] = g.mpuls_config.get('evaluations', 'default-end-date-field')
 
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def index(self):
-        raise HTTPNotFound()
+    options['typelist'] = c.evalconfig.get_evaluations()
 
-    def search(self):
-        user = session['USER_AUTHORIZED']
-        search_str = SEARCH_STR % user.id
-        validator = SearchCaseForm()
-        c.form_result = {}
-        c.form_errors = {}
-        try:
-            form_result = validator.to_python(request.params)
-            # Update the searchoptions with params coming from the search
-            # dialog on the evaluation page 
-            old_session = session.get('CASE_OVERVIEW_SEARCHOPTIONS', {}) 
-            for key, value in form_result.iteritems():
-                if value:
-                   old_session[key] = value 
-            session['CASE_OVERVIEW_SEARCHOPTIONS'] = old_session
-            session.save()
+    phases = []
+    for p in g.mpuls_config.get('search', 'phases'):
+        pt = [t for t in p.values() if int(t) >= 0]
+        phases.extend(pt)
+    options['phase'] =  phases
 
-            search_str2 = ";".join(parseSearchOptions(form_result))
-            search_str  = ";".join([search_str2, search_str])
-            search = CaseSearch()
-            result = search.perform(search_str)
-            # fetch ids of the new search 
-            new_case_ids = []
-            for row in result:
-                new_case_ids.append(row['id'])
+    # convert dates to locale
+    options['start_date'] = format_date(options['start_date']) 
+    options['end_date']   = format_date(options['end_date']) 
 
-            # fetch ids from the old casebundle 
-            old_case_bundle = session.get('casebundle_for_eval')
-            if not old_case_bundle:
-                old_case_bundle = self._getNewCaseBundle()
-            old_case_ids = old_case_bundle.listDatasetIds()
+    return options
 
-            #print "old: %s new: %s" % (old_case_ids, new_case_ids)
-            # now only take those ids which intersects.
-            ids = Set(old_case_ids) & Set(new_case_ids)
+class EvaluateController(BaseController):
 
-            ## build casebundle
-            case_bundle = CaseBundle([id for id in ids])
-            session['casebundle'] = case_bundle
-            session.save()
-        except formencode.Invalid, error:
-            form_result = error.value
-            form_errors = error.error_dict or {}
+    def index(self):
+        return self.evaluate()
 
-        return self.evaluate(form_result.get('eval_id'))
+    def evaluate(self, id=None):
+        conn, cur = None, None
+        try:
+            try:
+                config_file = get_configfile(id)
+                conn = db.getConnection()
+                c.evalconfig   = EvaluationConfig(
+                                config_file,
+                                conn,
+                                None,
+                                None,
+                                None,
+                                None,
+                                None,
+                                None,
+                                None)
+            except:
+                print 'Error: Evaluation failed %s' % traceback.print_exc()
+                log.error(_('Error: Evaluation failed'))
+        finally:
+            db.recycleConnection(conn, cur)
 
-    def _getNewCaseBundle(self, search_str=None):
-            user = session['USER_AUTHORIZED']
-            if not search_str:
-                search_str = SEARCH_STR % user.id
-            search = CaseSearch()
-            result = search.perform(search_str)
-            # fetch ids if the cases
-            ids = []
-            for row in result:
-                ids.append(row['id'])
-            # build casebundle
-            case_bundle = CaseBundle(ids)
-            session['casebundle'] = case_bundle
-            session.save()
-            return case_bundle
+        c.evaloptions = get_search_options(session.get('evaluation.options'), id)
 
-    def _getCompressedIds(self, reset=False):
-        # Load case bundle and build where to define cases for the evaluation
-        if reset:
-            case_bundle = self._getNewCaseBundle()
+        # If user selects adele-evaluation render page with disabled configuration elements. 
+        # Change default params
+        if id == '0':
+            c.evaloptions['phase'] = '2'
+            c.evaloptions['start_date_field'] = ['datum_cm_start']
+            c.evaloptions['end_date_field'] = ['datum_cm_end']
+            form = render('/evaluation/evaluate_adele.mako')
         else:
-            case_bundle = session.get('casebundle')
-            if not case_bundle:
-                case_bundle = self._getNewCaseBundle()
-        ids = sorted(case_bundle.listDatasetIds())
-        rc = range_compress(ids)
-        return rc
+            form = render('/evaluation/evaluate.mako')
+        return formencode.htmlfill.render(unicode(form, 'utf-8'), \
+                defaults=c.evaloptions, \
+                errors={}, \
+                auto_insert_errors=False)
 
-    def evaluateAdele(self):
+    def _get_evalparams(self, form_result):
         params = {}
-        params['start_date'] = '2008-09-01'
-        params['end_date']   = '2009-08-31'
-        c.select = 3
-        if request.params:
-            if request.params.get('timeframe') == '1':
-                params['start_date'] = '2008-09-01'
-                params['end_date']   = '2008-12-31'
-                c.select = 1
-            elif request.params.get('timeframe') == '2':
-                params['start_date'] = '2009-01-01'
-                params['end_date']   = '2009-03-31'
-                c.select = 2
-            elif request.params.get('timeframe') == '3':
-                params['start_date'] = '2008-09-01'
-                params['end_date']   = '2009-08-31'
-                c.select = 3
+        params['id'] = form_result['id']
+        params['start_date'] = str(form_result['start_date'])
+        params['end_date'] = str(form_result['end_date'])
+        params['typelist'] = form_result['typelist']
+        params['phase']    = form_result['phase']
+        params['ending']    = form_result['type_ending']
 
-        params['agencyid']   = 'inte0002'
+        # Dates
+        # Build timeframes bases on selected phases.
+        dates = []
+        all_phases = []
+        tdates = []
+        phase = params.get('phase')
+        dates.append('( ')
+        if params.get('start_date') != 'None' and params.get('end_date') != 'None':
+            if phase:
+                for p in phase:
+                    if int(p) >= 0: # phase is unknown -> has no start and endphase
+                        sdf = g.mpuls_config.get('agency-fields-mapping', 'date_phase%s_start' % p)
+                        edf = g.mpuls_config.get('agency-fields-mapping', 'date_phase%s_end' % p) 
+                        suc = get_phasesuccessors(p)
+                        all_phases.extend(suc)
+                        tdates.append("('%s'::date <= %s AND '%s'::date >= %s AND phase IN (%s) )" % (params.get('start_date'), edf, params.get('end_date'), sdf, ",".join(["%s" % s for s in suc])))
+                    else:
+                        tdates.append('phase IN (-1)')
+                dates.append(" OR ".join(tdates))
+            else:
+                dates.append("FALSE")
+        else:
+            dates.append("TRUE")
+        dates.append(' )')
 
-        y,m,d = [int(i) for i in params['start_date'].split('-')]
-        c.start_date = datetime(y,m,d)
-        y,m,d = [int(i) for i in params['end_date'].split('-')]
-        c.end_date = datetime(y,m,d)
+        # Type of ending
+        ending = " TRUE " 
+        endingdate = " TRUE " 
+        if params['ending'] and params.get('start_date') != 'None' and params.get('end_date') != 'None':
+            enddatefield = g.mpuls_config.get('agency-fields-mapping', 'date_phase3_end')
+            endingdate = "( '%s'::date <= %s AND %s <= '%s'::date )" % (params['start_date'], enddatefield, enddatefield, params['end_date'])
+            ending = "cm_end_art in ( %s )" % ", ".join(['%s' % e for e in params['ending']])
 
-        evaluation = AdeleXML(params)
-        c.eval = evaluation.perform()
-        return render('casemanagement/evaluation/evaluation_adele.mako')
+        params['sql'] = "SELECT %%(fields)s from master_tbl_eval_total_view m WHERE %s AND %s AND %s" % ("".join(dates), ending, endingdate)
 
-    def evaluateBasic(self):
-        params = {}
-        params['start_date'] = '2008-09-01'
-        params['end_date']   = '2009-04-27'
-        c.select = 2
-        # no other timeframes available yet
-        #if request.params:
-        #    if request.params.get('timeframe') == '1':
-        #        params['start_date'] = '2008-09-01'
-        #        params['end_date']   = '2008-12-31'
-        #        c.select = 1
-        #    else:
-        #        params['start_date'] = '2009-01-01'
-        #        params['end_date']   = '2009-03-31'
-        #        c.select = 2
+        #Datefields
+        if all_phases:
+            params['start_date_field'] = g.mpuls_config.get('agency-fields-mapping', 'date_phase%s_start' % min(all_phases))
+            params['end_date_field'] = g.mpuls_config.get('agency-fields-mapping', 'date_phase%s_start' % max(all_phases))
+        else:
+            params['start_date_field'] = g.mpuls_config.get('evaluations', 'default-start-date-field')
+            params['end_date_field'] =  g.mpuls_config.get('evaluations', 'default-end-date-field')
+        return params
 
-        params['agencyid']   = 'inte0002'
 
-        y,m,d = [int(i) for i in params['start_date'].split('-')]
-        c.start_date = datetime(y,m,d)
-        y,m,d = [int(i) for i in params['end_date'].split('-')]
-        c.end_date = datetime(y,m,d)
+    def evaluateAction(self):
+            '''Return an HTML file containing the result of one or more evaluations.'''
+            params = formencode.variabledecode.variable_decode(request.params)
+            #params = request.params
+            validator    = EvaluationFormValidator() 
+            form_result  = {}
+            form_errors  = {}
 
-        evaluation = BasicEvaluation(params)
-        c.eval = evaluation.perform()
-        return render('casemanagement/evaluation/evaluation_basic.mako')
+            # Check values
+            conn, cur = None, None
+            conn = db.getConnection()
+            id = int(params['id'])
+            c.evalconfig   = EvaluationConfig(
+                            get_configfile(id),
+                            conn,
+                            None,
+                            None,
+                            None,
+                            None,
+                            None,
+                            None,
+                            None)
+            try:
+                form_result  = validator.to_python(params)
+            except formencode.Invalid, error:
+                form_result = error.value
+                form_errors = error.error_dict or {}
+                c.evaloptions = get_search_options(session.get('evaluation.options'), id)
+                form = render('/evaluation/evaluate.mako')
+                return formencode.htmlfill.render(unicode(form, 'utf-8'), \
+                        defaults=form_result, \
+                        errors=form_errors, \
+                        auto_insert_errors=False)
 
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def evaluate(self, id, reset=0):
-        reset = self._checkBool(reset)
-        if reset:
-            if c.isEvaluationServer:
-                form_defaults = {}
-                search_options = parseSearchOptions(form_defaults)
-                # sql query fails if no sort order is given.
-                search_options.append('sort_field:fkz')
-                search_options.append('sort_order:asc')
-                agency_ids = [a.fkz for a in AgencyOverview().search(";".join(search_options))]
-                agency_bundle = AgencyBundle(agency_ids)
-                session['agencybundle'] = agency_bundle
+            # Build evaluation
+            eval_params = self._get_evalparams(form_result)
+            try:
+                try:
+                    evalconfig   = EvaluationConfig(
+                                    get_configfile(form_result['id']),
+                                    conn,
+                                    eval_params['start_date'], 
+                                    eval_params['end_date'],
+                                    eval_params['start_date_field'], 
+                                    eval_params['end_date_field'], 
+                                    None,
+                                    eval_params['sql'], 
+                                    eval_params['typelist'])
+                    evalset      = EvaluationSet(evalconfig, True)
+                    evalset.evaluate()
+                    c.result = evalset.export(EvaluationExportHTML(show_percent=form_result['show_percent']))
+                    session['evaluation.params'] = eval_params
+                    session.save()
+                    form = render('/evaluation/result.mako')
+                    return formencode.htmlfill.render(unicode(form, 'utf-8'), \
+                        defaults=form_result, \
+                        errors=form_errors, \
+                        auto_insert_errors=False)
+                except:
+                    log.error(_('Error: Evaluation failed'))
+                    log.error(traceback.print_exc())
+            finally:
+                db.recycleConnection(conn, cur)
 
-            session['hide_search_option_on_eval'] = False 
-            session['CASE_OVERVIEW_SEARCHOPTIONS'] = {}
-            session.save()
-        page = None
+    def exportXML(self):
+        '''Return an XML file containing the result of one or more evaluations.'''
+        response.headers['Content-Type'] = 'application/xml; charset=utf8'
+        response.headers['Content-Disposition'] = 'attachment; filename=evaluation-export.xml'
+        form_result = session.get('evaluation.params')
         try:
-            c.eval_id = id
-            if id == '0':
-                # Zeitaufwände Logbuch
-                e14 = Evaluation_14(self._getCompressedIds(reset))
-                c.eval_effort = e14.perform() 
-                c.eval_avg_effort = c.eval_effort 
-                c.count_total = e14.getTotal()
-                c.count_total_valid = e14.getTotalValid()
-                page = render('casemanagement/evaluation/evaluation_result_0.mako')
-            if id == '1':
-                # Verhältnis Beratungskunden
-                e1 = Evaluation_1(self._getCompressedIds(reset))
-                c.eval_1_total, c.eval_1_ber, c.eval_1_ber_percent, c.eval_1_cm, c.eval_1_cm_percent = e1.perform()
-                c.count_total = e1.getTotal()
-                c.count_total_valid = e1.getTotalValid()
-                # Zugang zur KA
-                e4 = Evaluation_4(self._getCompressedIds(reset))
-                c.eval_4 = e4.perform()
-                # Rechtskreis Zugang
-                e5 = Evaluation_5(self._getCompressedIds(reset))
-                c.eval_5 = e5.perform()
-                # Schulabschluss Zugang
-                e11 = Evaluation_11(self._getCompressedIds(reset))
-                c.eval_11 = e11.perform()
-                # Arbeitssituation
-                e12 = Evaluation_12(self._getCompressedIds(reset))
-                c.eval_12 = e12.perform()
-                page = render('casemanagement/evaluation/evaluation_result_1.mako')
-            elif id == '2':
-                # Altersverteilung 
-                e8 = Evaluation_8(self._getCompressedIds(reset)) 
-                c.eval_8 = e8.perform()
-                # Migration
-                e3 = Evaluation_3(self._getCompressedIds(reset))
-                c.eval_3 = e3.perform()
-                # Verteilung Förderangebote
-                e9 = Evaluation_9(self._getCompressedIds(reset))
-                c.eval_9 = e9.perform()
-                # Geschlecht
-                e2 = Evaluation_2(self._getCompressedIds(reset))
-                c.eval_2_t, c.eval_2_m, c.eval_2_w, c.eval_2_i, c.eval_2_u = e2.perform()
-                # Arbeitslose
-                e19 = Evaluation_19(self._getCompressedIds(reset))
-                c.eval_19 = e19.perform()
-                # Nicht-Erwerbspersonen
-                e20 = Evaluation_20(self._getCompressedIds(reset))
-                c.eval_20 = e20.perform()
-                # ESF-Stammblatt 
-                #e21 = Evaluation_21(self._getCompressedIds(reset))
-                #c.eval_21 = e21.perform()
-                page = render('casemanagement/evaluation/evaluation_result_2.mako')
-            elif id == '3':
-                # Verweildauer CM
-                e10 = Evaluation_10(self._getCompressedIds(reset))
-                c.eval_10 = e10.perform()
-                c.count_total = e10.getTotal()
-                c.count_total_valid = e10.getTotalValid()
-                e13 = Evaluation_13(self._getCompressedIds(reset))
-                c.eval_13 = e13.perform()
-                # Vermittlung
-                e6 = Evaluation_6(self._getCompressedIds(reset))
-                c.eval_6 = e6.perform()
-                c.count_total = e6.getTotal()
-                c.count_total_valid = e6.getTotalValid()
-                # Rechtskreis nach Vermittlung
-                e7 = Evaluation_7(self._getCompressedIds(reset))
-                c.eval_7 = e7.perform()
-                # Zeitaufwände Logbuch
-                e15 = Evaluation_15(self._getCompressedIds(reset))
-                c.eval_effort = e15.perform()
-                c.eval_avg_effort = c.eval_effort 
-                page = render('casemanagement/evaluation/evaluation_result_3.mako')
+            try:
+                conn, cur = db.getConnection(), None
+                evalconfig   = EvaluationConfig(
+                                get_configfile(form_result['id']),
+                                conn,
+                                form_result['start_date'], 
+                                form_result['end_date'],
+                                form_result['start_date_field'], 
+                                form_result['end_date_field'], 
+                                None,
+                                form_result['sql'], 
+                                form_result['typelist'])
+                evalset      = EvaluationSet(evalconfig)
+                evalset.evaluate()
+                return evalset.export(EvaluationExportXML())
+            except:
+                log.error(_('Error: Evaluation failed'))
+                log.error(traceback.print_exc())
+        finally:
+            db.recycleConnection(conn, cur)
 
-            if page:
-                form_result = session.get('CASE_OVERVIEW_SEARCHOPTIONS', {})
-                if form_result.has_key('eval_id'):
-                    del form_result['eval_id'] # do not fillout eval_id with htmlfill
-                return formencode.htmlfill.render(unicode(page, 'utf-8'),defaults=form_result)
-        except:
-            return render('/tests/trace.mako')
 
-        raise HTTPNotFound()
-
-    def _export(self, evaluation):
-        content = evaluation.export()
-        data = paste.fileapp.DataApp(
-            content,
-            content_type='text/comma-separated-values',
-            content_encoding='UTF-8',
-            cache_control='must-revalidate',
-            pragma='public')
-        return data(request.environ, self.start_response)
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_1(self):
+    def exportCSV(self):
+        '''Return an CSV file containing the result of one or more evaluations.'''
+        response.headers['Content-Type'] = 'application/csv; charset=utf8'
+        response.headers['Content-Disposition'] = 'attachment; filename=evaluation-export.csv'
+        form_result = session.get('evaluation.params')
         try:
-            e = Evaluation_1(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_2(self):
-        try:
-            e = Evaluation_2(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_3(self):
-        try:
-            e = Evaluation_3(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_4(self):
-        try:
-            e = Evaluation_4(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_5(self):
-        try:
-            e = Evaluation_5(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_6(self):
-        try:
-            e = Evaluation_6(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_7(self):
-        try:
-            e = Evaluation_7(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_8(self):
-        try:
-            e = Evaluation_8(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_9(self):
-        try:
-            e = Evaluation_9(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_10(self):
-        try:
-            e = Evaluation_10(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_11(self):
-        try:
-            e = Evaluation_11(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_12(self):
-        try:
-            e = Evaluation_12(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_13(self):
-        try:
-            e = Evaluation_13(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_14(self):
-        try:
-            e = Evaluation_14(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_15(self):
-        try:
-            e = Evaluation_15(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_16(self):
-        try:
-            e = Evaluation_16(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_17(self):
-        try:
-            e = Evaluation_17(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_19(self):
-        try:
-            e = Evaluation_19(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_20(self):
-        try:
-            e = Evaluation_20(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-    @checkRole(('admin_ka', 'cm_ka', 'pt_dlr', 'pb_ka'))
-    def exportEvaluation_21(self):
-        try:
-            e = Evaluation_21(self._getCompressedIds())
-            return self._export(e)
-        except:
-            traceback.print_exc(file=sys.stderr)
-            raise HTTPNotFound()
-
-# vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
+            try:
+                conn, cur = db.getConnection(), None
+                evalconfig   = EvaluationConfig(
+                                get_configfile(form_result['id']),
+                                conn,
+                                form_result['start_date'], 
+                                form_result['end_date'],
+                                form_result['start_date_field'], 
+                                form_result['end_date_field'], 
+                                None,
+                                form_result['sql'], 
+                                form_result['typelist'])
+                evalset      = EvaluationSet(evalconfig)
+                evalset.evaluate()
+                return evalset.export(EvaluationExportCSV())
+            except:
+                log.error(_('Error: Evaluation failed'))
+                log.error(traceback.print_exc())
+        finally:
+            db.recycleConnection(conn, cur)

Modified: waska/trunk/waskaweb/lib/app_globals.py
===================================================================
--- waska/trunk/waskaweb/lib/app_globals.py	2009-11-27 07:36:03 UTC (rev 710)
+++ waska/trunk/waskaweb/lib/app_globals.py	2009-11-27 13:10:03 UTC (rev 711)
@@ -22,6 +22,7 @@
 # the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and 
 # European Social Fund resources.
 """The application's Globals object"""
+import pylons
 from pylons import config
 
 from waskaweb.model.io.document import openDocument 
@@ -31,6 +32,7 @@
 import waskaweb.lib.security    as security
 
 from waskaweb.lib.timelog import setupTimeLogging
+from waskaweb.lib.config import MpulsConfig, get_path
 
 import os, sys, traceback
 
@@ -44,6 +46,17 @@
         initialization and is available during requests via the 'g'
         variable
         """
+        # Load mpuls configuration
+        config_file = pylons.config['app_conf'].get('mpuls_config', 'mpuls.json')
+        if config_file:
+            if not os.path.isabs(config_file):
+                root = pylons.config.get('pylons.paths').get('root')
+                config_file = os.path.join(root, '..', config_file)
+
+
+        self.config_path = os.path.dirname(config_file)
+        self.mpuls_config = MpulsConfig(config_file)
+
         # XXX: Dead ugly!
         path = os.path.join(os.path.dirname(__file__), '..', '..', 'formed')
         treeFile  = os.path.join(path, 'formedtree_web.xml')

Modified: waska/trunk/waskaweb/lib/helpers.py
===================================================================
--- waska/trunk/waskaweb/lib/helpers.py	2009-11-27 07:36:03 UTC (rev 710)
+++ waska/trunk/waskaweb/lib/helpers.py	2009-11-27 13:10:03 UTC (rev 711)
@@ -245,3 +245,46 @@
     except:
         print >> sys.stderr, "Could not fetch KA-name from client certificate"
     return ''
+
+def format_date(dt):
+    return date2str(dt)
+
+def date2str(dt):
+    if dt is None: return ''
+    try:
+        #print "dt: %s fmt: %s" % (dt, locale.nl_langinfo(locale.D_FMT))
+        return dt.strftime(locale.nl_langinfo(locale.D_FMT))
+    except Exception, err:
+        log.error(err)
+        return dd_mm_YYYY(dt)
+
+# Phases helpers. Used in evaluation
+def get_phasesuccessors(p):
+    #p = int(p)
+    phasesuc = []
+    pairs = g.mpuls_config.get('phases', 'pairs')[0]
+    for phase, symbols in pairs.iteritems():
+        if p in symbols:
+            for pair in phase_successors_path(phase, None, True):
+                phasesuc.extend(pairs.get(pair))
+    return phasesuc
+
+def phase_successors(phase):
+    try:
+        suc = g.mpuls_config.get('phases', 'successors')[0][phase]
+        return suc
+    except KeyError:
+        return []
+
+def phase_successors_path(phase, path=None, include_root=False):
+    '''returns list of phase ids (not phasepairs)'''
+    if not path:
+        path = []
+        if include_root:
+            path.append(phase)
+    for p in phase_successors(phase):
+        path.append(p)
+        phase_successors_path(p, path=path)
+    return path
+
+    return phasesuc

Modified: waska/trunk/waskaweb/lib/validators.py
===================================================================
--- waska/trunk/waskaweb/lib/validators.py	2009-11-27 07:36:03 UTC (rev 710)
+++ waska/trunk/waskaweb/lib/validators.py	2009-11-27 13:10:03 UTC (rev 711)
@@ -22,11 +22,14 @@
 # within the programme Kompetenzagenturen (Durchfuehrungsphase) funded by
 # the Bundesministerium fuer Familie, Senioren, Frauen und Jugend and 
 # European Social Fund resources.
-from pylons import session
+from pylons import session, g
+from pylons.i18n import _
 from waskaweb.lib.db import db
 import re
 import formencode
 import datetime
+import time
+import locale
 
 class ValidatorStateObject:
 
@@ -43,6 +46,24 @@
     allow_extra_fields = True
     filter_extra_fields = False 
 
+class MyDateConverter(formencode.validators.FancyValidator):
+
+    messages = {
+        'wrong_format': _('Date is invalid')}
+
+    def _to_python(self, value, state):
+        value.strip()
+        try:
+            try:
+                d = time.strptime(value, locale.nl_langinfo(locale.D_FMT))
+            except:
+                d = time.strptime(value, locale.nl_langinfo(locale.D_FMT).lower())
+            return datetime.date(d[0], d[1], d[2])
+        except:
+            raise formencode.Invalid(self.message("wrong_format", state), value, state)
+
+
+
 class MaxMinInt(formencode.validators.FancyValidator):
 
     """
@@ -381,4 +402,16 @@
 class SetPhaseForm(BaseFormValidator):
     pass
 
+class EvaluationFormValidator(BaseFormValidator):
+    id                  = formencode.validators.String(if_missing='0')
+    agencyid            = formencode.validators.String(if_missing=g.mpuls_config.get('common', 'agencyname'))
+    start_date          = MyDateConverter(not_empty=True, if_missing='')
+    end_date            = MyDateConverter(not_empty=True, if_missing='')
+    start_date_field    = formencode.validators.String(if_missing=g.mpuls_config.get('evaloptions', 'default-start-date-field'))
+    end_date_field      = formencode.validators.String(if_missing=g.mpuls_config.get('evaloptions', 'default-end-date-field'))
+    typelist            = formencode.ForEach(formencode.validators.String(), convert_to_list=True)
+    type_ending         = formencode.ForEach(formencode.validators.String(), convert_to_list=True)
+    phase               = formencode.ForEach(formencode.validators.String(), convert_to_list=True)
+    show_percent        = formencode.validators.Bool(if_missing=False)
+
 # vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8

Modified: waska/trunk/waskaweb/public/styles/all.css
===================================================================
--- waska/trunk/waskaweb/public/styles/all.css	2009-11-27 07:36:03 UTC (rev 710)
+++ waska/trunk/waskaweb/public/styles/all.css	2009-11-27 13:10:03 UTC (rev 711)
@@ -15,6 +15,18 @@
 	border:none;
 }
 
+.container { 
+	padding: 0.25em;
+}
+
+.widget {
+	border: 1pt solid;
+	margin: 1pt 0 1pt 0;
+	border-color: #ccc;
+	-webkit-border-radius: 5px;
+	-moz-border-radius:5px;
+}
+
 /*------------------*/
 /* 1. Table Formats */
 /*------------------*/
@@ -33,6 +45,28 @@
 	margin:0.6em 0 1em 0;
 }
 
+tr.hl, td.hl, th.hl {
+	background-color: #ebebeb;
+}
+td.header, th {
+	font-size: 0.9em;
+	font-weight: bold;
+	background-color: #D5D5D5;
+	border-bottom: 1pt solid;
+}
+td.label {
+	width: 8em;
+	border-right: 1pt solid;
+	padding-right: 0.25em;
+	text-align: right;
+}
+td.actions, th.actions {
+	width: 6em;
+	text-align: right;
+}
+
+
+
 table th {
 	padding: 0 0.6em 0 0.25em!important;
 	padding: 0.1em 0.6em 0.1em 0.25em;
@@ -105,10 +139,23 @@
 table#searchoptiontable { 
 	width: 30em;
 }
+
 /*----------------------*/
 /* 2. Evaluation Formats*/
 /*----------------------*/
 
+.evaluation table, .evaluation td, .evaluation th {
+	border: 1pt solid;
+	border-collapse: collapse;
+	empty-cells: hide;
+}
+
+.evaluation th, .evaluation td.num {
+	text-align: center;
+	vertical-align: middle;
+}
+
+
 table.evaluation {
 	margin: 0.3em 0.5em 0.3em 0.5em;
 }

Modified: waska/trunk/waskaweb/templates/main.mako
===================================================================
--- waska/trunk/waskaweb/templates/main.mako	2009-11-27 07:36:03 UTC (rev 710)
+++ waska/trunk/waskaweb/templates/main.mako	2009-11-27 13:10:03 UTC (rev 711)
@@ -73,9 +73,9 @@
       % endif
       <h1>${_('Auswertungen')}</h1>
       <ul>
-        ##<li><a href="${h.url_for(controller='/evaluate', action='evaluateBasic')}">Fortschreibung</a></li>
-        <li><a href="${h.url_for(controller='/evaluate', action='evaluateAdele')}">Verwendungsnachweis</a></li>
-        <li><a href="${h.url_for(controller='/evaluate', action='evaluate', id=1, reset=1)}"> ${_('cm_actions_link_evaluate')}</a></li>
+        % for eval in g.mpuls_config.get('evaluations', 'enabled'): 
+        <li><a href="/evaluate/evaluate/${eval.get('id')}">${eval.get('name')}</a></li>
+        % endfor
         %if session.get('hascaseerrors'):
         <li><a href="${h.url_for(controller='/case_overview', action='listBadCases')}">Inkonsistente Fallakten</a></li>
         %endif



More information about the Mpuls-commits mailing list