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)
......@@ -143,9 +143,9 @@ class Publication(Subscription):
# Constructor
def __init__(self, id, title, publication_url, destination_path,
source_uri, query, xml_mapping, conduit, gpg_key, id_generator,
gid_generator, media_type, auth_required, authentication_format,
authentication_type, activity_enabled, synchronize_with_erp5_sites,
source_uri, query, xml_mapping, conduit, gpg_key, id_generator,
gid_generator, media_type, auth_required, authentication_format,
authentication_type, activity_enabled, synchronize_with_erp5_sites,
sync_content_type):
"""
constructor
......@@ -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:
return o
return None
o = None
for sub in self.getSubscriberList():
if sub.getSubscriptionUrl() == subscription_url:
o = sub
break
return o
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,14 +113,14 @@ 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(),
publication.getAuthenticationFormat(),
xml(self.SyncMLChal(cmd_id, "SyncHdr",
publication.getPublicationUrl(), subscriber.getSubscriptionUrl(),
publication.getAuthenticationFormat(),
publication.getAuthenticationType(), auth_code))
cmd_id += 1
# chal message
......@@ -154,8 +149,7 @@ class PublicationSynchronization(XMLSyncUtils):
break
else:
auth_code=self.UNAUTHORIZED
#in all others cases, the auth_code is set to 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:
......@@ -163,25 +157,25 @@ class PublicationSynchronization(XMLSyncUtils):
cmd_id, next_anchor, subscription=subscriber).values()
xml(xml_status)
# alert message
xml(self.SyncMLAlert(cmd_id, sync_type, subscriber.getTargetURI(),
subscriber.getSourceURI(), subscriber.getLastAnchor(),
xml(self.SyncMLAlert(cmd_id, sync_type, subscriber.getTargetURI(),
subscriber.getSourceURI(), subscriber.getLastAnchor(),
next_anchor))
cmd_id += 1
else:
# chal message
xml(self.SyncMLChal(cmd_id, "SyncHdr",
publication.getPublicationUrl(), subscriber.getSubscriptionUrl(),
publication.getAuthenticationFormat(),
xml(self.SyncMLChal(cmd_id, "SyncHdr",
publication.getPublicationUrl(), subscriber.getSubscriptionUrl(),
publication.getAuthenticationFormat(),
publication.getAuthenticationType(), auth_code))
cmd_id += 1
xml_status, cmd_id = self.SyncMLStatus(xml_client,
self.AUTH_REQUIRED, cmd_id, next_anchor,
xml_status, cmd_id = self.SyncMLStatus(xml_client,
self.AUTH_REQUIRED, cmd_id, next_anchor,
subscription=subscriber).values()
xml(xml_status)
elif alert is not None: #if no identification is required :
# syncml header
xml_status, cmd_id = self.SyncMLStatus(xml_client, self.AUTH_ACCEPTED,
xml_status, cmd_id = self.SyncMLStatus(xml_client, self.AUTH_ACCEPTED,
cmd_id, next_anchor, subscription=subscriber).values()
xml(xml_status)
# alert message
......@@ -203,28 +197,27 @@ 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(),
to_url=subscriber.getSubscriptionUrl(), sync_id=publication.getTitle(),
xml=xml_a, domain=publication,
to_url=subscriber.getSubscriptionUrl(), sync_id=publication.getTitle(),
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
......@@ -272,8 +264,8 @@ class PublicationSynchronization(XMLSyncUtils):
elif subscriber is not None:
# 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)
result = self.PubSyncInit(publication=publication, xml_client=None,
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):
......@@ -229,12 +229,11 @@ class Conflict(SyncCode, Base):
"""
copy_path = self.copy_path
return copy_path
def setCopyPath(self, path):
"""
"""
self.copy_path = path
class Signature(Folder,SyncCode):
"""
......@@ -249,10 +248,14 @@ class Signature(Folder,SyncCode):
"""
isIndexable = 0
isPortalContent = 0 # Make sure RAD generated accessors at the class level
# Constructor
def __init__(self, id=None, rid=None, status=None, xml_string=None,
object=None):
def __init__(self,
id=None,
rid=None,
status=None,
xml_string=None,
object=None):
if object is not None:
self.setPath(object.getPhysicalPath())
self.setObjectId(object.getId())
......@@ -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
......@@ -441,7 +444,7 @@ class Signature(Folder,SyncCode):
"""
set the rid
"""
if rid is type(u'a'):
if rid is type(u'a'):
rid = rid.encode('utf-8')
self.rid = rid
......@@ -455,7 +458,7 @@ class Signature(Folder,SyncCode):
"""
set the id
"""
if id is type(u'a'):
if id is type(u'a'):
id = id.encode('utf-8')
self.id = id
......@@ -469,7 +472,7 @@ class Signature(Folder,SyncCode):
"""
set the gid
"""
if gid is type(u'a'):
if gid is type(u'a'):
gid = gid.encode('utf-8')
self.gid = gid
......@@ -483,7 +486,7 @@ class Signature(Folder,SyncCode):
"""
set the id of the object associated to this signature
"""
if id is type(u'a'):
if id is type(u'a'):
id = id.encode('utf-8')
self.object_id = id
......@@ -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:
......@@ -646,10 +647,10 @@ class Subscription(Folder, SyncCode):
)
# Constructor
def __init__(self, id, title, publication_url, subscription_url,
destination_path, source_uri, target_uri, query, xml_mapping,
conduit, gpg_key, id_generator, gid_generator, media_type, login,
password, activity_enabled, alert_code, synchronize_with_erp5_sites,
def __init__(self, id, title, publication_url, subscription_url,
destination_path, source_uri, target_uri, query, xml_mapping,
conduit, gpg_key, id_generator, gid_generator, media_type, login,
password, activity_enabled, alert_code, synchronize_with_erp5_sites,
sync_content_type):
"""
We need to create a dictionnary of
......@@ -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)
......@@ -721,7 +721,7 @@ class Subscription(Folder, SyncCode):
setter for title
"""
self.title = value
def setSourceURI(self, value):
"""
setter for source_uri
......@@ -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):
......@@ -1103,17 +1102,7 @@ class Subscription(Folder, SyncCode):
o = destination.getPortalObject().restrictedTraverse(signature.getPath())
except:
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
#
return o
def getObjectList(self, **kw):
"""
......@@ -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
......@@ -1203,7 +1192,7 @@ class Subscription(Folder, SyncCode):
return the current subscription
"""
return self
def setSessionId(self, session_id):
"""
set the session id
......@@ -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
......@@ -1247,7 +1233,7 @@ class Subscription(Folder, SyncCode):
set the message id to 0
"""
self.message_id = 0
def setMessageId(self, message_id):
"""
set the message id to 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,8 +1420,8 @@ 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):
"""
set at True or False the value of is_authenticated is the subscriber
......@@ -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):
......@@ -48,8 +48,8 @@ class SubscriptionSynchronization(XMLSyncUtils):
xml = xml_list.append
xml('<SyncML>\n')
# syncml header
xml(self.SyncMLHeader(subscription.incrementSessionId(),
subscription.incrementMessageId(), subscription.getPublicationUrl(),
xml(self.SyncMLHeader(subscription.incrementSessionId(),
subscription.incrementMessageId(), subscription.getPublicationUrl(),
subscription.getSubscriptionUrl(), source_name=subscription.getLogin()))
# syncml body
......@@ -62,7 +62,7 @@ class SubscriptionSynchronization(XMLSyncUtils):
xml(self.SyncMLAlert(cmd_id, subscription.getSynchronizationType(),
subscription.getTargetURI(),
subscription.getSourceURI(),
subscription.getLastAnchor(),
subscription.getLastAnchor(),
subscription.getNextAnchor()))
cmd_id += 1
syncml_put = self.SyncMLPut(cmd_id, subscription)
......@@ -74,9 +74,9 @@ class SubscriptionSynchronization(XMLSyncUtils):
xml_a = ''.join(xml_list)
self.sendResponse(from_url=subscription.subscription_url,
to_url=subscription.publication_url, sync_id=subscription.getTitle(),
xml=xml_a,domain=subscription,
content_type=subscription.getSyncContentType())
to_url=subscription.publication_url, sync_id=subscription.getTitle(),
xml=xml_a,domain=subscription,
content_type=subscription.getSyncContentType())
return {'has_response':1,'xml':xml_a}
......@@ -87,7 +87,7 @@ class SubscriptionSynchronization(XMLSyncUtils):
response = None #check if subsync replies to this messages
subscription = self.unrestrictedTraverse(subscription_path)
if msg==None and (subscription.getSubscriptionUrl()).find('file')>=0:
msg = self.readResponse(sync_id=subscription.getSubscriptionUrl(),
msg = self.readResponse(sync_id=subscription.getSubscriptionUrl(),
from_url=subscription.getSubscriptionUrl())
if msg==None:
response = self.SubSyncInit(subscription)
......@@ -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,14 +113,14 @@ 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:
else:
response = self.SubSyncModif(subscription, xml_client)
if RESPONSE is not None:
......@@ -141,12 +141,12 @@ class SubscriptionSynchronization(XMLSyncUtils):
data=subscription.encode(subscription.getAuthenticationFormat(), data)
xml(self.SyncMLHeader(
subscription.incrementSessionId(),
subscription.incrementMessageId(),
subscription.incrementMessageId(),
subscription.getPublicationUrl(),
subscription.getSubscriptionUrl(),
source_name=subscription.getLogin(),
subscription.getSubscriptionUrl(),
source_name=subscription.getLogin(),
dataCred=data,
authentication_format=subscription.getAuthenticationFormat(),
authentication_format=subscription.getAuthenticationFormat(),
authentication_type=subscription.getAuthenticationType()))
# syncml body
......@@ -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):
"""
......@@ -76,7 +76,7 @@ class TimeoutHTTPHandler(urllib2.HTTPHandler):
class SynchronizationTool( SubscriptionSynchronization,
class SynchronizationTool( SubscriptionSynchronization,
PublicationSynchronization, UniqueObject, Folder):
"""
This tool implements the synchronization algorithm
......@@ -183,7 +183,7 @@ class SynchronizationTool( SubscriptionSynchronization,
authentication_type='', RESPONSE=None, activity_enabled = False,
sync_content_type='application/vnd.syncml+xml',
synchronize_with_erp5_sites=True):
"""
"""
create a new publication
"""
#if not('publications' in self.objectIds()):
......@@ -191,12 +191,12 @@ class SynchronizationTool( SubscriptionSynchronization,
# self._setObject(publications.id, publications)
folder = self.getObjectContainer()
new_id = self.getPublicationIdFromTitle(title)
pub = Publication(new_id, title, publication_url,
destination_path, source_uri, query, xml_mapping,
conduit, gpg_key, synchronization_id_generator,
gid_generator, media_type, auth_required,
authentication_format, authentication_type,
activity_enabled, synchronize_with_erp5_sites,
pub = Publication(new_id, title, publication_url,
destination_path, source_uri, query, xml_mapping,
conduit, gpg_key, synchronization_id_generator,
gid_generator, media_type, auth_required,
authentication_format, authentication_type,
activity_enabled, synchronize_with_erp5_sites,
sync_content_type)
folder._setObject( new_id, pub )
#if len(self.list_publications) == 0:
......@@ -205,16 +205,16 @@ class SynchronizationTool( SubscriptionSynchronization,
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'manage_addSubscription')
def manage_addSubscription(self, title, publication_url, subscription_url,
destination_path, source_uri, target_uri, query,
xml_mapping, conduit, gpg_key,
synchronization_id_generator=None, gid_generator=None,
media_type=None, login=None, password=None,
RESPONSE=None, activity_enabled=False,
alert_code=SyncCode.TWO_WAY,
synchronize_with_erp5_sites = True,
RESPONSE=None, activity_enabled=False,
alert_code=SyncCode.TWO_WAY,
synchronize_with_erp5_sites = True,
sync_content_type='application/vnd.syncml+xml'):
"""
XXX should be renamed as addSubscription
......@@ -308,7 +308,7 @@ class SynchronizationTool( SubscriptionSynchronization,
if RESPONSE is not None:
RESPONSE.redirect('manageSubscriptions')
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'manage_deletePublication')
def manage_deletePublication(self, title, RESPONSE=None):
"""
......@@ -320,7 +320,7 @@ class SynchronizationTool( SubscriptionSynchronization,
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'manage_deleteSubscription')
def manage_deleteSubscription(self, title, RESPONSE=None):
"""
......@@ -332,7 +332,7 @@ class SynchronizationTool( SubscriptionSynchronization,
if RESPONSE is not None:
RESPONSE.redirect('manageSubscriptions')
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'manage_resetPublication')
def manage_resetPublication(self, title, RESPONSE=None):
"""
......@@ -343,7 +343,7 @@ class SynchronizationTool( SubscriptionSynchronization,
if RESPONSE is not None:
RESPONSE.redirect('managePublications')
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'manage_resetSubscription')
def manage_resetSubscription(self, title, RESPONSE=None):
"""
......@@ -355,7 +355,7 @@ class SynchronizationTool( SubscriptionSynchronization,
if RESPONSE is not None:
RESPONSE.redirect('manageSubscriptions')
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'manage_syncSubscription')
def manage_syncSubscription(self, title, RESPONSE=None):
"""
......@@ -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,7 +538,12 @@ class SynchronizationTool( SubscriptionSynchronization,
state_list += [[subscriber,state]]
return state_list
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.AccessContentsInformation,
'getAlertCodeList')
def getAlertCodeList(self):
return self.CODE_LIST
security.declareProtected(Permissions.ModifyPortalContent,
'applyPublisherValue')
def applyPublisherValue(self, conflict):
"""
......@@ -556,38 +553,37 @@ 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():
directory._delObject(copy_id)
signature.setStatus(self.PUB_CONFLICT_MERGE)
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'applyPublisherDocument')
def applyPublisherDocument(self, conflict):
"""
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:
......@@ -646,7 +641,7 @@ class SynchronizationTool( SubscriptionSynchronization,
def _getCopyId(self, object):
directory = object.aq_inner.aq_parent
if directory.getId() != 'portal_repository':
if directory.getId() != 'portal_repository':
object_id = object.getId() + '_conflict_copy'
if object_id in directory.objectIds():
directory._delObject(object_id)
......@@ -656,10 +651,9 @@ class SynchronizationTool( SubscriptionSynchronization,
new_rev = repotool.getFreeRevision(docid) + 10 # make sure it's not gonna provoke conflicts
object_id = repotool._getId(docid, new_rev)
return object_id
security.declareProtected(Permissions.AccessContentsInformation,
'getSubscriberDocumentPath')
def getSubscriberDocumentPath(self, conflict):
"""
apply the publisher value for all conflict of the given document
......@@ -672,19 +666,14 @@ class SynchronizationTool( SubscriptionSynchronization,
publisher_object = self.unrestrictedTraverse(publisher_object_path)
publisher_xml = subscriber.getXMLFromObject(publisher_object)
directory = publisher_object.aq_inner.aq_parent
object_id = self._getCopyId(publisher_object)
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()):
......@@ -693,7 +682,7 @@ class SynchronizationTool( SubscriptionSynchronization,
copy_path = subscriber_document.getPhysicalPath()
conflict.setCopyPath(copy_path)
return copy_path
security.declareProtected(Permissions.AccessContentsInformation,
'getSubscriberDocument')
def getSubscriberDocument(self, conflict):
......@@ -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:
......@@ -756,9 +743,9 @@ class SynchronizationTool( SubscriptionSynchronization,
directory._delObject(copy_id)
signature.setStatus(self.PUB_CONFLICT_MERGE)
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'managePublisherValue')
def managePublisherValue(self, subscription_url, property_id, object_path,
def managePublisherValue(self, subscription_url, property_id, object_path,
RESPONSE=None):
"""
Do whatever needed in order to store the local value on
......@@ -766,20 +753,18 @@ class SynchronizationTool( SubscriptionSynchronization,
Suggestion (API)
add method to view document with applied xupdate
of a given subscriber XX
of a given subscriber XX
(ex. viewSubscriberDocument?path=ddd&subscriber_id=dddd)
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,31 +777,29 @@ 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')
security.declareProtected(Permissions.ModifyPortalContent,
security.declareProtected(Permissions.ModifyPortalContent,
'manageSubscriberDocument')
def manageSubscriberDocument(self, subscription_url, object_path):
"""
"""
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)
security.declareProtected(Permissions.ModifyPortalContent,
'managePublisherDocument')
def managePublisherDocument(self, 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,24 +870,20 @@ 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,
xml=xml,
domain_path=domain.getPath(),
content_type=content_type)
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,
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)
......@@ -980,33 +954,23 @@ class SynchronizationTool( SubscriptionSynchronization,
url_file = urllib2.urlopen(request)
result = url_file.read()
except socket.error, msg:
self.activate(activity='RAMQueue').sendHttpResponse(to_url=to_url,
sync_id=sync_id, xml=xml, domain_path=domain.getPath(),
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,
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=''):
......@@ -1162,29 +1119,29 @@ class SynchronizationTool( SubscriptionSynchronization,
start = 0
done = False
while not done:
end = start + 16
max = len(str(raw))
if end > max:
end = max
done = True
chunk = raw[start:end]
for i in xrange(len(chunk)):
if i > 0:
spacing = " "
else:
spacing = ""
buf += "%s%02x" % (spacing, ord(chunk[i]))
if done:
for i in xrange(16 - (end % 16)):
buf += " "
buf += " "
for c in chunk:
val = ord(c)
if val >= 33 and val <= 126:
buf += c
else:
buf += "."
buf += "\n"
start += 16
return buf
end = start + 16
max = len(str(raw))
if end > max:
end = max
done = True
chunk = raw[start:end]
for i in xrange(len(chunk)):
if i > 0:
spacing = " "
else:
spacing = ""
buf += "%s%02x" % (spacing, ord(chunk[i]))
if done:
for i in xrange(16 - (end % 16)):
buf += " "
buf += " "
for c in chunk:
val = ord(c)
if val >= 33 and val <= 126:
buf += c
else:
buf += "."
buf += "\n"
start += 16
return buf
InitializeClass( SynchronizationTool )
......@@ -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,15 +191,19 @@ 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)
return {'xml':xml_a, 'cmd_id':cmd_id}
def SyncMLConfirmation(self, cmd_id=None, target_ref=None, cmd=None,
sync_code=None, msg_ref=None, cmd_ref=None, source_ref=None,
def SyncMLConfirmation(self, cmd_id=None, target_ref=None, cmd=None,
sync_code=None, msg_ref=None, cmd_ref=None, source_ref=None,
remote_xml=None):
"""
This is used in order to confirm that an object was correctly
......@@ -238,8 +236,8 @@ class XMLSyncUtilsMixin(SyncCode):
xml(' </Status>\n')
xml_a = ''.join(xml_list)
return xml_a
def SyncMLChal(self, cmd_id, cmd, target_ref, source_ref, auth_format,
def SyncMLChal(self, cmd_id, cmd, target_ref, source_ref, auth_format,
auth_type, data_code):
"""
This is used in order to ask crendentials
......@@ -264,25 +262,15 @@ class XMLSyncUtilsMixin(SyncCode):
xml_a = ''.join(xml_list)
return xml_a
def SyncMLPut(self, cmd_id, subscription, markup='Put', cmd_ref=None,
def SyncMLPut(self, cmd_id, subscription, markup='Put', cmd_ref=None,
message_id=None):
"""
this is used to inform the server of the CTType version supported
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()
......@@ -488,7 +474,7 @@ class XMLSyncUtilsMixin(SyncCode):
session_id = xml.xpath('string(/SyncML/SyncHdr/SessionID)')
session_id = int(session_id)
return session_id
def getMessageId(self, xml):
"""
We will retrieve the message id of the message
......@@ -533,7 +519,7 @@ class XMLSyncUtilsMixin(SyncCode):
if isinstance(source_uri, unicode):
source_uri = source_uri.encode('utf-8')
return source_uri
def getTargetURI(self, xml):
"""
return the target uri of the data base
......@@ -551,7 +537,7 @@ class XMLSyncUtilsMixin(SyncCode):
if isinstance(subscription_url, unicode):
subscription_url = subscription_url.encode('utf-8')
return subscription_url
def getStatusTarget(self, xml):
"""
Return the value of the alert code inside the xml_stream
......@@ -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
return cmd
def getCred(self, xml):
"""
......@@ -604,14 +589,12 @@ 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):
"""
return the chalenge information : format and type
"""
"""
format=None
type=None
......@@ -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):
"""
......@@ -651,7 +628,7 @@ class XMLSyncUtilsMixin(SyncCode):
gid = map_item.xpath('string(.//Target/LocURI)').encode('utf-8')
signature = subscriber.getSignatureFromGid(gid)
rid = map_item.xpath('string(.//Source/LocURI)').encode('utf-8')
signature.setRid(rid)
signature.setRid(rid)
def getAlertCode(self, xml_stream):
"""
......@@ -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):
"""
......@@ -783,7 +749,7 @@ class XMLSyncUtilsMixin(SyncCode):
if subnode.nodeType == subnode.TEXT_NODE:
subnode_list += [subnode]
return subnode_list
def getAttributeNodeList(self, node):
"""
Return childNodes that are ElementNode
......@@ -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
# 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,21 +865,28 @@ 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,
cmd='Replace')
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):
set_synchronized = 0
......@@ -926,69 +900,80 @@ 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,
gid=gid, rid=rid,
xml_string=xml_string,
more_data=more_data,
media_type=subscriber.getMediaType())
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())
cmd_id += 1
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),
simulate=0)
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,
cmd='Replace')
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,
media_type=subscriber.getMediaType())
elif signature.getAction()=='Add':
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':
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,18 +1124,20 @@ 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,
simulate=simulate)
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)
if conflict_list != []:
......@@ -1153,67 +1146,66 @@ 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(\
cmd_id=cmd_id,
cmd='Replace',
sync_code=status_code,
remote_xml=action)
xml_confirmation += self.SyncMLConfirmation(
cmd_id=cmd_id,
cmd='Replace',
sync_code=status_code,
remote_xml=action)
cmd_id +=1
if simulate:
# This means we are on the publisher side and we want to store
# 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)))
if subscriber.getMediaType() != self.MEDIA_TYPE['TEXT_XML']:
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,
object_id=subscriber.getObjectFromGid(object_id).getId())
conduit.deleteNode(
xml=data_subnode,
object=destination,
object_id=subscriber.getObjectFromGid(object_id).getId())
subscriber.delSignature(gid)
xml_confirmation += self.SyncMLConfirmation(
cmd_id=cmd_id,
cmd='Delete',
sync_code=status_code,
remote_xml=action)
cmd_id=cmd_id,
cmd='Delete',
sync_code=status_code,
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(\
cmd_id=cmd_id,
cmd=action.nodeName,
sync_code=self.WAITING_DATA,
remote_xml=action)
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,
remote_xml=action)
if conflict_list != [] and signature is not None:
# 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,27 +1287,24 @@ 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
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
simulate = 0 # used by applyActionList, should be 0 for client
if domain.domain_type == self.PUB:
simulate = 1
subscription_url = self.getSubscriptionUrl(xml_header)
subscription_url = self.getSubscriptionUrl(xml_header)
subscriber = domain.getSubscriber(subscription_url)
# We have to check if this message was not already, this can be dangerous
......@@ -1326,72 +1312,84 @@ 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(),
xml=last_xml,domain=domain,
content_type=domain.getSyncContentType())
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,
content_type=domain.getSyncContentType())
return {'has_response':has_response,'xml':last_xml}
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}
subscriber.setLastSentMessage('')
# First apply the list of status codes
(destination_waiting_more_data,has_status_list) = self.applyStatusList(
subscriber=subscriber,
remote_xml=remote_xml)
subscriber=subscriber,
remote_xml=remote_xml)
alert_code = self.getAlertCode(remote_xml)
# Import the conduit and get it
conduit = self.getConduitByName(subscriber.getConduit())
# Then apply the list of actions
(xml_confirmation, has_next_action, cmd_id) = self.applyActionList(
cmd_id=cmd_id,
domain=domain,
subscriber=subscriber,
remote_xml=remote_xml,
conduit=conduit, simulate=simulate)
#LOG('SyncModif, has_next_action:',0,has_next_action)
cmd_id=cmd_id,
domain=domain,
subscriber=subscriber,
remote_xml=remote_xml,
conduit=conduit, simulate=simulate)
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(),
domain.getPublicationUrl()))
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,
subscriber.getTargetURI(),
subscriber.getSourceURI(),
subscriber.getLastAnchor(),
subscriber.getNextAnchor()))
xml(self.SyncMLAlert(
cmd_id,
self.WAITING_DATA,
subscriber.getTargetURI(),
subscriber.getSourceURI(),
subscriber.getLastAnchor(),
subscriber.getNextAnchor()))
# Now we should send confirmations
cmd_id_before_getsyncmldata = cmd_id
cmd_id = cmd_id+1
......@@ -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,20 +1487,25 @@ 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,
content_type=domain.getSyncContentType())
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(),
xml=xml_a,domain=domain,
content_type=domain.getSyncContentType())
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
return {'has_response':has_response,'xml':xml_a}
......@@ -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
......@@ -66,12 +66,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
</label></div>
</td>
<td align="left" valign="top">
<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>
</dtml-let>
</dtml-in>
<select name="alert_code">
<dtml-in getAlertCodeList>
<dtml-let item=sequence-item>
<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