Commit 24b3ec49 authored by Nicolas Delaby's avatar Nicolas Delaby

Refactor ERP5SyncML partialy

  - replace 4Suite by lxml
  - use new None type
  - store Partial Data in CDATA node instead a Comment node (avoid replacement of '--' by '@-@@-@')
  - list type are loads with marshaler
  - several optimisations, clean useless code
  - testERP5SyncML ran 33% faster than before.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@25205 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 52b3897e
This diff is collapsed.
......@@ -69,8 +69,7 @@ class VCardConduit(ERP5Conduit, SyncCode):
portal_type = 'Person' #the VCard can just use Person
if sub_object is None:
new_object, reset_local_roles, reset_workflow = ERP5Conduit.constructContent(self, object, object_id,
portal_type)
new_object, reset_local_roles, reset_workflow = ERP5Conduit.constructContent(self, object, object_id, portal_type)
else: #if the object exist, it juste must be update
new_object = sub_object
#LOG('addNode', 0, 'new_object:%s, sub_object:%s' % (new_object, sub_object))
......@@ -80,7 +79,7 @@ class VCardConduit(ERP5Conduit, SyncCode):
simulate=simulate,
**kw)
#in a first time, conflict are not used
return {'conflict_list':None, 'object': new_object}
return {'conflict_list':[], 'object': new_object}
security.declareProtected(Permissions.ModifyPortalContent, 'deleteNode')
def deleteNode(self, xml=None, object=None, object_id=None, force=None,
......@@ -89,12 +88,11 @@ class VCardConduit(ERP5Conduit, SyncCode):
A node is deleted
"""
#LOG('deleteNode :', 0, 'object:%s, object_id:%s' % (str(object), str(object_id)))
conflict_list = []
try:
object._delObject(object_id)
except (AttributeError, KeyError):
LOG('VCardConduit',0,'deleteNode, Unable to delete: %s' % str(object_id))
return conflict_list
return []
security.declareProtected(Permissions.ModifyPortalContent, 'updateNode')
def updateNode(self, xml=None, object=None, previous_xml=None, force=0,
......@@ -156,7 +154,7 @@ class VCardConduit(ERP5Conduit, SyncCode):
property_value_list_well_incoded.append(property_value)
#elif ... put here the other encodings
else:
property_value_list_well_incoded=property_value_list
property_value_list_well_incoded = property_value_list
return property_value_list_well_incoded
......@@ -175,7 +173,7 @@ class VCardConduit(ERP5Conduit, SyncCode):
for vcard_line in vcard_list:
if ':' in vcard_line:
property, property_value = vcard_line.split(':')
property_value_list=property_value.split(';')
property_value_list = property_value.split(';')
property_parameters_list = []
property_name = ''
if ';' in property:
......@@ -195,28 +193,28 @@ class VCardConduit(ERP5Conduit, SyncCode):
property_parameters_list = tmp
#now property_parameters_list looks like :
# [{'ENCODING':'QUOTED-PRINTABLE'}, {'CHARSET':'UTF-8'}]
property_value_list = \
self.changePropertyEncoding(property_parameters_list,
property_value_list)
self.changePropertyEncoding(property_parameters_list,
property_value_list)
else:
property_name=property
if type(property_name) is type(u'a'):
if isinstance(property_name, unicode):
property_name = property_name.encode('utf-8')
tmp=[]
tmp = []
for property_value in property_value_list:
if type(property_value) is type(u'a'):
if isinstance(property_value, unicode):
property_value = property_value.encode('utf-8')
tmp.append(property_value)
property_value_list=tmp
property_value_list = tmp
if property_name in convert_dict.keys():
if property_name == 'N' and len(property_value_list) > 1:
edit_dict[convert_dict['N']]=property_value_list[0]
edit_dict[convert_dict['FN']]=property_value_list[1]
edit_dict[convert_dict['N']] = property_value_list[0]
edit_dict[convert_dict['FN']] = property_value_list[1]
else:
edit_dict[convert_dict[property_name]]=property_value_list[0]
edit_dict[convert_dict[property_name]] = property_value_list[0]
#LOG('edit_dict =',0,edit_dict)
return edit_dict
......@@ -29,7 +29,6 @@
import smtplib # to send emails
from Publication import Publication,Subscriber
from Subscription import Signature
from XMLSyncUtils import Parse
from XMLSyncUtils import XMLSyncUtils
from Conduit.ERP5Conduit import ERP5Conduit
from Products.CMFCore.utils import getToolByName
......@@ -54,9 +53,9 @@ class PublicationSynchronization(XMLSyncUtils):
"""
LOG('PubSyncInit', INFO, 'Starting... publication: %s' % (publication.getPath()))
#the session id is set at the same value of those of the client
subscriber.setSessionId(self.getSessionId(xml_client))
subscriber.setSessionId(self.getSessionIdFromXml(xml_client))
#same for the message id
subscriber.setMessageId(self.getMessageId(xml_client))
subscriber.setMessageId(self.getMessageIdFromXml(xml_client))
#at the begining of the synchronization the subscriber is not authenticated
subscriber.setAuthenticated(False)
#the last_message_id is 1 because the message that
......@@ -137,7 +136,7 @@ class PublicationSynchronization(XMLSyncUtils):
if authentication_type == publication.getAuthenticationType():
authentication_format = publication.getAuthenticationFormat()
decoded = subscriber.decode(authentication_format, data)
if decoded not in ('', None) and ':' in decoded:
if decoded and ':' in decoded:
(login, password) = decoded.split(':')
uf = self.getPortalObject().acl_users
for plugin_name, plugin in uf._getOb('plugins').listPlugins(
......
......@@ -492,10 +492,6 @@ class Signature(Folder, SyncCode):
Set the partial string we will have to
deliver in the future
"""
if type(xml) is type(u'a'):
xml = xml.encode('utf-8')
if xml is not None:
xml = xml.replace('@-@@-@','--') # need to put back '--'
self.partial_xml = xml
def getPartialXML(self):
......
......@@ -28,7 +28,7 @@
import smtplib # to send emails
from Subscription import Subscription,Signature
from XMLSyncUtils import XMLSyncUtils, Parse
from XMLSyncUtils import XMLSyncUtils
import commands
from Conduit.ERP5Conduit import ERP5Conduit
from AccessControl import getSecurityManager
......
......@@ -28,6 +28,7 @@
from Products.ERP5Type.Accessor.TypeDefinition import list_types
from Globals import Persistent
import re
class SyncCode(Persistent):
"""
......@@ -87,6 +88,7 @@ class SyncCode(Persistent):
tuple(XUPDATE_UPDATE) + tuple(XUPDATE_DEL)
text_type_list = ('text','string')
list_type_list = list_types
none_type = 'None'
force_conflict_list = ('layout_and_schema','ModificationDate')
binary_type_list = ('image','file','document','pickle')
date_type_list = ('date',)
......@@ -105,18 +107,12 @@ class SyncCode(Persistent):
ADDABLE_PROPERTY = local_role_list + (history_tag,) + local_permission_list
NOT_EDITABLE_PROPERTY = ('id','object','uid','xupdate:attribute') \
+ XUPDATE_EL + ADDABLE_PROPERTY
sub_object_exp = "/object\[@id='.*'\]/"
object_exp = "/object\[@id='.*'\]"
sub_sub_object_exp = "/object\[@id='.*'\]/object\[@id='.*'\]/"
history_exp = "/%s\[@id='.*'\]" % history_tag
local_role_exp = "/%s\[@id='.*'\]" % local_role_tag
local_group_exp = "/%s\[@id='.*'\]" % local_group_tag
bad_local_role_exp = "/%s\[@id='.*'\]/" % local_role_tag
bad_local_group_exp = "/%s\[@id='.*'\]/" % local_group_tag
bad_history_exp = "/%s\[@id='.*'\]/" % history_tag
local_role_and_group_list = (local_group_exp,local_role_exp)
bad_local_role_and_group_list = (bad_local_group_exp,bad_local_role_exp)
sub_object_exp = re.compile("/object\[@id='.*'\]/")
object_exp = re.compile("/object\[@id='.*'\]")
attribute_type_exp = re.compile("^.*attribute::type$")
sub_sub_object_exp = re.compile("/object\[@id='.*'\]/object\[@id='.*'\]/")
history_exp = re.compile("/%s\[@id='.*'\]" % history_tag)
bad_history_exp = re.compile("/%s\[@id='.*'\]/" % history_tag)
#media types :
......
......@@ -40,7 +40,6 @@ from Products.ERP5SyncML import Conduit
from Publication import Publication, Subscriber
from Products.BTreeFolder2.BTreeFolder2 import BTreeFolder2
from Subscription import Subscription
from XMLSyncUtils import Parse
from Products.ERP5Type import Permissions
from PublicationSynchronization import PublicationSynchronization
from SubscriptionSynchronization import SubscriptionSynchronization
......@@ -490,7 +489,7 @@ class SynchronizationTool( SubscriptionSynchronization,
for conflict in conflict_list:
if conflict.getObjectPath() == path:
#LOG('getSynchronizationState', DEBUG, 'found a conflict: %s' % str(conflict))
state_list += [[conflict.getSubscriber(),self.CONFLICT]]
state_list.append([conflict.getSubscriber(), self.CONFLICT])
for domain in self.getSynchronizationList():
destination = domain.getDestinationPath()
#LOG('getSynchronizationState', TRACE, 'destination: %s' % str(destination))
......@@ -499,7 +498,6 @@ class SynchronizationTool( SubscriptionSynchronization,
if j_path.find(destination)==0:
o_id = j_path[len(destination)+1:].split('/')[0]
#LOG('getSynchronizationState', TRACE, 'o_id: %s' % o_id)
subscriber_list = []
if domain.domain_type==self.PUB:
subscriber_list = domain.getSubscriberList()
else:
......@@ -512,13 +510,13 @@ class SynchronizationTool( SubscriptionSynchronization,
state = signature.getStatus()
#LOG('getSynchronizationState:', TRACE, 'sub.dest :%s, state: %s' % \
#(subscriber.getSubscriptionUrl(),str(state)))
found = None
found = False
# Make sure there is not already a conflict giving the state
for state_item in state_list:
if state_item[0]==subscriber:
found = 1
if found is None:
state_list += [[subscriber,state]]
if state_item[0] == subscriber:
found = True
if not found:
state_list.append([subscriber, state])
return state_list
security.declareProtected(Permissions.AccessContentsInformation,
......
This diff is collapsed.
# -*- coding: utf-8 -*-
##############################################################################
#
#
# Copyright (c) 2004 Nexedi SARL and Contributors. All Rights Reserved.
# Sebastien Robin <seb@nexedi.com>
#
......@@ -486,23 +487,23 @@ class TestERP5SyncML(TestERP5SyncMLMixin, ERP5TypeTestCase):
ZopeTestCase._print('\nTest First Synchronization ')
LOG('Testing... ',0,'test_08_FirstSynchronization')
self.login()
self.setupPublicationAndSubscription(quiet=1,run=1)
nb_person = self.populatePersonServer(quiet=1,run=1)
self.setupPublicationAndSubscription(quiet=1, run=1)
nb_person = self.populatePersonServer(quiet=1, run=1)
portal_sync = self.getSynchronizationTool()
for sub in portal_sync.getSubscriptionList():
self.assertEquals(sub.getSynchronizationType(),SyncCode.SLOW_SYNC)
self.assertEquals(sub.getSynchronizationType(), SyncCode.SLOW_SYNC)
# Synchronize the first client
nb_message1 = self.synchronize(self.sub_id1)
for sub in portal_sync.getSubscriptionList():
if sub.getTitle() == self.sub_id1:
self.assertEquals(sub.getSynchronizationType(),SyncCode.TWO_WAY)
self.assertEquals(sub.getSynchronizationType(), SyncCode.TWO_WAY)
else:
self.assertEquals(sub.getSynchronizationType(),SyncCode.SLOW_SYNC)
self.assertEquals(sub.getSynchronizationType(), SyncCode.SLOW_SYNC)
self.assertEqual(nb_message1, self.nb_message_first_synchronization)
# Synchronize the second client
nb_message2 = self.synchronize(self.sub_id2)
for sub in portal_sync.getSubscriptionList():
self.assertEquals(sub.getSynchronizationType(),SyncCode.TWO_WAY)
self.assertEquals(sub.getSynchronizationType(), SyncCode.TWO_WAY)
self.assertEqual(nb_message2, self.nb_message_first_synchronization)
self.checkFirstSynchronization(id=self.id1, nb_person=nb_person)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment