Commit eacbecf5 authored by Nicolas Delaby's avatar Nicolas Delaby

Add log management, optimisation, typo

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@15587 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 7c1ab281
......@@ -48,7 +48,7 @@ from xml.sax.saxutils import escape, unescape
import re, copy
import cStringIO
from zLOG import LOG
from zLOG import LOG, INFO, DEBUG
try:
from Ft.Xml.Domlette import Print, PrettyPrint
except ImportError:
......@@ -180,10 +180,9 @@ class ERP5Conduit(XMLSyncUtilsMixin):
and self.getSubObjectDepth(xml)>=1:
sub_object_id = self.getSubObjectId(xml)
if previous_xml is not None and sub_object_id is not None:
#LOG('addNode',0,'previous xml is not none and also sub_object_id')
# Find the previous xml corresponding to this subobject
sub_previous_xml = self.getSubObjectXml(sub_object_id,previous_xml)
#LOG('addNode',0,'isSubObjectModification sub_p_xml: %s' % str(sub_previous_xml))
sub_previous_xml = self.getSubObjectXml(sub_object_id, previous_xml)
LOG('addNode', DEBUG,'isSubObjectModification sub_previous_xml: %s' % str(sub_previous_xml))
if sub_previous_xml is not None:
sub_object = None
try:
......@@ -191,11 +190,11 @@ class ERP5Conduit(XMLSyncUtilsMixin):
except (AttributeError, KeyError, TypeError):
pass
if sub_object is not None:
#LOG('addNode',0,'subobject.id: %s' % sub_object.id)
LOG('addNode', DEBUG, 'subobject.id: %s' % sub_object.id)
# Change the xml in order to directly apply
# modifications to the subobject
sub_xml = self.getSubObjectXupdate(xml)
#LOG('addNode',0,'sub_xml: %s' % str(sub_xml))
LOG('addNode', DEBUG, 'sub_xml: %s' % str(sub_xml))
# Then do the udpate
conflict_list += self.addNode(xml=sub_xml,object=sub_object,
previous_xml=sub_previous_xml, force=force,
......@@ -220,14 +219,12 @@ class ERP5Conduit(XMLSyncUtilsMixin):
A node is deleted
"""
# In the case where we have to delete an object
#LOG('ERP5Conduit',0,'deleteNode')
#LOG('ERP5Conduit',0,'deleteNode, object.id: %s' % object.getId())
#LOG('ERP5Conduit',0,'deleteNode, object path: %s' % repr(object.getPhysicalPath()))
LOG('ERP5Conduit.deleteNode', DEBUG, 'deleteNode, object path: %s' % repr(object.getPhysicalPath()))
conflict_list = []
if xml is not None:
xml = self.convertToXml(xml)
if object_id is None:
#LOG('ERP5Conduit',0,'deleteNode, SubObjectDepth: %i' % self.getSubObjectDepth(xml))
LOG('ERP5Conduit.deleteNode', DEBUG, 'deleteNode, SubObjectDepth: %i' % self.getSubObjectDepth(xml))
if xml.nodeName == self.xml_object_tag:
object_id = self.getAttribute(xml,'id')
elif self.getSubObjectDepth(xml)==1:
......@@ -241,7 +238,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
conflict_list += self.deleteNode(xml=sub_xml,object=sub_object,
force=force, simulate=simulate, **kw)
except (KeyError, AttributeError, TypeError):
#LOG('ERP5Conduit',0,'deleteNode, Unable to delete SubObject: %s' % str(sub_object_id))
LOG('ERP5Conduit.deleteNode', DEBUG, 'deleteNode, Unable to delete SubObject: %s' % str(sub_object_id))
pass
if object_id is not None: # We do have an object_id
self.deleteObject(object, object_id)
......@@ -252,7 +249,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if xml.nodeName in self.local_role_list and not simulate:
# We want to del a local role
user = self.getAttribute(xml,'id')
#LOG('local_role: ',0,'user: %s' % repr(user))
LOG('ERP5Conduit.deleteNode local_role: ', DEBUG, 'user: %s' % repr(user))
if xml.nodeName.find(self.local_role_tag)>=0:
object.manage_delLocalRoles([user])
elif xml.nodeName.find(self.local_group_tag)>=0:
......@@ -267,7 +264,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
try:
object._delObject(object_id)
except (AttributeError, KeyError):
#LOG('ERP5Conduit',0,'deleteObject, Unable to delete: %s' % str(object_id))
LOG('ERP5Conduit.deleteObject', DEBUG, 'Unable to delete: %s' % str(object_id))
pass
security.declareProtected(Permissions.ModifyPortalContent, 'updateNode')
......@@ -282,8 +279,8 @@ class ERP5Conduit(XMLSyncUtilsMixin):
"""
conflict_list = []
xml = self.convertToXml(xml)
#LOG('updateNode',0,'xml.nodeName: %s' % xml.nodeName)
#LOG('updateNode, force: ',0,force)
LOG('ERP5Conduit.updateNode', DEBUG, 'xml.nodeName: %s' % xml.nodeName)
LOG('ERP5Conduit.updateNode, force: ', DEBUG, force)
# we have an xupdate xml
if xml.nodeName == 'xupdate:modifications':
conflict_list += self.applyXupdate(object=object, xupdate=xml,
......@@ -292,12 +289,10 @@ class ERP5Conduit(XMLSyncUtilsMixin):
# we may have only the part of an xupdate
else:
args = {}
#LOG('isSubObjectModification',0,'result: %s' % str(self.isSubObjectModification(xml)))
if self.isProperty(xml) and not(self.isSubObjectModification(xml)):
keyword = None
for subnode in self.getAttributeNodeList(xml):
if subnode.nodeName=='select':
#LOG('updateNode',0,'selection: %s' % str(subnode.nodeValue))
select_list = subnode.nodeValue.split('/') # Something like:
#('','object[1]','sid[1]')
new_select_list = ()
......@@ -309,7 +304,6 @@ class ERP5Conduit(XMLSyncUtilsMixin):
keyword = select_list[len(select_list)-1] # this will be 'sid'
data_xml = xml
data = None
#LOG('updateNode',0,'keyword: %s' % str(keyword))
if xml.nodeName not in self.XUPDATE_INSERT_OR_ADD:
for subnode in self.getElementNodeList(xml):
if subnode.nodeName=='xupdate:element':
......@@ -343,7 +337,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if not (keyword in self.NOT_EDITABLE_PROPERTY):
# We will look for the data to enter
data_type = object.getPropertyType(keyword)
#LOG('updateNode',0,'data_type: %s' % str(data_type))
LOG('ERP5Conduit.updateNode', DEBUG, 'data_type: %s for keyword: %s' % (str(data_type), keyword))
data = self.convertXmlValue(data,data_type=data_type)
args[keyword] = data
args = self.getFormatedArgs(args=args)
......@@ -358,12 +352,12 @@ class ERP5Conduit(XMLSyncUtilsMixin):
data_type=data_type)
#current_data = object.getProperty(keyword)
current_data = self.getProperty(object, keyword)
#LOG('updateNode',0,'Conflict data: %s' % str(data))
#LOG('updateNode',0,'Conflict old_data: %s' % str(old_data))
#LOG('updateNode',0,'Conflict current_data: %s' % str(current_data))
LOG('ERP5Conduit.updateNode', DEBUG, 'Conflict data: %s' % str(data))
LOG('ERP5Conduit.updateNode', DEBUG, 'Conflict old_data: %s' % str(old_data))
LOG('ERP5Conduit.updateNode', DEBUG, 'Conflict current_data: %s' % str(current_data))
if (old_data != current_data) and (data != current_data) \
and keyword not in self.force_conflict_list:
#LOG('updateNode',0,'Conflict on : %s' % keyword)
LOG('ERP5Conduit.updateNode', DEBUG, 'Conflict on : %s' % keyword)
# Hack in order to get the synchronization working for demo
# XXX this have to be removed after
#if not (data_type in self.binary_type_list):
......@@ -379,11 +373,6 @@ class ERP5Conduit(XMLSyncUtilsMixin):
conflict.setLocalValue(current_data)
conflict.setRemoteValue(data)
conflict_list += [conflict]
#conflict_list += [Conflict(object_path=object.getPhysicalPath(),
# keyword=keyword,
# xupdate=string_io)]
#publisher_value=current_data, # not needed any more
#subscriber_value=data)] # not needed any more
# We will now apply the argument with the method edit
if args != {} and (isConflict==0 or force) and (not simulate):
self.editDocument(object=object,**args)
......@@ -399,9 +388,9 @@ class ERP5Conduit(XMLSyncUtilsMixin):
# 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']
elif keyword in (self.local_role_tag,self.local_permission_tag) and not simulate:
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('updateNode',0,'we will add a local role')
#LOG('ERP5Conduit.updateNode', DEBUG, 'we will add a local role')
#user = self.getSubObjectId(xml)
#roles = self.convertXmlValue(data,data_type='tokens')
#object.manage_setLocalRoles(user,roles)
......@@ -412,11 +401,10 @@ class ERP5Conduit(XMLSyncUtilsMixin):
# We should find the object corresponding to
# this update, so we have to look in the previous_xml
sub_object_id = self.getSubObjectId(xml)
#LOG('updateNode',0,'isSubObjectModification sub_object_id: %s' % sub_object_id)
LOG('ERP5Conduit.updateNode', DEBUG,'isSubObjectModification sub_object_id: %s' % sub_object_id)
if previous_xml is not None and sub_object_id is not None:
#LOG('updateNode',0,'previous xml is not none and also sub_object_id')
sub_previous_xml = self.getSubObjectXml(sub_object_id,previous_xml)
#LOG('updateNode',0,'isSubObjectModification sub_p_xml: %s' % str(sub_previous_xml))
LOG('ERP5Conduit.updateNode', DEBUG, 'isSubObjectModification sub_previous_xml: %s' % str(sub_previous_xml))
if sub_previous_xml is not None:
sub_object = None
try:
......@@ -424,11 +412,11 @@ class ERP5Conduit(XMLSyncUtilsMixin):
except KeyError:
pass
if sub_object is not None:
#LOG('updateNode',0,'subobject.id: %s' % sub_object.id)
LOG('ERP5Conduit.updateNode', DEBUG, 'subobject.id: %s' % sub_object.id)
# Change the xml in order to directly apply
# modifications to the subobject
sub_xml = self.getSubObjectXupdate(xml)
#LOG('updateNode',0,'sub_xml: %s' % str(sub_xml))
LOG('ERP5Conduit.updateNode', DEBUG, 'sub_xml: %s' % str(sub_xml))
# Then do the udpate
conflict_list += self.updateNode(xml=sub_xml, object=sub_object,
force=force, previous_xml=sub_previous_xml,
......@@ -485,7 +473,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
data = data.encode(self.getEncoding())
data = data.replace('@@@','\n')
if keyword == 'binary_data':
#LOG('ERP5Conduit.getFormatedArgs',0,'binary_data keyword: %s' % str(keyword))
LOG('ERP5Conduit.getFormatedArgs', DEBUG, 'binary_data keyword: %s' % str(keyword))
msg = MIMEBase('application','octet-stream')
Encoders.encode_base64(msg)
msg.set_payload(data)
......
......@@ -95,7 +95,7 @@ def addPublication( self, id, title='', REQUEST=None ):
Add a new Category and generate UID by calling the
ZSQLCatalog
"""
o = Publication( id ,'','','','','')
o = Publication( id, '', '', '', '', '')
self._setObject( id, o )
if REQUEST is not None:
return self.manage_main(self, REQUEST, update_menu=1)
......@@ -157,7 +157,6 @@ class Publication(Subscription):
self.setSourceURI(source_uri)
self.setQuery(query)
self.xml_mapping = xml_mapping
#self.list_subscribers = PersistentMapping()
self.domain_type = self.PUB
self.gpg_key = gpg_key
self.setGidGenerator(gid_generator)
......@@ -231,26 +230,24 @@ class Publication(Subscription):
"""
Add a new subscriber to the publication
"""
LOG('addSubscriber starting ...',0,'')
# We have to remove the subscriber if it already exist (there were probably a reset on the client)
self.delSubscriber(subscriber.getSubscriptionUrl())
new_id = subscriber.getId()
if new_id is None:
new_id = str(self.generateNewId())
subscriber.id = new_id
#if len(self.list_subscribers) == 0:
# self.list_subscribers = []
#self.list_subscribers = self.list_subscribers + [subscriber]
self._setObject(new_id,subscriber)
self._setObject(new_id, subscriber)
def getSubscriber(self, subscription_url):
"""
return the subscriber corresponding the to subscription_url
"""
for o in self.objectValues():
if o.getSubscriptionUrl() == subscription_url:
o = None
for sub in self.getSubscriberList():
if sub.getSubscriptionUrl() == subscription_url:
o = sub
break
return o
return None
def getSubscriberList(self):
"""
......@@ -263,16 +260,16 @@ class Publication(Subscription):
"""
Delete a subscriber for this publication
"""
for o in self.objectValues():
for o in self.getSubscriberList():
if o.getSubscriptionUrl() == subscription_url:
self._delObject(o.id)
self.activate().manage_delObjects(o.id)
def resetAllSubscribers(self):
"""
Reset all subscribers
"""
for o in self.objectValues():
self._delObject(o.id)
for o in self.getSubscriberList():
self.activate().manage_delObjects(o.id)
def getConflictList(self):
"""
......@@ -280,6 +277,6 @@ class Publication(Subscription):
"""
conflict_list = []
for subscriber in self.getSubscriberList():
conflict_list += subscriber.getConflictList()
conflict_list.extend(subscriber.getConflictList())
return conflict_list
......@@ -39,11 +39,11 @@ from Products.PluggableAuthService.interfaces.plugins import\
from AccessControl.SecurityManagement import newSecurityManager
import commands
from DateTime import DateTime
from zLOG import LOG
from zLOG import LOG, DEBUG, INFO, WARNING
class PublicationSynchronization(XMLSyncUtils):
"""
Receive the first XML message from the client
"""
def PubSyncInit(self, publication=None, xml_client=None, subscriber=None,
......@@ -52,8 +52,7 @@ class PublicationSynchronization(XMLSyncUtils):
Read the client xml message
Send the first XML message from the server
"""
LOG('PubSyncInit',0,'Starting... publication: %s' % str(publication))
LOG('PubSyncInit', DEBUG, '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))
#same for the message id
......@@ -80,8 +79,8 @@ class PublicationSynchronization(XMLSyncUtils):
# If slow sync, then resend everything
if alert_code == self.SLOW_SYNC:
LOG('Warning !!!, reseting client synchronization for subscriber:',0,
subscriber)
LOG('Warning !!!, reseting client synchronization for subscriber:', WARNING,
subscriber.getPath())
subscriber.resetAllSignatures()
# Check if the last time synchronization is the same as the client one
......@@ -89,16 +88,12 @@ class PublicationSynchronization(XMLSyncUtils):
\nlast_anchor:\t\t\t%s\nnext_anchor:\t\t\t%s' % \
(subscriber.getNextAnchor(), subscriber.getLastAnchor(), last_anchor, \
next_anchor)
#LOG('PubSyncInit',0,mess)
if subscriber.getNextAnchor() != last_anchor:
if last_anchor in (None, ''):
LOG('PubSyncInit',0,'anchor null')
#raise ValueError, "Sorry, the anchor was null"
LOG('PubSyncInit', DEBUG, 'anchor null')
else:
message = "bad anchors in PubSyncInit! " + \
subscriber.getNextAnchor() + " and " + last_anchor
LOG('PubSyncInit',0,message)
else:
subscriber.setNextAnchor(next_anchor)
......@@ -118,10 +113,10 @@ class PublicationSynchronization(XMLSyncUtils):
if publication.isAuthenticationRequired():
#at the begining, the code is initialised at UNAUTHORIZED
auth_code=self.UNAUTHORIZED
LOG('PubSyncInit',0,'authentication required')
LOG('PubSyncInit', INFO, 'authentication required')
if not cred:
auth_code=self.AUTH_REQUIRED
LOG("there's no credential !!!",0,'')
LOG("PubSyncInit there's no credential !!!", INFO,'')
# Prepare the xml message for the Sync initialization package
xml(self.SyncMLChal(cmd_id, "SyncHdr",
publication.getPublicationUrl(), subscriber.getSubscriptionUrl(),
......@@ -156,7 +151,6 @@ class PublicationSynchronization(XMLSyncUtils):
auth_code=self.UNAUTHORIZED
#in all others cases, the auth_code is set to UNAUTHORIZED
# Prepare the xml message for the Sync initialization package
if auth_code == self.AUTH_ACCEPTED:
xml_status, cmd_id = self.SyncMLStatus(xml_client, auth_code,
......@@ -203,7 +197,6 @@ class PublicationSynchronization(XMLSyncUtils):
xml(' </SyncBody>\n')
xml('</SyncML>\n')
xml_a = ''.join(xml_list)
if publication.getSyncContentType() == self.CONTENT_TYPE['SYNCML_WBXML']:
xml_a = self.xml2wbxml(xml_a)
self.sendResponse(from_url=publication.getPublicationUrl(),
......@@ -211,20 +204,20 @@ class PublicationSynchronization(XMLSyncUtils):
xml=xml_a, domain=publication,
content_type=publication.getSyncContentType())
return {'has_response':1,'xml':xml_a}
return {'has_response':1, 'xml':xml_a}
def PubSync(self, publication_path, msg=None, RESPONSE=None, subscriber=None):
"""
This is the synchronization method for the server
"""
LOG('PubSync',0,'Starting... publication: %s' % str(publication_path))
LOG('PubSync', DEBUG, 'Starting... publication: %s' % (publication_path))
# Read the request from the client
publication = self.unrestrictedTraverse(publication_path)
xml_client = msg
if xml_client is None:
xml_client = self.readResponse(from_url=publication.getPublicationUrl())
#LOG('PubSync',0,'Starting... msg: %s' % str(xml_client))
LOG('PubSync', DEBUG, 'Starting... msg: %s' % str(xml_client))
result = None
if xml_client is not None:
......@@ -233,14 +226,13 @@ class PublicationSynchronization(XMLSyncUtils):
first_node = xml_client.childNodes[0]
if first_node.nodeName != "SyncML":
#LOG('PubSync',0,'This is not a SyncML Message')
LOG('PubSync', INFO, 'This is not a SyncML Message')
raise ValueError, "Sorry, This is not a SyncML Message"
alert_code = self.getAlertCode(xml_client)
# Get informations from the header
client_header = first_node.childNodes[1]
if client_header.nodeName != "SyncHdr":
#LOG('PubSync',0,'This is not a SyncML Header')
LOG('PubSync', INFO, 'This is not a SyncML Header')
raise ValueError, "Sorry, This is not a SyncML Header"
subscription_url = self.getSubscriptionUrl(client_header)
# Get the subscriber or create it if not already in the list
......@@ -273,7 +265,7 @@ class PublicationSynchronization(XMLSyncUtils):
# This looks like we are starting a synchronization after
# a conflict resolution by the user
result = self.PubSyncInit(publication=publication, xml_client=None,
subscriber=subscriber,sync_type=self.TWO_WAY)
subscriber=subscriber, sync_type=self.TWO_WAY)
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
......@@ -284,4 +276,4 @@ class PublicationSynchronization(XMLSyncUtils):
"""
The modidification message for the publication
"""
return self.SyncModif(publication,xml_client)
return self.SyncModif(publication, xml_client)
......@@ -37,7 +37,7 @@ from Products.ERP5Type.Base import Base
from Products.ERP5Type import Permissions
from Products.ERP5Type import PropertySheet
from DateTime import DateTime
from zLOG import LOG
from zLOG import LOG, DEBUG, INFO
import md5
......@@ -141,7 +141,7 @@ class Conflict(SyncCode, Base):
after a conflict resolution, we have decided
to keep the local version of this object
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync = getToolByName(self, 'portal_synchronizations')
p_sync.applyPublisherValue(self)
def applyPublisherDocument(self):
......@@ -149,7 +149,7 @@ class Conflict(SyncCode, Base):
after a conflict resolution, we have decided
to keep the local version of this object
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync = getToolByName(self, 'portal_synchronizations')
p_sync.applyPublisherDocument(self)
def getPublisherDocument(self):
......@@ -157,7 +157,7 @@ class Conflict(SyncCode, Base):
after a conflict resolution, we have decided
to keep the local version of this object
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync = getToolByName(self, 'portal_synchronizations')
return p_sync.getPublisherDocument(self)
def getPublisherDocumentPath(self):
......@@ -165,7 +165,7 @@ class Conflict(SyncCode, Base):
after a conflict resolution, we have decided
to keep the local version of this object
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync = getToolByName(self, 'portal_synchronizations')
return p_sync.getPublisherDocumentPath(self)
def getSubscriberDocument(self):
......@@ -173,7 +173,7 @@ class Conflict(SyncCode, Base):
after a conflict resolution, we have decided
to keep the local version of this object
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync = getToolByName(self, 'portal_synchronizations')
return p_sync.getSubscriberDocument(self)
def getSubscriberDocumentPath(self):
......@@ -181,7 +181,7 @@ class Conflict(SyncCode, Base):
after a conflict resolution, we have decided
to keep the local version of this object
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync = getToolByName(self, 'portal_synchronizations')
return p_sync.getSubscriberDocumentPath(self)
def applySubscriberDocument(self):
......@@ -189,14 +189,14 @@ class Conflict(SyncCode, Base):
after a conflict resolution, we have decided
to keep the local version of this object
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync = getToolByName(self, 'portal_synchronizations')
p_sync.applySubscriberDocument(self)
def applySubscriberValue(self,object=None):
"""
get the domain
"""
p_sync = getToolByName(self,'portal_synchronizations')
p_sync = getToolByName(self, 'portal_synchronizations')
p_sync.applySubscriberValue(self,object=object)
def setSubscriber(self, subscriber):
......@@ -235,7 +235,6 @@ class Conflict(SyncCode, Base):
"""
self.copy_path = path
class Signature(Folder,SyncCode):
"""
status -- SENT, CONFLICT...
......@@ -251,7 +250,11 @@ class Signature(Folder,SyncCode):
isPortalContent = 0 # Make sure RAD generated accessors at the class level
# Constructor
def __init__(self, id=None, rid=None, status=None, xml_string=None,
def __init__(self,
id=None,
rid=None,
status=None,
xml_string=None,
object=None):
if object is not None:
self.setPath(object.getPhysicalPath())
......@@ -312,7 +315,7 @@ class Signature(Folder,SyncCode):
"""
get the force value (if we need to force update or not)
"""
return getattr(self,'path',None)
return getattr(self, 'path', None)
def setPath(self, path):
"""
......@@ -337,28 +340,28 @@ class Signature(Folder,SyncCode):
get the last modfication date, so that we don't always
check the xml
"""
return getattr(self,'modification_date',None)
return getattr(self, 'modification_date', None)
def setLastModificationDate(self,value):
"""
set the last modfication date, so that we don't always
check the xml
"""
setattr(self,'modification_date',value)
setattr(self, 'modification_date', value)
def getLastSynchronizationDate(self):
"""
get the last modfication date, so that we don't always
check the xml
"""
return getattr(self,'synchronization_date',None)
return getattr(self, 'synchronization_date', None)
def setLastSynchronizationDate(self,value):
"""
set the last modfication date, so that we don't always
check the xml
"""
setattr(self,'synchronization_date',value)
setattr(self, 'synchronization_date', value)
def setXML(self, xml):
"""
......@@ -373,7 +376,7 @@ class Signature(Folder,SyncCode):
"""
get the XML corresponding to the object
"""
xml = getattr(self,'xml',None)
xml = getattr(self, 'xml', None)
if xml == '':
xml = None
return xml
......@@ -507,7 +510,7 @@ class Signature(Folder,SyncCode):
Set the partial string we will have to
deliver in the future
"""
#LOG('Subscriber.getPartialXML',0,'partial_xml: %s' % str(self.partial_xml))
#LOG('Subscriber.getPartialXML', DEBUG, 'partial_xml: %s' % str(self.partial_xml))
if self.partial_xml is not None:
self.partial_xml = self.partial_xml.replace('@-@@-@','--') # need to put back '--'
return self.partial_xml
......@@ -544,7 +547,6 @@ class Signature(Folder,SyncCode):
"""
Return the actual action for a partial synchronization
"""
# LOG('setConflictList, list',0,conflict_list)
if conflict_list is None or conflict_list==[]:
self.resetConflictList()
else:
......@@ -554,7 +556,7 @@ class Signature(Folder,SyncCode):
"""
Return the actual action for a partial synchronization
"""
# LOG('delConflict, conflict',0,conflict)
LOG('delConflict, conflict', DEBUG, conflict)
conflict_list = []
for c in self.getConflictList():
#LOG('delConflict, c==conflict',0,c==aq_base(conflict))
......@@ -575,7 +577,6 @@ def addSubscription( self, id, title='', REQUEST=None ):
"""
Add a new Subscribption
"""
LOG('addSubscription starting...',0,'')
o = Subscription( id ,'','','','','','')
self._setObject( id, o )
if REQUEST is not None:
......@@ -686,8 +687,7 @@ class Subscription(Folder, SyncCode):
#self.signatures = PersitentMapping()
def getAlertCodeList(self):
#XXX replace by a dictionary or a list in SyncCode
return [self.TWO_WAY, self.ONE_WAY_FROM_SERVER]
return self.CODE_LIST
def getAlertCode(self):
return getattr(self, 'alert_code', 200)
......@@ -751,7 +751,7 @@ class Subscription(Folder, SyncCode):
"""
content type used by the subscriber
"""
self.sync_content_type=sync_content_type
self.sync_content_type = sync_content_type
# the varible name is sync_content_type instead of content_type because
# content_type seems to be a function name already used
......@@ -768,16 +768,16 @@ class Subscription(Folder, SyncCode):
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# XXX for debugging only, to be removed
#dict_sign = {}
#for o in self.objectValues():
#for o in self.getSignatureList():
#dict_sign[o.getId()] = o.getStatus()
# LOG('getSignature',0,'signatures_status: %s' % str(dict_sign))
# LOG('getSignature', DEBUG, 'signatures_status: %s' % str(dict_sign))
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
code = self.SLOW_SYNC
if len(self.objectValues()) > 0:
if len(self.getSignatureList()) > 0:
code = self.getAlertCode()
if default is not None:
code = default
#LOG('Subscription',0,'getSynchronizationType: %s' % code)
#LOG('Subscription', DEBUG, 'getSynchronizationType: %s' % code)
return code
def setXMLMapping(self, value):
......@@ -801,7 +801,7 @@ class Subscription(Folder, SyncCode):
"""
return True if the synchronisation is between two erp5 sites
"""
return getattr(self, 'synchronize_with_erp5_sites', None)
return getattr(self, 'synchronize_with_erp5_sites', True)
def checkCorrectRemoteSessionId(self, session_id):
"""
......@@ -810,7 +810,7 @@ class Subscription(Folder, SyncCode):
return True if the session id was not seen, False if already seen
"""
last_session_id = getattr(self,'last_session_id',None)
last_session_id = getattr(self, 'last_session_id', None)
if last_session_id == session_id:
return False
self.last_session_id = session_id
......@@ -824,8 +824,8 @@ class Subscription(Folder, SyncCode):
return True if the message id was not seen, False if already seen
"""
last_message_id = getattr(self,'last_message_id',None)
# LOG('checkCorrectRemoteMessageId last_message_id =',0,last_message_id)
# LOG('checkCorrectRemoteMessageId message_id =',0,message_id)
LOG('checkCorrectRemoteMessageId last_message_id = ', DEBUG, last_message_id)
LOG('checkCorrectRemoteMessageId message_id = ', DEBUG, message_id)
if last_message_id == message_id:
return False
self.last_message_id = message_id
......@@ -835,13 +835,13 @@ class Subscription(Folder, SyncCode):
"""
set the last message id to 0
"""
self.last_message_id=last_message_id
self.last_message_id = last_message_id
def getLastSentMessage(self):
"""
This is the getter for the last message we have sent
"""
return getattr(self,'last_sent_message','')
return getattr(self, 'last_sent_message', '')
def setLastSentMessage(self,xml):
"""
......@@ -889,7 +889,7 @@ class Subscription(Folder, SyncCode):
"""
return the gnupg key name
"""
return getattr(self,'gpg_key','')
return getattr(self, 'gpg_key', '')
def setGPGKey(self, value):
"""
......@@ -971,7 +971,7 @@ class Subscription(Folder, SyncCode):
"""
set the type of media used
"""
if media_type in (None,''):
if media_type in (None, ''):
media_type = self.MEDIA_TYPE['TEXT_XML']
self.media_type = media_type
......@@ -985,7 +985,7 @@ class Subscription(Folder, SyncCode):
"""
set the login at new_login
"""
self.login=new_login
self.login = new_login
def getPassword(self):
"""
......@@ -997,8 +997,7 @@ class Subscription(Folder, SyncCode):
"""
set the password at new_password
"""
self.password=new_password
self.password = new_password
def setAuthentication(self, auth):
"""
......@@ -1037,7 +1036,7 @@ class Subscription(Folder, SyncCode):
o_gid = None
gid_gen = self.getGidGenerator()
if callable(gid_gen):
o_gid=gid_gen(object)
o_gid = gid_gen(object)
elif getattr(o_base, gid_gen, None) is not None:
generator = getattr(object, gid_gen)
o_gid = generator() # XXX - used to be o_gid = generator(object=object) which is redundant
......@@ -1066,17 +1065,17 @@ class Subscription(Folder, SyncCode):
o_id = signature.getObjectId()
#try with id param too, because gid is not catalogged
object_list = self.getObjectList(gid = b16decode(gid), id = o_id)
#LOG('getObjectFromGid :',0,'object_list=%s, gid=%s, o_id=%s' % (object_list, gid, o_id))
LOG('getObjectFromGid :', DEBUG, 'object_list=%s, gid=%s, o_id=%s' % (object_list, gid, o_id))
if o is not None and o in object_list:
return o
#LOG('entering in the slow loop of getObjectFromGid !!!',0,'')
object_list = self.getObjectList(gid = b16decode(gid))
#LOG('getObjectFromGid :', 0, 'object_list slow loop=%s, gid=%s' % (object_list, gid))
LOG('getObjectFromGid :', DEBUG, 'object_list slow loop=%s, gid=%s' % (object_list, gid))
for o in object_list:
o_gid = self.getGidFromObject(o)
if o_gid == gid:
return o
#LOG('getObjectFromGid',0,'returning None')
LOG('getObjectFromGid', DEBUG, 'returning None')
return None
def getObjectFromId(self, id):
......@@ -1105,16 +1104,6 @@ class Subscription(Folder, SyncCode):
pass
return o
# def setOneWaySyncFromServer(self,value):
# """
# If this option is enabled, then we will not
# send our own modifications
# """
# self.one_way_sync_from_server = value
#
def getObjectList(self, **kw):
"""
This returns the list of sub-object corresponding
......@@ -1124,7 +1113,7 @@ class Subscription(Folder, SyncCode):
query = self.getQuery()
query_list = []
if query is not None and isinstance(query, str):
query_method = getattr(destination,query,None)
query_method = getattr(destination, query, None)
if query_method is not None:
query_list = query_method(**kw)
elif callable(query): # used in the test
......@@ -1132,7 +1121,7 @@ class Subscription(Folder, SyncCode):
return [x for x in query_list
if not getattr(x,'_conflict_resolution',False)]
def generateNewIdWithGenerator(self, object=None,gid=None):
def generateNewIdWithGenerator(self, object=None, gid=None):
"""
This tries to generate a new Id
"""
......@@ -1141,15 +1130,15 @@ class Subscription(Folder, SyncCode):
o_base = aq_base(object)
new_id = None
if callable(id_generator):
new_id = id_generator(object,gid=gid)
new_id = id_generator(object, gid=gid)
elif getattr(o_base, id_generator, None) is not None:
generator = getattr(object, id_generator)
new_id = generator()
else:
# This is probably a python script
generator = getattr(object, id_generator)
new_id = generator(object=object,gid=gid)
#LOG('generateNewId, new_id: ',0,new_id)
new_id = generator(object=object, gid=gid)
LOG('generateNewId, new_id: ', DEBUG, new_id)
return new_id
return None
......@@ -1158,7 +1147,7 @@ class Subscription(Folder, SyncCode):
This set the method name wich allows to generate
a new id
"""
if method in ('','None'):
if method in ('', 'None'):
method = None
self.synchronization_id_generator = method
......@@ -1229,9 +1218,6 @@ class Subscription(Folder, SyncCode):
"""
return the message id
"""
#self.message_id += 1
#return self.message_id
#return 5
value = getattr(self, 'message_id', 0)
self.message_id = value +1
return self.message_id
......@@ -1298,7 +1284,7 @@ class Subscription(Folder, SyncCode):
"""
add a Signature to the subscription
"""
if self.getSignatureFromGid(signature.getGid()) != None:
if self.getSignatureFromGid(signature.getGid()) is not None:
self.delSignature(signature.getGid())
self._setObject(signature.getGid(), aq_base(signature))
......@@ -1306,12 +1292,11 @@ class Subscription(Folder, SyncCode):
"""
del a Signature of the subscription
"""
#del self.signatures[gid]
self._delObject(gid)
def getSignatureFromObjectId(self, id):
"""
return the signature corresponding to the gid
return the signature corresponding to the id
"""
o = None
# XXX very slow
......@@ -1343,35 +1328,23 @@ class Subscription(Folder, SyncCode):
"""
Returns the list of gids from signature
"""
object_id_list = []
for signature in self.getSignatureList():
if signature.getObjectId() is not None:
object_id_list.append(signature.getObjectId())
return object_id_list
return [s for s in self.getSignatureList() if s.getObjectId() is not None]
def getGidList(self):
"""
Returns the list of gids from signature
"""
gid_list = []
for signature in self.getSignatureList():
if signature.getGid() is not None:
gid_list.append(signature.getGid())
return gid_list
return [s.getGid() for s in self.getSignatureList() if s.getGid() is not None]
def getRidList(self):
"""
Returns the list of rids from signature
"""
rid_list = []
for signature in self.getSignatureList():
if signature.getRid() is not None:
rid_list.append(signature.getRid())
return rid_list
return [s.getRid() for s in self.getSignatureList() if s.getRid() is not None]
def getSignatureList(self):
"""
add a Signature to the subscription
Returns the list of Signatures
"""
return self.objectValues()
......@@ -1379,16 +1352,17 @@ class Subscription(Folder, SyncCode):
"""
Check if there's a signature with this uid
"""
#return self.signatures.has_key(gid)
return self.getSignatureFromGid(gid) is not None
def resetAllSignatures(self):
"""
Reset all signatures
Reset all signatures in activities
"""
while len(self.objectIds())>0:
for id in self.objectIds():
self._delObject(id)
object_id_list = [id for id in self.getObjectIds()]
object_list_len = len(object_id_list)
for i in xrange(0, object_list_len, 100):
current_id_list = object_id_list[i:i+100]
self.activate().manage_delObjects(current_id_list)
def getConflictList(self):
"""
......@@ -1396,7 +1370,7 @@ class Subscription(Folder, SyncCode):
"""
conflict_list = []
for signature in self.getSignatureList():
conflict_list += signature.getConflictList()
conflict_list.extend(signature.getConflictList())
return conflict_list
def getRemainingObjectPathList(self):
......@@ -1404,14 +1378,14 @@ class Subscription(Folder, SyncCode):
We should now wich objects should still
synchronize
"""
return getattr(self,'remaining_object_path_list',None)
return getattr(self, 'remaining_object_path_list', None)
def setRemainingObjectPathList(self, value):
"""
We should now wich objects should still
synchronize
"""
setattr(self,'remaining_object_path_list',value)
setattr(self, 'remaining_object_path_list', value)
def removeRemainingObjectPath(self, object_path):
"""
......@@ -1430,13 +1404,14 @@ class Subscription(Folder, SyncCode):
"""
Set the status of every object as NOT_SYNCHRONIZED
"""
for o in self.objectValues():
for s in self.getSignatureList():
# Change the status only if we are not in a conflict mode
if not(o.getStatus() in (self.CONFLICT,self.PUB_CONFLICT_MERGE,
self.PUB_CONFLICT_CLIENT_WIN)):
o.setStatus(self.NOT_SYNCHRONIZED)
o.setPartialXML(None)
o.setTempXML(None)
if s.getStatus() not in (self.CONFLICT,
self.PUB_CONFLICT_MERGE,
self.PUB_CONFLICT_CLIENT_WIN):
s.setStatus(self.NOT_SYNCHRONIZED)
s.setPartialXML(None)
s.setTempXML(None)
self.setRemainingObjectPathList(None)
......@@ -1445,7 +1420,7 @@ class Subscription(Folder, SyncCode):
return True if the subscriber is authenticated for this session, False
in other case
"""
return self.is_authenticated
return getattr(self, 'is_authenticated', None)
def setAuthenticated(self, value):
"""
......@@ -1464,7 +1439,7 @@ class Subscription(Folder, SyncCode):
return b64encode(string_to_encode)
#elif format is .... put here the other formats
else:#if there is no format corresponding with format, raise an error
#LOG('encode : unknown or not implemented format :', 0, format)
LOG('encode : unknown or not implemented format : ', INFO, format)
raise ValueError, "Sorry, the server ask for the format %s but it's unknow or not implemented" % format
def decode(self, format, string_to_decode):
......@@ -1478,7 +1453,7 @@ class Subscription(Folder, SyncCode):
return b64decode(string_to_decode)
#elif format is .... put here the other formats
else:#if there is no format corresponding with format, raise an error
#LOG('decode : unknown or not implemented format :', 0, format)
LOG('decode : unknown or not implemented format :', INFO, format)
raise ValueError, "Sorry, the format %s is unknow or not implemented" % format
def isDecodeEncodeTheSame(self, string_encoded, string_decoded, format):
......@@ -1486,20 +1461,16 @@ class Subscription(Folder, SyncCode):
return True if the string_encoded is equal to string_decoded encoded
in format
"""
isTheSame=False
if self.encode(format, string_decoded) == string_encoded:
isTheSame=True
return isTheSame
return self.encode(format, string_decoded) == string_encoded
def setUser(self, user):
"""
save the user logged in to log him on each transaction
"""
self.user=user
self.user = user
def getUser(self):
"""
retrun the user logged in
"""
return self.user
return getattr(self, 'user', None)
......@@ -32,7 +32,7 @@ from XMLSyncUtils import XMLSyncUtils, Parse
import commands
from Conduit.ERP5Conduit import ERP5Conduit
from DateTime import DateTime
from zLOG import LOG
from zLOG import LOG, DEBUG, INFO
class SubscriptionSynchronization(XMLSyncUtils):
......@@ -100,11 +100,11 @@ class SubscriptionSynchronization(XMLSyncUtils):
status_code_syncHdr = status_list[0]['code']
if status_code_syncHdr.isdigit():
status_code_syncHdr = int(status_code_syncHdr)
#LOG('readResponse status code :',0,status_code_syncHdr)
LOG('SubSync status code : ', DEBUG, status_code_syncHdr)
if status_code_syncHdr == self.AUTH_REQUIRED:
if self.checkChal(xml_client):
authentication_format, authentication_type = self.getChal(xml_client)
#LOG('auth_required :',0, 'format:%s, type:%s' % (authentication_format, authentication_type))
LOG('SubSync auth_required :', DEBUG, 'format:%s, type:%s' % (authentication_format, authentication_type))
if authentication_format is not None and \
authentication_type is not None:
subscription.setAuthenticationFormat(authentication_format)
......@@ -113,11 +113,11 @@ class SubscriptionSynchronization(XMLSyncUtils):
raise ValueError, "Sorry, the server chalenge for an \
authentication, but the authentication format is not find"
#LOG('readResponse', 0, 'Authentication required')
LOG('SubSync', INFO, 'Authentication required')
response = self.SubSyncCred(subscription, xml_client)
elif status_code_syncHdr == self.UNAUTHORIZED:
LOG('readResponse', 0, 'Bad authentication')
return {'has_response':0,'xml':xml_client}
LOG('SubSync', INFO, 'Bad authentication')
return {'has_response':0, 'xml':xml_client}
else:
response = self.SubSyncModif(subscription, xml_client)
else:
......@@ -174,7 +174,7 @@ class SubscriptionSynchronization(XMLSyncUtils):
xml=xml_a,domain=subscription,
content_type=subscription.getSyncContentType())
return {'has_response':1,'xml':xml_a}
return {'has_response':1, 'xml':xml_a}
def SubSyncModif(self, subscription, xml_client):
"""
......
......@@ -40,6 +40,7 @@ class SyncCode(Persistent):
ONE_WAY_FROM_SERVER = 204
WAITING_DATA = 214
REFRESH_REQUIRED = 508
CODE_LIST = ( TWO_WAY, ONE_WAY_FROM_SERVER )
# SyncML Status Codes
SUCCESS = 200
......
......@@ -60,7 +60,7 @@ import string
import commands
import random
from DateTime import DateTime
from zLOG import LOG
from zLOG import LOG, TRACE, DEBUG, INFO
class TimeoutHTTPConnection(httplib.HTTPConnection):
"""
......@@ -372,8 +372,8 @@ class SynchronizationTool( SubscriptionSynchronization,
Return a list of publications
"""
folder = self.getObjectContainer()
object_list = folder.objectValues()
object_list = filter(lambda x: x.id.find('pub')==0,object_list)
object_list = [pub for pub in folder.objectValues() if pub.getDomainType() == self.PUB]
#object_list = filter(lambda x: x.id.find('pub')==0,object_list)
return object_list
security.declareProtected(Permissions.AccessContentsInformation,
......@@ -382,10 +382,12 @@ class SynchronizationTool( SubscriptionSynchronization,
"""
Return the publications with this id
"""
pub = None
for p in self.getPublicationList():
if p.getTitle() == title:
return p
return None
pub = p
break
return pub
security.declareProtected(Permissions.AccessContentsInformation,
'getObjectContainer')
......@@ -407,18 +409,19 @@ class SynchronizationTool( SubscriptionSynchronization,
Return a list of publications
"""
folder = self.getObjectContainer()
object_list = folder.objectValues()
object_list = filter(lambda x: x.id.find('sub')==0,object_list)
object_list = [sub for sub in folder.objectValues() if sub.getDomainType() == self.SUB]
#object_list = filter(lambda x: x.id.find('sub')==0,object_list)
return object_list
def getSubscription(self, title):
"""
Returns the subscription with this title
"""
sub = None
for s in self.getSubscriptionList():
if s.getTitle() == title:
return s
return None
sub = s
return sub
security.declareProtected(Permissions.AccessContentsInformation,
......@@ -426,7 +429,6 @@ class SynchronizationTool( SubscriptionSynchronization,
def getSynchronizationList(self):
"""
Returns the list of subscriptions and publications
"""
return self.getSubscriptionList() + self.getPublicationList()
......@@ -437,9 +439,9 @@ class SynchronizationTool( SubscriptionSynchronization,
Returns the list of subscribers and subscriptions
"""
s_list = []
s_list += self.getSubscriptionList()
s_list.extend(self.getSubscriptionList())
for publication in self.getPublicationList():
s_list += publication.getSubscriberList()
s_list.extend(publication.getSubscriberList())
return s_list
security.declareProtected(Permissions.AccessContentsInformation,
......@@ -458,27 +460,17 @@ class SynchronizationTool( SubscriptionSynchronization,
for subscriber in publication.getSubscriberList():
sub_conflict_list = subscriber.getConflictList()
for conflict in sub_conflict_list:
#conflict.setDomain('Publication')
conflict.setSubscriber(subscriber)
#conflict.setDomainId(subscriber.getId())
if path is None or conflict.getObjectPath() == path:
conflict_list += [conflict.__of__(subscriber)]
for subscription in self.getSubscriptionList():
sub_conflict_list = subscription.getConflictList()
#LOG('SynchronizationTool.getConflictList, sub_conflict_list',0,
#sub_conflict_list)
LOG('SynchronizationTool.getConflictList, sub_conflict_list', DEBUG,
sub_conflict_list)
for conflict in sub_conflict_list:
#conflict.setDomain('Subscription')
conflict.setSubscriber(subscription)
#conflict.setDomainId(subscription.getId())
if path is None or conflict.getObjectPath() == path:
conflict_list += [conflict.__of__(subscription)]
#if path is not None: # Retrieve only conflicts for a given path
# new_list = []
# for conflict in conflict_list:
# if conflict.getObjectPath() == path:
# new_list += [conflict.__of__(self)]
# return new_list
return conflict_list
security.declareProtected(Permissions.AccessContentsInformation,
......@@ -511,32 +503,32 @@ class SynchronizationTool( SubscriptionSynchronization,
path = self.resolveContext(context)
conflict_list = self.getConflictList()
state_list= []
#LOG('getSynchronizationState',0,'path: %s' % str(path))
LOG('getSynchronizationState', DEBUG, 'path: %s' % str(path))
for conflict in conflict_list:
if conflict.getObjectPath() == path:
#LOG('getSynchronizationState',0,'found a conflict: %s' % str(conflict))
LOG('getSynchronizationState', DEBUG, 'found a conflict: %s' % str(conflict))
state_list += [[conflict.getSubscriber(),self.CONFLICT]]
for domain in self.getSynchronizationList():
destination = domain.getDestinationPath()
#LOG('getSynchronizationState',0,'destination: %s' % str(destination))
LOG('getSynchronizationState', TRACE, 'destination: %s' % str(destination))
j_path = '/'.join(path)
#LOG('getSynchronizationState',0,'j_path: %s' % str(j_path))
LOG('getSynchronizationState', TRACE, 'j_path: %s' % str(j_path))
if j_path.find(destination)==0:
o_id = j_path[len(destination)+1:].split('/')[0]
#LOG('getSynchronizationState',0,'o_id: %s' % o_id)
LOG('getSynchronizationState', TRACE, 'o_id: %s' % o_id)
subscriber_list = []
if domain.domain_type==self.PUB:
subscriber_list = domain.getSubscriberList()
else:
subscriber_list = [domain]
#LOG('getSynchronizationState, subscriber_list:',0,subscriber_list)
LOG('getSynchronizationState, subscriber_list:', TRACE, subscriber_list)
for subscriber in subscriber_list:
signature = subscriber.getSignatureFromObjectId(o_id)
#XXX check if signature could be not None ...
if signature is not None:
state = signature.getStatus()
#LOG('getSynchronizationState:',0,'sub.dest :%s, state: %s' % \
#(subscriber.getSubscriptionUrl(),str(state)))
LOG('getSynchronizationState:', TRACE, 'sub.dest :%s, state: %s' % \
(subscriber.getSubscriptionUrl(),str(state)))
found = None
# Make sure there is not already a conflict giving the state
for state_item in state_list:
......@@ -546,6 +538,11 @@ class SynchronizationTool( SubscriptionSynchronization,
state_list += [[subscriber,state]]
return state_list
security.declareProtected(Permissions.AccessContentsInformation,
'getAlertCodeList')
def getAlertCodeList(self):
return self.CODE_LIST
security.declareProtected(Permissions.ModifyPortalContent,
'applyPublisherValue')
def applyPublisherValue(self, conflict):
......@@ -556,21 +553,21 @@ class SynchronizationTool( SubscriptionSynchronization,
object = self.unrestrictedTraverse(conflict.getObjectPath())
subscriber = conflict.getSubscriber()
# get the signature:
#LOG('p_sync.applyPublisherValue, subscriber: ',0,subscriber)
LOG('p_sync.applyPublisherValue, subscriber: ', DEBUG, subscriber)
signature = subscriber.getSignatureFromObjectId(object.getId()) # XXX may be change for rid
copy_path = conflict.getCopyPath()
#LOG('p_sync.applyPublisherValue, copy_path: ',0,copy_path)
LOG('p_sync.applyPublisherValue, copy_path: ', TRACE, copy_path)
signature.delConflict(conflict)
if signature.getConflictList() == []:
if copy_path is not None:
#LOG('p_sync.applyPublisherValue, conflict_list empty on : ',0,signature)
LOG('p_sync.applyPublisherValue, conflict_list empty on : ', TRACE, signature)
# Delete the copy of the object if the there is one
directory = object.aq_parent
copy_id = copy_path[-1]
#LOG('p_sync.applyPublisherValue, copy_id: ',0,copy_id)
LOG('p_sync.applyPublisherValue, copy_id: ', TRACE, copy_id)
if hasattr(directory.aq_base, 'hasObject'):
# optimize the case of a BTree folder
#LOG('p_sync.applyPublisherValue, deleting...: ',0,copy_id)
LOG('p_sync.applyPublisherValue, deleting...: ', TRACE, copy_id)
if directory.hasObject(copy_id):
directory._delObject(copy_id)
elif copy_id in directory.objectIds():
......@@ -584,10 +581,9 @@ class SynchronizationTool( SubscriptionSynchronization,
apply the publisher value for all conflict of the given document
"""
subscriber = conflict.getSubscriber()
#LOG('applyPublisherDocument, subscriber: ',0,subscriber)
for c in self.getConflictList(conflict.getObjectPath()):
if c.getSubscriber() == subscriber:
#LOG('applyPublisherDocument, applying on conflict: ',0,conflict)
LOG('applyPublisherDocument, applying on conflict: ', DEBUG, conflict)
c.applyPublisherValue()
security.declareProtected(Permissions.AccessContentsInformation,
......@@ -606,9 +602,8 @@ class SynchronizationTool( SubscriptionSynchronization,
apply the publisher value for all conflict of the given document
"""
publisher_object_path = self.getPublisherDocumentPath(conflict)
#LOG('getPublisherDocument publisher_object_path',0,publisher_object_path)
LOG('getPublisherDocument publisher_object_path', TRACE, publisher_object_path)
publisher_object = self.unrestrictedTraverse(publisher_object_path)
#LOG('getPublisherDocument publisher_object',0,publisher_object)
return publisher_object
......@@ -621,23 +616,23 @@ class SynchronizationTool( SubscriptionSynchronization,
Thus, the manager will be able to open both version of the document
before selecting which one to keep.
"""
subscriber = conflict.getSubscriber()
publisher_object_path = conflict.getObjectPath()
publisher_object = self.unrestrictedTraverse(publisher_object_path)
publisher_xml = self.getXMLObject(object=publisher_object,xml_mapping\
= subscriber.getXMLMapping())
publisher_xml = self.getXMLObject(
object=publisher_object,
xml_mapping=subscriber.getXMLMapping())
directory = publisher_object.aq_parent
object_id = docid
if object_id in directory.objectIds():
directory._delObject(object_id)
# Import the conduit and get it
conduit_name = subscriber.getConduit()
conduit_module = __import__('.'.join([Conduit.__name__, conduit_name]),
globals(), locals(), [''])
conduit = getattr(conduit_module, conduit_name)()
conduit.addNode(xml=publisher_xml,object=directory,object_id=object_id)
conduit = self.getConduitByName(conduit_name)
conduit.addNode(
xml=publisher_xml,
object=directory,
object_id=object_id)
subscriber_document = directory._getOb(object_id)
for c in self.getConflictList(conflict.getObjectPath()):
if c.getSubscriber() == subscriber:
......@@ -659,7 +654,6 @@ class SynchronizationTool( SubscriptionSynchronization,
security.declareProtected(Permissions.AccessContentsInformation,
'getSubscriberDocumentPath')
def getSubscriberDocumentPath(self, conflict):
"""
apply the publisher value for all conflict of the given document
......@@ -675,16 +669,11 @@ class SynchronizationTool( SubscriptionSynchronization,
object_id = self._getCopyId(publisher_object)
# Import the conduit and get it
conduit_name = subscriber.getConduit()
if conduit_name.startswith('Products'):
path = conduit_name
conduit_name = conduit_name.split('.')[-1]
conduit_module = __import__(path, globals(), locals(), [''])
conduit = getattr(conduit_module, conduit_name)()
else:
conduit_module = __import__('.'.join([Conduit.__name__, conduit_name]),
globals(), locals(), [''])
conduit = getattr(conduit_module, conduit_name)()
conduit.addNode(xml=publisher_xml,object=directory,object_id=object_id)
conduit = self.getConduitByName(conduit_name)
conduit.addNode(
xml=publisher_xml,
object=directory,
object_id=object_id)
subscriber_document = directory._getOb(object_id)
subscriber_document._conflict_resolution = 1
for c in self.getConflictList(conflict.getObjectPath()):
......@@ -735,9 +724,7 @@ class SynchronizationTool( SubscriptionSynchronization,
signature = subscriber.getSignatureFromObjectId(object.getId()) # XXX may be change for rid
# Import the conduit and get it
conduit_name = subscriber.getConduit()
conduit_module = __import__('.'.join([Conduit.__name__, conduit_name]),
globals(), locals(), [''])
conduit = getattr(conduit_module, conduit_name)()
conduit = self.getConduitByName(conduit_name)
for xupdate in conflict.getXupdateList():
conduit.updateNode(xml=xupdate,object=object,force=1)
if solve_conflict:
......@@ -771,15 +758,13 @@ class SynchronizationTool( SubscriptionSynchronization,
Version=Version CPS
"""
# Retrieve the conflict object
#LOG('manageLocalValue',0,'%s %s %s' % (str(subscription_url),
# str(property_id),
# str(object_path)))
LOG('manageLocalValue', DEBUG, '%s %s %s' % (str(subscription_url),
str(property_id),
str(object_path)))
for conflict in self.getConflictList():
#LOG('manageLocalValue, conflict:',0,conflict)
if conflict.getPropertyId() == property_id:
#LOG('manageLocalValue',0,'found the property_id')
if '/'.join(conflict.getObjectPath())==object_path:
if conflict.getSubscriber().getSubscriptionUrl()==subscription_url:
if '/'.join(conflict.getObjectPath()) == object_path:
if conflict.getSubscriber().getSubscriptionUrl() == subscription_url:
conflict.applyPublisherValue()
if RESPONSE is not None:
RESPONSE.redirect('manageConflicts')
......@@ -792,15 +777,13 @@ class SynchronizationTool( SubscriptionSynchronization,
Do whatever needed in order to store the remote value locally
and confirmed that the remote box should keep it's value
"""
#LOG('manageLocalValue',0,'%s %s %s' % (str(subscription_url),
# str(property_id),
# str(object_path)))
LOG('manageLocalValue', DEBUG, '%s %s %s' % (str(subscription_url),
str(property_id),
str(object_path)))
for conflict in self.getConflictList():
#LOG('manageLocalValue, conflict:',0,conflict)
if conflict.getPropertyId() == property_id:
#LOG('manageLocalValue',0,'found the property_id')
if '/'.join(conflict.getObjectPath())==object_path:
if conflict.getSubscriber().getSubscriptionUrl()==subscription_url:
if '/'.join(conflict.getObjectPath()) == object_path:
if conflict.getSubscriber().getSubscriptionUrl() == subscription_url:
conflict.applySubscriberValue()
if RESPONSE is not None:
RESPONSE.redirect('manageConflicts')
......@@ -811,8 +794,8 @@ class SynchronizationTool( SubscriptionSynchronization,
"""
"""
for conflict in self.getConflictList():
if '/'.join(conflict.getObjectPath())==object_path:
if conflict.getSubscriber().getSubscriptionUrl()==subscription_url:
if '/'.join(conflict.getObjectPath()) == object_path:
if conflict.getSubscriber().getSubscriptionUrl() == subscription_url:
conflict.applySubscriberDocument()
break
self.managePublisherDocument(object_path)
......@@ -826,7 +809,7 @@ class SynchronizationTool( SubscriptionSynchronization,
while retry:
retry = False
for conflict in self.getConflictList():
if '/'.join(conflict.getObjectPath())==object_path:
if '/'.join(conflict.getObjectPath()) == object_path:
conflict.applyPublisherDocument()
retry = True
break
......@@ -855,17 +838,15 @@ class SynchronizationTool( SubscriptionSynchronization,
We will look at the url and we will see if we need to send mail, http
response, or just copy to a file.
"""
#LOG('sendResponse, self.getPhysicalPath: ',0,self.getPhysicalPath())
#LOG('sendResponse, to_url: ',0,to_url)
#LOG('sendResponse, from_url: ',0,from_url)
#LOG('sendResponse, sync_id: ',0,sync_id)
#LOG('sendResponse, xml: \n',0,xml)
LOG('sendResponse, self.getPhysicalPath: ', DEBUG, self.getPhysicalPath())
LOG('sendResponse, to_url: ', DEBUG, to_url)
LOG('sendResponse, from_url: ', DEBUG, from_url)
LOG('sendResponse, sync_id: ', DEBUG, sync_id)
LOG('sendResponse, xml: \n', DEBUG, xml)
if content_type == self.CONTENT_TYPE['SYNCML_WBXML']:
xml = self.xml2wbxml(xml)
#LOG('sendHttpResponse, xml after wbxml: \n',0,self.hexdump(xml))
#LOG('sendHttpResponse, xml after wbxml: \n', DEBUG, self.hexdump(xml))
if isinstance(xml, unicode):
xml = xml.encode('utf-8')
if domain is not None:
......@@ -879,7 +860,7 @@ class SynchronizationTool( SubscriptionSynchronization,
(status,output)=commands.getstatusoutput('gpg --yes --homedir \
/var/lib/zope/Products/ERP5SyncML/gnupg_keys -r "%s" -se \
/tmp/%s.gz' % (gpg_key,filename))
#LOG('readResponse, gpg output:',0,output)
#LOG('readResponse, gpg output:', DEBUG, output)
encrypted = file('/tmp/%s.gz.gpg' % filename,'r')
xml = encrypted.read()
encrypted.close()
......@@ -889,15 +870,12 @@ class SynchronizationTool( SubscriptionSynchronization,
if isinstance(to_url, str):
if to_url.find('http://')==0:
domain = aq_base(domain)
#LOG('domain.domain_type',0,domain.domain_type)
#LOG("getattr(domain, 'getActivityEnabled', None)",0,getattr(domain, 'getActivityEnabled', None))
#LOG("domain.getActivityEnabled()",0,domain.getActivityEnabled())
if domain.domain_type == self.PUB and not domain.getActivityEnabled():
# not use activity
# XXX Make sure this is not a problem
return None
#use activities to send send an http response
#LOG('sendResponse, will start sendHttpResponse, xml',0,'')
LOG('sendResponse, will start sendHttpResponse, xml', DEBUG, '')
self.activate(activity='RAMQueue').sendHttpResponse(sync_id=sync_id,
to_url=to_url,
xml=xml,
......@@ -906,7 +884,6 @@ class SynchronizationTool( SubscriptionSynchronization,
elif to_url.find('file://')==0:
filename = to_url[len('file:/'):]
stream = file(filename,'w')
#LOG('sendResponse, filename: ',0,filename)
stream.write(xml)
stream.close()
# we have to use local files (unit testing for example
......@@ -914,17 +891,14 @@ class SynchronizationTool( SubscriptionSynchronization,
# we will send an email
to_address = to_url[len('mailto:'):]
from_address = from_url[len('mailto:'):]
self.sendMail(from_address,to_address,sync_id,xml)
self.sendMail(from_address, to_address, sync_id, xml)
return xml
security.declarePrivate('sendHttpResponse')
def sendHttpResponse(self, to_url=None, sync_id=None, xml=None,
domain_path=None, content_type='application/vnd.syncml+xml'):
domain = self.unrestrictedTraverse(domain_path)
#LOG('sendHttpResponse, self.getPhysicalPath: ',0,self.getPhysicalPath())
#LOG('sendHttpResponse, starting with domain:',0,domain)
#LOG('sendHttpResponse, xml:',0,xml)
LOG('sendHttpResponse, starting with domain:', DEBUG, domain)
if domain is not None:
if domain.domain_type == self.PUB and not domain.getActivityEnabled():
return xml
......@@ -932,7 +906,7 @@ class SynchronizationTool( SubscriptionSynchronization,
proxy_url = ''
if os.environ.has_key('http_proxy'):
proxy_url = os.environ['http_proxy']
#LOG('sendHttpResponse, proxy_url:',0,proxy_url)
LOG('sendHttpResponse, proxy_url:', DEBUG, proxy_url)
if proxy_url !='':
proxy_handler = urllib2.ProxyHandler({"http" :proxy_url})
else:
......@@ -965,7 +939,7 @@ class SynchronizationTool( SubscriptionSynchronization,
# - http://svn.zope.org/soap/trunk/
if domain.getSynchronizeWithERP5Sites():
LOG('Synchronization with another ERP5 instance ...',0,'')
LOG('Synchronization with another ERP5 instance ...', DEBUG, '')
if to_url.find('readResponse')<0:
to_url = to_url + '/portal_synchronizations/readResponse'
encoded = urllib.urlencode(to_encode)
......@@ -983,30 +957,20 @@ class SynchronizationTool( SubscriptionSynchronization,
self.activate(activity='RAMQueue').sendHttpResponse(to_url=to_url,
sync_id=sync_id, xml=xml, domain_path=domain.getPath(),
content_type=content_type)
LOG('sendHttpResponse, socket ERROR:',0,msg)
#LOG('sendHttpResponse, url,data',0,(url, data))
LOG('sendHttpResponse, socket ERROR:', INFO, msg)
LOG('sendHttpResponse, url, data', INFO, (url, data))
return
except urllib2.URLError, msg:
LOG("sendHttpResponse, can't open url %s :" % to_url, 0, msg)
LOG('sendHttpResponse, to_url,data',0,(to_url, data))
LOG("sendHttpResponse, can't open url %s :" % to_url, INFO, msg)
LOG('sendHttpResponse, to_url, data', INFO, (to_url, data))
return
#LOG('sendHttpResponse, before result, domain:',0,domain)
if domain is not None:
if domain.domain_type == self.SUB and not domain.getActivityEnabled():
#if we don't use activity :
gpg_key = domain.getGPGKey()
if result not in (None,''):
#if gpg_key not in ('',None):
# result = self.sendResponse(domain=domain,xml=result,send=0)
#uf = self.acl_users
#user = UnrestrictedUser('syncml','syncml',['Manager','Member'],'')
#user = uf.getUserById('syncml').__of__(uf)
#newSecurityManager(None, user)
#self.activate(activity='RAMQueue').readResponse(sync_id=sync_id,text=result)
self.readResponse(sync_id=sync_id,text=result)
if result not in (None, ''):
self.readResponse(sync_id=sync_id, text=result)
return result
security.declarePublic('sync')
......@@ -1016,68 +980,68 @@ class SynchronizationTool( SubscriptionSynchronization,
"""
# Login as a manager to make sure we can create objects
uf = self.acl_users
user = UnrestrictedUser('syncml','syncml',['Manager','Member'],'')
user = UnrestrictedUser('syncml', 'syncml', ['Manager', 'Member'], '')
newSecurityManager(None, user)
message_list = self.portal_activities.getMessageList()
#LOG('sync, message_list:',0,message_list)
LOG('sync, message_list:', DEBUG, message_list)
if len(message_list) == 0:
for subscription in self.getSubscriptionList():
#LOG('sync, type(subcription):',0,type(subscription))
LOG('sync, type(subcription):', DEBUG, type(subscription))
self.activate(activity='RAMQueue').SubSync(subscription.getPath())
security.declarePublic('readResponse')
def readResponse(self, text=None, sync_id=None, to_url=None, from_url=None):
def readResponse(self, text='', sync_id=None, to_url=None, from_url=None):
"""
We will look at the url and we will see if we need to send mail, http
response, or just copy to a file.
"""
#LOG('readResponse, text :', 0, text)
#LOG('readResponse, text :', 0, self.hexdump(text))
LOG('readResponse, text :', DEBUG, text)
#LOG('readResponse, hexdump(text) :', DEBUG, self.hexdump(text))
# Login as a manager to make sure we can create objects
uf = self.acl_users
user = uf.getUserById('syncml').__of__(uf)
user = UnrestrictedUser('syncml','syncml',['Manager','Member'],'')
user = UnrestrictedUser('syncml', 'syncml', ['Manager', 'Member'], '')
newSecurityManager(None, user)
status_code = None
if text is not None:
if text not in ('', None):
# XXX We will look everywhere for a publication/subsription with
# the id sync_id, this is not so good, but there is no way yet
# to know if we will call a publication or subscription XXX
gpg_key = ''
for publication in self.getPublicationList():
if publication.getTitle()==sync_id:
if publication.getTitle() == sync_id:
gpg_key = publication.getGPGKey()
domain = publication
if gpg_key == '':
for subscription in self.getSubscriptionList():
if subscription.getTitle()==sync_id:
if subscription.getTitle() == sync_id:
gpg_key = subscription.getGPGKey()
domain = subscription
# decrypt the message if needed
if gpg_key not in (None,''):
filename = str(random.randrange(1,2147483600)) + '.txt'
filename = str(random.randrange(1, 2147483600)) + '.txt'
encrypted = file('/tmp/%s.gz.gpg' % filename,'w')
encrypted.write(text)
encrypted.close()
(status,output)=commands.getstatusoutput('gpg --homedir \
/var/lib/zope/Products/ERP5SyncML/gnupg_keys -r "%s" --decrypt \
/tmp/%s.gz.gpg > /tmp/%s.gz' % (gpg_key, filename, filename))
#LOG('readResponse, gpg output:', 0, output)
LOG('readResponse, gpg output:', TRACE, output)
(status,output)=commands.getstatusoutput('gunzip /tmp/%s.gz' % filename)
decrypted = file('/tmp/%s' % filename,'r')
text = decrypted.read()
#LOG('readResponse, text:', 0, text)
LOG('readResponse, text:', TRACE, text)
decrypted.close()
commands.getstatusoutput('rm -f /tmp/%s' % filename)
commands.getstatusoutput('rm -f /tmp/%s.gz.gpg' % filename)
# Get the target and then find the corresponding publication or
# Subscription
#LOG('type(text) : ',0,type(text))
LOG('type(text) : ', TRACE, type(text))
if domain.getSyncContentType() == self.CONTENT_TYPE['SYNCML_WBXML']:
text = self.wbxml2xml(text)
#LOG('readResponse, text after wbxml :\n', 0, text)
LOG('readResponse, text after wbxml :\n', TRACE, text)
xml = Parse(text)
url = self.getTarget(xml)
for publication in self.getPublicationList():
......@@ -1089,37 +1053,33 @@ class SynchronizationTool( SubscriptionSynchronization,
text)
return ' '
else:
result = self.PubSync(publication.getPath(),xml)
result = self.PubSync(publication.getPath(), xml)
# Then encrypt the message
xml = result['xml']
#must be commented because this method is alredy called
#xml = self.sendResponse(xml=xml,domain=publication,send=0)
if publication.getSyncContentType() == self.CONTENT_TYPE['SYNCML_WBXML']:
if publication.getSyncContentType() ==\
self.CONTENT_TYPE['SYNCML_WBXML']:
xml = self.xml2wbxml(xml)
return xml
for subscription in self.getSubscriptionList():
if subscription.getSubscriptionUrl()==url and \
subscription.getTitle()==sync_id:
if subscription.getSubscriptionUrl() == url and \
subscription.getTitle() == sync_id:
subscription_path = self.getSubscription(sync_id).getPath()
self.activate(activity='RAMQueue').SubSync(subscription_path,
text)
return ' '
#result = self.SubSync(self.getSubscription(sync_id),xml)
# we use from only if we have a file
elif isinstance(from_url, str):
if from_url.find('file://')==0:
if from_url.find('file://') == 0:
try:
filename = from_url[len('file:/'):]
stream = file(filename,'r')
stream = file(filename, 'r')
xml = stream.read()
#stream.seek(0)
#LOG('readResponse',0,'Starting... msg: %s' % str(stream.read()))
LOG('readResponse', DEBUG, 'file... msg: %s' % str(stream.read()))
except IOError:
LOG('readResponse, cannot read file: ',0,filename)
LOG('readResponse, cannot read file: ', DEBUG, filename)
xml = None
if xml is not None and len(xml)==0:
if xml is not None and len(xml) == 0:
xml = None
return xml
......@@ -1140,14 +1100,11 @@ class SynchronizationTool( SubscriptionSynchronization,
return 'sub_' + title
security.declareProtected(Permissions.ModifyPortalContent, 'addNode')
def addNode(self, conduit='ERP5Conduit',**kw):
def addNode(self, conduit='ERP5Conduit', **kw):
"""
"""
# Import the conduit and get it
from Products.ERP5SyncML import Conduit
conduit_module = __import__('.'.join([Conduit.__name__, conduit]),
globals(), locals(), [''])
conduit_object = getattr(conduit_module, conduit)()
conduit_object = self.getConduitByName(conduit)
return conduit_object.addNode(**kw)
def hexdump(self, raw=''):
......
......@@ -33,11 +33,11 @@ from StringIO import StringIO
from xml.dom.ext import PrettyPrint
from ERP5Diff import ERP5Diff
import random
from zLOG import LOG
from zLOG import LOG, INFO, DEBUG, TRACE
try:
from Products.CMFActivity.ActiveObject import ActiveObject
except ImportError:
LOG('XMLSyncUtils',0,"Can't import ActiveObject")
LOG('XMLSyncUtils', INFO, "Can't import ActiveObject")
class ActiveObject:
pass
import commands
......@@ -45,7 +45,7 @@ import commands
try:
from Ft.Xml import Parse
except ImportError:
LOG('XMLSyncUtils',0,"Can't import Parse")
LOG('XMLSyncUtils', INFO, "Can't import Parse")
class Parse:
def __init__(self, *args, **kw):
raise ImportError, "Sorry, it was not possible to import Ft library"
......@@ -131,7 +131,6 @@ class XMLSyncUtilsMixin(SyncCode):
#list of element in the SyncBody bloc
syncbody_element_list = remote_xml.xpath('//SyncBody/*')
message_id = self.getMessageId(remote_xml)
xml_list = []
xml = xml_list.append
......@@ -155,8 +154,7 @@ class XMLSyncUtilsMixin(SyncCode):
xml(' </Status>\n')
#add the status bloc corresponding to the receive command
for syncbody_element in syncbody_element_list:
#LOG('SyncMLStatus : ',0,"command:%s, subscription:%s" % (str(syncbody_element.nodeName), subscription))
LOG('SyncMLStatus : ', DEBUG, "command:%s, subscription:%s" % (str(syncbody_element.nodeName), subscription))
if str(syncbody_element.nodeName) not in ('Status', 'Final', 'Get'):
xml(' <Status>\n')
xml(' <CmdID>%s</CmdID>\n' % cmd_id)
......@@ -172,8 +170,6 @@ class XMLSyncUtilsMixin(SyncCode):
source_ref = syncbody_element.xpath('string(.//Source/LocURI)').encode('utf-8')
if source_ref not in (None, ''):
xml(' <SourceRef>%s</SourceRef>\n' % source_ref )
#xml(' <Data>%s</Data>\n' % subscriber.getSynchronizationType())
if syncbody_element.nodeName.encode('utf-8') == 'Add':
xml(' <Data>%s</Data>\n' % str(self.ITEM_ADDED))
elif syncbody_element.nodeName.encode('utf-8') == 'Alert' and \
......@@ -183,8 +179,6 @@ class XMLSyncUtilsMixin(SyncCode):
else:
xml(' <Data>%s</Data>\n' % str(self.SUCCESS))
# if syncbody_element.xpath('.//Item') not in ([], None, '') and\
# syncbody_element.xpath('.//Item.....'): #contient une ancre Next...
if str(syncbody_element.nodeName) == 'Alert':
xml(' <Item>\n')
xml(' <Data>\n')
......@@ -197,8 +191,12 @@ class XMLSyncUtilsMixin(SyncCode):
if str(syncbody_element.nodeName) == 'Get' and subscription != None:
cmd_ref = syncbody_element.xpath('string(.//CmdID)').encode('utf-8')
syncml_result = self.SyncMLPut(cmd_id, subscription, markup='Results',
cmd_ref=cmd_ref, message_id=self.getMessageId(remote_xml))
syncml_result = self.SyncMLPut(
cmd_id,
subscription,
markup='Results',
cmd_ref=cmd_ref,
message_id=self.getMessageId(remote_xml))
xml(syncml_result)
cmd_id += 1
xml_a = ''.join(xml_list)
......@@ -271,18 +269,8 @@ class XMLSyncUtilsMixin(SyncCode):
but if the server use it to respond to a Get request, it's a <Result> markup
instead of <Put>
"""
from Products.ERP5SyncML import Conduit
# Import the conduit and get it
conduit_name = subscription.getConduit()
if conduit_name.startswith('Products'):
path = conduit_name
conduit_name = conduit_name.split('.')[-1]
conduit_module = __import__(path, globals(), locals(), [''])
conduit = getattr(conduit_module, conduit_name)()
else:
conduit_module = __import__('.'.join([Conduit.__name__, conduit_name]),
globals(), locals(), [''])
conduit = getattr(conduit_module, conduit_name)()
conduit = self.getConduitByName(conduit_name)
#if the conduit support the SyncMLPut :
if hasattr(conduit, 'getCapabilitiesCTTypeList') and \
hasattr(conduit, 'getCapabilitiesVerCTList') and \
......@@ -368,7 +356,7 @@ class XMLSyncUtilsMixin(SyncCode):
header = "Subject: %s\n" % id_sync
header += "To: %s\n\n" % toaddr
msg = header + msg
#LOG('SubSendMail',0,'from: %s, to: %s' % (fromaddr,toaddr))
LOG('SubSendMail', DEBUG,'from: %s, to: %s' % (fromaddr,toaddr))
server = smtplib.SMTP('localhost')
server.sendmail(fromaddr, toaddr, msg)
# if we want to send the email to someone else (debugging)
......@@ -376,7 +364,7 @@ class XMLSyncUtilsMixin(SyncCode):
server.quit()
def addXMLObject(self, cmd_id=0, object=None, xml_string=None,
more_data=0,gid=None, media_type=None):
more_data=0, gid=None, media_type=None):
"""
Add an object with the SyncML protocol
"""
......@@ -423,8 +411,6 @@ class XMLSyncUtilsMixin(SyncCode):
xml(' <Source>\n')
xml(' <LocURI>%s</LocURI>\n' % object_gid)
xml(' </Source>\n')
#xml(' <Data>\n') #this 2 lines seems to be useless
#xml(' </Data>\n')
xml(' </Item>\n')
xml(' </Delete>\n')
xml_a = ''.join(xml_list)
......@@ -472,7 +458,7 @@ class XMLSyncUtilsMixin(SyncCode):
attr_ns = xupdate_doc.createAttribute('xmlns:xupdate')
attr_ns.value = 'http://www.xmldb.org/xupdate'
attr_version = xupdate_doc.createAttribute('version')
attr_version.value='1.0'
attr_version.value = '1.0'
xupdate_doc.documentElement.setAttributeNode(attr_ns)
xupdate_doc.documentElement.setAttributeNode(attr_version)
xupdate = xupdate_doc.toxml()
......@@ -574,13 +560,12 @@ class XMLSyncUtilsMixin(SyncCode):
"""
Return the value of the command inside the xml_stream
"""
cmd = None
if xml.nodeName=='Status':
cmd = xml.xpath('string(//Status/Cmd)')
if isinstance(cmd, unicode):
cmd = cmd.encode('utf-8')
return cmd
else:
return None
def getCred(self, xml):
"""
......@@ -604,9 +589,7 @@ class XMLSyncUtilsMixin(SyncCode):
"""
Check if there's a Cred section in the xml_stream
"""
if xml_stream.xpath('string(SyncML/SyncHdr/Cred)') not in ('', None, []):
return True
return False
return xml_stream.xpath('string(SyncML/SyncHdr/Cred)') not in ('', None, [])
def getChal(self, xml):
"""
......@@ -627,19 +610,13 @@ class XMLSyncUtilsMixin(SyncCode):
"""
Check if there's a Chal section in the xml_stream
"""
if xml_stream.xpath('string(SyncML/SyncBody/Status/Chal)') \
not in ('', None, []):
return True
return False
return xml_stream.xpath('string(SyncML/SyncBody/Status/Chal)') not in ('', None, [])
def checkMap(self, xml_stream):
"""
Check if there's a Map section in the xml_stream
"""
if xml_stream.xpath('string(SyncML/SyncBody/Map)') \
not in ('', None, []):
return True
return False
return xml_stream.xpath('string(SyncML/SyncBody/Map)') not in ('', None, [])
def setRidWithMap(self, xml_stream, subscriber):
"""
......@@ -667,28 +644,19 @@ class XMLSyncUtilsMixin(SyncCode):
"""
Check if there's an Alert section in the xml_stream
"""
alert = False
if xml_stream.xpath('string(SyncML/SyncBody/Alert)') not in ('', None, []):
alert = True
return alert
return xml_stream.xpath('string(SyncML/SyncBody/Alert)') not in ('', None, [])
def checkSync(self, xml_stream):
"""
Check if there's an Sync section in the xml_xtream
"""
sync = False
if xml_stream.xpath('string(SyncML/SyncBody/Sync)') not in ('', None, []):
sync = True
return sync
return xml_stream.xpath('string(SyncML/SyncBody/Sync)') not in ('', None, [])
def checkStatus(self, xml_stream):
"""
Check if there's a Status section in the xml_xtream
"""
status = False
if xml_stream.xpath('string(SyncML/SyncBody/Status)') not in ('', None, []):
status = True
return status
return xml_stream.xpath('string(SyncML/SyncBody/Status)') not in ('', None, [])
def getSyncActionList(self, xml_stream):
"""
......@@ -755,9 +723,7 @@ class XMLSyncUtilsMixin(SyncCode):
"""
Return the rid of the object described by the action
"""
if action.xpath('Item/MoreData') not in ([],None) :
return True
return False
return action.xpath('Item/MoreData') not in ([],None)
def getActionType(self, action):
"""
......@@ -800,7 +766,7 @@ class XMLSyncUtilsMixin(SyncCode):
if object is not None, this usually means we want to set the
actual xupdate on the signature.
"""
LOG('getSyncMLData starting...',0,'')
LOG('getSyncMLData starting...', DEBUG, domain.getId())
if isinstance(conduit, str):
conduit = self.getConduitByName(conduit)
local_gid_list = []
......@@ -815,21 +781,22 @@ class XMLSyncUtilsMixin(SyncCode):
local_gid_list = map(lambda x: domain.getGidFromObject(x),object_list)
# Objects to remove
#LOG('remove object to remove ...',0,'')
LOG('remove object to remove ...', DEBUG, '')
for object_gid in subscriber.getGidList():
if object_gid not in local_gid_list:
# This is an object to remove
signature = subscriber.getSignatureFromGid(object_gid)
if signature.getStatus()!=self.PARTIAL: # If partial, then we have a signature
# but no local object
if signature.getStatus() != self.PARTIAL:
# If partial, then we have a signature but no local object
xml_object = signature.getXML()
if xml_object is not None: # This prevent to delete an object that
# we were not able to create
rid = signature.getRid()
#if rid != None:
# object_gid=rid #to use the remote id if it exist
syncml_data += self.deleteXMLObject(xml_object=signature.getXML()\
or '', object_gid=object_gid, rid=rid,cmd_id=cmd_id)
syncml_data += self.deleteXMLObject(
xml_object=signature.getXML() or '',
object_gid=object_gid,
rid=rid,
cmd_id=cmd_id)
cmd_id += 1
#delete Signature if object does not exist anymore
for known_gid in subscriber.getGidList():
......@@ -851,18 +818,18 @@ class XMLSyncUtilsMixin(SyncCode):
if syncml_data.count('\n') < self.MAX_LINES and not \
object.id.startswith('.'):
# If not we have to cut
#LOG('getSyncMLData',0,'object_path: %s' % '/'.join(object_path))
#LOG('getSyncMLData',0,'xml_mapping: %s' % str(domain.getXMLMapping()))
#LOG('getSyncMLData',0,'code: %s' % str(self.getAlertCode(remote_xml)))
#LOG('getSyncMLData',0,'gid_list: %s' % str(local_gid_list))
#LOG('getSyncMLData',0,'subscriber.getGidList: %s' % subscriber.getGidList())
#LOG('getSyncMLData',0,'hasSignature: %s' % str(subscriber.hasSignature(object_gid)))
#LOG('getSyncMLData',0,'alert_code == slowsync: %s' % str(self.getAlertCode(remote_xml)==self.SLOW_SYNC))
LOG('getSyncMLData', DEBUG, 'object_path: %s' % '/'.join(object_path))
LOG('getSyncMLData', DEBUG, 'xml_mapping: %s' % str(domain.getXMLMapping()))
LOG('getSyncMLData', DEBUG, 'code: %s' % str(self.getAlertCode(remote_xml)))
LOG('getSyncMLData', DEBUG, 'gid_list: %s' % str(local_gid_list))
LOG('getSyncMLData', DEBUG, 'subscriber.getGidList: %s' % subscriber.getGidList())
LOG('getSyncMLData', DEBUG, 'hasSignature: %s' % str(subscriber.hasSignature(object_gid)))
LOG('getSyncMLData', DEBUG, 'alert_code == slowsync: %s' % str(self.getAlertCode(remote_xml) == self.SLOW_SYNC))
signature = subscriber.getSignatureFromGid(object_gid)
## Here we first check if the object was modified or not by looking at dates
#if signature is not None:
#LOG('getSyncMLData',0,'signature.getStatus: %s' % signature.getStatus())
#LOG('getSyncMLData', DEBUG, 'signature.getStatus: %s' % signature.getStatus())
status = self.SENT
more_data=0
# For the case it was never synchronized, we have to send everything
......@@ -871,13 +838,13 @@ class XMLSyncUtilsMixin(SyncCode):
elif signature is None or (signature.getXML() is None and \
signature.getStatus() != self.PARTIAL) or \
self.getAlertCode(remote_xml) == self.SLOW_SYNC:
#LOG('getSyncMLData',0,'Current object.getPath: %s' % object.getPath())
LOG('getSyncMLData', DEBUG, 'Current object.getPath: %s' % object.getPath())
xml_object = domain.getXMLFromObject(object)
xml_string = xml_object
if isinstance(xml_string, unicode):
xml_string = xml_object.encode('utf-8')
gid = subscriber.getGidFromObject(object)
signature = Signature(id=gid,object=object)
signature = Signature(id=gid, object=object)
signature.setTempXML(xml_object)
if xml_string.count('\n') > self.MAX_LINES:
if xml_string.find('--') >= 0: # This make comment fails, so we need to replace
......@@ -890,7 +857,7 @@ class XMLSyncUtilsMixin(SyncCode):
short_string += rest_string[:rest_string.find('\n')+1]
rest_string = xml_string[len(short_string):]
i += 1
#LOG('getSyncMLData',0,'setPartialXML with: %s' % str(rest_string))
LOG('getSyncMLData', DEBUG, 'setPartialXML with: %s' % str(rest_string))
signature.setPartialXML(rest_string)
status = self.PARTIAL
signature.setAction('Add')
......@@ -898,20 +865,27 @@ class XMLSyncUtilsMixin(SyncCode):
gid = signature.getRid()#in fisrt, we try with rid if there is one
if gid == None:
gid = signature.getGid()
syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object,
gid=gid, xml_string=xml_string,
more_data=more_data, media_type=subscriber.getMediaType())
syncml_data += self.addXMLObject(
cmd_id=cmd_id,
object=object,
gid=gid,
xml_string=xml_string,
more_data=more_data,
media_type=subscriber.getMediaType())
cmd_id += 1
signature.setStatus(status)
subscriber.addSignature(signature)
elif signature.getStatus()==self.NOT_SYNCHRONIZED \
or signature.getStatus()==self.PUB_CONFLICT_MERGE: # We don't have synchronized this object yet
elif signature.getStatus() == self.NOT_SYNCHRONIZED \
or signature.getStatus() == self.PUB_CONFLICT_MERGE:
# We don't have synchronized this object yet
xml_object = domain.getXMLFromObject(object)
#LOG('getSyncMLData',0,'checkMD5: %s' % str(signature.checkMD5(xml_object)))
#LOG('getSyncMLData',0,'getStatus: %s' % str(signature.getStatus()))
if signature.getStatus()==self.PUB_CONFLICT_MERGE:
xml_confirmation += self.SyncMLConfirmation(cmd_id=cmd_id,
source_ref=signature.getGid(), sync_code=self.CONFLICT_MERGE,
LOG('getSyncMLData', DEBUG, 'checkMD5: %s' % str(signature.checkMD5(xml_object)))
LOG('getSyncMLData', DEBUG, 'getStatus: %s' % str(signature.getStatus()))
if signature.getStatus() == self.PUB_CONFLICT_MERGE:
xml_confirmation += self.SyncMLConfirmation(
cmd_id=cmd_id,
source_ref=signature.getGid(),
sync_code=self.CONFLICT_MERGE,
cmd='Replace')
set_synchronized = 1
if not signature.checkMD5(xml_object):
......@@ -926,25 +900,27 @@ class XMLSyncUtilsMixin(SyncCode):
if xml_string.count('\n') > self.MAX_LINES:
# This make comment fails, so we need to replace
if xml_string.find('--') >= 0:
xml_string = xml_string.replace('--','@-@@-@')
xml_string = xml_string.replace('--', '@-@@-@')
i = 0
more_data=1
short_string = ''
more_data = 1
short_string_list = []
short_string_list_ap = short_string_list.append
rest_string = xml_string
while i < self.MAX_LINES:
short_string += rest_string[:rest_string.find('\n')+1]
rest_string = xml_string[len(short_string):]
short_string_list_ap(rest_string[:rest_string.find('\n')+1])
rest_string = xml_string[len(''.join(short_string_list)):]
i += 1
signature.setPartialXML(rest_string)
status = self.PARTIAL
signature.setAction('Replace')
xml_string = '<!--' + short_string + '-->'
xml_string = '<!--' + ''.join(short_string_list) + '-->'
signature.setStatus(status)
if subscriber.getMediaType() != self.MEDIA_TYPE['TEXT_XML']:
xml_string = domain.getXMLFromObject(object)
rid = signature.getRid()#in fisrt, we try with rid if there is one
gid = signature.getGid()
syncml_data += self.replaceXMLObject(cmd_id=cmd_id, object=object,
syncml_data += self.replaceXMLObject(
cmd_id=cmd_id, object=object,
gid=gid, rid=rid,
xml_string=xml_string,
more_data=more_data,
......@@ -953,42 +929,51 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setTempXML(xml_object)
# Now we can apply the xupdate from the subscriber
subscriber_xupdate = signature.getSubscriberXupdate()
#LOG('getSyncMLData subscriber_xupdate',0,subscriber_xupdate)
LOG('getSyncMLData subscriber_xupdate', DEBUG, subscriber_xupdate)
if subscriber_xupdate is not None:
old_xml = signature.getXML()
conduit.updateNode(xml=subscriber_xupdate, object=object,
previous_xml=old_xml, force=(domain.getDomainType() == self.SUB),
conduit.updateNode(
xml=subscriber_xupdate,
object=object,
previous_xml=old_xml,
force=(domain.getDomainType() == self.SUB),
simulate=0)
xml_object = domain.getXMLFromObject(object)
signature.setTempXML(xml_object)
if set_synchronized: # We have to do that after this previous update
# We should not have this case when we are in CONFLICT_MERGE
signature.setStatus(self.SYNCHRONIZED)
elif signature.getStatus()==self.PUB_CONFLICT_CLIENT_WIN:
elif signature.getStatus() == self.PUB_CONFLICT_CLIENT_WIN:
# We have decided to apply the update
# XXX previous_xml will be geXML instead of getTempXML because
# some modification was already made and the update
# may not apply correctly
xml_update = signature.getPartialXML()
conduit.updateNode(xml=signature.getPartialXML(), object=object,
previous_xml=signature.getXML(),force=1)
xml_confirmation += self.SyncMLConfirmation(cmd_id=cmd_id,
target_ref=object_gid, sync_code=self.CONFLICT_CLIENT_WIN,
conduit.updateNode(
xml=signature.getPartialXML(),
object=object,
previous_xml=signature.getXML(),
force=1)
xml_confirmation += self.SyncMLConfirmation(
cmd_id=cmd_id,
target_ref=object_gid,
sync_code=self.CONFLICT_CLIENT_WIN,
cmd='Replace')
signature.setStatus(self.SYNCHRONIZED)
elif signature.getStatus()==self.PARTIAL:
elif signature.getStatus() == self.PARTIAL:
xml_string = signature.getPartialXML()
if xml_string.count('\n') > self.MAX_LINES:
i = 0
more_data=1
short_string = ''
short_string_list = []
short_string_list_ap = short_string_list.append
rest_string = xml_string
while i < self.MAX_LINES:
short_string += rest_string[:rest_string.find('\n')+1]
rest_string = xml_string[len(short_string):]
short_string_list_ap(rest_string[:rest_string.find('\n')+1])
rest_string = xml_string[len(''.join(short_string_list)):]
i += 1
signature.setPartialXML(rest_string)
xml_string = short_string
xml_string = ''.join(short_string_list)
status = self.PARTIAL
if xml_string.find('--') >= 0: # This make comment fails, so we need to replace
xml_string = xml_string.replace('--','@-@@-@')
......@@ -996,20 +981,28 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setStatus(status)
if(subscriber.getMediaType() != self.MEDIA_TYPE['TEXT_XML']):
xml_string = domain.getXMLFromObject(object)
#LOG('xml_string =', 0, xml_string)
if signature.getAction()=='Replace':
if signature.getAction() == 'Replace':
rid = signature.getRid()#in fisrt, we try with rid if there is one
gid = signature.getGid()
syncml_data += self.replaceXMLObject(cmd_id=cmd_id, object=object,
gid=gid, rid=rid, xml_string=xml_string, more_data=more_data,
syncml_data += self.replaceXMLObject(
cmd_id=cmd_id,
object=object,
gid=gid,
rid=rid,
xml_string=xml_string,
more_data=more_data,
media_type=subscriber.getMediaType())
elif signature.getAction()=='Add':
elif signature.getAction() == 'Add':
gid = signature.getRid()#in fisrt, we try with rid if there is one
if gid == None:
gid = signature.getGid()
syncml_data += self.addXMLObject(cmd_id=cmd_id, object=object,
gid=gid, xml_string=xml_string,
more_data=more_data, media_type=subscriber.getMediaType())
syncml_data += self.addXMLObject(
cmd_id=cmd_id,
object=object,
gid=gid,
xml_string=xml_string,
more_data=more_data,
media_type=subscriber.getMediaType())
if not more_data:
subscriber.removeRemainingObjectPath(object_path)
else:
......@@ -1022,7 +1015,7 @@ class XMLSyncUtilsMixin(SyncCode):
return result
def applyActionList(self, domain=None, subscriber=None, cmd_id=0,
remote_xml=None,conduit=None,simulate=0):
remote_xml=None, conduit=None, simulate=0):
"""
This just look to a list of action to do, then id applies
each action one by one, thanks to a conduit
......@@ -1030,8 +1023,8 @@ class XMLSyncUtilsMixin(SyncCode):
xml_confirmation = ''
has_next_action = 0
destination = self.unrestrictedTraverse(domain.getDestinationPath())
#LOG('applyActionList args',0,'domain : %s\n subscriber : %s\n cmd_id : %s' % (domain, subscriber, cmd_id))
LOG('applyActionList', 0, self.getSyncActionList(remote_xml))
LOG('applyActionList args', DEBUG, 'domain : %s\n subscriber : %s\n cmd_id : %s' % (domain.getPath(), subscriber.getPath(), cmd_id))
LOG('applyActionList', DEBUG, self.getSyncActionList(remote_xml))
for action in self.getSyncActionList(remote_xml):
if isinstance(action, unicode):
action = action.encode('utf-8')
......@@ -1047,19 +1040,19 @@ class XMLSyncUtilsMixin(SyncCode):
gid=rid
else:
gid=rid
object_id = domain.generateNewIdWithGenerator(object=destination,gid=gid)
object_id = domain.generateNewIdWithGenerator(object=destination, gid=gid)
signature = subscriber.getSignatureFromGid(gid)
if signature is not None and rid != gid:
#in this case, the object was created on another subscriber than erp5
# and we should save it's remote id
signature.setRid(rid)
#LOG('gid == rid ?', 0, 'gid=%s, rid=%s' % (gid, rid))
LOG('gid == rid ?', DEBUG, 'gid=%s, rid=%s' % (gid, rid))
object = subscriber.getObjectFromGid(gid)
if object == None:
object = subscriber.getObjectFromRid(rid)
#LOG('applyActionList subscriber.getObjectFromGid %s' % gid,0,object)
LOG('applyActionList subscriber.getObjectFromGid %s' % gid, DEBUG, object)
if signature is None:
#LOG('applyActionList, signature is None',0,signature)
LOG('applyActionList, signature is None', DEBUG, signature)
if gid == rid:
signature = Signature(id=gid, status=self.NOT_SYNCHRONIZED,
object=object).__of__(subscriber)
......@@ -1069,7 +1062,6 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setObjectId(object_id)
subscriber.addSignature(signature)
force = signature.getForce()
#LOG('applyActionList',0,'object: %s' % repr(object))
if self.checkActionMoreData(action) == 0:
data_subnode = None
if partial_data != None:
......@@ -1078,7 +1070,7 @@ class XMLSyncUtilsMixin(SyncCode):
data_subnode = signature.getPartialXML() + partial_data
else:
data_subnode = partial_data
#LOG('SyncModif',0,'data_subnode: %s' % data_subnode)
LOG('applyActionList', DEBUG, 'data_subnode: %s' % data_subnode)
if subscriber.getMediaType() == self.MEDIA_TYPE['TEXT_XML']:
data_subnode = Parse(data_subnode)
data_subnode = data_subnode.childNodes[0] # Because we just created a new xml
......@@ -1098,7 +1090,6 @@ class XMLSyncUtilsMixin(SyncCode):
conflict_list += add_data['conflict_list']
# Retrieve directly the object from addNode
object = add_data['object']
#LOG('XMLSyncUtils, in ADD add_data',0,add_data)
if object is not None:
signature.setPath(object.getPhysicalPath())
signature.setObjectId(object.getId())
......@@ -1113,7 +1104,7 @@ class XMLSyncUtilsMixin(SyncCode):
if add_data['conflict_list'] not in ('', None, []):
conflict_list += add_data['conflict_list']
if object is not None:
#LOG('SyncModif',0,'addNode, found the object')
LOG('applyActionList', DEBUG, 'addNode, found the object')
if reset:
#After a reset we want copy the LAST XML view on Signature.
#this implementation is not sufficient, need to be improved.
......@@ -1133,17 +1124,19 @@ class XMLSyncUtilsMixin(SyncCode):
remote_xml=action)
cmd_id +=1
elif action.nodeName == 'Replace':
#LOG('SyncModif',0,'object: %s will be updated...' % str(object))
LOG('applyActionList', DEBUG, 'object: %s will be updated...' % str(object))
if object is not None:
#LOG('SyncModif',0,'object: %s will be updated...' % object.id)
LOG('applyActionList', DEBUG, 'object: %s will be updated...' % object.id)
signature = subscriber.getSignatureFromGid(gid)
if signature is None:
signature = subscriber.getSignatureFromRid(gid)
#LOG('SyncModif',0,'previous signature: %s' % str(signature))
LOG('applyActionList', DEBUG, 'previous signature: %s' % str(signature))
previous_xml = signature.getXML()
#LOG('SyncModif',0,'previous signature: %i' % len(previous_xml))
conflict_list += conduit.updateNode(xml=data_subnode, object=object,
previous_xml=signature.getXML(),force=force,
conflict_list += conduit.updateNode(
xml=data_subnode,
object=object,
previous_xml=signature.getXML(),
force=force,
simulate=simulate)
xml_object = domain.getXMLFromObject(object)
signature.setTempXML(xml_object)
......@@ -1153,12 +1146,12 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setConflictList(signature.getConflictList() \
+ conflict_list)
string_io = StringIO()
PrettyPrint(data_subnode,stream=string_io)
PrettyPrint(data_subnode, stream=string_io)
data_subnode_string = string_io.getvalue()
signature.setPartialXML(data_subnode_string)
elif not simulate:
signature.setStatus(self.SYNCHRONIZED)
xml_confirmation += self.SyncMLConfirmation(\
xml_confirmation += self.SyncMLConfirmation(
cmd_id=cmd_id,
cmd='Replace',
sync_code=status_code,
......@@ -1169,21 +1162,23 @@ class XMLSyncUtilsMixin(SyncCode):
# the xupdate from the subscriber and we also want to generate
# the current xupdate from the last synchronization
string_io = StringIO()
PrettyPrint(data_subnode,stream=string_io)
PrettyPrint(data_subnode, stream=string_io)
data_subnode_string = string_io.getvalue()
#LOG('applyActionList, subscriber_xupdate:',0,data_subnode_string)
LOG('applyActionList, subscriber_xupdate:', TRACE, data_subnode_string)
signature.setSubscriberXupdate(data_subnode_string)
elif action.nodeName == 'Delete':
object_id = signature.getId()
#LOG('Delete on : ',0, (signature.getId(), subscriber.getObjectFromGid(object_id)))
LOG('applyActionList Delete on : ', DEBUG, (signature.getId(), subscriber.getObjectFromGid(object_id)))
if subscriber.getMediaType() != self.MEDIA_TYPE['TEXT_XML']:
data_subnode = self.getDataText(action)
else:
data_subnode = self.getDataSubNode(action)
if subscriber.getObjectFromGid(object_id) not in (None, ''):
#if the object exist:
conduit.deleteNode(xml=data_subnode, object=destination,
conduit.deleteNode(
xml=data_subnode,
object=destination,
object_id=subscriber.getObjectFromGid(object_id).getId())
subscriber.delSignature(gid)
xml_confirmation += self.SyncMLConfirmation(
......@@ -1193,16 +1188,13 @@ class XMLSyncUtilsMixin(SyncCode):
remote_xml=action)
else: # We want to retrieve more data
signature.setStatus(self.PARTIAL)
#LOG('SyncModif',0,'setPartialXML: %s' % str(previous_partial))
previous_partial = signature.getPartialXML() or ''
#if previous_partial.find(partial_data)<0: # XXX bad thing
previous_partial += partial_data
LOG('applyActionList', DEBUG, 'setPartialXML: %s' % str(previous_partial))
signature.setPartialXML(previous_partial)
#LOG('SyncModif',0,'previous_partial: %s' % str(previous_partial))
#LOG('SyncModif',0,'waiting more data for :%s' % signature.getId())
#xml_confirmation += self.SyncMLConfirmation(cmd_id, object_gid,
# self.WAITING_DATA, action.nodeName)
xml_confirmation += self.SyncMLConfirmation(\
LOG('applyActionList', DEBUG, 'previous_partial: %s' % str(previous_partial))
LOG('applyActionList', DEBUG, 'waiting more data for :%s' % signature.getId())
xml_confirmation += self.SyncMLConfirmation(
cmd_id=cmd_id,
cmd=action.nodeName,
sync_code=self.WAITING_DATA,
......@@ -1211,9 +1203,9 @@ class XMLSyncUtilsMixin(SyncCode):
# We had a conflict
signature.setStatus(self.CONFLICT)
return (xml_confirmation,has_next_action,cmd_id)
return (xml_confirmation, has_next_action, cmd_id)
def applyStatusList(self, subscriber=None,remote_xml=None):
def applyStatusList(self, subscriber=None, remote_xml=None):
"""
This read a list of status list (ie syncml confirmations).
This method have to change status codes on signatures
......@@ -1224,9 +1216,6 @@ class XMLSyncUtilsMixin(SyncCode):
if status_list != []:
for status in status_list:
status_cmd = status['cmd']
#if status_cmd in ('Delete'):
# object_gid = status['target']
#else:
object_gid = status['source']
if object_gid in ('', None, []):
object_gid = status['target']
......@@ -1298,20 +1287,17 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
"""
Modification Message, this is used after the first
message in order to send modifications.
"""
"""
Send the server modification, this happens after the Synchronization
initialization
"""
has_response = 0 #check if syncmodif replies to this messages
cmd_id = 1 # specifies a SyncML message-unique command identifier
LOG('SyncModif',0,'Starting... domain: %s' % str(domain))
LOG('SyncModif', DEBUG, 'Starting... domain: %s' % domain.getId())
first_node = remote_xml.childNodes[0]
# Get informations from the header
xml_header = first_node.childNodes[1]
if xml_header.nodeName != "SyncHdr":
LOG('PubSyncModif',0,'This is not a SyncML Header')
LOG('SyncModif', INFO, 'This is not a SyncML Header')
raise ValueError, "Sorry, This is not a SyncML Header"
subscriber = domain # If we are the client, this is fine
......@@ -1326,22 +1312,27 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
message_id = self.getMessageId(remote_xml)
correct_message = subscriber.checkCorrectRemoteMessageId(message_id)
if not correct_message: # We need to send again the message
LOG('SyncModif, no correct message:',0,"sending again...")
LOG('SyncModif, no correct message:', INFO, "sending again...")
last_xml = subscriber.getLastSentMessage()
LOG("last_xml :", 0, last_xml)
LOG("SyncModif last_xml :", INFO, last_xml)
if last_xml != '':
has_response = 1
if domain.domain_type == self.PUB: # We always reply
self.sendResponse(from_url=domain.publication_url,
to_url=subscriber.subscription_url, sync_id=domain.getTitle(),
self.sendResponse(
from_url=domain.publication_url,
to_url=subscriber.subscription_url,
sync_id=domain.getTitle(),
xml=last_xml,domain=domain,
content_type=domain.getSyncContentType())
elif domain.domain_type == self.SUB:
self.sendResponse(from_url=domain.subscription_url,
to_url=domain.publication_url, sync_id=domain.getTitle(),
xml=last_xml, domain=domain,
self.sendResponse(
from_url=domain.subscription_url,
to_url=domain.publication_url,
sync_id=domain.getTitle(),
xml=last_xml,
domain=domain,
content_type=domain.getSyncContentType())
return {'has_response':has_response,'xml':last_xml}
return {'has_response':has_response, 'xml':last_xml}
subscriber.setLastSentMessage('')
# First apply the list of status codes
......@@ -1359,35 +1350,42 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
subscriber=subscriber,
remote_xml=remote_xml,
conduit=conduit, simulate=simulate)
#LOG('SyncModif, has_next_action:',0,has_next_action)
xml_list = []
xml = xml_list.append
xml('<SyncML>\n')
# syncml header
if domain.domain_type == self.PUB:
xml(self.SyncMLHeader(subscriber.getSessionId(),
subscriber.incrementMessageId(), subscriber.getSubscriptionUrl(),
xml(self.SyncMLHeader(
subscriber.getSessionId(),
subscriber.incrementMessageId(),
subscriber.getSubscriptionUrl(),
domain.getPublicationUrl()))
elif domain.domain_type == self.SUB:
xml(self.SyncMLHeader(domain.getSessionId(), domain.incrementMessageId(),
domain.getPublicationUrl(), domain.getSubscriptionUrl()))
xml(self.SyncMLHeader(
domain.getSessionId(), domain.incrementMessageId(),
domain.getPublicationUrl(),
domain.getSubscriptionUrl()))
# Add or replace objects
syncml_data = ''
# syncml body
xml(' <SyncBody>\n')
xml_status, cmd_id = self.SyncMLStatus(remote_xml, self.SUCCESS, cmd_id,
subscriber.getNextAnchor(), subscription=subscriber).values()
xml_status, cmd_id = self.SyncMLStatus(
remote_xml,
self.SUCCESS,
cmd_id,
subscriber.getNextAnchor(),
subscription=subscriber).values()
xml(xml_status)
destination_url = ''
# alert message if we want more data
if destination_waiting_more_data == 1:
xml(self.SyncMLAlert(cmd_id, self.WAITING_DATA,
xml(self.SyncMLAlert(
cmd_id,
self.WAITING_DATA,
subscriber.getTargetURI(),
subscriber.getSourceURI(),
subscriber.getLastAnchor(),
......@@ -1432,14 +1430,17 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
domain = self.unrestrictedTraverse(kw['domain_relative_url'])
subscriber = self.unrestrictedTraverse(kw['subscriber_relative_url'])
conduit = subscriber.getConduit()
result = self.getSyncMLData(domain = domain, subscriber = subscriber,
conduit = conduit, max = self.MAX_OBJECTS, **kw)
result = self.getSyncMLData(
domain = domain,
subscriber = subscriber,
conduit = conduit,
max = self.MAX_OBJECTS,
**kw)
syncml_data = result['syncml_data']
cmd_id = result['cmd_id']
kw['syncml_data'] = syncml_data
kw['cmd_id'] = cmd_id
finished = result['finished']
#LOG('finished =',0,finished)
if not finished:
self.activate(activity='SQLQueue').SyncModifActivity(**kw)
else:
......@@ -1450,9 +1451,16 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
xml_list = kw['xml_list']
has_status_list = kw['has_status_list']
has_response = kw['has_response']
return self.sendSyncModif(syncml_data, cmd_id_before_getsyncmldata,
subscriber, domain, xml_confirmation,
remote_xml, xml_list, has_status_list, has_response)
return self.sendSyncModif(
syncml_data,
cmd_id_before_getsyncmldata,
subscriber,
domain,
xml_confirmation,
remote_xml,
xml_list,
has_status_list,
has_response)
def sendSyncModif(self, syncml_data, cmd_id_before_getsyncmldata, subscriber,
domain, xml_confirmation, remote_xml, xml_list,
......@@ -1479,18 +1487,23 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
if domain.domain_type == self.PUB: # We always reply
subscriber.setLastSentMessage(xml_a)
self.sendResponse(from_url=domain.publication_url,
to_url=subscriber.subscription_url, sync_id=domain.getTitle(),
xml=xml_a,domain=domain,
self.sendResponse(
from_url=domain.publication_url,
to_url=subscriber.subscription_url,
sync_id=domain.getTitle(),
xml=xml_a,
domain=domain,
content_type=domain.getSyncContentType())
has_response = 1
elif domain.domain_type == self.SUB:
if self.checkAlert(remote_xml) or \
(xml_confirmation,syncml_data)!=('','') or \
(xml_confirmation,syncml_data) != ('','') or \
has_status_list:
subscriber.setLastSentMessage(xml_a)
self.sendResponse(from_url=domain.subscription_url,
to_url=domain.publication_url, sync_id=domain.getTitle(),
self.sendResponse(
from_url=domain.subscription_url,
to_url=domain.publication_url,
sync_id=domain.getTitle(),
xml=xml_a,domain=domain,
content_type=domain.getSyncContentType())
has_response = 1
......@@ -1500,7 +1513,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
"""
convert xml string to wbxml using a temporary file
"""
LOG('xml2wbxml starting ...',0,'')
LOG('xml2wbxml starting ...', DEBUG, '')
import os
f = open('/tmp/xml2wbxml', 'w')
f.write(xml)
......@@ -1515,7 +1528,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
"""
convert wbxml string to xml using a temporary file
"""
LOG('wbxml2xml starting ...',0,'')
LOG('wbxml2xml starting ...', DEBUG, '')
import os
f = open('/tmp/wbxml2xml', 'w')
f.write(wbxml)
......
......@@ -48,7 +48,7 @@ class XupdateUtils(XMLSyncUtilsMixin):
for subnode in self.getElementNodeList(xupdate):
selection_name = ''
if subnode.nodeName in self.XUPDATE_INSERT_OR_ADD:
conflict_list += conduit.addNode(xml=subnode,object=object, \
conflict_list += conduit.addNode(xml=subnode, object=object, \
force=force, **kw)
elif subnode.nodeName in self.XUPDATE_DEL:
conflict_list += conduit.deleteNode(xml=subnode, object=object, \
......@@ -56,9 +56,6 @@ class XupdateUtils(XMLSyncUtilsMixin):
elif subnode.nodeName in self.XUPDATE_UPDATE:
conflict_list += conduit.updateNode(xml=subnode, object=object, \
force=force, **kw)
#elif subnode.nodeName in self.XUPDATE_INSERT:
# conflict_list += conduit.addNode(xml=subnode, object=object, force=force, **kw)
return conflict_list
......@@ -69,9 +69,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
<select name="alert_code">
<dtml-in getAlertCodeList>
<dtml-let item=sequence-item>
<option value="<dtml-var item>" <dtml-if expr="getAlertCode() == str(item)">SELECTED</dtml-if>><dtml-var item></option>
<option value="<dtml-var item>" <dtml-if expr="getAlertCode() == item">SELECTED</dtml-if>><dtml-var item></option>
</dtml-let>
</dtml-in>
</select>
</td>
</tr>
<tr>
......
......@@ -147,7 +147,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
</label></div>
</td>
<td align="left" valign="top">
<input type="checkbox" name="synchronize_with_erp5_sites" value="1">
<input type="checkbox" name="synchronize_with_erp5_sites" value="1" checked="checked">
</td>
</tr>
<tr>
......
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