559 lines
19 KiB
Python
559 lines
19 KiB
Python
#! /usr/bin/env python
|
|
|
|
import sys
|
|
import re
|
|
import random
|
|
import hashlib
|
|
|
|
class ShorterException(Exception):
|
|
pass
|
|
|
|
class LongerException(Exception):
|
|
pass
|
|
|
|
class Item:
|
|
def __init__(self, line, parent):
|
|
self.parent = parent
|
|
self.indent = len(re.findall(r'^\s*', line)[0]) + 1
|
|
self.text = line[self.indent+1:].strip()
|
|
self.elems = []
|
|
self.set_identifier()
|
|
if '{' in self.text:
|
|
self.massage_identifier()
|
|
|
|
def set_identifier(self):
|
|
self.identifier = 'x' + hashlib.md5(str(random.random())).hexdigest()[:10]
|
|
|
|
def feed(self, line):
|
|
if line.strip()[1] == ':': # command
|
|
if not line.startswith(' '*self.indent):
|
|
raise ShorterException()
|
|
raise LongerException()
|
|
self.text += '\n' + line.strip()
|
|
if '{' in self.text:
|
|
self.massage_identifier()
|
|
|
|
def massage_identifier(self):
|
|
self.identifier = re.findall (r'\{(.*)\}', self.text)[0]
|
|
if self.parent:
|
|
self.identifier = self.parent.identifier + '_' + self.identifier
|
|
self.text = self.text[:self.text.index('{')].strip()
|
|
|
|
def prt(self):
|
|
print ('\t'*self.indent) + 'text:' + repr(self.text)
|
|
for elem in self.elems:
|
|
elem.prt()
|
|
|
|
def as_schema_field(self):
|
|
return ''
|
|
|
|
def get_child_schema_fields(self):
|
|
return []
|
|
|
|
def get_child_schema_fields(self):
|
|
r = []
|
|
for child in self.elems:
|
|
if isinstance(child, Yes) or isinstance(child, No):
|
|
if child.text:
|
|
r.append(child.as_schema_field())
|
|
else:
|
|
for grandchild in child.elems:
|
|
r.append(grandchild.as_schema_field())
|
|
r.extend(grandchild.get_child_schema_fields())
|
|
else:
|
|
r.append(child.as_schema_field())
|
|
return r
|
|
|
|
|
|
class Question(Item):
|
|
def as_schema_field(self):
|
|
s = []
|
|
s.append('''
|
|
StringField(
|
|
name='%s',
|
|
widget=MasterSelectWidget(
|
|
label=u"""%s""",
|
|
slave_fields =
|
|
''' % (self.identifier, self.text))
|
|
|
|
for child in self.elems:
|
|
if isinstance(child, No):
|
|
if child.text:
|
|
slaves = "'%s'" % child.identifier
|
|
else:
|
|
slaves = ', '.join(["'%s'" % x.identifier for x in child.elems])
|
|
s.append(''' slaveFields('showIfNo', %s)''' % slaves)
|
|
elif isinstance(child, Yes):
|
|
if child.text:
|
|
slaves = "'%s'" % child.identifier
|
|
else:
|
|
slaves = ', '.join(["'%s'" % x.identifier for x in child.elems])
|
|
s.append(''' slaveFields('showIfYes', %s)''' % slaves)
|
|
else:
|
|
raise AssertionError('unhandled child: %r' % child)
|
|
if child is self.elems[-1]:
|
|
s.append(',')
|
|
else:
|
|
s.append(' + \\\n')
|
|
|
|
s.append('''
|
|
label_msgid='AvisLegis_%s',
|
|
i18n_domain='Avis',
|
|
),
|
|
enforceVocabulary=True,
|
|
required=True,\n''' % self.identifier)
|
|
if self.elems and isinstance(self.elems[0], Yes):
|
|
s.append(""" vocabulary='getResponses'\n""")
|
|
else:
|
|
s.append(""" vocabulary='getResponsesInversed'\n""")
|
|
s.append(' ),\n')
|
|
return ''.join(s)
|
|
|
|
class Answer(Item):
|
|
def set_identifier(self):
|
|
self.identifier = self.parent.identifier + '_analyse'
|
|
|
|
def as_schema_field(self):
|
|
return '''
|
|
TextField(
|
|
name='%s',
|
|
widget=TextAreaWidget(
|
|
label=u"Analyse",
|
|
label_msgid='Avis_label_%s',
|
|
i18n_domain='Avis',
|
|
),
|
|
default_output_type="text/html",
|
|
default=defaultAnalysisValues['%s']['%s']
|
|
),
|
|
''' % (self.identifier, self.identifier, self.identifier, self.default_answer)
|
|
|
|
|
|
class No(Answer):
|
|
default_answer = 'no'
|
|
|
|
def get_analysis_value(self):
|
|
return """
|
|
'%s': \\
|
|
{'yes': '',
|
|
'no' : u'''%s'''
|
|
},""" % (self.identifier, self.text)
|
|
|
|
class Yes(Answer):
|
|
default_answer = 'yes'
|
|
|
|
def get_analysis_value(self):
|
|
return """
|
|
'%s': \\
|
|
{'yes': u'''%s''',
|
|
'no' : ''
|
|
},""" % (self.identifier, self.text)
|
|
|
|
class Title(Item):
|
|
pass
|
|
|
|
class Subtitle(Item):
|
|
pass
|
|
|
|
class Comment(Item):
|
|
pass
|
|
|
|
|
|
def new_from_line(line, parent):
|
|
line0 = line.strip()[0]
|
|
if line0 == 'C':
|
|
return Comment(line, parent=parent)
|
|
if line0 == 'T':
|
|
return Title(line, parent=parent)
|
|
if line0 == 't':
|
|
return Subtitle(line, parent=parent)
|
|
if line0 == 'Q':
|
|
return Question(line, parent=parent)
|
|
if line0 == 'Y':
|
|
return Yes(line, parent=parent)
|
|
if line0 == 'N':
|
|
return No(line, parent=parent)
|
|
print 'unknown type:', line.strip()[0]
|
|
print repr(line)
|
|
|
|
def parse_file(filename):
|
|
elems = []
|
|
stack = []
|
|
for line in file(filename):
|
|
if not line.strip():
|
|
continue
|
|
try:
|
|
stack[-1].feed(line)
|
|
except IndexError: # empty stack
|
|
current_item = new_from_line(line, parent=None)
|
|
elems.append(current_item)
|
|
stack.append(current_item)
|
|
except ShorterException:
|
|
new_indent = len(re.findall(r'^\s*', line)[0])
|
|
while stack and stack[-1].indent > new_indent:
|
|
stack.pop()
|
|
if len(stack):
|
|
current_item = new_from_line(line, parent=stack[-1])
|
|
stack[-1].elems.append(current_item)
|
|
else:
|
|
current_item = new_from_line(line, parent=None)
|
|
elems.append(current_item)
|
|
stack.append(current_item)
|
|
except LongerException:
|
|
if len(stack):
|
|
current_item = new_from_line(line, parent=stack[-1])
|
|
stack[-1].elems.append(current_item)
|
|
else:
|
|
current_item = new_from_line(line, parent=None)
|
|
elems.append(current_item)
|
|
stack.append(current_item)
|
|
return elems
|
|
|
|
def get_analysis_values(elems, results):
|
|
for x in elems:
|
|
if isinstance(x, Answer):
|
|
results.append(x.get_analysis_value())
|
|
if x.elems:
|
|
get_analysis_values(x.elems, results)
|
|
|
|
def flatten_elems(elems, results):
|
|
for x in elems:
|
|
results.append(x)
|
|
if x.elems:
|
|
flatten_elems(x.elems, results)
|
|
|
|
|
|
def write_py_file(fd, elems):
|
|
schema_fields = []
|
|
|
|
for elem in elems:
|
|
schema_fields.append(elem.as_schema_field())
|
|
schema_fields.extend(elem.get_child_schema_fields())
|
|
|
|
print >> fd, '# -*- coding: utf-8 -*-'
|
|
|
|
r = []
|
|
print >> fd, 'defaultAnalysisValues = {'
|
|
get_analysis_values(elems, r)
|
|
for analysis_value in r:
|
|
print >> fd, analysis_value
|
|
print >> fd, '}'
|
|
|
|
print >> fd, """
|
|
from Products.Archetypes.atapi import *
|
|
from Products.MasterSelectWidget.MasterSelectWidget import MasterSelectWidget
|
|
|
|
def slaveFields(action, *slaves):
|
|
'''Helps to define more smartly the slave fields of a master field
|
|
(MasterSelectWidget). The master is always a "yes/no" field.
|
|
If p_action is:
|
|
- "showIfYes": slaves will be shown when master is "yes" ;
|
|
- "showIfNo": slaves will be shown when master is "no" ;
|
|
- "setValue": it defines slaves whose values may change depending on
|
|
actions on the master. '''
|
|
res = []
|
|
for slave in slaves:
|
|
slaveDict = {'name': slave}
|
|
if action == "showIfYes":
|
|
slaveDict.update({'action': 'show', 'hide_values': ['yes'] })
|
|
elif action == "showIfNo":
|
|
slaveDict.update({'action': 'show', 'hide_values': ['no'] })
|
|
elif action == "setValue":
|
|
sName = slave[:-7]
|
|
slaveDict.update({'action': 'value',
|
|
'vocab_method': 'defo%s' % sName,
|
|
'control_param': '%sCP' % sName})
|
|
res.append(slaveDict)
|
|
return tuple(res)
|
|
|
|
"""
|
|
print >> fd, 'schema = Schema(('
|
|
for s in schema_fields:
|
|
print >> fd, s
|
|
print >> fd, '),)'
|
|
|
|
|
|
def write_edit_pt_file(fd, elems):
|
|
print >> fd, """
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"
|
|
lang="en-US" i18n:domain="plone">
|
|
|
|
<body>
|
|
|
|
<!-- Body redefinition -->
|
|
|
|
<div metal:define-macro="body"
|
|
tal:define="portal_type portal_type|string:unknowntype">
|
|
<form name="edit_form"
|
|
method="post"
|
|
enctype="multipart/form-data"
|
|
class="enableUnloadProtection atBaseEditForm"
|
|
action=""
|
|
id=""
|
|
tal:attributes="action python:here.absolute_url()+'/'+template.id;
|
|
id string:${portal_type}-base-edit">
|
|
|
|
<metal:block define-slot="extra_top" />
|
|
|
|
<metal:block define-slot="widgets">
|
|
"""
|
|
|
|
flattened_elems = []
|
|
flatten_elems(elems, flattened_elems)
|
|
|
|
in_fieldset = False
|
|
for elem in flattened_elems:
|
|
if isinstance(elem, Title):
|
|
if in_fieldset:
|
|
print >> fd, '</fieldset>'
|
|
print >> fd, '''<fieldset style="border-width: 4px;"><legend>%s</legend>''' % \
|
|
unicode(elem.text, 'utf-8').encode('ascii', 'xmlcharrefreplace')
|
|
in_fieldset = True
|
|
elif isinstance(elem, Subtitle):
|
|
print >> fd, '''<h3>%s</h3>''' % unicode(elem.text, 'utf-8').encode('ascii', 'xmlcharrefreplace')
|
|
elif isinstance(elem, Comment):
|
|
print >> fd, '''<p>%s</p>''' % unicode(elem.text, 'utf-8').encode('ascii', 'xmlcharrefreplace')
|
|
elif isinstance(elem, Question) or (isinstance(elem, Answer) and not elem.elems):
|
|
print >> fd, '''<span metal:use-macro="python:here.widget('%s', mode='edit')" />''' % elem.identifier
|
|
|
|
if in_fieldset:
|
|
print >> fd, '</fieldset>'
|
|
|
|
|
|
print >> fd, """
|
|
</metal:block>
|
|
|
|
<metal:block define-slot="extra_bottom" />
|
|
|
|
<div class="formControls">
|
|
|
|
<input type="hidden"
|
|
name="fieldset"
|
|
value="default"
|
|
tal:attributes="value fieldset"
|
|
/>
|
|
<input type="hidden"
|
|
name="form.submitted"
|
|
value="1"
|
|
/>
|
|
<input type="hidden"
|
|
name="add_reference.field:record"
|
|
value=""
|
|
/>
|
|
<input type="hidden"
|
|
name="add_reference.type:record"
|
|
value=""
|
|
/>
|
|
<input type="hidden"
|
|
name="add_reference.destination:record"
|
|
value=""
|
|
/>
|
|
|
|
<tal:env define="env request/controller_state/kwargs">
|
|
<tal:loop repeat="varname python:('reference_source_url', 'reference_source_field', 'reference_source_fieldset')">
|
|
<tal:reference define="items python:env.get(varname, request.get(varname))"
|
|
condition="items">
|
|
<input tal:repeat="item items"
|
|
type="hidden"
|
|
name="form_env.reference_source_url:list:record"
|
|
value="value"
|
|
tal:attributes="value item;
|
|
name string:form_env.${varname}:list:record"
|
|
/>
|
|
</tal:reference>
|
|
</tal:loop>
|
|
</tal:env>
|
|
|
|
<tal:comment replace="nothing">
|
|
Turn 'persistent_' variables from controller_state persistent
|
|
</tal:comment>
|
|
<tal:env repeat="env request/controller_state/kwargs/items">
|
|
<input type="hidden"
|
|
name="key"
|
|
value="value"
|
|
tal:define="key python:env[0];
|
|
value python:env[1]"
|
|
tal:condition="python:key.startswith('persistent_')"
|
|
tal:attributes="name string:form_env.${key}:record;
|
|
value value"
|
|
/>
|
|
</tal:env>
|
|
|
|
<tal:comment replace="nothing">
|
|
Turn 'persistent_' variables from forms (GET/POST) persistent
|
|
</tal:comment>
|
|
<tal:env repeat="env request/form">
|
|
<input type="hidden"
|
|
name="key"
|
|
value="value"
|
|
tal:define="key env;
|
|
value request/?env"
|
|
tal:condition="python:key.startswith('persistent_')"
|
|
tal:attributes="name string:form_env.${key}:record;
|
|
value value"
|
|
/>
|
|
</tal:env>
|
|
|
|
<tal:comment replace="nothing">
|
|
Store referrer to remember where to go back
|
|
</tal:comment>
|
|
<input type="hidden"
|
|
name="last_referer"
|
|
tal:define="last_referer python:here.session_restore_value('HTTP_REFERER', request.form.get('last_referer', request.get('HTTP_REFERER')))"
|
|
tal:attributes="value python:(last_referer and '%s/%s' % (here.absolute_url(), template.id) not in last_referer) and last_referer or (here.getParentNode() and here.getParentNode().absolute_url())"
|
|
/>
|
|
|
|
<metal:block define-slot="buttons"
|
|
tal:define="fieldset_index python:fieldsets.index(fieldset);
|
|
n_fieldsets python:len(fieldsets)">
|
|
|
|
<input tal:condition="python:fieldset_index > 0"
|
|
class="context"
|
|
tabindex=""
|
|
type="submit"
|
|
name="form_previous"
|
|
value="Previous"
|
|
i18n:attributes="value label_previous;"
|
|
tal:attributes="tabindex tabindex/next;
|
|
disabled python:test(isLocked, 'disabled', None);"
|
|
/>
|
|
<input tal:condition="python:fieldset_index < n_fieldsets - 1"
|
|
class="context"
|
|
tabindex=""
|
|
type="submit"
|
|
name="form_next"
|
|
value="Next"
|
|
i18n:attributes="value label_next;"
|
|
tal:attributes="tabindex tabindex/next;
|
|
disabled python:test(isLocked, 'disabled', None);"
|
|
/>
|
|
<input class="context"
|
|
tabindex=""
|
|
type="submit"
|
|
name="form_submit"
|
|
value="Save"
|
|
i18n:attributes="value label_save;"
|
|
tal:attributes="tabindex tabindex/next;
|
|
disabled python:test(isLocked, 'disabled', None);"
|
|
/>
|
|
<input class="standalone"
|
|
tabindex=""
|
|
type="submit"
|
|
name="form.button.cancel"
|
|
value="Cancel"
|
|
i18n:attributes="value label_cancel;"
|
|
tal:attributes="tabindex tabindex/next"
|
|
/>
|
|
</metal:block>
|
|
|
|
<metal:block define-slot="extra_buttons" />
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html>
|
|
"""
|
|
def write_view_pt_file(fd, elems):
|
|
print >> fd, """
|
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US"
|
|
lang="en-US" i18n:domain="plone">
|
|
|
|
<body>
|
|
|
|
<!-- Body redefinition -->
|
|
|
|
<div metal:define-macro="body">
|
|
|
|
<fieldset>
|
|
<legend>Texte en projet</legend>
|
|
<div tal:define="f python:here.getField('apTitle')">
|
|
<b tal:content="f/widget/label"></b> : <span tal:content="here/getApTitle"></span>
|
|
</div>
|
|
<div tal:define="f python:here.getField('apDescription')">
|
|
<b tal:content="f/widget/label"></b> : <span tal:content="here/getApDescription"></span>
|
|
</div>
|
|
<div tal:define="f python:here.getField('apType')">
|
|
<b tal:content="f/widget/label"></b> : <span tal:content="python: f.vocabulary.getValue(here.getApType())"></span>
|
|
</div>
|
|
"""
|
|
|
|
flattened_elems = []
|
|
flatten_elems(elems, flattened_elems)
|
|
|
|
in_fieldset = False
|
|
for elem in flattened_elems:
|
|
if isinstance(elem, Title):
|
|
if in_fieldset:
|
|
print >> fd, '</fieldset>'
|
|
print >> fd, '''<fieldset style="border-width: 4px;"><legend>%s</legend>''' % \
|
|
unicode(elem.text, 'utf-8').encode('ascii', 'xmlcharrefreplace')
|
|
in_fieldset = True
|
|
elif isinstance(elem, Subtitle):
|
|
print >> fd, '''<h3>%s</h3>''' % unicode(elem.text, 'utf-8').encode('ascii', 'xmlcharrefreplace')
|
|
elif isinstance(elem, Comment):
|
|
print >> fd, '''<p>%s</p>''' % unicode(elem.text, 'utf-8').encode('ascii', 'xmlcharrefreplace')
|
|
elif isinstance(elem, Question) or (isinstance(elem, Answer) and not elem.elems):
|
|
print >> fd, '''<div tal:define="f python:here.getField('%s')">''' % elem.identifier
|
|
print >> fd, ''' <b tal:content="f/widget/label"></b> '''
|
|
print >> fd, ''' <span i18n:translate="" tal:content="here/%s"></span>''' % \
|
|
('get' + elem.identifier[0].upper() + elem.identifier[1:])
|
|
print >> fd, '''</div>'''
|
|
|
|
if in_fieldset:
|
|
print >> fd, '</fieldset>'
|
|
|
|
|
|
print >> fd, """
|
|
</div>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
|
|
def write_section_tests(fd, elems):
|
|
flattened_elems = []
|
|
flatten_elems(elems, flattened_elems)
|
|
|
|
for elem in flattened_elems:
|
|
if isinstance(elem, Title):
|
|
print >> fd, ' def has_section_%s(self):' % elem.identifier
|
|
print >> fd, ' return \\'
|
|
in_fieldset = True
|
|
elif isinstance(elem, Question):
|
|
print >> fd, ' not(self.hasFieldDefaultValue(\'%s\')) or \\' % elem.identifier
|
|
|
|
|
|
def write_ooo_qa(fd, elems):
|
|
flattened_elems = []
|
|
flatten_elems(elems, flattened_elems)
|
|
|
|
for elem in flattened_elems:
|
|
if isinstance(elem, Title):
|
|
print >> fd, '\n'*3
|
|
if isinstance(elem, Subtitle):
|
|
print >> fd, '\n'*3
|
|
elif isinstance(elem, Question):
|
|
print >> fd, ''' <text:p text:style-name="Standard"><office:annotation><dc:date>2007-05-16T00:00:00</dc:date><text:p>do text if not avis.legis.hasFieldDefaultValue('%s')</text:p></office:annotation>%s</text:p>''' % (elem.identifier, elem.text)
|
|
prev_identifier = elem.identifier
|
|
elif isinstance(elem, Answer) and not elem.elems:
|
|
print >> fd, ''' <text:p text:style-name="Analyse"><office:annotation><dc:date>2007-05-16T00:00:00</dc:date><text:p>do text if not avis.legis.hasFieldDefaultValue('%s')</text:p><text:p>from xhtml(avis.legis.%s)</text:p></office:annotation>%s</text:p>''' % (prev_identifier, elem.identifier, elem.identifier)
|
|
|
|
if __name__ == '__main__':
|
|
elems = parse_file(sys.argv[1])
|
|
|
|
fd = file(sys.argv[2], 'w')
|
|
write_py_file(fd, elems)
|
|
|
|
fd = file(sys.argv[3], 'w')
|
|
write_edit_pt_file(fd, elems)
|
|
|
|
fd = file(sys.argv[4], 'w')
|
|
write_view_pt_file(fd, elems)
|
|
|
|
fd = sys.stdout
|
|
write_ooo_qa(fd, elems)
|