186 lines
6.8 KiB
Python
186 lines
6.8 KiB
Python
#! /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
|
||
|
||
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-custom':
|
||
if validation.text:
|
||
assert field_type == 'textinput'
|
||
field.validation = fix_encoding(validation.text[1:-1])
|
||
|
||
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)}
|
||
|
||
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()
|