Commit ee110eaa authored by Sebastien Robin's avatar Sebastien Robin

Commit the work of Fabien

- use list of string instead of adding string to strings
  in order to improve performance
- use message id instead of session id. Increase message id
  for each message
- start to implement authentication


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@14280 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent b3833444
...@@ -39,12 +39,21 @@ from zLOG import LOG ...@@ -39,12 +39,21 @@ from zLOG import LOG
class PublicationSynchronization(XMLSyncUtils): class PublicationSynchronization(XMLSyncUtils):
def PubSyncInit(self, publication=None, xml_client=None, subscriber=None, sync_type=None): def PubSyncInit(self, publication=None, xml_client=None, subscriber=None,
sync_type=None, auth_required=0):
""" """
Read the client xml message Read the client xml message
Send the first XML message from the server Send the first XML message from the server
""" """
LOG('PubSyncInit',0,'Starting... publication: %s' % str(publication)) LOG('PubSyncInit',0,'Starting... publication: %s' % str(publication))
#the session id is set at the same value of those of the client
subscriber.setSessionId(self.getSessionId(xml_client))
# for a new session, the message Id must be reset
subscriber.resetMessageId()
#the last_message_id is 1 because the message that
#we are about to send is the message 1
subscriber.initLastMessageId(1)
alert = None alert = None
# Get informations from the body # Get informations from the body
...@@ -53,55 +62,91 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -53,55 +62,91 @@ class PublicationSynchronization(XMLSyncUtils):
next_anchor = self.getAlertNextAnchor(xml_client) next_anchor = self.getAlertNextAnchor(xml_client)
alert = self.checkAlert(xml_client) alert = self.checkAlert(xml_client)
alert_code = self.getAlertCode(xml_client) alert_code = self.getAlertCode(xml_client)
cred = self.checkCred(xml_client)
# If slow sync, then resend everything #XXX this is in developement, it's just for tests
if alert_code == self.SLOW_SYNC: if not cred and auth_required:
LOG('Warning !!!, reseting client synchronization for subscriber:',0,subscriber) LOG('PubSyncInit',0,'authentication required')
subscriber.resetAllSignatures() # Prepare the xml message for the Sync initialization package
cmd_id = 1 # specifies a SyncML message-unique command identifier
# Check if the last time synchronization is the same as the client one xml_list = []
if subscriber.getNextAnchor() != last_anchor: xml = xml_list.append
if last_anchor == None: xml('<SyncML>\n')
LOG('PubSyncInit',0,'anchor null') # syncml header
xml(self.SyncMLHeader(subscriber.getSessionId(),
subscriber.incrementMessageId(), subscriber.getSubscriptionUrl(),
publication.getPublicationUrl()))
# syncml body
xml(' <SyncBody>\n')
# chal message
xml(self.SyncMLChal(cmd_id, "SyncHdr", publication.getPublicationUrl(),
subscriber.getSubscriptionUrl(), "b64", "syncml:auth-basic",
self.UNAUTHORIZED))
cmd_id += 1
xml(' </SyncBody>\n')
xml('</SyncML>\n')
xml_a = ''.join(xml_list)
self.sendResponse(from_url=publication.getPublicationUrl(),
to_url=subscriber.getSubscriptionUrl(),sync_id=publication.getTitle(),
xml=xml_a,domain=publication)
else :
# If slow sync, then resend everything
if alert_code == self.SLOW_SYNC:
LOG('Warning !!!, reseting client synchronization for subscriber:',0,
subscriber)
subscriber.resetAllSignatures()
# Check if the last time synchronization is the same as the client one
mess='\nsubscriber.getNextAnchor:\t%s\nsubscriber.getLastAnchor:\t%s\
\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 == None:
LOG('PubSyncInit',0,'anchor null')
raise ValueError, "Sorry, the anchor was null"
else:
message = "bad anchors in PubSyncInit! " + subscriber.getNextAnchor() + \
" and " + last_anchor
LOG('PubSyncInit',0,message)
else: else:
message = "bad anchors in PubSyncInit! " + subscriber.getNextAnchor() + \ subscriber.setNextAnchor(next_anchor)
" and " + last_anchor
LOG('PubSyncInit',0,message)
else:
subscriber.setNextAnchor(next_anchor)
# We have to set every object as NOT_SYNCHRONIZED # We have to set every object as NOT_SYNCHRONIZED
subscriber.startSynchronization() subscriber.startSynchronization()
else: else:
# We have started the sync from the server (may be for a conflict resolution) # We have started the sync from the server (may be for a conflict resolution)
pass pass
xml = "" if alert is not None and auth_required==0:
#if alert is not None: #if 1:
if 1:
# Prepare the xml message for the Sync initialization package # Prepare the xml message for the Sync initialization package
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
xml = "" xml_list = []
xml += '<SyncML>\n' xml = xml_list.append
xml('<SyncML>\n')
# syncml header # syncml header
xml += self.SyncMLHeader(subscriber.getSessionId(), "1", xml(self.SyncMLHeader(subscriber.getSessionId(),
subscriber.getSubscriptionUrl(), publication.getPublicationUrl()) subscriber.incrementMessageId(), subscriber.getSubscriptionUrl(),
publication.getPublicationUrl()))
# syncml body # syncml body
xml += ' <SyncBody>\n' xml(' <SyncBody>\n')
# alert message # alert message
xml += self.SyncMLAlert(cmd_id, sync_type, subscriber.getSubscriptionUrl(), xml(self.SyncMLAlert(cmd_id, sync_type, subscriber.getSubscriptionUrl(),
publication.getPublicationUrl(), subscriber.getLastAnchor(), subscriber.getNextAnchor()) publication.getPublicationUrl(), subscriber.getLastAnchor(),
subscriber.getNextAnchor()))
cmd_id += 1 cmd_id += 1
xml += ' </SyncBody>\n' xml(' </SyncBody>\n')
xml('</SyncML>\n')
xml += '</SyncML>\n' xml_a = ''.join(xml_list)
self.sendResponse(from_url=publication.getPublicationUrl(), self.sendResponse(from_url=publication.getPublicationUrl(),
to_url=subscriber.getSubscriptionUrl(),sync_id=publication.getTitle(),xml=xml, to_url=subscriber.getSubscriptionUrl(), sync_id=publication.getTitle(),
domain=publication) xml=xml_a, domain=publication)
return {'has_response':1,'xml':xml} return {'has_response':1,'xml':xml_a}
def PubSync(self, id, msg=None, RESPONSE=None, subscriber=None): def PubSync(self, id, msg=None, RESPONSE=None, subscriber=None):
...@@ -118,23 +163,27 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -118,23 +163,27 @@ class PublicationSynchronization(XMLSyncUtils):
publication = self.getPublication(id) publication = self.getPublication(id)
if xml_client is not None: if xml_client is not None:
if type(xml_client) in (type('a'),type(u'a')): if isinstance(xml_client, str) or isinstance(xml_client, unicode):
xml_client = parseString(xml_client) xml_client = parseString(xml_client)
first_node = xml_client.childNodes[0] first_node = xml_client.childNodes[0]
if first_node.nodeName != "SyncML": if first_node.nodeName != "SyncML":
LOG('PubSync',0,'This is not a SyncML Message') LOG('PubSync',0,'This is not a SyncML Message')
return raise ValueError, "Sorry, This is not a SyncML Message"
alert_code = self.getAlertCode(xml_client) alert_code = self.getAlertCode(xml_client)
# Get informations from the header # Get informations from the header
client_header = first_node.childNodes[1] client_header = first_node.childNodes[1]
if client_header.nodeName != "SyncHdr": if client_header.nodeName != "SyncHdr":
LOG('PubSync',0,'This is not a SyncML Header') LOG('PubSync',0,'This is not a SyncML Header')
return raise ValueError, "Sorry, This is not a SyncML Header"
for subnode in client_header.childNodes: for subnode in client_header.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Source": if subnode.nodeType == subnode.ELEMENT_NODE and \
subscription_url = str(subnode.childNodes[0].data) subnode.nodeName == "Source":
for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == "LocURI":
subscription_url = str(subnode2.childNodes[0].data)
# Get the subscriber or create it if not already in the list # Get the subscriber or create it if not already in the list
subscriber = publication.getSubscriber(subscription_url) subscriber = publication.getSubscriber(subscription_url)
if subscriber == None: if subscriber == None:
...@@ -142,19 +191,21 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -142,19 +191,21 @@ class PublicationSynchronization(XMLSyncUtils):
subscriber.setXMLMapping(publication.getXMLMapping()) subscriber.setXMLMapping(publication.getXMLMapping())
publication.addSubscriber(subscriber) publication.addSubscriber(subscriber)
# first synchronization # first synchronization
result = self.PubSyncInit(publication,xml_client,subscriber=subscriber,sync_type=self.SLOW_SYNC) result = self.PubSyncInit(publication,xml_client,subscriber=subscriber,
sync_type=self.SLOW_SYNC)
elif self.checkAlert(xml_client) and alert_code in (self.TWO_WAY,self.SLOW_SYNC): elif self.checkAlert(xml_client) and \
result = self.PubSyncInit(publication=publication, alert_code in (self.TWO_WAY,self.SLOW_SYNC):
xml_client=xml_client, subscriber=subscriber,sync_type=alert_code) result = self.PubSyncInit(publication=publication,
xml_client=xml_client, subscriber=subscriber, sync_type=alert_code)
else: else:
result = self.PubSyncModif(publication, xml_client) result = self.PubSyncModif(publication, xml_client)
elif subscriber is not None: elif subscriber is not None:
# This looks like we are starting a synchronization after # This looks like we are starting a synchronization after
# a conflict resolution by the user # a conflict resolution by the user
result = self.PubSyncInit(publication=publication, result = self.PubSyncInit(publication=publication, xml_client=None,
xml_client=None, subscriber=subscriber,sync_type=self.TWO_WAY) subscriber=subscriber,sync_type=self.TWO_WAY)
if RESPONSE is not None: if RESPONSE is not None:
RESPONSE.redirect('managePublications') RESPONSE.redirect('managePublications')
......
...@@ -660,7 +660,7 @@ class Subscription(Folder, SyncCode): ...@@ -660,7 +660,7 @@ class Subscription(Folder, SyncCode):
self.setConduit(conduit) self.setConduit(conduit)
Folder.__init__(self, id) Folder.__init__(self, id)
self.title = title self.title = title
#self.signatures = PersitentMapping() #self.signatures = PersitentMapping()
def getTitle(self): def getTitle(self):
...@@ -723,6 +723,26 @@ class Subscription(Folder, SyncCode): ...@@ -723,6 +723,26 @@ class Subscription(Folder, SyncCode):
self.last_session_id = session_id self.last_session_id = session_id
return 1 return 1
def checkCorrectRemoteMessageId(self, message_id):
"""
We will see if the last message id was the same
wich means that the same message was sent again
return 1 if the message id was not seen, 0 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)
if last_message_id == message_id:
return 0
self.last_message_id = message_id
return 1
def initLastMessageId(self, last_message_id=None):
"""
set the last message id to 0
"""
self.last_message_id=last_message_id
def getLastSentMessage(self): def getLastSentMessage(self):
""" """
...@@ -926,7 +946,7 @@ class Subscription(Folder, SyncCode): ...@@ -926,7 +946,7 @@ class Subscription(Folder, SyncCode):
query_list = [] query_list = []
if query is None: if query is None:
return query_list return query_list
if type(query) is type('a'): if isinstance(query, str):
query_method = getattr(destination,query,None) query_method = getattr(destination,query,None)
if query_method is not None: if query_method is not None:
query_list = query_method() query_list = query_method()
...@@ -1009,14 +1029,51 @@ class Subscription(Folder, SyncCode): ...@@ -1009,14 +1029,51 @@ class Subscription(Folder, SyncCode):
return the current subscription return the current subscription
""" """
return self return self
def setSessionId(self, session_id):
"""
set the session id
"""
self.session_id = session_id
def getSessionId(self): def getSessionId(self):
""" """
return the session id return the session id
""" """
#self.session_id += 1 #to be commented
return self.session_id
def incrementSessionId(self):
"""
increment and return the session id
"""
self.session_id += 1 self.session_id += 1
self.resetMessageId() # for a new session, the message Id must be reset
return self.session_id return self.session_id
def incrementMessageId(self):
"""
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
def getMessageId(self):
"""
increment and return the message id
"""
return self.message_id
def resetMessageId(self):
"""
set the message id to 0
"""
self.message_id = 0
def getLastAnchor(self): def getLastAnchor(self):
""" """
return the id of the last synchronisation return the id of the last synchronisation
......
...@@ -44,38 +44,43 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -44,38 +44,43 @@ class SubscriptionSynchronization(XMLSyncUtils):
""" """
LOG('SubSyncInit',0,'starting....') LOG('SubSyncInit',0,'starting....')
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
xml = "" xml_list = []
xml += '<SyncML>\n' xml = xml_list.append
xml('<SyncML>\n')
# syncml header # syncml header
xml += self.SyncMLHeader(subscription.getSessionId(), "1", xml(self.SyncMLHeader(subscription.incrementSessionId(),
subscription.getPublicationUrl(), subscription.getSubscriptionUrl()) subscription.incrementMessageId(), subscription.getPublicationUrl(),
subscription.getSubscriptionUrl()))
# syncml body # syncml body
xml += ' <SyncBody>\n' xml(' <SyncBody>\n')
subscription.NewAnchor() subscription.NewAnchor()
subscription.initLastMessageId()
# We have to set every object as NOT_SYNCHRONIZED # We have to set every object as NOT_SYNCHRONIZED
subscription.startSynchronization() subscription.startSynchronization()
# alert message # alert message
xml += self.SyncMLAlert(cmd_id, subscription.getSynchronizationType(), xml(self.SyncMLAlert(cmd_id, subscription.getSynchronizationType(),
subscription.getPublicationUrl(), subscription.getPublicationUrl(),
subscription.getDestinationPath(), subscription.getDestinationPath(),
subscription.getLastAnchor(), subscription.getNextAnchor()) subscription.getLastAnchor(),
subscription.getNextAnchor()))
cmd_id += 1 cmd_id += 1
xml += ' <Put>\n' xml(' <Put>\n')
xml += ' <CmdID>%s</CmdID>\n' % cmd_id ; cmd_id += 1 xml(' <CmdID>%s</CmdID>\n' % cmd_id)
xml += ' </Put>\n' cmd_id += 1
xml += ' </SyncBody>\n' xml(' </Put>\n')
xml(' </SyncBody>\n')
xml += '</SyncML>\n' xml('</SyncML>\n')
xml_a = ''.join(xml_list)
self.sendResponse(from_url=subscription.subscription_url, to_url=subscription.publication_url, self.sendResponse(from_url=subscription.subscription_url,
sync_id=subscription.getTitle(), xml=xml,domain=subscription) to_url=subscription.publication_url, sync_id=subscription.getTitle(),
xml=xml_a,domain=subscription)
return {'has_response':1,'xml':xml} return {'has_response':1,'xml':xml_a}
def SubSync(self, id, msg=None, RESPONSE=None): def SubSync(self, id, msg=None, RESPONSE=None):
""" """
...@@ -83,17 +88,17 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -83,17 +88,17 @@ class SubscriptionSynchronization(XMLSyncUtils):
""" """
LOG('SubSync',0,'starting... id: %s' % str(id)) LOG('SubSync',0,'starting... id: %s' % str(id))
LOG('SubSync',0,'starting... msg: %s' % str(msg)) LOG('SubSync',0,'starting... msg: %s' % str(msg))
response = None #check if subsync replies to this messages response = None #check if subsync replies to this messages
subscription = self.getSubscription(id) subscription = self.getSubscription(id)
if msg==None and (subscription.getSubscriptionUrl()).find('file')>=0: if msg==None and (subscription.getSubscriptionUrl()).find('file')>=0:
msg = self.readResponse(sync_id=id,from_url=subscription.getSubscriptionUrl()) msg = self.readResponse(sync_id=id,
from_url=subscription.getSubscriptionUrl())
if msg==None: if msg==None:
response = self.SubSyncInit(self.getSubscription(id)) response = self.SubSyncInit(self.getSubscription(id))
else: else:
xml_client = msg xml_client = msg
if type(xml_client) in (type('a'),type(u'a')): if isinstance(xml_client, str) or isinstance(xml_client, unicode):
xml_client = parseString(xml_client) xml_client = parseString(xml_client)
response = self.SubSyncModif(self.getSubscription(id),xml_client) response = self.SubSyncModif(self.getSubscription(id),xml_client)
......
...@@ -47,6 +47,9 @@ class SyncCode(Persistent): ...@@ -47,6 +47,9 @@ class SyncCode(Persistent):
# whatever is needed to change(replace) # whatever is needed to change(replace)
CONFLICT_CLIENT_WIN = 208 # The client is the "winner", we keep CONFLICT_CLIENT_WIN = 208 # The client is the "winner", we keep
# the version of the client # the version of the client
UNAUTHORIZED = 401
AUTH_REQUIRED = 407
AUTH_ACCEPTED = 212
# Difference between publication and subscription # Difference between publication and subscription
PUB = 1 PUB = 1
......
...@@ -734,9 +734,9 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati ...@@ -734,9 +734,9 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
""" """
if context is None: if context is None:
return context return context
elif type(context) is type(()): elif isinstance(context, tuple):
return context return context
elif type(context) is type('a'): elif isinstance(context, tuple):
return tuple(context.split('/')) return tuple(context.split('/'))
else: else:
return context.getPhysicalPath() return context.getPhysicalPath()
...@@ -751,7 +751,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati ...@@ -751,7 +751,7 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
LOG('sendResponse, to_url: ',0,to_url) LOG('sendResponse, to_url: ',0,to_url)
LOG('sendResponse, from_url: ',0,from_url) LOG('sendResponse, from_url: ',0,from_url)
LOG('sendResponse, sync_id: ',0,sync_id) LOG('sendResponse, sync_id: ',0,sync_id)
LOG('sendResponse, xml: ',0,xml) LOG('sendResponse, xml: \n',0,xml)
if domain is not None: if domain is not None:
gpg_key = domain.getGPGKey() gpg_key = domain.getGPGKey()
if gpg_key not in ('',None): if gpg_key not in ('',None):
...@@ -768,14 +768,14 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati ...@@ -768,14 +768,14 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
commands.getstatusoutput('rm -f /tmp/%s.gz' % filename) commands.getstatusoutput('rm -f /tmp/%s.gz' % filename)
commands.getstatusoutput('rm -f /tmp/%s.gz.gpg' % filename) commands.getstatusoutput('rm -f /tmp/%s.gz.gpg' % filename)
if send: if send:
if type(to_url) is type('a'): if isinstance(to_url, str):
if to_url.find('http://')==0: if to_url.find('http://')==0:
# XXX Make sure this is not a problem # XXX Make sure this is not a problem
if domain.domain_type == self.PUB: if domain.domain_type == self.PUB:
return None return None
# we will send an http response # we will send an http response
domain = aq_base(domain) domain = aq_base(domain)
LOG('sendResponse, will start sendHttpResponse, xml',0,xml) LOG('sendResponse, will start sendHttpResponse, xml\n',0,xml)
self.activate(activity='RAMQueue').sendHttpResponse(sync_id=sync_id, self.activate(activity='RAMQueue').sendHttpResponse(sync_id=sync_id,
to_url=to_url, to_url=to_url,
xml=xml, domain=domain) xml=xml, domain=domain)
...@@ -907,30 +907,38 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati ...@@ -907,30 +907,38 @@ class SynchronizationTool( SubscriptionSynchronization, PublicationSynchronizati
commands.getstatusoutput('rm -f /tmp/%s.gz.gpg' % filename) commands.getstatusoutput('rm -f /tmp/%s.gz.gpg' % filename)
# Get the target and then find the corresponding publication or # Get the target and then find the corresponding publication or
# Subscription # Subscription
LOG('readResponse, xml before parseSTring',0,text) LOG('readResponse, xml before parseSTring\n',0,text)
xml = parseString(text) xml = parseString(text)
url = ''
for subnode in self.getElementNodeList(xml): #XXX this function is not very optimized and should be improved
if subnode.nodeName == 'SyncML': url = self.getTarget(xml)
for subnode1 in self.getElementNodeList(subnode):
if subnode1.nodeName == 'SyncHdr':
for subnode2 in self.getElementNodeList(subnode1):
if subnode2.nodeName == 'Target':
url = subnode2.childNodes[0].data
for publication in self.getPublicationList(): for publication in self.getPublicationList():
if publication.getPublicationUrl()==url and publication.getTitle()==sync_id: if publication.getPublicationUrl()==url and publication.getTitle()==sync_id:
result = self.PubSync(sync_id,xml) result = self.PubSync(sync_id,xml)
# Then encrypt the message # Then encrypt the message
xml = result['xml'] xml = result['xml']
xml = self.sendResponse(xml=xml,domain=publication,send=0)
#must be commented because this method is alredy called
#xml = self.sendResponse(xml=xml,domain=publication,send=0)
return xml return xml
for subscription in self.getSubscriptionList(): for subscription in self.getSubscriptionList():
if subscription.getSubscriptionUrl()==url and subscription.getTitle()==sync_id: if subscription.getSubscriptionUrl()==url and \
result = self.activate(activity='RAMQueue').SubSync(sync_id,xml) subscription.getTitle()==sync_id:
next_status = self.getNextSyncBodyStatus(xml, None)
if next_status is not None:
status_code = self.getStatusCode(next_status)
LOG('readResponse status code :',0,status_code)
if status_code == self.UNAUTHORIZED or \
status_code == self.AUTH_REQUIRED:
LOG('readResponse', 0, 'Authentication required')
raise ValueError, "Authentication required"
else:
result = self.activate(activity='RAMQueue').SubSync(sync_id,xml)
#result = self.SubSync(sync_id,xml) #result = self.SubSync(sync_id,xml)
# we use from only if we have a file # we use from only if we have a file
elif type(from_url) is type('a'): elif isinstance(from_url, str):
if from_url.find('file://')==0: if from_url.find('file://')==0:
try: try:
filename = from_url[len('file:/'):] filename = from_url[len('file:/'):]
......
...@@ -46,78 +46,124 @@ from zLOG import LOG ...@@ -46,78 +46,124 @@ from zLOG import LOG
class XMLSyncUtilsMixin(SyncCode): class XMLSyncUtilsMixin(SyncCode):
def SyncMLHeader(self, session_id, msg_id, target, source): def SyncMLHeader(self, session_id, msg_id, target, source, target_name=None,
source_name=None):
""" """
Since the Header is always almost the same, this is the Since the Header is always almost the same, this is the
way to set one quickly. way to set one quickly.
""" """
xml = "" xml_list = []
xml += ' <SyncHdr>\n' xml = xml_list.append
xml += ' <VerDTD>1.1</VerDTD>\n' xml(' <SyncHdr>\n')
xml += ' <VerProto>SyncML/1.1</VerProto>\n' xml(' <VerDTD>1.1</VerDTD>\n')
xml += ' <SessionID>%s</SessionID>\n' % session_id xml(' <VerProto>SyncML/1.1</VerProto>\n')
xml += ' <MsgID>%s</MsgID>\n' % msg_id xml(' <SessionID>%s</SessionID>\n' % session_id)
xml += ' <Target>%s</Target>\n' % target xml(' <MsgID>%s</MsgID>\n' % msg_id)
xml += ' <Source>%s</Source>\n' % source xml(' <Target>\n')
xml += ' </SyncHdr>\n' xml(' <LocURI>%s</LocURI>\n' % target)
return xml if target_name is not None:
xml(' <LocName>%s</LocName>\n' %target_name)
xml(' </Target>\n')
xml(' <Source>\n')
xml(' <LocURI>%s</LocURI>\n' % source)
if source_name is not None:
xml(' <LocName>%s</LocName>\n' % source_name)
xml(' </Source>\n')
xml(' </SyncHdr>\n')
xml_a = ''.join(xml_list)
return xml_a
def SyncMLAlert(self, cmd_id, sync_code, target, source, last_anchor, next_anchor): def SyncMLAlert(self, cmd_id, sync_code, target, source, last_anchor,
next_anchor):
""" """
Since the Alert section is always almost the same, this is the Since the Alert section is always almost the same, this is the
way to set one quickly. way to set one quickly.
""" """
xml = "" xml_list = []
xml += ' <Alert>\n' xml = xml_list.append
xml += ' <CmdID>%s</CmdID>\n' % cmd_id xml(' <Alert>\n')
xml += ' <Data>%s</Data>\n' % sync_code xml(' <CmdID>%s</CmdID>\n' % cmd_id)
xml += ' <Item>\n' xml(' <Data>%s</Data>\n' % sync_code)
xml += ' <Target>%s</Target>\n' % target xml(' <Item>\n')
xml += ' <Source>%s</Source>\n' % source xml(' <Target>\n')
xml += ' <Meta>\n' xml(' <LocURI>%s</LocURI>\n' % target)
xml += ' <Anchor xmlns=\'syncml:metinf\'>\n' xml(' </Target>\n')
xml += ' <Last>%s</Last>\n' % last_anchor xml(' <Source>\n')
xml += ' <Next>%s</Next>\n' % next_anchor xml(' <LocURI>%s</LocURI>\n' % source)
xml += ' </Anchor>\n' xml(' </Source>\n')
xml += ' </Meta>\n' xml(' <Meta>\n')
xml += ' </Item>\n' xml(' <Anchor xmlns=\'syncml:metinf\'>\n')
xml += ' </Alert>\n' xml(' <Last>%s</Last>\n' % last_anchor)
return xml xml(' <Next>%s</Next>\n' % next_anchor)
xml(' </Anchor>\n')
xml(' </Meta>\n')
xml(' </Item>\n')
xml(' </Alert>\n')
xml_a = ''.join(xml_list)
return xml_a
def SyncMLStatus(self, cmd_id, target_ref, source_ref, sync_code, next_anchor): def SyncMLStatus(self, cmd_id, target_ref, source_ref, sync_code,
next_anchor):
""" """
Since the Status section is always almost the same, this is the Since the Status section is always almost the same, this is the
way to set one quickly. way to set one quickly.
""" """
xml = "" xml_list = []
xml += ' <Status>\n' xml = xml_list.append
xml += ' <CmdID>%s</CmdID>\n' % cmd_id xml(' <Status>\n')
xml += ' <TargetRef>%s</TargetRef>\n' % target_ref xml(' <CmdID>%s</CmdID>\n' % cmd_id)
xml += ' <SourceRef>%s</SourceRef>\n' % source_ref xml(' <TargetRef>%s</TargetRef>\n' % target_ref)
xml += ' <Data>%s</Data>\n' % sync_code xml(' <SourceRef>%s</SourceRef>\n' % source_ref)
xml += ' <Item>\n' xml(' <Data>%s</Data>\n' % sync_code)
xml += ' <Data>\n' xml(' <Item>\n')
xml += ' <Anchor xmlns=\'syncml:metinf\'>\n' xml(' <Data>\n')
xml += ' <Next>%s</Next>\n' % next_anchor xml(' <Anchor xmlns=\'syncml:metinf\'>\n')
xml += ' </Anchor>\n' xml(' <Next>%s</Next>\n' % next_anchor)
xml += ' </Data>\n' xml(' </Anchor>\n')
xml += ' </Item>\n' xml(' </Data>\n')
xml += ' </Status>\n' xml(' </Item>\n')
return xml xml(' </Status>\n')
xml_a = ''.join(xml_list)
return xml_a
def SyncMLConfirmation(self, cmd_id, target_ref, sync_code, cmd): def SyncMLConfirmation(self, cmd_id, target_ref, sync_code, cmd):
""" """
This is used in order ton confirm that an object was correctly This is used in order to confirm that an object was correctly
synchronized synchronized
""" """
xml = "" xml_list = []
xml += ' <Status>\n' xml = xml_list.append
xml += ' <CmdID>%s</CmdID>\n' % cmd_id xml(' <Status>\n')
xml += ' <TargetRef>%s</TargetRef>\n' % target_ref xml(' <CmdID>%s</CmdID>\n' % cmd_id)
xml += ' <Cmd>%s</Cmd>' % cmd xml(' <TargetRef>%s</TargetRef>\n' % target_ref)
xml += ' <Data>%s</Data>\n' % sync_code xml(' <Cmd>%s</Cmd>\n' % cmd)
xml += ' </Status>\n' xml(' <Data>%s</Data>\n' % sync_code)
return xml xml(' </Status>\n')
xml_a = ''.join(xml_list)
return xml_a
def SyncMLChal(self, cmd_id, cmd, target_ref, source_ref, auth_format,
auth_type, data_code):
"""
This is used in order to ask crendentials
"""
xml_list = []
xml = xml_list.append
xml(' <Status>\n')
xml(' <CmdID>%s</CmdID>\n' % cmd_id)
xml(' <Cmd>%s</Cmd>\n' % cmd)
xml(' <TargetRef>%s</TargetRef>\n' % target_ref)
xml(' <SourceRef>%s</SourceRef>\n' % source_ref)
xml(' <Chal>\n')
xml(' <Meta>\n')
xml(' <Format>%s</Format>\n' % auth_format)
xml(' <Type>%s</Type>\n' % auth_type)
xml(' </Meta>\n')
xml(' </Chal>\n')
xml(' <Data>%s</Data>\n' % str(data_code))
xml(' </Status>\n')
xml_a = ''.join(xml_list)
return xml_a
def sendMail(self, fromaddr, toaddr, id_sync, msg): def sendMail(self, fromaddr, toaddr, id_sync, msg):
""" """
...@@ -140,55 +186,67 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -140,55 +186,67 @@ class XMLSyncUtilsMixin(SyncCode):
""" """
Add an object with the SyncML protocol Add an object with the SyncML protocol
""" """
xml = "" xml_list = []
xml += ' <Add>\n' xml = xml_list.append
xml += ' <CmdID>%s</CmdID>\n' % cmd_id xml(' <Add>\n')
xml += ' <Meta><Type>%s</Type></Meta>\n' % object.portal_type xml(' <CmdID>%s</CmdID>\n' % cmd_id)
xml += ' <Item>\n' xml(' <Meta><Type>%s</Type></Meta>\n' % object.portal_type)
xml += ' <Source><LocURI>%s</LocURI></Source>\n' % gid xml(' <Item>\n')
xml += ' <Data>\n' xml(' <Source>\n')
xml += xml_string xml(' <LocURI>%s</LocURI>\n' % gid)
xml += ' </Data>\n' xml(' </Source>\n')
xml(' <Data>\n')
xml(xml_string)
xml(' </Data>\n')
if more_data == 1: if more_data == 1:
xml += ' <MoreData/>\n' xml(' <MoreData/>\n')
xml += ' </Item>\n' xml(' </Item>\n')
xml += ' </Add>\n' xml(' </Add>\n')
return xml xml_a = ''.join(xml_list)
return xml_a
def deleteXMLObject(self, cmd_id=0, object_gid=None, xml_object=''): def deleteXMLObject(self, cmd_id=0, object_gid=None, xml_object=''):
""" """
Add an object with the SyncML protocol Delete an object with the SyncML protocol
""" """
xml = "" xml_list = []
xml += ' <Delete>\n' xml = xml_list.append
xml += ' <CmdID>%s</CmdID>\n' % cmd_id xml(' <Delete>\n')
xml += ' <Item>\n' xml(' <CmdID>%s</CmdID>\n' % cmd_id)
xml += ' <Source><LocURI>%s</LocURI></Source>\n' % object_gid xml(' <Item>\n')
xml += ' <Data>\n' xml(' <Source>\n')
xml += ' </Data>\n' xml(' <LocURI>%s</LocURI>\n' % object_gid)
xml += ' </Item>\n' xml(' </Source>\n')
xml += ' </Delete>\n' xml(' <Data>\n')
return xml xml(' </Data>\n')
xml(' </Item>\n')
xml(' </Delete>\n')
xml_a = ''.join(xml_list)
return xml_a
def replaceXMLObject(self, cmd_id=0, object=None, xml_string=None, def replaceXMLObject(self, cmd_id=0, object=None, xml_string=None,
more_data=0,gid=None): more_data=0,gid=None):
""" """
Add an object with the SyncML protocol Replace an object with the SyncML protocol
""" """
xml = "" xml_list = []
xml += ' <Replace>\n' xml = xml_list.append
xml += ' <CmdID>%s</CmdID>\n' % cmd_id xml(' <Replace>\n')
xml += ' <Meta><Type>%s</Type></Meta>\n' % object.portal_type xml(' <CmdID>%s</CmdID>\n' % cmd_id)
xml += ' <Item>\n' xml(' <Meta><Type>%s</Type></Meta>\n' % object.portal_type)
xml += ' <Source><LocURI>%s</LocURI></Source>\n' % str(gid) xml(' <Item>\n')
xml += ' <Data>\n' xml(' <Source>\n')
xml += xml_string xml(' <LocURI>%s</LocURI>\n' % str(gid))
xml += ' </Data>\n' xml(' </Source>\n')
xml(' <Data>\n')
xml(xml_string)
xml(' </Data>\n')
if more_data == 1: if more_data == 1:
xml += ' <MoreData/>\n' xml(' <MoreData/>\n')
xml += ' </Item>\n' xml(' </Item>\n')
xml += ' </Replace>\n' xml(' </Replace>\n')
return xml xml_a = ''.join(xml_list)
return xml_a
def getXupdateObject(self, object=None, xml_mapping=None, old_xml=None): def getXupdateObject(self, object=None, xml_mapping=None, old_xml=None):
""" """
...@@ -206,7 +264,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -206,7 +264,8 @@ class XMLSyncUtilsMixin(SyncCode):
file2 = open('/tmp/%s'% old_filename,'w') file2 = open('/tmp/%s'% old_filename,'w')
file2.write(old_xml) file2.write(old_xml)
file2.close() file2.close()
xupdate = commands.getoutput('erp5diff /tmp/%s /tmp/%s' % (old_filename,new_filename)) xupdate = commands.getoutput('erp5diff /tmp/%s /tmp/%s' %
(old_filename,new_filename))
xupdate = xupdate[xupdate.find('<xupdate:modifications'):] xupdate = xupdate[xupdate.find('<xupdate:modifications'):]
commands.getstatusoutput('rm -f /tmp/%s' % old_filename) commands.getstatusoutput('rm -f /tmp/%s' % old_filename)
commands.getstatusoutput('rm -f /tmp/%s' % new_filename) commands.getstatusoutput('rm -f /tmp/%s' % new_filename)
...@@ -240,6 +299,38 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -240,6 +299,38 @@ class XMLSyncUtilsMixin(SyncCode):
if subnode2.nodeName == 'SessionID': if subnode2.nodeName == 'SessionID':
session_id = int(subnode2.childNodes[0].data) session_id = int(subnode2.childNodes[0].data)
return session_id return session_id
def getMessageId(self, xml):
"""
We will retrieve the message id of the message
"""
message_id = 0
for subnode in self.getElementNodeList(xml):
if subnode.nodeName == 'SyncML':
for subnode1 in self.getElementNodeList(subnode):
if subnode1.nodeName == 'SyncHdr':
for subnode2 in self.getElementNodeList(subnode1):
if subnode2.nodeName == 'MsgID':
message_id = int(subnode2.childNodes[0].data)
return message_id
def getTarget(self, xml):
"""
return the target in the SyncHdr section
"""
url = ''
for subnode in self.getElementNodeList(xml):
if subnode.nodeName == 'SyncML':
for subnode1 in self.getElementNodeList(subnode):
if subnode1.nodeName == 'SyncHdr':
for subnode2 in self.getElementNodeList(subnode1):
if subnode2.nodeName == 'Target':
for subnode3 in self.getElementNodeList(subnode2):
if subnode3.nodeName == 'LocURI':
url = subnode3.childNodes[0].data
return url
def getAlertLastAnchor(self, xml_stream): def getAlertLastAnchor(self, xml_stream):
""" """
...@@ -251,18 +342,23 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -251,18 +342,23 @@ class XMLSyncUtilsMixin(SyncCode):
# Get informations from the body # Get informations from the body
client_body = first_node.childNodes[3] client_body = first_node.childNodes[3]
for subnode in client_body.childNodes: for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Alert": if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == "Alert":
for subnode2 in subnode.childNodes: for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == "Item": if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == "Item":
for subnode3 in subnode2.childNodes: for subnode3 in subnode2.childNodes:
if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == "Meta": if subnode3.nodeType == subnode3.ELEMENT_NODE and \
for subnode4 in subnode3.childNodes: subnode3.nodeName == "Meta":
if subnode4.nodeType == subnode4.ELEMENT_NODE and subnode4.nodeName == "Anchor": for subnode4 in subnode3.childNodes:
if subnode4.nodeType == subnode4.ELEMENT_NODE and \
subnode4.nodeName == "Anchor":
for subnode5 in subnode4.childNodes: for subnode5 in subnode4.childNodes:
# Get the last time we had a synchronization # Get the last time we had a synchronization
if subnode5.nodeType == subnode5.ELEMENT_NODE and subnode5.nodeName == "Last": if subnode5.nodeType == subnode5.ELEMENT_NODE and \
subnode5.nodeName == "Last":
last_anchor = subnode5.childNodes[0].data last_anchor = subnode5.childNodes[0].data
return last_anchor return last_anchor
def getAlertNextAnchor(self, xml_stream): def getAlertNextAnchor(self, xml_stream):
""" """
...@@ -278,16 +374,21 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -278,16 +374,21 @@ class XMLSyncUtilsMixin(SyncCode):
if client_body.nodeName != "SyncBody": if client_body.nodeName != "SyncBody":
print "This is not a SyncML Body" print "This is not a SyncML Body"
for subnode in client_body.childNodes: for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Alert": if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == "Alert":
for subnode2 in subnode.childNodes: for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == "Item": if subnode2.nodeType == subnode2.ELEMENT_NODE and \
subnode2.nodeName == "Item":
for subnode3 in subnode2.childNodes: for subnode3 in subnode2.childNodes:
if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == "Meta": if subnode3.nodeType == subnode3.ELEMENT_NODE and \
subnode3.nodeName == "Meta":
for subnode4 in subnode3.childNodes: for subnode4 in subnode3.childNodes:
if subnode4.nodeType == subnode4.ELEMENT_NODE and subnode4.nodeName == "Anchor": if subnode4.nodeType == subnode4.ELEMENT_NODE and \
subnode4.nodeName == "Anchor":
for subnode5 in subnode4.childNodes: for subnode5 in subnode4.childNodes:
# Get the last time we had a synchronization # Get the last time we had a synchronization
if subnode5.nodeType == subnode5.ELEMENT_NODE and subnode5.nodeName == "Next": if subnode5.nodeType == subnode5.ELEMENT_NODE and \
subnode5.nodeName == "Next":
next_anchor = subnode5.childNodes[0].data next_anchor = subnode5.childNodes[0].data
return next_anchor return next_anchor
...@@ -298,7 +399,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -298,7 +399,8 @@ class XMLSyncUtilsMixin(SyncCode):
# Get informations from the body # Get informations from the body
if xml.nodeName=='Status': if xml.nodeName=='Status':
for subnode in xml.childNodes: for subnode in xml.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'TargetRef': if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == 'TargetRef':
return subnode.childNodes[0].data return subnode.childNodes[0].data
return None return None
...@@ -309,10 +411,32 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -309,10 +411,32 @@ class XMLSyncUtilsMixin(SyncCode):
# Get informations from the body # Get informations from the body
if xml.nodeName=='Status': if xml.nodeName=='Status':
for subnode in xml.childNodes: for subnode in xml.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Data': if subnode.nodeType == subnode.ELEMENT_NODE and \
subnode.nodeName == 'Data':
return int(subnode.childNodes[0].data) return int(subnode.childNodes[0].data)
return None return None
#def getStatusCode(self, xml):
# """
# Return the value of the alert code inside the xml_stream
# """
# # Get informations from the body
# first_node = xml.childNodes[0]
# if first_node.nodeName != "SyncML":
# print "This is not a SyncML message"
#
# client_body = first_node.childNodes[3]
# if client_body.nodeName != "SyncBody":
# print "This is not a SyncML Body"
#
# for subnode in client_body.childNodes:
# if subnode.nodeName=='Status':
# for subnode2 in subnode.childNodes:
# if subnode2.nodeType == subnode.ELEMENT_NODE and subnode2.nodeName == 'Data':
# return int(subnode2.childNodes[0].data)
# return None
def getStatusCommand(self, xml): def getStatusCommand(self, xml):
""" """
Return the value of the command inside the xml_stream Return the value of the command inside the xml_stream
...@@ -333,6 +457,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -333,6 +457,7 @@ class XMLSyncUtilsMixin(SyncCode):
client_body = first_node.childNodes[3] client_body = first_node.childNodes[3]
if client_body.nodeName != "SyncBody": if client_body.nodeName != "SyncBody":
LOG('XMLSyncUtils.getAlertCode',0,"This is not a SyncML Body") LOG('XMLSyncUtils.getAlertCode',0,"This is not a SyncML Body")
raise ValueError, "Sorry, This is not a SyncML Body"
alert = 0 alert = 0
for subnode in client_body.childNodes: for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName=='Alert': if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName=='Alert':
...@@ -341,9 +466,25 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -341,9 +466,25 @@ class XMLSyncUtilsMixin(SyncCode):
return int(subnode1.childNodes[0].data) return int(subnode1.childNodes[0].data)
return None return None
def checkCred(self, xml_stream):
"""
Check if there's a Cred section in the xml_stream
"""
first_node = xml_stream.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')
raise ValueError, "Sorry, This is not a SyncML Header"
cred = 0
for subnode in xml_header.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Cred":
cred=1
return cred
def checkAlert(self, xml_stream): def checkAlert(self, xml_stream):
""" """
Check if there's an Alert section in the xml_xtream Check if there's an Alert section in the xml_stream
""" """
first_node = xml_stream.childNodes[0] first_node = xml_stream.childNodes[0]
client_body = first_node.childNodes[3] client_body = first_node.childNodes[3]
...@@ -363,6 +504,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -363,6 +504,7 @@ class XMLSyncUtilsMixin(SyncCode):
client_body = first_node.childNodes[3] client_body = first_node.childNodes[3]
if client_body.nodeName != "SyncBody": if client_body.nodeName != "SyncBody":
LOG('checkSync',0,"This is not a SyncML Body") LOG('checkSync',0,"This is not a SyncML Body")
raise ValueError, "Sorry, This is not a SyncML Body"
for subnode in client_body.childNodes: for subnode in client_body.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Sync": if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Sync":
return 1 return 1
...@@ -420,6 +562,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -420,6 +562,7 @@ class XMLSyncUtilsMixin(SyncCode):
client_body = first_node.childNodes[3] client_body = first_node.childNodes[3]
if client_body.nodeName != "SyncBody": if client_body.nodeName != "SyncBody":
LOG('getNextSyncBodyStatus',0,"This is not a SyncML Body") LOG('getNextSyncBodyStatus',0,"This is not a SyncML Body")
raise ValueError, "Sorry, This is not a SyncML Body"
next_status = None next_status = None
found = None found = None
for subnode in client_body.childNodes: for subnode in client_body.childNodes:
...@@ -463,7 +606,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -463,7 +606,7 @@ class XMLSyncUtilsMixin(SyncCode):
# data = subnode3.data # data = subnode3.data
# data = data[data.find('<!--')+4:data.rfind('-->')] # data = data[data.find('<!--')+4:data.rfind('-->')]
xml = subnode3.data xml = subnode3.data
if type(xml) is type(u'a'): if isinstance(xml, unicode):
xml = xml.encode('utf-8') xml = xml.encode('utf-8')
return xml return xml
...@@ -936,6 +1079,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -936,6 +1079,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
xml_header = first_node.childNodes[1] xml_header = first_node.childNodes[1]
if xml_header.nodeName != "SyncHdr": if xml_header.nodeName != "SyncHdr":
LOG('PubSyncModif',0,'This is not a SyncML Header') LOG('PubSyncModif',0,'This is not a SyncML Header')
raise ValueError, "Sorry, This is not a SyncML Header"
return return
subscriber = domain # If we are the client, this is fine subscriber = domain # If we are the client, this is fine
...@@ -944,14 +1088,17 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -944,14 +1088,17 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
simulate = 1 simulate = 1
for subnode in xml_header.childNodes: for subnode in xml_header.childNodes:
if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Source": if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == "Source":
subscription_url = str(subnode.childNodes[0].data) for subnode2 in subnode.childNodes:
if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'LocURI':
subscription_url = str(subnode2.childNodes[0].data)
subscriber = domain.getSubscriber(subscription_url) subscriber = domain.getSubscriber(subscription_url)
# We have to check if this message was not already, this can be dangerous # We have to check if this message was not already, this can be dangerous
# to update two times the same object # to update two times the same object
session_id = self.getSessionId(remote_xml) message_id = self.getMessageId(remote_xml)
correct_session = subscriber.checkCorrectRemoteSessionId(session_id) correct_message = subscriber.checkCorrectRemoteMessageId(message_id)
if not correct_session: # We need to send again the message if not correct_message: # We need to send again the message
LOG('SyncModif, no correct message:',0,"sending again...")
last_xml = subscriber.getLastSentMessage() last_xml = subscriber.getLastSentMessage()
if last_xml != '': if last_xml != '':
has_response = 1 has_response = 1
...@@ -974,7 +1121,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -974,7 +1121,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
conduit_name = subscriber.getConduit() conduit_name = subscriber.getConduit()
conduit_module = __import__('.'.join([Conduit.__name__, conduit_name]), globals(), locals(), ['']) conduit_module = __import__('.'.join([Conduit.__name__, conduit_name]), globals(), locals(), [''])
conduit = getattr(conduit_module, conduit_name)() conduit = getattr(conduit_module, conduit_name)()
LOG('SyncModif, subscriber: ',0,subscriber) LOG('SyncModif, subscriber:',0,subscriber)
# Then apply the list of actions # Then apply the list of actions
(xml_confirmation,has_next_action,cmd_id) = self.applyActionList(cmd_id=cmd_id, (xml_confirmation,has_next_action,cmd_id) = self.applyActionList(cmd_id=cmd_id,
domain=domain, domain=domain,
...@@ -984,16 +1131,17 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -984,16 +1131,17 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
conduit=conduit, simulate=simulate) conduit=conduit, simulate=simulate)
LOG('SyncModif, has_next_action:',0,has_next_action) LOG('SyncModif, has_next_action:',0,has_next_action)
xml = "" xml_list = []
xml += '<SyncML>\n' xml = xml_list.append
xml('<SyncML>\n')
# syncml header # syncml header
if domain.domain_type == self.PUB: if domain.domain_type == self.PUB:
xml += self.SyncMLHeader(subscriber.getSessionId(), "1", xml(self.SyncMLHeader(subscriber.getSessionId(), subscriber.incrementMessageId(),
subscriber.getSubscriptionUrl(), domain.getPublicationUrl()) subscriber.getSubscriptionUrl(), domain.getPublicationUrl()))
elif domain.domain_type == self.SUB: elif domain.domain_type == self.SUB:
xml += self.SyncMLHeader(domain.getSessionId(), "1", xml(self.SyncMLHeader(domain.getSessionId(), domain.incrementMessageId(),
domain.getPublicationUrl(), domain.getSubscriptionUrl()) domain.getPublicationUrl(), domain.getSubscriptionUrl()))
cmd_id += 1 cmd_id += 1
...@@ -1010,47 +1158,51 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1010,47 +1158,51 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
conduit=conduit) conduit=conduit)
# syncml body # syncml body
xml += ' <SyncBody>\n' xml(' <SyncBody>\n')
destination_url = '' destination_url = ''
if domain.domain_type == self.PUB: if domain.domain_type == self.PUB:
subscriber.NewAnchor() subscriber.NewAnchor()
destination_url = domain.getPublicationUrl() destination_url = domain.getPublicationUrl()
xml += self.SyncMLStatus(cmd_id, subscriber.getSubscriptionUrl(), xml(self.SyncMLStatus(cmd_id, subscriber.getSubscriptionUrl(),
domain.getDestinationPath(), domain.getDestinationPath(),
subscriber.getSynchronizationType(), subscriber.getSynchronizationType(),
subscriber.getNextAnchor()) subscriber.getNextAnchor()))
elif domain.domain_type == self.SUB: elif domain.domain_type == self.SUB:
destination_url = domain.getPublicationUrl() destination_url = domain.getPublicationUrl()
xml += self.SyncMLStatus(cmd_id, domain.getPublicationUrl(), xml(self.SyncMLStatus(cmd_id, domain.getPublicationUrl(),
subscriber.getDestinationPath(), subscriber.getDestinationPath(),
subscriber.getSynchronizationType(), subscriber.getSynchronizationType(),
subscriber.getNextAnchor()) subscriber.getNextAnchor()))
# alert message if we want more data # alert message if we want more data
if destination_waiting_more_data == 1: if destination_waiting_more_data == 1:
xml += self.SyncMLAlert(cmd_id, self.WAITING_DATA, xml(self.SyncMLAlert(cmd_id, self.WAITING_DATA,
destination_url, destination_url,
domain.getDestinationPath(), domain.getDestinationPath(),
subscriber.getLastAnchor(), subscriber.getNextAnchor()) subscriber.getLastAnchor(),
subscriber.getNextAnchor()))
# Now we should send confirmations # Now we should send confirmations
xml += xml_confirmation xml(xml_confirmation)
if syncml_data != '': if syncml_data != '':
xml += ' <Sync>\n' xml(' <Sync>\n')
xml += syncml_data xml(syncml_data)
xml += ' </Sync>\n' xml(' </Sync>\n')
xml += ' <Final/>\n' xml(' <Final/>\n')
xml += ' </SyncBody>\n' xml(' </SyncBody>\n')
xml += '</SyncML>\n' xml('</SyncML>\n')
xml_a = ''.join(xml_list)
if domain.domain_type == self.PUB: # We always reply if domain.domain_type == self.PUB: # We always reply
subscriber.setLastSentMessage(xml) subscriber.setLastSentMessage(xml_a)
self.sendResponse(from_url=domain.publication_url, to_url=subscriber.subscription_url, self.sendResponse(from_url=domain.publication_url,
sync_id=domain.getTitle(), xml=xml,domain=domain) to_url=subscriber.subscription_url, sync_id=domain.getTitle(),
xml=xml_a,domain=domain)
has_response = 1 has_response = 1
elif domain.domain_type == self.SUB: elif domain.domain_type == self.SUB:
if self.checkAlert(remote_xml) or \ if self.checkAlert(remote_xml) or \
(xml_confirmation,syncml_data)!=('','') or \ (xml_confirmation,syncml_data)!=('','') or \
has_status_list: has_status_list:
subscriber.setLastSentMessage(xml) subscriber.setLastSentMessage(xml_a)
self.sendResponse(from_url=domain.subscription_url, to_url=domain.publication_url, self.sendResponse(from_url=domain.subscription_url,
sync_id=domain.getTitle(), xml=xml,domain=domain) to_url=domain.publication_url, sync_id=domain.getTitle(),
xml=xml_a,domain=domain)
has_response = 1 has_response = 1
return {'has_response':has_response,'xml':xml} return {'has_response':has_response,'xml':xml_a}
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