Skip to content
Snippets Groups Projects
Commit 2dd94cb2 authored by Benoit Favre's avatar Benoit Favre
Browse files

add editor for xml

parent b9bbf763
No related branches found
No related tags found
No related merge requests found
...@@ -2,4 +2,4 @@ slu: 0 ...@@ -2,4 +2,4 @@ slu: 0
xml_filename: data/homeostasis_25nov.xml xml_filename: data/homeostasis_25nov.xml
osc_host: 127.0.0.1 osc_host: 127.0.0.1
osc_port: 1234 osc_port: 1234
asr_model: asr/mika-fred-1.cfg asr_model: asr/custom.cfg
#!/usr/bin/env python2
import os, threading, locale, sys
from gi.repository import GObject, Gtk, Gdk
GObject.threads_init()
Gdk.threads_init()
encoding = locale.getpreferredencoding()
utf8conv = lambda x : unicode(x, encoding).encode('utf8')
class Command(Gtk.ScrolledWindow):
def __init__(self):
super(Command, self).__init__()
self.view = Gtk.TextView()
self.view.set_editable(False)
self.view.set_cursor_visible(False)
self.buffer = self.view.get_buffer()
self.add(self.view)
self.listeners = []
def clear(self):
self.buffer.set_text('')
def add_listener(self, listener):
self.listeners.append(listener)
def run(self, command):
thread = threading.Thread(target=self._read_command_output, args=(command,))
thread.start()
def _read_command_output(self, command):
stdin, stdouterr = os.popen4(command)
while 1:
line = stdouterr.readline()
if not line:
break
Gdk.threads_enter()
self.add_text(utf8conv(line))
Gdk.threads_leave()
for listener in self.listeners:
listener(command, self.buffer.get_text())
def add_text(self, line):
if not line.endswith('\n'):
line += '\n'
self.buffer.insert_at_cursor(line)
adj = self.get_vadjustment()
adj.set_value(adj.get_upper() - adj.get_page_size())
if __name__ == '__main__':
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
command = Command(' '.join(sys.argv[1:]))
window = Gtk.Window()
window.add(command)
window.set_default_size(800, 600)
window.show_all()
window.connect("delete-event", Gtk.main_quit)
Gtk.main()
from xml.etree import ElementTree as ET
import re
seen_section_ids = {}
seen_actions = {}
class VerifyException(Exception):
def __init__(self, message, node):
self.message = message
self.node = node
def __str__(self):
return self.message + ': ' + ET.tostring(self.node)[:200].strip()
def __repr__(self):
return str(self)
def is_int(text):
return re.match(r'^\d+$', text)
def has_blank(text):
return re.match(r'\s', text)
def verify_keyword(node):
global seen_actions
for key in node.attrib:
if key not in ['action', 'lang']:
raise VerifyException('attribute "%s" not allowed in <%s>' % (key, node.tag), node)
for key in ['action']:
if key not in node.attrib:
raise VerifyException('node <%s> must contain attribute "%s"' % (node.tag, key), node)
if node.get('action').strip() == '':
print 'WARNING: empty action for %s' % ET.tostring(node).strip()
#raise VerifyException('empty action', node)
if has_blank(node.get('action')):
raise VerifyException('spaces not allowed in action "%s"', node)
seen_actions[node.get('action')] = True
if node.get('lang') not in [None, 'eng', 'esp']:
raise VerifyException('unsupported lang "%s"' % node.get('lang'), node)
for child in node:
raise VerifyException('child <%s> not allowed in <%s>' % (child.tag, node.tag), node)
def verify_sequence(node):
for key in node.attrib:
if key not in ['ordre', 'repetition', 'action', 'lang']:
raise VerifyException('attribute "%s" not allowed in <%s>' % (key, node.tag), node)
if node.get('lang') not in [None, 'eng', 'esp']:
raise VerifyException('unsupported lang "%s"' % node.get('lang'), node)
for child in node:
if child.tag == 'keyword':
verify_keyword(child)
else:
raise VerifyException('child <%s> not allowed in <%s>' % (child.tag, node.tag), node)
def verify_section(node):
global seen_section_ids
for key in node.attrib:
if key not in ['id', 'action']:
raise VerifyException('attribute "%s" not allowed in <%s>' % (key, node.tag), node)
for key in ['id']:
if key not in node.attrib:
raise VerifyException('node <%s> must contain attribute "%s"' % (node.tag, key), node)
if not is_int(node.get('id')):
raise VerifyException('only integers allowed for section id "%s"' % node.get('id'))
if node.get('id') in seen_section_ids:
raise VerifyException('repeated section id "%s"' % node.get('id'))
seen_section_ids[node.get('id')] = True
for child in node:
if child.tag == 'sequence':
verify_sequence(child)
else:
raise VerifyException('child <%s> not allowed in <%s>' % (child.tag, node.tag), node)
if node.text != None and node.text.strip() != '':
raise VerifyException('no text allowed directly in <%s>' % (node.tag), node)
if node.tail != None and node.tail.strip() != '':
raise VerifyException('no text allowed directly after <%s>' % (node.tag), node)
def verify_liste_section(node):
for key in node.attrib:
if key not in ['sequences', 'ordre', 'repetition', 'action']:
raise VerifyException('attribute "%s" not allowed in <%s>' % (key, node.tag), node)
for child in node:
if child.tag == 'section':
verify_section(child)
else:
raise VerifyException('child <%s> not allowed in <%s>' % (child.tag, node.tag), node)
if node.text != None and node.text.strip() != '':
raise VerifyException('no text allowed directly in <%s>' % (node.tag), node)
if node.tail != None and node.tail.strip() != '':
raise VerifyException('no text allowed directly after <%s>' % (node.tag), node)
def verify_root(node):
if node.tag != 'homeostasis':
raise VerifyException('root tag should be <homeostasis>')
for key in node.attrib:
if key not in ['version']:
raise VerifyException('attribute "%s" not allowed in <%s>' % (key, node.tag), node)
for child in node:
if child.tag == 'liste_section':
verify_liste_section(child)
else:
raise VerifyException('child <%s> not allowed in <%s>' % (child.tag, node.tag), node)
if node.text != None and node.text.strip() != '':
raise VerifyException('no text allowed directly in <%s>' % (node.tag), node)
if node.tail != None and node.tail.strip() != '':
raise VerifyException('no text allowed directly after <%s>' % (node.tag), node)
def validate_xml(filename):
global seen_section_ids, seen_actions
seen_section_ids = {}
seen_actions = {}
try:
root = ET.parse(filename).getroot()
verify_root(root)
except Exception as e:
return (False, str(e))
return (True, 'successfuly validated "%s"\nfound %d sections, %d types of action' % (filename, len(seen_section_ids), len(seen_actions)))
if __name__ == '__main__':
import sys
print validate_xml(sys.argv[1])
#!/usr/bin/env python2
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
import os, sys
os.environ['GTK_THEME'] = 'light'
from gi.repository import GObject, Gst, Gtk, Gdk, GtkSource
GObject.threads_init()
Gdk.threads_init()
import command, validate
class SourceView(Gtk.Window):
def __init__(self, filename):
super(SourceView, self).__init__()
self.filename = filename
self.connect("destroy", self.quit)
self.set_default_size(800,600)
self.set_border_width(10)
self.set_title('SourceView')
tabs = Gtk.Notebook()
self.tabs = tabs
vbox = Gtk.VBox() # contains tabs and buttons
self.source_buffer = GtkSource.Buffer()
lang_manager = GtkSource.LanguageManager()
self.source_buffer.set_language(lang_manager.get_language('xml'))
self.source_view = GtkSource.View.new_with_buffer(self.source_buffer)
self.source_view.set_show_line_numbers(True)
self.source_view.set_tab_width(4)
self.source_view.set_wrap_mode(Gtk.WrapMode.WORD)
self.scrolled = Gtk.ScrolledWindow()
self.scrolled.add(self.source_view)
#vbox.pack_start(self.scrolled, True, True, 5)
self.command = command.Command()
#vbox.pack_start(self.command, False, True, 5)
hbox = Gtk.HBox()
revert_button = Gtk.Button('Revert')
revert_button.connect('clicked', self.load)
hbox.pack_start(revert_button, False, False, 5)
validate_button = Gtk.Button('Validate')
validate_button.connect('clicked', self.validate)
hbox.pack_start(validate_button, False, False, 5)
compile_button = Gtk.Button('Compile')
compile_button.connect('clicked', self.compile)
hbox.pack_start(compile_button, False, False, 5)
save_button = Gtk.Button('Save')
save_button.connect('clicked', self.save)
hbox.pack_start(save_button, False, False, 5)
vbox.pack_start(tabs, True, True, 5)
vbox.pack_start(hbox, False, True, 5)
tabs.append_page(self.scrolled, Gtk.Label(filename))
tabs.append_page(self.command, Gtk.Label('Compilation result'))
tabs.set_show_border(False)
self.add(vbox)
self.show_all()
self.load()
def load(self, *args):
self.source_buffer.set_text(open(self.filename).read())
def save(self, *args):
self.command.clear()
try:
with open('data/edited.xml', 'w') as fp:
bounds = self.source_buffer.get_bounds()
fp.write(self.source_buffer.get_text(bounds[0], bounds[1], True))
except Exception as e:
print e
self.command.add_text('FAILED to save as data/edited.xml')
def validate(self, *args):
self.command.clear()
self.save()
self.command.add_text('VALIDATE...')
self.tabs.set_current_page(1)
result, message = validate.validate_xml('data/edited.xml')
self.command.add_text(message)
if result:
self.command.add_text('SUCCESS')
else:
self.command.add_text('FAILED')
return result
def compile(self, *args):
self.command.clear()
self.tabs.set_current_page(1)
self.save()
self.validate()
self.command.add_text('COMPILE...')
self.command.run('./tools/compile.ben.sh data/edited.xml tools/model')
def quit(self, window):
Gtk.main_quit()
if __name__ == '__main__':
app = SourceView(sys.argv[1])
Gtk.main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment