passerelle/passerelle/contrib/greco/formdata.py

145 lines
4.5 KiB
Python

# Copyright (C) 2016 Entr'ouvert
#
# This program 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.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
def is_required(value):
if not value:
raise ValueError('is required')
return value
def to_datetime(value):
if not value:
return
return datetime.strptime(value[:19], '%Y-%m-%dT%H:%M:%S')
def default_to_now(value):
if not value:
return datetime.now()
return value
CREATION_SCHEMA = (
('iddemande', is_required),
('description', is_required),
('domaineobjettype', is_required),
('datecreation', to_datetime, default_to_now),
('datedepot', to_datetime, default_to_now),
('danger', bool),
'mediareponse',
'priorite',
'application',
'beneficiaire_civilite',
'beneficiaire_nom',
'beneficiaire_prenom',
'beneficiaire_email',
'beneficiaire_mobile',
'beneficiaire_telephone',
'beneficiaire_fax',
'beneficiaire_numerovoie',
'beneficiaire_voie',
'beneficiaire_codefuvvoie',
'beneficiaire_coderivolivoie',
'beneficiaire_complement',
'beneficiaire_codepostal',
'beneficiaire_commune',
'beneficiaire_organisation',
'beneficiaire_typetiers',
'localisation_numerovoie',
'localisation_voie',
'localisation_codefuvvoie',
'localisation_coderivolivoie',
'localisation_complement',
'localisation_commune',
'localisation_voiesecante',
'localisation_codefuvvoiesecante',
'localisation_coderivolivoiesecante',
'localisation_xgeoloc',
'localisation_ygeoloc',
'transmetteur_civilite',
'transmetteur_nom',
'transmetteur_prenom',
'transmetteur_email',
'transmetteur_mobile',
'transmetteur_telephone',
'transmetteur_fax',
'transmetteur_service',
)
def list_schema_fields(schema):
for fieldname in schema:
yield fieldname[0] if isinstance(fieldname, tuple) else fieldname
class FormData:
def __init__(self, formdata, schema):
if not isinstance(formdata, dict):
raise ValueError('formdata must be a dict')
if 'fields' in formdata and isinstance(formdata['fields'], dict):
values = formdata['fields']
if 'extra' in formdata:
values.update(formdata['extra'])
else:
values = formdata
# extract/create/validate fields according to schema
self.fields = {}
self.json = {}
for fieldname in schema:
if isinstance(fieldname, tuple):
value = values.get(fieldname[0])
for modifier in fieldname[1:]:
try:
value = modifier(value)
except ValueError as e:
raise ValueError('%s: %s' % (fieldname[0], e))
fieldname = fieldname[0]
else:
value = values.get(fieldname)
if value is not None:
self.fields[fieldname] = value
if isinstance(value, datetime):
value = value.strftime('%Y-%m-%dT%H:%M:%S')
if '_' not in fieldname:
self.json[fieldname] = value
continue
key, subkey = fieldname.split('_')
if key not in self.json:
self.json[key] = {}
self.json[key][subkey] = value
# https://dev.entrouvert.org/issues/75259
danger = self.json.get('danger', '')
if danger:
self.json['danger'] = 'true'
else:
self.json['danger'] = 'false'
# extract attachments
self.attachments = []
attachments = {
key: value
for key, value in values.items()
if isinstance(value, dict)
and ('filename' in value and 'content_type' in value and 'content' in value)
}
for key in sorted(attachments.keys()):
self.attachments.append(attachments[key])