misc-fred/strasbourg/reprise.py

220 lines
7.8 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# fonctionnalités manquantes :
# - fieldset repeat
# - choicegroup (uniquement présent dans 104)
# - condition
import os
import sys
import xml.etree.ElementTree as ET
import csv
import wcs
from wcs.formdef import FormDef
from wcs.workflows import Workflow
from wcs import fields
def fix_encoding(x):
# their encoding process is real garbage, it looks like there's a
# broken post-processing step "beautifying" characters like quotes
# but it operates on latin1 bytes and fed utf8 bytes.
x = x.replace(u'\xc5\u2019', unicode('Œ', 'latin1'))
x = x.replace(u'\xc5\u201c', unicode('Œ', 'latin1'))
x = x.replace(u'\xc3\u201a', unicode('Â', 'latin1'))
x = x.replace(u'\xc3\u2030', unicode('É', 'latin1'))
x = x.replace(u'\xc3\u017d', unicode('Î', 'latin1'))
x = x.replace(u'\xc3\u20ac', unicode('À', 'latin1'))
x = x.replace(u'\xe2\u20ac\xa6', unicode('', 'latin1'))
x = x.replace(u'\xe2\u20ac\u2122', "'")
try:
return x.encode('raw_unicode_escape').decode('utf-8').encode('utf-8')
except:
import pdb; pdb.set_trace()
raise
tree = ET.parse(sys.argv[1])
root = tree.getroot()
formdef = FormDef()
formdef.name = fix_encoding(root.attrib['name'])
print formdef.name
try:
formdef = [x for x in FormDef.select() if x.name == formdef.name][0]
if formdef.category_id:
print ' skipped'
sys.exit(0)
except IndexError:
pass
formdef.fields = [
fields.PageField(id='1', type='page')
]
formdef.store() # this will clean the db
field_id = 1
first_fieldset = True
prefill = {
'_title': ['Civilité'],
'_first_name': ['Prénom'],
'_last_name': ['Nom'],
'_email': ['Courriel', 'Adresse e-mail', 'Adresse courriel', 'Adresse mail'],
'_zipcode': ['Code postal'],
'_city': ['Commune', 'Ville'],
'_phone': ['Téléphone', 'Téléphone (portable ou fixe)'],
'_mobile': ['Téléphone mobile'],
}
prefill_used = {}
regexes = {
'Code postal': r'\d+',
'Téléphone': r'\d+',
}
def process_children(node):
global field_id, first_fieldset
if 'repeat' in node.attrib:
formdef.fields.append(fields.CommentField(id=str(field_id),
type='comment',
label='<p><big>!!! Attention info qui peut se répéter plusieurs fois sur le formulaire d\'origine. (tableau de longueur libre possible ?)</big></p>'))
print '!!! fieldset repeat'
field_id += 1
children_nodes = node.getchildren()
for field_node in children_nodes:
field_id += 1
if field_node.tag in ('action', 'label'):
continue
if field_node.tag == 'title':
formdef.fields.append(fields.TitleField(id=str(field_id), type='title', label=fix_encoding(field_node.text)))
continue
if field_node.tag == 'htmlsection':
formdef.fields.append(fields.CommentField(id=str(field_id), type='comment', label='<div>%s</div>' % fix_encoding(field_node.text)))
continue
if field_node.tag == 'fieldset':
try:
if first_fieldset:
first_fieldset = False
formdef.fields.append(fields.TitleField(id=str(field_id),
type='title',
label=fix_encoding(field_node.find('label').attrib['plain'])))
formdef.fields[0].label = fix_encoding(field_node.find('label').attrib['plain'])
else:
formdef.fields.append(fields.PageField(id=str(field_id),
type='page',
label=fix_encoding(field_node.find('label').attrib['plain'])))
except AttributeError:
pass
process_children(field_node)
if node is root and len([x for x in children_nodes[children_nodes.index(field_node)+1:] if x.tag == 'fieldset']) == 0:
# no more fieldsets, create a new page to end the form
field_id += 1
formdef.fields.append(fields.PageField(id=str(field_id),
type='page',
label='Informations sur vos données personnelles'))
continue
if field_node.tag != 'field':
raise Exception('unhandled tag type: %r' % field_node.tag)
field_type = field_node.attrib['type']
validation = field_node.find('validation')
if validation is not None and validation.attrib.get('type') == 'validate-email':
field_type = 'email'
if validation is not None and validation.attrib.get('type') == 'validate-datecal':
field_type = 'date'
if field_type == 'hidden':
continue
if field_type == 'checkbox':
if len(field_node.findall('choices/choice')) > 1:
field_type = 'items'
field_klass = {
'textinput': fields.StringField,
'textarea': fields.TextField,
'email': fields.EmailField,
'checkbox': fields.BoolField,
'items': fields.ItemsField,
'radio': fields.ItemField,
'select1': fields.ItemField,
'date': fields.DateField,
'fileupload': fields.FileField,
}[field_type]
field = field_klass(id=str(field_id), type=field_klass.key,
label=fix_encoding(field_node.find('label').attrib['plain']))
formdef.fields.append(field)
if field_type == 'checkbox':
field.label = fix_encoding(field_node.findall('choices/choice/label')[0].attrib['plain'])
if field_type == 'radio':
field.show_as_radio = True
if validation is not None and validation.attrib.get('required') == 'required':
field.required = True
else:
field.required = False
if validation is not None and validation.attrib.get('type') == 'validate-integer':
field.validation = r'\d+'
if validation is not None and validation.attrib.get('type') == 'validate-custom':
if validation.text:
assert field_type == 'textinput'
field.validation = fix_encoding(validation.text[1:-1])
for label in regexes:
if field.label.startswith(label):
field.validation = regexes.get(label)
if field_node.attrib.get('size'):
size = field_node.attrib['size']
assert size.endswith('px')
if len(field_node.findall('hint')):
field.hint = fix_encoding(field_node.find('hint').text or '')
if field_type in ('items', 'radio', 'select1'):
field.items = []
for choice in field_node.findall('choices/choice'):
field.items.append(fix_encoding(choice.find('label').attrib['plain']))
value = field_node.find('value')
if value is not None and value.text:
field.prefill = {'type': 'string', 'value': fix_encoding(value.text)}
else:
# prefill with user profile?
for key, field_names in prefill.items():
if key in prefill_used:
continue
if field.label in field_names:
field.prefill = {'type': 'user', 'value': key}
prefill_used[key] = True
process_children(root)
for line in csv.reader(file(os.path.join(os.path.dirname(sys.argv[1]), 'formulaires_prod_reprise_données.csv')),
delimiter=','):
if line[0] + '.xml' == os.path.basename(sys.argv[1]):
formdef.fields.insert(1,
fields.CommentField(id=str(field_id+2), type='comment',
label='<p>Origine: <a href="%s">%s</a></p>' % (line[7], line[7])))
formdef.workflow_options = {'email': line[8]}
break
for workflow in Workflow.select(ignore_migration=True, ignore_errors=True):
if workflow.name == 'Envoi email':
formdef.workflow_id = workflow.id
break
formdef.store()