strasbourg: add script to convert their current forms to wcs

This commit is contained in:
Frédéric Péters 2017-07-09 20:17:06 +02:00
parent c177464260
commit b22a9cc784
1 changed files with 133 additions and 0 deletions

133
strasbourg/reprise.py Normal file
View File

@ -0,0 +1,133 @@
#! /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 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'])
try:
formdef = [x for x in FormDef.select() if x.name == formdef.name][0]
except IndexError:
pass
print formdef.name
formdef.fields = []
field_id = 0
def process_children(node):
global field_id
for field_node in node.getchildren():
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':
if 'repeat' in field_node.attrib:
print '!!! fieldset repeat'
try:
formdef.fields.append(fields.SubtitleField(id=str(field_id),
type='subtitle',
label=fix_encoding(field_node.find('label').attrib['plain'])))
except AttributeError:
pass
process_children(field_node)
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
field = {
'textinput': fields.StringField,
'textarea': fields.TextField,
'email': fields.EmailField,
'checkbox': fields.ItemField,
'radio': fields.ItemField,
'select1': fields.ItemField,
'date': fields.DateField,
'fileupload': fields.FileField,
}[field_type](id=str(field_id),
label=fix_encoding(field_node.find('label').attrib['plain']))
formdef.fields.append(field)
if field_type == 'radio':
field.show_as_radio = True
if validation is not None and validation.attrib.get('required') == 'required':
field.required = True
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 ('checkbox', 'radio', 'select1'):
field.items = []
for choice in field_node.findall('choices/choice'):
field.items.append(fix_encoding(choice.find('label').attrib['plain']))
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(0,
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
formdef.store()