[Mpuls-commits] r212 - in waska/trunk: . waskaweb/controllers waskaweb/lib waskaweb/model waskaweb/templates/casemanagement
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Thu Oct 30 10:28:34 CET 2008
Author: teichmann
Date: 2008-10-30 10:28:33 +0100 (Thu, 30 Oct 2008)
New Revision: 212
Removed:
waska/trunk/waskaweb/lib/pdfimporter.py
Modified:
waska/trunk/ChangeLog.txt
waska/trunk/waskaweb/controllers/case.py
waska/trunk/waskaweb/lib/app_globals.py
waska/trunk/waskaweb/model/case.py
waska/trunk/waskaweb/templates/casemanagement/upload.mako
Log:
Removed PDF import.
Modified: waska/trunk/ChangeLog.txt
===================================================================
--- waska/trunk/ChangeLog.txt 2008-10-24 13:01:02 UTC (rev 211)
+++ waska/trunk/ChangeLog.txt 2008-10-30 09:28:33 UTC (rev 212)
@@ -1,3 +1,14 @@
+2008-10-30 Sascha L. Teichmann <sascha.teichmann at intevation.de>
+
+ Removed PDF import.
+
+ * waskaweb/lib/pdfimporter.py: Deleted, no longer required.
+ * waskaweb/model/case.py: Removed call to pdfimporter
+ * waskaweb/controllers/case.py: Removed controller to handle imports.
+ * waskaweb/lib/app_globals.py: Removed configuration for pdf2xfa
+ * waskaweb/templates/casemanagement/upload.mako: Removed GUI for
+ PDF import.
+
2008-10-24 Torsten Irlaender <torsten.irlaender at intevation.de>
Fixed issue 618
Modified: waska/trunk/waskaweb/controllers/case.py
===================================================================
--- waska/trunk/waskaweb/controllers/case.py 2008-10-24 13:01:02 UTC (rev 211)
+++ waska/trunk/waskaweb/controllers/case.py 2008-10-30 09:28:33 UTC (rev 212)
@@ -534,36 +534,6 @@
return render('/casemanagement/upload.mako')
@checkRole('cm_ka')
- def importAction(self):
- factory = CaseFactory()
- try:
- pdf = request.POST['pdffile']
- case = factory.importPdf(pdf)
- pdf.file.close()
- # Check if the file should be anonymized directly after the import
- if request.POST.get('anonymize'):
- if case.getState().setState(4):
- c.success_for = IMPORT_ANON_SUCCESS
- c.success_text = IMPORT_ANON_SUCCESS_TEXT
- c.url_ok = h.url_for(controller="/case_overview")
- # TODO: Initialisation must be done :( maybe we coud change
- # this?)
- case = self.__init_case(case.id)
- return render('/casemanagement/dialogs/success_import_anon.mako')
- else:
- return self.select(str(case.id), "0")
- except ImportCaseExistsError, err:
- c.failed_for = PDF_DUB_NOTIFICATION
- c.failed_text = PDF_DUB_NOTIFICATION_TEXT % err.value
- c.url_ok = "/case/importCase"
- return render('/casemanagement/dialogs/notificate_import_dub.mako')
- except:
- c.failed_for = IMPORT_FAILED
- c.failed_text = IMPORT_FAILED_TEXT
- c.url_ok = "/case/importCase"
- return render('/casemanagement/dialogs/failed_anonymize.mako')
-
- @checkRole('cm_ka')
def importXMLAction(self):
factory = CaseFactory()
try:
Modified: waska/trunk/waskaweb/lib/app_globals.py
===================================================================
--- waska/trunk/waskaweb/lib/app_globals.py 2008-10-24 13:01:02 UTC (rev 211)
+++ waska/trunk/waskaweb/lib/app_globals.py 2008-10-30 09:28:33 UTC (rev 212)
@@ -29,7 +29,6 @@
from waskaweb.lib.formular_help import HelpProvider
import waskaweb.lib.security as security
-import waskaweb.lib.pdfimporter as pdfimporter
from waskaweb.lib.timelog import setupTimeLogging
@@ -88,13 +87,6 @@
if not dbname is None: security.DBNAME = u"%s" % dbname
if not user is None: security.USER = u"%s" % user
- # data for pdf2xfa connections
- pdf_host = config.get('pdf2xfa_host')
- pdf_port = config.get('pdf2xfa_port')
-
- if not pdf_host is None: pdfimporter.HOST = pdf_host
- if not pdf_port is None: pdfimporter.PORT = int(pdf_port)
-
# set time logging
time_host = config.get('time_host')
time_port = config.get('time_port')
Deleted: waska/trunk/waskaweb/lib/pdfimporter.py
===================================================================
--- waska/trunk/waskaweb/lib/pdfimporter.py 2008-10-24 13:01:02 UTC (rev 211)
+++ waska/trunk/waskaweb/lib/pdfimporter.py 2008-10-30 09:28:33 UTC (rev 212)
@@ -1,876 +0,0 @@
-# -*- 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:
-# Sascha L. Teichmann <teichmann at intevation.de>
-#
-import socket
-
-from xml.dom.minidom import parse, parseString
-
-from waskaweb.model.nodecomponents import Leaf, Node, VISIT_CONTINUE, VISIT_IGNORE_CHILDREN
-
-import waskaweb.model.data as data
-from waskaweb.model.semantic import convertFromDescription, SematicError
-
-import sys
-import traceback
-
-HOST = "192.168.11.17"
-PORT = 1111
-
-#massnahme1_tbl:
-# no page
-
-#rg_beherrschung_sprache_tbl:
-# no page
-
-TBL_TO_PAGES = {
- 'master_tbl': [
- "page_einverstaendnis",
- "page_0",
- "page_25",
- "page_1",
- "page_2",
- "page_3",
- "page_4",
- "page_5",
- "page_6",
- "page_7",
- "page_10",
- "page_15",
- "page_16",
- "page_17",
- "page_18",
- "page_19",
- "page_20" ],
- 'rg_kompetenzfestellung_tbl': [
- "page_8",
- "page_9",
- "page_26",
- "page_27",
- "page_28",
- "page_29" ],
- 'rg_angebote_bildenden_bereich_tbl': [
- "page_21" ],
- 'rg_angebote_berufsvorbereitung_tbl': [
- "page_22" ],
- 'rg_angebote_berufliche_qualifizierung_tbl': [
- "page_23" ],
- 'rg_angebote_lebensbewaeltigung_tbl': [
- "page_24" ],
-}
-
-
-UNTERSTUETZUNGS_ANGEBOTE = [
- (u"rg_angebote_bildenden_bereich",
- u"Unterstützungsangebote_%d_im_allgemein_bildenden_Bereich",
- u"page_21"),
-
- (u"rg_angebote_berufsvorbereitung",
- u"Unterstützungsangebote_%d_im_Bereich_der_Berufsvorbereitung",
- u"page_22"),
-
- (u"rg_angebote_berufliche_qualifizierung",
- u"Unterstützungsangebote_%d_im_Bereich_der_beruflichen_Qualifizierung",
- u"page_23"),
-
- (u"rg_angebote_lebensbewaeltigung",
- u"Unterstützungsangebote_%d_im_Bereich_der_Lebensbewältigung",
- u"page_24")
-]
-
-# This list models the fact that some XFA fields are mapped
-# to other FormEd tree fields.
-
-REMAP_TO_OTHER = [
- (u"Maßnahme_Nennung", u"Vermittlung_Nennung"),
- (u"Ausbildung_Nennung", u"Vermittlung_Nennung"),
- (u"Arbeit_Nennung", u"Vermittlung_Nennung"),
- (u"Schule_Nennung", u"Vermittlung_Nennung"),
- (u"Sonstiges_Nennung", u"Vermittlung_Nennung"),
- (u"allgemein_bildender_Bereich_Kulturtechniken", u"bildender_Bereich"),
- (u"ausbildungsbezogene_Kompetenzen", u"Bereich_Berufsvorbereitung"),
- (u"arbeitsweltbezogene_Kompetenzen", u"Bereich_berufliche_Qualifizierung"),
- (u"personalesoziale_Kompetenzen", u"Bereich_Lebensbewältigung"),
- (u"Kompetenzagentur", u"Kundennummer")
-]
-
-# There are a number of combo boxes in the PDFs which are
-# modelled in FormEd as a choice with an extra text field.
-
-COMBO_BOX_CONVERSION = set([
- u"Sprache1",
- u"Sprache2",
- u"Sprache3",
- u"Schulabschlusserwerbsland",
- u"Muttersprache",
- u"Staatsangehörigkeit",
- u"Geburtsland"
-])
-
-# In v1.0 'Aufenthaltsstatus' is named 'Familienstand' so
-# we have to check if a given value is a valid value for
-# 'Familienstand' or 'Aufenthaltsstatus'
-
-def checkFamily(fe, name, value):
- try:
- widget = fe.formularname2widgets[u'Familienstand'][0]
- convertFromDescription(widget, value)
- # if this works we have a valid Familienstand value
- return u'Familienstand'
- except (KeyError, IndexError, SematicError), err:
- pass
-
- try:
- widget = fe.formularname2widgets[u'Aufenthaltsstatus'][0]
- convertFromDescription(widget, value)
- # if this works we have a valid Aufenthaltsstatus value
- return u'Aufenthaltsstatus'
- except (KeyError, IndexError, SematicError), err:
- pass
-
- return name
-
-# to be prepared to have other cases like this
-# we map it over a dictionary.
-PRE_INSPECT = {
- 'Familienstand': checkFamily
-}
-
-# TODO: fetch from config file
-
-def asXFA(buf, host=None, port=None):
-
- if host is None: host = HOST
- if port is None: port = PORT
-
- s = None, None
- out = []
- l = len(buf)
- try:
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((host, port))
-
- s.sendall("%d " % l)
- s.sendall(buf)
-
- while True:
- block = s.recv(4096)
- if not block: break
- out.append(block)
- finally:
- if s:
- try: s.close()
- except: pass
-
- return parseString("".join(out))
-
-def allWidgets(formedTree):
- """extracts all widgets from a FormEd tree in form
- of dictionary:
- formular name -> list of widgets
- """
-
- widgets = {}
-
- def visitor(nc):
- if isinstance(nc, Node):
- if isinstance(nc, (data.RadioNode, data.ChoiceNode)):
- widgets.setdefault(nc.getFormularName(), []).append(nc)
- return VISIT_IGNORE_CHILDREN
- elif isinstance(nc, Leaf) and not isinstance(nc,
- (data.RuleLeaf, data.ExternalChoiceListLeaf, data.InfoLeaf)):
- widgets.setdefault(nc.getFormularName(), []).append(nc)
-
- return VISIT_CONTINUE
-
- formedTree.root.visit(visitor)
-
- for k, v in REMAP_TO_OTHER:
- try:
- widgets.setdefault(k, []).extend(widgets[v])
- except KeyError:
- pass
-
- return widgets
-
-def xfaContext(element):
- return element.parentNode.nodeName
-
-def findRelationName(widget):
- parent = widget.parent
-
- while parent:
- if isinstance(parent, data.PageNode) or \
- isinstance(parent, data.GroupNode) and parent.isRepeat():
- return parent.getName()
- parent = parent.getParent()
-
- return None
-
-def widgetContext(widget):
- parent = widget.getParent()
- while parent:
- fname = parent.getFormularName()
- if fname: return fname
- parent = parent.parent
- return None
-
-def _out(x):
- if type(x) == type(u""): return x
- if type(x) == type(""): return unicode(x, "latin1")
- return str(x)
-
-class Relation:
-
- def __init__(self, name, separate = False):
- self.name = name
- self.columns = []
- self.separate = separate
-
- def add(self, widget, value):
- widget_name = widget.getName()
- for w, v in self.columns:
- if w.getName() == widget_name:
- return
- self.columns.append([widget, value])
-
- def getColumn(self, name):
- for w, v in self.columns:
- if w.getName() == name:
- return v
- raise KeyError("No such column")
-
- def dump(self):
- out = [u"Relation: %s" % self.name]
- for column in self.columns:
- try:
- out.append(u" '%s': '%s'" % (column[0].getName(), _out(column[1])))
- except UnicodeEncodeError:
- out.append(u" Kodierungsfehler fuer '%s'" % repr(column[1]))
- return u"\n".join(out)
-
- def isEmpty(self):
- return len(self.columns) == 0
-
- def sqlUpdate(self, con, mid):
-
- if not self.columns:
- print >> sys.stderr, "No columns in relation '%s'" % self.name
- return
-
- sets = u", ".join([u"%s=%%(%s)s" % (c[0].getName(), c[0].getName()) for c in self.columns])
- stmnt = u"UPDATE %s_view SET %s where id = %%(id)s" % (self.name, sets)
- fields = dict([(c[0].getName(), c[1]) for c in self.columns])
- fields['id'] = int(mid)
-
- #print >> sys.stderr, "%s" % str(stmnt)
-
- cur = None
- try:
- cur = con.cursor()
- cur.execute(stmnt, fields)
- con.commit()
- finally:
- if cur:
- try: cur.close()
- except: pass
-
- def typeConvert(self, fe):
- to_remove = []
- new_columns = []
- for column in self.columns:
- try:
- column[1] = convertFromDescription(column[0], column[1])
- except SematicError, err:
- # check if we have to handle the combo box case
- name = column[0].getFormularName()
- if name in COMBO_BOX_CONVERSION:
- sonstige_nennung = "%s_sonstige_nennung" % name
- try:
- widget = fe.formularname2widgets[sonstige_nennung][0]
- except:
- fe.addMessage("Kann Textfeld von Combobox '%s' nicht finden" % name)
- to_remove.insert(0, column)
- continue
-
- new_column = [widget, column[1]]
- try:
- new_column[1] = convertFromDescription(new_column[0], new_column[1])
- except SematicError, err:
- fe.addMessage("Combobox Text fuer '%s' fehlerhaft");
- to_remove.insert(0, column)
- continue
- # XXX: 'Sonstiges' is -2 by convention. It may be better solution
- # to run through the descriptions to figure out the real value.
- column[1] = -2
- new_columns.append(new_column)
- else:
- to_remove.insert(0, column)
- for d in to_remove:
- self.columns.remove(d)
-
- self.columns.extend(new_columns)
-
- def __repr__(self):
- return "Relation: " + str(self.name)
-
-def pagesToTbl():
- p2t = {}
- for t, pages in TBL_TO_PAGES.iteritems():
- for p in pages:
- p2t[p] = t
- return p2t
-
-PAGES_TO_TBL = pagesToTbl()
-
-class PDFImportException(Exception):
-
- def __init__(self, value):
- self.value = value
-
- def __str__(self):
- return repr(self.value)
-
-
-class ContextAction:
- def __init__(self, name, parent_name=None):
- self.name = name
- self.parent_name = parent_name
-
- def enter(self, xfa_traverser, element):
- pass
-
- def consume(self, xfa_traverser, element, value):
- pass
-
- def exit(self, xfa_traverser, element):
- pass
-
-class StandardContext(ContextAction):
- def __init__(self, name):
- ContextAction.__init__(self, name)
-
- def consume(self, xfa_traverser, element, value):
- # redirect to XFAExtractor
- xfa_traverser.fieldExtractor.consume(element, value)
-
-class Unterstuetzungsangebot(ContextAction):
- def __init__(self, name, relation, context):
- ContextAction.__init__(self, name)
- self.relation = relation
- self.context = context
-
- def enter(self, xfa_traverser, element):
- pass
- #xfa_traverser.fieldExtractor.addMessage(u"enter %s" % self.name)
-
- def consume(self, xfa_traverser, element, value):
- # redirect to XFAExtractor and use our special relation
- xfa_traverser.fieldExtractor.consume(
- element, value, self.context, self.relation)
-
- def exit(self, xfa_traverser, element):
- pass
- #xfa_traverser.fieldExtractor.addMessage(u"exit %s" % self.name)
-
-# XXX: This is a workaround due to the fact that 'Sozioökonomische_Lage'
-# is modeled in 1.x (x > 0) different than 1.0.
-SOZIO_OEKO = {
- u"versicherungspflichtig": 2,
- u"geringfuegig": 2,
- u"selbststaendig": 2,
- u"Arbeitslosengeld1": 3,
- u"Arbeitslosengeld2": 3,
- u"Eltern": 4,
- u"Unterhaltszahlungen": 3,
- u"Erziehungsgeld": 3,
- u"Krankengeld": 3,
- u"Unterstützung_Partner": 4,
- u"Elterngeld": 3
-}
-
-SOZIO_TARGET = [
- u"Familie_selbstständig",
- u"Familie_staatliche_Unterstützung",
- u"Jugendlicher_selbstständig",
- u"Jugendlicher_staatliche_Unterstützung",
- u"Jugendlicher_Unterstützung_soziales_Umfeld" ]
-
-class SozioOekonomischLage(ContextAction):
- def __init__(self, name):
- ContextAction.__init__(self, name)
- self.mapping = [None] * len(SOZIO_OEKO)
-
- def enter(self, xfa_traverser, element):
- pass
- #xfa_traverser.fieldExtractor.addMessage(u"enter %s" % self.name)
-
- def consume(self, xfa_traverser, element, value):
- fe = xfa_traverser.fieldExtractor
-
- idx = SOZIO_OEKO.get(element.nodeName)
- if not idx is None:
- value = value.lower()
- if value == "ja" or value == "1":
- self.mapping[idx] = True
- elif value == "nein" or value == "0" and self.mapping[idx] is None:
- self.mapping[idx] = False
- else:
- fe.consume(element, value)
-
- def exit(self, xfa_traverser, element):
- fe = xfa_traverser.fieldExtractor
- for idx, flag in enumerate(self.mapping):
- if not flag is None:
- flag = flag and "1" or "0"
- try:
- match = fe.formularname2widgets[SOZIO_TARGET[idx]][0]
- fe.addToRelation(match, flag)
- except (IndexError, KeyError):
- fe.addMessage(u"Kann Feld '%s' nicht finden" % SOZIO_TARGET[idx])
- #fe.addMessage(u"exit %s" % self.name)
-
-# XXX: This is a workaround due to the fact that we
-# modeled 'Sorgeberechtigte' as a Choice in FormEd
-# not as list of individual boolean fields.
-SORGEBERECHTIGTE = set([
- u"Mutter_Vater",
- u"Mutter",
- u"Vater",
- u"Amtsvormund",
- u"andere_Verwandte",
- u"Pflegefamilie"])
-
-class FamiliaereSituation(ContextAction):
- def __init__(self, name):
- ContextAction.__init__(self, name)
- self.sorgeberechtigte = None
-
- def enter(self, xfa_traverser, element):
- pass
- #xfa_traverser.fieldExtractor.addMessage(u"enter %s" % self.name)
-
- def consume(self, xfa_traverser, element, value):
- fe = xfa_traverser.fieldExtractor
- if element.nodeName in SORGEBERECHTIGTE:
- value = value.lower()
- if value == "ja" or value == "1":
- if not self.sorgeberechtigte is None:
- fe.addMessage(u" Mehrfache Nennung von Sorgeberechtigten!")
- else:
- self.sorgeberechtigte = element.nodeName
- else:
- fe.consume(element, value)
-
- def exit(self, xfa_traverser, element):
- fe = xfa_traverser.fieldExtractor
- if not self.sorgeberechtigte is None:
- try:
- match = fe.formularname2widgets[u"Familiäre_Situation"][0]
- #fe.addMessage(" Sorgeberechtigte: %s" % self.sorgeberechtigte)
- fe.addToRelation(match, self.sorgeberechtigte)
- except (IndexError, KeyError):
- fe.addMessage(u"Kann Feld 'Familiäre_Situation' nicht finden")
- #fe.addMessage(u"exit %s" % self.name)
-
-# XXX: This is a workaround due to the fact that we
-# modeled 'Beratungsbedarf' as a Choice in FormEd
-# with on attached text field and not as a radiogroup
-# with text fields for every radio item.
-WELCHE_MASSNAHME = {
- u"welche_Maßnahme": u"selbständig",
- u"welche_Ausbildung": u"Ausbildung",
- u"welche_Arbeit": u"Arbeit" }
-
-class Beratungsbedarf(ContextAction):
- def __init__(self, name):
- ContextAction.__init__(self, name)
- self.text = None
- self.choice = None
-
- def enter(self, xfa_traverser, element):
- pass
- #xfa_traverser.fieldExtractor.addMessage(u"enter %s" % self.name)
-
- def consume(self, xfa_traverser, element, value):
- fe = xfa_traverser.fieldExtractor
- #fe.addMessage(u"'%s' -> '%s'" % (element.nodeName, value))
-
- alternative = WELCHE_MASSNAHME.get(element.nodeName)
- if not alternative is None:
- if not self.text is None:
- fe.addMessage(u"Mehrfache Nennung einer Beratungsbedarfsmaßnahme")
- else:
- #fe.addMessage(" setze Alternative '%s'" % alternative)
- self.text = value
- self.choice = alternative
- else:
- fe.consume(element, value)
-
- def exit(self, xfa_traverser, element):
- fe = xfa_traverser.fieldExtractor
- if not self.text is None:
- try:
- match = fe.formularname2widgets[u"welche_vermittlung_nennung"][0]
- fe.addToRelation(match, self.text)
- except (IndexError, KeyError):
- fe.addMessage(u"Kann Feld 'welche_vermittlung_nennung' nicht finden")
-
- try:
- match = fe.formularname2widgets[u"Begleitung"][0]
- fe.addToRelation(match, self.choice)
- except (IndexError, KeyError):
- fe.addMessage(u"Kann Feld 'Begleitung' nicht finden")
- #fe.addMessage(u"exit %s" % self.name)
-
-# In case we find the field 'Optionsfeldliste' we have to check
-# if its value is explicit 'ja'. 'nein' is interpreted as 'noch nicht'.
-class EinverstaendnisErklaerung(ContextAction):
- def __init__(self, name):
- ContextAction.__init__(self, name)
- self.value = None
-
- def enter(self, xfa_traverser, element):
- pass
- #xfa_traverser.fieldExtractor.addMessage(u"enter %s" % self.name)
-
- def consume(self, xfa_traverser, element, value):
- fe = xfa_traverser.fieldExtractor
-
- if element.nodeName == u"Optionsfeldliste":
- if value.lower() == "ja":
- self.value = "ja"
- else:
- fe.consume(element, value)
-
- def exit(self, xfa_traverser, element):
- fe = xfa_traverser.fieldExtractor
- if not self.value is None:
- try:
- match = fe.formularname2widgets[u"Optionsfeldliste"][0]
- fe.addToRelation(match, self.value)
- except (IndexError, KeyError):
- fe.addMessage(u"Kann Feld 'Optionsfeldliste' nicht finden")
-
- #fe.addMessage(u"exit %s" % self.name)
-
-# In v1.0 there are fields which ask for the concrete birth countries
-# of father and mother. We are modelling only if they were born in
-# Germany or not.
-class ElternteilAusDeutschland(ContextAction):
-
- def __init__(self, name):
- ContextAction.__init__(self, name, u"Formular1")
-
- def consume(self, xfa_traverser, element, value):
- fe = xfa_traverser.fieldExtractor
-
- if element.nodeName == u'Geburtsland_%s' % self.name:
- try:
- if not value: return
- found = None
- for parent in fe.formularname2widgets[self.name]:
- if parent.getParent().getName() == u"sonstigeangaben":
- found = parent
- break
- if found is None:
- raise KeyError()
-
- value = value.lower() == u"deutschland" and u"Ja" or u"Nein"
- fe.addToRelation(found, value)
-
- except (KeyError, IndexError):
- fe.addMessage(u"Konnte Kontext für %s nicht finden" % self.name)
- else:
- fe.consume(element, value)
-
-class XFATraverser:
-
- def __init__(self, fieldExtractor):
- self.fieldExtractor = fieldExtractor
- self.contextActions = {}
- self.stack = None
-
- def addContextAction(self, contextAction):
- self.contextActions[contextAction.name] = contextAction
-
- def __recursiveTraverse(self, element):
-
- # look if have special treatment for this context
- contextAction = self.contextActions.get(element.nodeName)
-
- if contextAction:
- parent_name = contextAction.parent_name
- if not parent_name is None:
- parent_node = element.parentNode
- if not parent_node or parent_node.nodeName != parent_name:
- contextAction = None
-
- if contextAction:
- self.stack.append(contextAction)
- contextAction.enter(self, element)
-
- text = []
- for child in element.childNodes:
- if child.nodeType == child.TEXT_NODE:
- text.append(child.data)
- else:
- self.__recursiveTraverse(child)
-
- # found an item -> feed to topmost context
- if len(text) and len(text) == len(element.childNodes):
- text = u"".join(text).strip()
- if text: self.stack[-1].consume(self, element, text)
-
- if contextAction:
- contextAction.exit(self, element)
- self.stack.pop()
-
- def traverse(self, xfaTree, stdContext):
- base = None
- for r in ['Formular1', 'Case_Management', 'root']:
- x = xfaTree.getElementsByTagName(r)
- if x:
- base = x[0]
- break
-
- if not base:
- raise PDFImportException("Keine Formulardaten gefunden")
-
- self.stack = [ stdContext ]
- stdContext.enter(self, None)
- self.__recursiveTraverse(base)
- self.stack.pop().exit(self, None)
-
-class FieldExtractor:
-
- def __init__(self, formedTree):
- self.formularname2widgets = allWidgets(formedTree)
- self.messages = []
- self.relations = {}
- self.missingFields = []
- self.extraRelations = []
-
- def preInspect(self, name, value):
- checker = PRE_INSPECT.get(name)
- if checker is None:
- return name
-
- return checker(self, name, value)
-
- def consume(self, xfa_element, value, context=None, relation=None):
-
- try:
- widgets = self.formularname2widgets[
- self.preInspect(xfa_element.nodeName, value)]
- except KeyError:
- self.addMissingField(xfa_element, value)
- return
-
- if len(widgets) == 1: # unique -> no need to check contexts
- match = widgets[0]
- else:
- # Need XFA context to figure out which one is really meant.
- if context: # if forced use this one
- pdfContext = context
- else:
- pdfContext = xfaContext(xfa_element)
-
- if pdfContext is None:
- self.addMessage(
- u"Kann PDF-Kontext für '%s' nicht finden. Wert: '%s'" % (xfa_element.nodeName, value))
- return
-
- match = None
- for widget in widgets:
- formedContext = widgetContext(widget)
- if formedContext == pdfContext:
- match = widget
- break
-
- if match is None:
- self.addMessage(
- u"Kann Widget-Kontext für '%s' nicht finden. Wert: '%s'" % (xfa_element.nodeName, value))
- return
-
- if relation is None:
- self.addToRelation(match, value)
- else:
- relation.add(match, value)
-
- def addToRelation(self, widget, value):
- relationName = findRelationName(widget)
-
- if relationName is None:
- self.addMessage(
- u"Kann keine zu '%s' passende Relation finden." % widget.getName())
- return
- try:
- relation = self.relations[relationName]
- except KeyError:
- relation = Relation(relationName)
- self.relations[relationName] = relation
-
- relation.add(widget, value)
-
- def addMissingField(self, element, value):
- self.missingFields.append((element, value))
-
- def missingFieldsAsString(self):
- missing = []
- for x in self.missingFields:
- try:
- missing.append(unicode(str(x[0].nodeName), 'ascii', 'replace'))
- except:
- pass
-
- try:
- return u", ".join(missing)
- except:
- return u""
-
- def requiredTables(self):
- """ returns a list of
- (table entry to create,
- list of relations to be stored under this id,
- True/False to indicate if separate)
- """
-
- tables = []
-
- for relation in list(self.relations.itervalues()) + self.extraRelations:
-
- if relation.isEmpty(): # no need for empty relations
- continue
-
- try:
- name = PAGES_TO_TBL[relation.name]
- except KeyError:
- print >> sys.stderr, "Relation '%s' has no table" % relation.name
- continue
-
- if relation.separate: # need a separate table entry
-
- tables.append((name, [relation], True))
-
- else: # try to reuse an already created table entry
- found = None
- for tname, l, flag in tables:
- if tname == name:
- found = l
- break
-
- if found is None:
- l = []
- tables.append((name, l, False))
-
- l.append(relation)
-
- return tables
-
- def sqlUpdateTables(self, dbPool, tbl2id):
- #print >> sys.stderr, "tbl2id: " + str(tbl2id)
- for relation in self.relations.itervalues():
- if not relation.isEmpty():
- try:
- tbl = list(PAGES_TO_TBL[relation.name])[0]
- id = tbl2id[tbl]
- except KeyError:
- print >> sys.stderr, "No id found for relation '%s'" % relation.name
- continue
- relation.sqlUpdate(dbPool, id)
-
- def addMessage(self, msg):
- self.messages.append(msg)
-
- def allMessages(self):
- return u"\n".join(self.messages)
-
- def typeConvert(self):
-
- for relation in self.extraRelations:
- relation.typeConvert(self)
-
- for relation in self.relations.itervalues():
- relation.typeConvert(self)
-
- def dump(self):
- out = []
- for relation in self.extraRelations:
- if not relation.isEmpty():
- out.append(relation.dump())
- out.append("")
-
- for relation in self.relations.itervalues():
- if not relation.isEmpty():
- out.append(relation.dump())
- out.append("")
- self.addMessage("\n".join(out))
-
- def extractFields(self, xfaTree):
-
- xfaTraverser = XFATraverser(self)
-
- for relation, pattern, page in UNTERSTUETZUNGS_ANGEBOTE:
- for i in range(1, 4):
- context = pattern % i
- # create a separate relation
- rel = Relation(page, True)
- self.extraRelations.append(rel)
- angebot = Unterstuetzungsangebot(context, rel, relation)
- xfaTraverser.addContextAction(angebot)
-
- familiaereSituation = FamiliaereSituation(u"Familiäre_Situation")
- beratungsbedarf = Beratungsbedarf(u"Beratungsbedarf")
- sozioOeko = SozioOekonomischLage(u"Sozioökonomische_Lage")
- einverstaendnis = EinverstaendnisErklaerung(u"Text")
- mad = ElternteilAusDeutschland(u"Mutter")
- vad = ElternteilAusDeutschland(u"Vater")
-
- xfaTraverser.addContextAction(familiaereSituation)
- xfaTraverser.addContextAction(beratungsbedarf)
- xfaTraverser.addContextAction(sozioOeko)
- xfaTraverser.addContextAction(einverstaendnis)
- xfaTraverser.addContextAction(mad)
- xfaTraverser.addContextAction(vad)
-
- stdContext = StandardContext("")
- xfaTraverser.traverse(xfaTree, stdContext)
-
- #self.addMessage("\nKonversionsfehler:");
- self.typeConvert()
- #self.addMessage("\nAnzahl Felder, die nicht im FormEd-Baum gefunden wurden: %d" % len(self.missingFields))
- #self.addMessage(" %s\n" % ",\n ".join([x[0].nodeName for x in self.missingFields]))
- #self.dump()
- #if self.missingFields:
- # try:
- # print >> sys.stderr, "Missing fields: %s" % self.missingFieldsAsString()
- # except:
- # traceback.print_exc(file=sys.stderr)
-
-# vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
Modified: waska/trunk/waskaweb/model/case.py
===================================================================
--- waska/trunk/waskaweb/model/case.py 2008-10-24 13:01:02 UTC (rev 211)
+++ waska/trunk/waskaweb/model/case.py 2008-10-30 09:28:33 UTC (rev 212)
@@ -46,7 +46,6 @@
from waskaweb.lib.xmlexport import exportAsXML
from waskaweb.lib.base import session, g, h, config
import waskaweb.lib.filters as F
-from waskaweb.lib.pdfimporter import asXFA, FieldExtractor
from waskaweb.model.user import UserObject
from waskaweb.model.agencysettings import Agency
from waskaweb.model.repeatgroup import AidList, CREATE_RG_BILDEN_DS,CREATE_RG_LEBEN_DS, CREATE_RG_QUALI_DS, CREATE_RG_BERUF_DS
@@ -405,38 +404,6 @@
case.privacy_statement_signed = einverst in (1, -1) and True or False
return case
- def importPdf(self, pdf):
-
- # XXX: We are loading it all into memory. This is bad -> DoS
- buf = StringIO.StringIO()
- shutil.copyfileobj(pdf.file, buf)
- b = buf.getvalue()
- buf.close()
-
- fe = FieldExtractor(g.formedTree)
-
- xfa = None
- try:
- xfa = asXFA(b)
- #print >> sys.stderr, "XFA fetched"
- fe.extractFields(xfa)
- finally:
- if xfa:
- xfa.unlink()
- xfa = None
-
- tbls = fe.requiredTables()
-
- knummer = self._fetchKundennummerFromPDF(tbls)
-
- if not knummer is None:
- in_db = self._caseExists(knummer)
- if in_db:
- raise ImportCaseExistsError(knummer)
-
- new_case_id = self._createTablesForImport(tbls)
- return self.loadById(new_case_id)
-
def createNew(self, init=True, uuid=None):
'''This method creates a new case in the database and takes care about
creating the right dependencies for repeat groups. If 'init' is true
Modified: waska/trunk/waskaweb/templates/casemanagement/upload.mako
===================================================================
--- waska/trunk/waskaweb/templates/casemanagement/upload.mako 2008-10-24 13:01:02 UTC (rev 211)
+++ waska/trunk/waskaweb/templates/casemanagement/upload.mako 2008-10-30 09:28:33 UTC (rev 212)
@@ -9,20 +9,6 @@
<h1>${_('cm_header_import')}</h1>
<div id="waska_form" class="import_box">
-<h2>PDF-Import</h2>
-<p class="import_p">Es können Dateien im PDF-Format (.pdf) angegeben werden.<br>
-Die Größe einer Datei darf 10MB nicht überschreiten.</p>
-<div class="import_box_dialog">
-${h.form(h.url(action='importAction'), multipart=True)}
-<label class="import_label" for="pdffile"><strong class="import_number">1.</strong> Datei wählen:</label>
-${h.file_field('pdffile')}<br>
-<label class="import_label" for="anonymize"><strong class="import_number">2.</strong> ${h.check_box('anonymize')} Akte nach Import umgehend anonymisieren.</label>
-<br>
-<label class="import_label" for="pdfimport"><strong class="import_number">3.</strong> Datei importieren:</label>
-${h.submit(_('cm_from_import_submit'))}
-${h.end_form()}
-</div>
-
<h2>XML-Import</h2>
<p class="import_p">Es können Dateien im XML-Format (.xml) angegeben werden. <br>
Die Größe einer Datei darf 10MB nicht überschreiten.</p>
More information about the Mpuls-commits
mailing list