diff --git a/trytond/ir/actions.xml b/trytond/ir/actions.xml index bccc03ae7f..f1a4997759 100644 --- a/trytond/ir/actions.xml +++ b/trytond/ir/actions.xml @@ -7,6 +7,7 @@ ir.actions.actions form + @@ -21,6 +22,7 @@ + ]]> @@ -28,10 +30,12 @@ ir.actions.actions tree + + ]]> @@ -61,6 +65,7 @@ ir.actions.report form + @@ -68,6 +73,7 @@ + ]]> @@ -75,11 +81,13 @@ ir.actions.report tree + + ]]> @@ -109,6 +117,7 @@ ir.actions.act_window form + @@ -136,6 +145,7 @@ + ]]> @@ -143,6 +153,7 @@ ir.actions.act_window tree + @@ -150,6 +161,7 @@ + ]]> @@ -177,12 +189,14 @@ ir.actions.wizard form + + ]]> @@ -190,12 +204,14 @@ ir.actions.wizard tree + + ]]> diff --git a/trytond/ir/attachment.xml b/trytond/ir/attachment.xml index c813c44491..61c5be3ff3 100644 --- a/trytond/ir/attachment.xml +++ b/trytond/ir/attachment.xml @@ -6,6 +6,7 @@ ir.attachment form + @@ -16,6 +17,7 @@ + ]]> @@ -23,11 +25,13 @@ ir.attachment tree + + ]]> diff --git a/trytond/ir/cron.xml b/trytond/ir/cron.xml index 5b60e8d902..3dd72333b1 100644 --- a/trytond/ir/cron.xml +++ b/trytond/ir/cron.xml @@ -6,6 +6,7 @@ ir.cron tree + @@ -13,6 +14,7 @@ + ]]> @@ -20,6 +22,7 @@ ir.cron form + @@ -38,6 +41,7 @@ + ]]> diff --git a/trytond/ir/exports.xml b/trytond/ir/exports.xml index a0d43df6ef..4e8b10c4cc 100644 --- a/trytond/ir/exports.xml +++ b/trytond/ir/exports.xml @@ -6,11 +6,13 @@ ir.exports form + + ]]> @@ -18,10 +20,12 @@ ir.exports tree + + ]]> diff --git a/trytond/ir/model.xml b/trytond/ir/model.xml index 91a6f839be..5113b193cb 100644 --- a/trytond/ir/model.xml +++ b/trytond/ir/model.xml @@ -6,6 +6,7 @@ ir.model form + @@ -21,6 +22,7 @@ + ]]> @@ -28,10 +30,12 @@ ir.model tree + + ]]> @@ -60,6 +64,7 @@ ir.model.fields form + @@ -67,6 +72,7 @@ + ]]> @@ -74,10 +80,12 @@ ir.model.fields tree + + ]]> @@ -106,11 +114,13 @@ ir.model.access tree + + ]]> @@ -118,6 +128,7 @@ ir.model.access form + @@ -128,6 +139,7 @@ + ]]> diff --git a/trytond/ir/property.xml b/trytond/ir/property.xml index caa1754da0..1bbb4cbe71 100644 --- a/trytond/ir/property.xml +++ b/trytond/ir/property.xml @@ -6,6 +6,8 @@ ir.property form + @@ -14,6 +16,7 @@ + ]]> @@ -21,11 +24,13 @@ ir.property tree + + ]]> diff --git a/trytond/ir/rule.xml b/trytond/ir/rule.xml index f97187c5f2..d3d224c6af 100644 --- a/trytond/ir/rule.xml +++ b/trytond/ir/rule.xml @@ -6,6 +6,7 @@ ir.rule.group form + @@ -18,6 +19,7 @@ colspan="6" align="0.0"/> + ]]> @@ -25,11 +27,13 @@ ir.rule.group tree + + ]]> @@ -58,6 +62,7 @@ ir.rule form + @@ -65,6 +70,7 @@ + ]]> @@ -72,11 +78,13 @@ ir.rule tree + + ]]> diff --git a/trytond/ir/sequence.xml b/trytond/ir/sequence.xml index 9df66ae783..8ce92a0d04 100644 --- a/trytond/ir/sequence.xml +++ b/trytond/ir/sequence.xml @@ -7,6 +7,7 @@ ir.sequence form + @@ -22,18 +23,22 @@ + ]]> + + ir.sequence.tree ir.sequence tree + + ]]> @@ -64,10 +69,12 @@ ir.sequence.type form + + ]]> @@ -75,10 +82,12 @@ ir.sequence.type tree + + ]]> ir.translation form + @@ -14,6 +15,7 @@ + ]]> @@ -21,6 +23,7 @@ ir.translation tree + @@ -28,6 +31,7 @@ + ]]> diff --git a/trytond/ir/ui/menu.xml b/trytond/ir/ui/menu.xml index 7e5f5cdfa8..184743c716 100644 --- a/trytond/ir/ui/menu.xml +++ b/trytond/ir/ui/menu.xml @@ -6,9 +6,11 @@ ir.ui.menu tree + + ]]> child_id @@ -32,9 +34,11 @@ tree + + ]]> @@ -42,6 +46,7 @@ ir.ui.menu form + @@ -51,6 +56,7 @@ + ]]> diff --git a/trytond/ir/ui/view.xml b/trytond/ir/ui/view.xml index 8be49533f0..b356063289 100644 --- a/trytond/ir/ui/view.xml +++ b/trytond/ir/ui/view.xml @@ -6,6 +6,7 @@ ir.ui.view form + @@ -15,6 +16,7 @@ + ]]> @@ -22,11 +24,13 @@ ir.ui.view tree + + ]]> @@ -55,11 +59,13 @@ ir.ui.view_sc form + + ]]> @@ -67,11 +73,13 @@ ir.ui.view_sc tree + + ]]> diff --git a/trytond/ir/values.xml b/trytond/ir/values.xml index d0d09a35e3..de99bd3c13 100644 --- a/trytond/ir/values.xml +++ b/trytond/ir/values.xml @@ -6,6 +6,7 @@ ir.values form + @@ -17,6 +18,7 @@ + ]]> @@ -24,6 +26,7 @@ ir.values tree + @@ -31,6 +34,7 @@ + ]]> diff --git a/trytond/res/users.xml b/trytond/res/users.xml index a884aba5d8..a07384fa5c 100644 --- a/trytond/res/users.xml +++ b/trytond/res/users.xml @@ -18,6 +18,7 @@ res.user form + @@ -40,6 +41,7 @@ + ]]> @@ -47,10 +49,12 @@ res.user tree + + ]]> @@ -80,6 +84,7 @@ res.group form + @@ -93,6 +98,7 @@ + ]]> @@ -100,9 +106,11 @@ res.group tree + + ]]> @@ -132,10 +140,12 @@ res.role form + + ]]> @@ -144,9 +154,11 @@ tree parent_id + + ]]> diff --git a/trytond/tools/convert.py b/trytond/tools/convert.py index 301953a99e..c56db72f9d 100644 --- a/trytond/tools/convert.py +++ b/trytond/tools/convert.py @@ -766,8 +766,9 @@ def convert_xml_import_dom(cursor, module, xmlstream, idref=None, mode='init', # - classe monolythique vs instancier des sous-classe par type de record # (que l'on re-reference a la volee des qu'on lit le debut du record). # - utilser des pointeur de fct plutot que que inTitle=1 -# - verifier ce qu'il faut passer a _update +# - analyser le code _update, source d'amelioration # - ajouter un handler d'exception +# - faire un cache en debut de traitement : {xml_id: (db_id, model)} # tuto : http://pyxml.sourceforge.net/topics/howto/node14.html @@ -791,27 +792,9 @@ class DummyTagHandler: pass -class RecordTagHandler: - """Taghandler for the tag """ - def __init__(self): - pass - - def startElement(self, name, attributes): - return - - def characters(self, data): - pass - - def endElement(self, name): - """Must return the object to use for the next call """ - if name != "record": - return self - else: - return None - class MenuitemTagHandler: """Taghandler for the tag """ - def __init__(self): + def __init__(self, master_handler): pass def startElement(self, name, attributes): @@ -827,49 +810,159 @@ class MenuitemTagHandler: else: return None -class XmlHandler(sax.handler.ContentHandler): - def __init__(self): +class RecordTagHandler: + + """Taghandler for the tag and all the tags inside it""" + + def __init__(self, master_handler): + # Remind reference of parent handler + self.mh = master_handler + + + def startElement(self, name, attributes): + + # Manage the top level tag + if name == "record": + self.model = self.mh.pool.get(attributes["model"]) + assert self.model, "The model %s does not exist !" % (rec_model,) + + self.xml_id = attributes["id"] + + # create/update a dict containing fields values + self.values = {} + self.current_field = None + + return self.xml_id + + # Manage included tags: + elif name == "field": + + field_name = attributes['name'] + # Create a new entry in the values + self.values[field_name] = "" + + # Remind the current name (see characters) + self.current_field = field_name + + search_attr = attributes.get('search',False) + ref_attr = attributes.get('ref', False) + + if search_attr: + answer = f_obj.browse( + cursor, self.mh.user, + model.search(self.mh.cursor,self.mh.user, search_attr)) + + if not answer: return + + if field_name in model._columns: + if model._columns[field_name]._type == 'many2many': + f_val = [(6, 0, [x['id'] for x in answer])] + + elif model._columns[field_name]._type == 'many2one': + f_val = answer[0]['id'] + + elif ref_attr: + # TODO avec cache sur les ids..: + self.id_get(cursor, f_ref) + + else: + raise Exception("Tags '%s' not supported inside tag record."% (name,)) + + def characters(self, data): + + """If whe are in a field tag, consume all the content""" + + if self.current_field: + self.values[self.current_field] += data + + + def endElement(self, name): + + """Must return the object to use for the next call, if name is + not 'record' we return self to keep our hand on the + process. If name is 'record' we return None to end the + delegation""" + + if name == "field": + self.current_field = None + return self + elif name == "record": + # db access: TODO : use the object reference instead of + # the name of the model because _update do a new get to + # obtain the reference + self.mh.pool.get('ir.model.data')._update( + self.mh.cursor, self.mh.user, + self.model._name, self.mh.module, self.values, self.xml_id, + noupdate=self.mh.noupdate, mode=self.mh.mode) + + return None + else: + raise Exception("Unexpected closing tag '%s'"% (name,)) + +class TrytondXmlHandler(sax.handler.ContentHandler): + + def __init__(self, cursor, pool, mode, module, noupdate): "Register known taghandlers, and manged tags." + self.pool = pool + self.mode = mode + self.noupdate = noupdate + self.cursor = cursor + self.user = 1 + self.module = module + # Tag handlders are used to delegate the processing self.taghandlerlist = { - 'record': RecordTagHandler(), - 'menuitem': MenuitemTagHandler(), + 'record': RecordTagHandler(self), + 'menuitem': MenuitemTagHandler(self), } self.taghandler = None # Managed tags are handled by the current class self.managedtags= ["data", "terp"] - + self.idlist = [] def startElement(self, name, attributes): """Rebind the current handler if necessary and call startElement on it""" - if not self.taghandler: + if name in self.taghandlerlist: self.taghandler = self.taghandlerlist[name] - elif name in self.managedtags: - return + xml_id = self.taghandler.startElement(name, attributes) + if xml_id : self.idlist.append(xml_id) + + elif name == "data": + self.noupdate = attributes.get("noupdate", False) + + elif name == "terp": + pass + else: # TODO logger, logger, logger, ... print "Tag", name , "not supported" + raise return - - self.taghandler.startElement(name, attributes) - - + else: + self.taghandler.startElement(name, attributes) + def characters(self, data): if self.taghandler: self.taghandler.characters(data) def endElement(self, name): + + # Closing tag found, if we are in a delegation the handler + # tell us what to do: if self.taghandler: self.taghandler = self.taghandler.endElement(name) + def get_state(self): + return "Not implemented" + def convert_xml_import_sax(cursor, module, xmlstream, idref=None, mode='init', noupdate=False, report=None, demo=False): if idref is None: @@ -878,15 +971,27 @@ def convert_xml_import_sax(cursor, module, xmlstream, idref=None, mode='init', report = AssertionReport() - parser = sax.make_parser( ) + parser = sax.make_parser() # Tell the parser we are not interested in XML namespaces parser.setFeature(sax.handler.feature_namespaces, 0) - handler = XmlHandler( ) + + handler = TrytondXmlHandler( + cursor=cursor, + pool=pooler.get_pool(cursor.dbname), + mode=mode, + module=module, + noupdate=noupdate,) + parser.setContentHandler(handler) source = sax.InputSource() source.setByteStream(xmlstream) - parser.parse(source) - + try: + parser.parse(source) + except Exception, e: + print "-- parsing states: --" + print handler.get_state() + print "-- --" + raise e return True diff --git a/trytond/workflow/workflow.xml b/trytond/workflow/workflow.xml index 63298939a5..df5323bffa 100644 --- a/trytond/workflow/workflow.xml +++ b/trytond/workflow/workflow.xml @@ -7,6 +7,7 @@ workflow form + @@ -14,6 +15,7 @@ + ]]> @@ -21,11 +23,13 @@ workflow tree + + ]]> @@ -54,6 +58,7 @@ workflow.activity form + @@ -89,6 +94,7 @@ + ]]> @@ -96,6 +102,7 @@ workflow.activity tree + @@ -104,6 +111,7 @@ + ]]> @@ -132,6 +140,7 @@ workflow.transition form + @@ -141,6 +150,7 @@ + ]]> @@ -148,6 +158,7 @@ workflow.transition tree + @@ -157,6 +168,7 @@ + ]]> @@ -185,6 +197,7 @@ workflow.instance form + @@ -192,6 +205,7 @@ + ]]> @@ -199,6 +213,7 @@ workflow.instance tree + @@ -206,6 +221,7 @@ + ]]> @@ -227,12 +243,14 @@ workflow.workitem form + + ]]> @@ -240,12 +258,14 @@ workflow.workitem tree + + ]]>