[Erp5-report] r29144 - in /erp5/trunk/products/ERP5SyncML: ./ Conduit/

nobody at svn.erp5.org nobody at svn.erp5.org
Wed Sep 23 10:10:56 CEST 2009


Author: daniele
Date: Wed Sep 23 10:10:55 2009
New Revision: 29144

URL: http://svn.erp5.org?rev=29144&view=rev
Log:
Add the 'data' type for the document synchronisation 
During a 'slow sync' synchronisation it retrieve data while before it delete data and add it

Modified:
    erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py
    erp5/trunk/products/ERP5SyncML/SyncCode.py
    erp5/trunk/products/ERP5SyncML/XMLSyncUtils.py

Modified: erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py?rev=29144&r1=29143&r2=29144&view=diff
==============================================================================
--- erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py [utf8] (original)
+++ erp5/trunk/products/ERP5SyncML/Conduit/ERP5Conduit.py [utf8] Wed Sep 23 10:10:55 2009
@@ -36,14 +36,16 @@
 from Products.ERP5Type import Permissions, interfaces
 from Globals import PersistentMapping
 import pickle
-from cStringIO import StringIO
 from xml.sax.saxutils import escape, unescape
 import re
-import cStringIO
+import StringIO
+import string
 from lxml import etree
 parser = etree.XMLParser(remove_blank_text=True)
 from xml.marshal.generic import loads as unmarshaler
 from zLOG import LOG, INFO, DEBUG
+from base64 import standard_b64decode
+from OFS.Image import Pdata
 
 class ERP5Conduit(XMLSyncUtilsMixin):
   """
@@ -102,7 +104,8 @@
 
   security.declareProtected(Permissions.ModifyPortalContent, 'addNode')
   def addNode(self, xml=None, object=None, previous_xml=None,
-              object_id=None, sub_object=None, force=0, simulate=0, **kw):
+              object_id=None, sub_object=None, force=0, simulate=0,
+              reset=0, **kw):
     """
     A node is added
 
@@ -137,7 +140,7 @@
                                     previous_xml=previous_xml,
                                     force=force,
                                     simulate=simulate,
-                                    **kw)['conflict_list']
+                                    reset=reset, **kw)['conflict_list']
     elif xml.xpath('local-name()') == self.xml_object_tag:
       if object_id is None:
         object_id = self.getAttribute(xml, 'id')
@@ -161,6 +164,7 @@
                   object=sub_object,
                   xml=xml,
                   simulate=simulate,
+                  reset=reset,
                   reset_local_roles=reset_local_roles,
                   reset_workflow=reset_workflow)
     elif xml.xpath('name()') in self.XUPDATE_INSERT_OR_ADD \
@@ -185,8 +189,9 @@
             # Then do the udpate
             conflict_list += self.addNode(xml=sub_xml,object=sub_object,
                             previous_xml=sub_previous_xml, force=force,
-                            simulate=simulate, **kw)['conflict_list']
-    elif xml.xpath('local-name()') == self.history_tag or self.isHistoryAdd(xml)>0:
+                            simulate=simulate, reset=reset, **kw)['conflict_list']
+    elif (xml.xpath('local-name()') == self.history_tag \
+       or self.isHistoryAdd(xml) > 0) and not reset:
       conflict_list += self.addWorkflowNode(object, xml, simulate)
     #elif xml.tag in self.local_role_list or self.isLocalRole(xml)>0 and not simulate:
     elif xml.xpath('local-name()') in self.local_role_list:
@@ -195,13 +200,13 @@
       conflict_list += self.addLocalPermissionNode(object, xml)
     else:
       conflict_list += self.updateNode(xml=xml,object=object, force=force,
-                                       simulate=simulate,  **kw)
+                                       simulate=simulate, reset=reset, **kw)
     # We must returns the object created
     return {'conflict_list':conflict_list, 'object': sub_object}
 
   security.declareProtected(Permissions.ModifyPortalContent, 'deleteNode')
   def deleteNode(self, xml=None, object=None, object_id=None, force=None,
-                 simulate=0, **kw):
+                 simulate=0, reset=0, **kw):
     """
     A node is deleted
     """
@@ -226,7 +231,8 @@
           sub_object = object._getOb(sub_object_id)
           sub_xml = self.getSubObjectXupdate(xml)
           conflict_list += self.deleteNode(xml=sub_xml,object=sub_object,
-                                       force=force, simulate=simulate, **kw)
+                                       force=force, simulate=simulate, 
+                                       reset=reset, **kw)
         except (KeyError, AttributeError, TypeError):
           #LOG('ERP5Conduit.deleteNode', DEBUG, 'deleteNode, Unable to delete SubObject: %s' % str(sub_object_id))
           pass
@@ -240,9 +246,9 @@
         # We want to del a local role
         user = self.getAttribute(xml,'id')
         #LOG('ERP5Conduit.deleteNode local_role: ', DEBUG, 'user: %s' % repr(user))
-        if xml.xpath('local-name()') == self.local_role_tag :
+        if xml.xpath('local-name()') == self.local_role_tag:
           object.manage_delLocalRoles([user])
-        elif xml.xpath('local-name()') ==self.local_group_tag :
+        elif xml.xpath('local-name()') ==self.local_group_tag:
           object.manage_delLocalGroupRoles([user])
       if xml.xpath('local-name()') in self.local_permission_list and not simulate:
         permission = self.getAttribute(xml,'id')
@@ -259,7 +265,7 @@
 
   security.declareProtected(Permissions.ModifyPortalContent, 'updateNode')
   def updateNode(self, xml=None, object=None, previous_xml=None, force=0,
-                 simulate=0,  **kw):
+                 simulate=0, reset=0, **kw):
     """
     A node is updated with some xupdate
       - xml : the xml corresponding to the update, it should be xupdate
@@ -281,7 +287,9 @@
                                          conduit=self,
                                          previous_xml=previous_xml,
                                          force=force,
-                                         simulate=simulate, **kw)
+                                         simulate=simulate,
+                                         reset=reset,
+                                         **kw)
     # we may have only the part of an xupdate
     else:
       args = {}
@@ -310,6 +318,7 @@
                                         object=object,
                                         force=force,
                                         simulate=simulate,
+                                        reset=reset,
                                         **kw)
           return conflict_list
 
@@ -318,6 +327,7 @@
                                            object=object,
                                            force=force,
                                            simulate=simulate,
+                                           reset=reset,
                                            **kw)
           return conflict_list
         if keyword is None: # This is not a selection, directly the property
@@ -363,7 +373,8 @@
                   conflict.setRemoteValue(data)
                 conflict_list += [conflict]
           # We will now apply the argument with the method edit
-          if args != {} and (isConflict == 0 or force) and (not simulate):
+          if args != {} and (isConflict == 0 or force) and \
+              (not simulate or reset):
             self.editDocument(object=object, **args)
             # It is sometimes required to do something after an edit
             if getattr(object, 'manage_afterEdit', None) is not None:
@@ -375,12 +386,13 @@
                                         object=object,
                                         force=force,
                                         simulate=simulate,
+                                        reset=reset,
                                         **kw)['conflict_list']
         elif keyword == self.history_tag and not simulate:
           # This is the case where we have to call addNode
           conflict_list += self.addNode(xml=subnode, object=object,
                                         force=force, simulate=simulate,
-                                        **kw)['conflict_list']
+                                        reset=reset, **kw)['conflict_list']
         elif keyword in (self.local_role_tag, self.local_permission_tag) and not simulate:
           # This is the case where we have to update Roles or update permission
           #LOG('ERP5Conduit.updateNode', DEBUG, 'we will add a local role')
@@ -390,7 +402,7 @@
           xml = self.getElementFromXupdate(xml)
           conflict_list += self.addNode(xml=xml, object=object,
                                        force=force, simulate=simulate,
-                                       **kw)['conflict_list']
+                                       reset=reset, **kw)['conflict_list']
       elif self.isSubObjectModification(xml):
         # We should find the object corresponding to
         # this update, so we have to look in the previous_xml
@@ -414,7 +426,7 @@
             conflict_list += self.updateNode(xml=sub_xml, object=sub_object,
                                               force=force,
                                               previous_xml=sub_previous_xml,
-                                              simulate=simulate, **kw)
+                                              simulate=simulate, reset=reset, **kw)
         elif previous_xml is None and xml is not None and sub_object_id is not None:
           sub_object = None
           try:
@@ -427,6 +439,7 @@
                                              object=sub_object,
                                              force=force,
                                              simulate=simulate,
+                                             reset=reset,
                                              **kw)
     return conflict_list
 
@@ -631,16 +644,23 @@
     """
       return a xml with id replace by a new id
     """
-    if xml is not None and new_id is not None :
-      xml = etree.XML(xml)
+    if xml is not None and new_id is not None:
+      if isinstance(xml, str):
+        xml = etree.XML(xml)
       #copy of xml object for modification
       from copy import deepcopy
       xml_copy = deepcopy(xml)
-      object_element = xml_copy.find('object')
+      if xml.nsmap == None or xml.nsmap == {}:
+        object_element = xml_copy.find(self.xml_object_tag)
+        id_element = object_element.find('id')
+      else:
+        object_element = xml_copy.xpath('//syncml:object', \
+            namespaces={'syncml':xml_copy.nsmap[xml_copy.prefix]})[0]
+        id_element = object_element.xpath('//syncml:object', \ 
+            namespaces={'syncml':xml_copy.nsmap[xml_copy.prefix]})[0]
       object_element.attrib['id'] = new_id
-      id_element = object_element.find('id')
       id_element.text = new_id
-      return xml_copy
+      return etree.tostring(xml_copy)
 
   def getXMLFromObjectWithId(self, object, xml_mapping):
     """
@@ -660,7 +680,7 @@
     """
     xml_id = self.getXMLFromObjectWithId(object, xml_mapping)
     xml_gid = self.replaceIdFromXML(xml_id, gid)
-    return etree.tostring(xml_gid)
+    return xml_gid
 
   def getXMLFromObjectWithRid(self, object, rid, xml_mapping=None):
     """
@@ -668,7 +688,7 @@
     """
     xml_id = self.getXMLFromObjectWithId(object, xml_mapping)
     xml_rid = self.replaceIdFromXML(xml_id, rid)
-    return etree.tostring(xml_rid)
+    return xml_rid
 
   security.declareProtected(Permissions.AccessContentsInformation,'convertToXml')
   def convertToXml(self, xml):
@@ -708,8 +728,8 @@
     return xml.xpath('string(.//*[name() == "xupdate:attribute"][@name = "portal_type"])') or None
 
   security.declareProtected(Permissions.ModifyPortalContent, 'newObject')
-  def newObject(self, object=None, xml=None, simulate=0, reset_local_roles=1,
-                reset_workflow=1):
+  def newObject(self, object=None, xml=None, simulate=0, reset=0, 
+      reset_local_roles=1, reset_workflow=1):
     """
       modify the object with datas from
       the xml (action section)
@@ -787,7 +807,7 @@
       result += '>'
       # Then dumps the xml and remove what we does'nt want
       xml_string = self.nodeToString(xml)
-      maxi = max(xml_string.find('>')+1,\
+      maxi = max(xml_string.find('>') + 1, \
                  xml_string.rfind('</xupdate:attribute>')+len('</xupdate:attribute>'))
       result += xml_string[maxi:xml_string.find('</xupdate:element>')]
       result += '</%s>' % tag_name
@@ -847,21 +867,26 @@
       data = data.encode('utf-8')
     elif data is None:
       if data_type in self.list_type_list:
-        data = ()
+        return ()
       elif data_type in self.text_type_list:
-        data = ''
-      return data
+        return ''
     # We can now convert string in tuple, dict, binary...
     if data_type in self.list_type_list:
       data = unmarshaler(node.text)
     elif data_type in self.text_type_list:
       data = unescape(data)
+    elif data_type in self.data_type_list:
+      if data is None:
+        # data is in blocks
+        type_data = node.get('type_data')
+        if type_data == 'str':
+          data = standard_b64decode(''.join([block.text \
+                 for block in node.iterchildren()]))
+        elif type_data == 'Pdata':
+          data = Pdata(standard_b64decode(''.join([block.text \
+              for block in node.iterchildren()])))
     elif data_type in self.pickle_type_list:
-      msg = MIMEBase('application', 'octet-stream')
-      Encoders.encode_base64(msg)
-      msg.set_payload(data)
-      data = msg.get_payload(decode=1)
-      data = pickle.loads(data)
+      data = pickle.loads(standard_b64decode(data))
     elif data_type in self.date_type_list:
       data = DateTime(data)
     elif data_type in self.int_type_list:
@@ -879,7 +904,7 @@
   # have some specific things to do
   security.declareProtected(Permissions.ModifyPortalContent, 'applyXupdate')
   def applyXupdate(self, object=None, xupdate=None, conduit=None, force=0,
-                   simulate=0, **kw):
+                   simulate=0, reset=0, **kw):
     """
     Parse the xupdate and then it will call the conduit
     """
@@ -893,13 +918,15 @@
       if subnode.xpath('name()') in self.XUPDATE_INSERT_OR_ADD:
         conflict_list += conduit.addNode(xml=sub_xupdate,object=object,
                                          force=force, simulate=simulate,
-                                         **kw)['conflict_list']
+                                         reset=reset, **kw)['conflict_list']
       elif subnode.xpath('name()') in self.XUPDATE_DEL:
         conflict_list += conduit.deleteNode(xml=sub_xupdate, object=object,
-                                            force=force, simulate=simulate, **kw)
+                                            force=force, simulate=simulate,
+                                            reset=reset, **kw)
       elif subnode.xpath('name()') in self.XUPDATE_UPDATE:
         conflict_list += conduit.updateNode(xml=sub_xupdate, object=object,
-                                            force=force, simulate=simulate, **kw)
+                                            force=force, simulate=simulate,
+                                            reset=reset, **kw)
 
     return conflict_list
 
@@ -990,9 +1017,9 @@
     #LOG('local_role: ',0,'user: %s roles: %s' % (repr(user),repr(roles)))
     #user = roles[0]
     #roles = roles[1:]
-    if xml.xpath('local-name()') == self.local_role_tag :
+    if xml.xpath('local-name()') == self.local_role_tag:
       object.manage_setLocalRoles(user, roles)
-    elif xml.xpath('local-name()') == self.local_group_tag :
+    elif xml.xpath('local-name()') == self.local_group_tag:
       object.manage_setLocalGroupRoles(user, roles)
 
   security.declareProtected(Permissions.ModifyPortalContent, 'addLocalPermissionNode')
@@ -1013,7 +1040,7 @@
     #LOG('local_role: ',0,'permission: %s roles: %s' % (repr(permission),repr(roles)))
     #user = roles[0]
     #roles = roles[1:]
-    if xml.xpath('local-name()') == self.local_permission_tag :
+    if xml.xpath('local-name()') == self.local_permission_tag:
       object.manage_setLocalPermissions(permission, roles)
     return conflict_list
 

Modified: erp5/trunk/products/ERP5SyncML/SyncCode.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5SyncML/SyncCode.py?rev=29144&r1=29143&r2=29144&view=diff
==============================================================================
--- erp5/trunk/products/ERP5SyncML/SyncCode.py [utf8] (original)
+++ erp5/trunk/products/ERP5SyncML/SyncCode.py [utf8] Wed Sep 23 10:10:55 2009
@@ -95,6 +95,7 @@
   dict_type_list = ('dict',)
   int_type_list = ('int',)
   pickle_type_list = ('object',)
+  data_type_list = ('data',)
   xml_object_tag = 'object'
   #history_tag = 'workflow_history'
   history_tag = 'workflow_action'

Modified: erp5/trunk/products/ERP5SyncML/XMLSyncUtils.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5SyncML/XMLSyncUtils.py?rev=29144&r1=29143&r2=29144&view=diff
==============================================================================
--- erp5/trunk/products/ERP5SyncML/XMLSyncUtils.py [utf8] (original)
+++ erp5/trunk/products/ERP5SyncML/XMLSyncUtils.py [utf8] Wed Sep 23 10:10:55 2009
@@ -1002,21 +1002,27 @@
               signature.setObjectId(object.getId())
           else:
             reset = 1
-            #Object was retrieve but need to be updated without recreated
-            #usefull when an object is only deleted by workflow.
+            # Object was retrieve but need to be updated without recreated
+            # usefull when an object is only deleted by workflow.
             if data_subnode is not None:
-              if not isinstance(data_subnode, str):
-                xml_string = etree.tostring(data_subnode, encoding='utf-8')
-              #force = 1
+              if isinstance(data_subnode, str):
+                xml_string = etree.XML(data_subnode)
+              else:
+                xml_string = data_subnode
               actual_xml = conduit.getXMLFromObjectWithId(object,\
                            xml_mapping=domain.getXMLMapping(force=1)) 
-              data_subnode = self.getXupdateObject(xml_string, actual_xml)
+              xml_string_gid = conduit.replaceIdFromXML(xml_string, gid)
+              actual_xml = etree.XML(actual_xml)
+              actual_xml_gid = conduit.replaceIdFromXML(actual_xml, gid)
+              # use gid as compare key because their ids can be different
+              data_subnode = self.getXupdateObject(xml_string_gid, actual_xml_gid)
             conflict_list.extend(conduit.updateNode(
                                         xml=data_subnode,
                                         object=object,
                                         previous_xml=signature.getXML(),
                                         force=force,
-                                        simulate=simulate))
+                                        simulate=simulate,
+                                        reset=reset))
             xml_object = conduit.getXMLFromObjectWithId(object,\
                          xml_mapping=domain.getXMLMapping()) 
             signature.setTempXML(xml_object)
@@ -1025,11 +1031,9 @@
             if reset:
               #After a reset we want copy the LAST XML view on Signature.
               #this implementation is not sufficient, need to be improved.
-              if not isinstance(data_subnode, str):
-                xml_object = etree.tostring(data_subnode, encoding='utf-8',
+              if not isinstance(xml_object, str):
+                xml_object = etree.tostring(xml_object, encoding='utf-8',
                                             pretty_print=True)
-              else:
-                xml_object = data_subnode
             else: 
               xml_object = conduit.getXMLFromObjectWithId(object,\
                            xml_mapping=domain.getXMLMapping()) 
@@ -1422,6 +1426,7 @@
                     subscriber, domain, xml_confirmation_list, remote_xml,
                     xml_tree, has_status_list, has_response):
     # XXX the better is a namespace for all
+    namespace = self.getNamespace(xml_tree.nsmap)
     sync_body = xml_tree.find('SyncBody')
     if sync_body is None:
       sync_body = xml_tree.xpath('syncml:SyncBody')[0]




More information about the Erp5-report mailing list