Commit 8af948d3 authored by Nicolas Delaby's avatar Nicolas Delaby

Objectify all XML handling

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@25356 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 3cb078f3
...@@ -1029,7 +1029,7 @@ class ERP5Conduit(XMLSyncUtilsMixin): ...@@ -1029,7 +1029,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
""" """
return an xml string corresponding to the node return an xml string corresponding to the node
""" """
return etree.tostring(node, encoding='utf-8') return etree.tostring(node, encoding='utf-8', pretty_print=True)
def getGidFromObject(self, object): def getGidFromObject(self, object):
""" """
......
...@@ -39,6 +39,8 @@ from AccessControl.SecurityManagement import newSecurityManager ...@@ -39,6 +39,8 @@ from AccessControl.SecurityManagement import newSecurityManager
import commands import commands
from DateTime import DateTime from DateTime import DateTime
from zLOG import LOG, DEBUG, INFO, WARNING from zLOG import LOG, DEBUG, INFO, WARNING
from lxml.etree import Element, SubElement
from lxml import etree
class PublicationSynchronization(XMLSyncUtils): class PublicationSynchronization(XMLSyncUtils):
""" """
...@@ -76,17 +78,15 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -76,17 +78,15 @@ class PublicationSynchronization(XMLSyncUtils):
subscriber.setSourceURI(self.getTargetURI(xml_client)) subscriber.setSourceURI(self.getTargetURI(xml_client))
subscriber.setTargetURI(self.getSourceURI(xml_client)) subscriber.setTargetURI(self.getSourceURI(xml_client))
xml_list = []
xml = xml_list.append
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
xml('<SyncML>\n') xml = Element('SyncML')
# syncml header # syncml header
xml(self.SyncMLHeader(subscriber.getSessionId(), xml.append(self.SyncMLHeader(subscriber.getSessionId(),
subscriber.getMessageId(), subscriber.getMessageId(),
subscriber.getSubscriptionUrl(), subscriber.getSubscriptionUrl(),
publication.getPublicationUrl())) publication.getPublicationUrl()))
# syncml body # syncml body
xml(' <SyncBody>\n') sync_body = SubElement(xml, 'SyncBody')
#at the begining, the code is initialised at UNAUTHORIZED #at the begining, the code is initialised at UNAUTHORIZED
...@@ -95,7 +95,7 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -95,7 +95,7 @@ class PublicationSynchronization(XMLSyncUtils):
auth_code = self.AUTH_REQUIRED auth_code = self.AUTH_REQUIRED
LOG("PubSyncInit there's no credential !!!", INFO,'') LOG("PubSyncInit there's no credential !!!", INFO,'')
# Prepare the xml message for the Sync initialization package # Prepare the xml message for the Sync initialization package
xml(self.SyncMLChal(cmd_id, "SyncHdr", sync_body.append(self.SyncMLChal(cmd_id, "SyncHdr",
publication.getPublicationUrl(), subscriber.getSubscriptionUrl(), publication.getPublicationUrl(), subscriber.getSubscriptionUrl(),
publication.getAuthenticationFormat(), publication.getAuthenticationFormat(),
publication.getAuthenticationType(), auth_code)) publication.getAuthenticationType(), auth_code))
...@@ -106,8 +106,8 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -106,8 +106,8 @@ class PublicationSynchronization(XMLSyncUtils):
auth_code, auth_code,
cmd_id, cmd_id,
next_anchor, next_anchor,
subscription=subscriber).values() subscription=subscriber)
xml(xml_status) sync_body.extend(xml_status)
else: else:
# If slow sync, then resend everything # If slow sync, then resend everything
if alert_code == self.SLOW_SYNC and \ if alert_code == self.SLOW_SYNC and \
...@@ -119,7 +119,7 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -119,7 +119,7 @@ class PublicationSynchronization(XMLSyncUtils):
# Check if the last time synchronization is the same as the client one # Check if the last time synchronization is the same as the client one
if subscriber.getNextAnchor() != last_anchor: if subscriber.getNextAnchor() != last_anchor:
if last_anchor in (None, ''): if not last_anchor:
LOG('PubSyncInit', INFO, 'anchor null') LOG('PubSyncInit', INFO, 'anchor null')
else: else:
mess = '\nsubscriber.getNextAnchor:\t%s\nsubscriber.getLastAnchor:\t%s\ mess = '\nsubscriber.getNextAnchor:\t%s\nsubscriber.getLastAnchor:\t%s\
...@@ -159,24 +159,30 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -159,24 +159,30 @@ class PublicationSynchronization(XMLSyncUtils):
# Prepare the xml message for the Sync initialization package # Prepare the xml message for the Sync initialization package
if auth_code == self.AUTH_ACCEPTED: if auth_code == self.AUTH_ACCEPTED:
xml_status, cmd_id = self.SyncMLStatus(xml_client, auth_code, xml_status, cmd_id = self.SyncMLStatus(xml_client, auth_code,
cmd_id, next_anchor, subscription=subscriber).values() cmd_id, next_anchor,
xml(xml_status) subscription=subscriber)
sync_body.extend(xml_status)
# alert message # alert message
xml(self.SyncMLAlert(cmd_id, sync_type, subscriber.getTargetURI(), sync_body.append(self.SyncMLAlert(cmd_id, sync_type,
subscriber.getSourceURI(), subscriber.getLastAnchor(), subscriber.getTargetURI(),
subscriber.getSourceURI(),
subscriber.getLastAnchor(),
next_anchor)) next_anchor))
cmd_id += 1 cmd_id += 1
else: else:
# chal message # chal message
xml(self.SyncMLChal(cmd_id, "SyncHdr", sync_body.append(self.SyncMLChal(cmd_id, "SyncHdr",
publication.getPublicationUrl(), subscriber.getSubscriptionUrl(), publication.getPublicationUrl(),
subscriber.getSubscriptionUrl(),
publication.getAuthenticationFormat(), publication.getAuthenticationFormat(),
publication.getAuthenticationType(), auth_code)) publication.getAuthenticationType(),
auth_code))
cmd_id += 1 cmd_id += 1
xml_status, cmd_id = self.SyncMLStatus(xml_client, xml_status, cmd_id = self.SyncMLStatus(xml_client,
self.AUTH_REQUIRED, cmd_id, next_anchor, self.AUTH_REQUIRED, cmd_id,
subscription=subscriber).values() next_anchor,
xml(xml_status) subscription=subscriber)
sync_body.extend(xml_status)
# We have to set every object as NOT_SYNCHRONIZED # We have to set every object as NOT_SYNCHRONIZED
subscriber.startSynchronization() subscriber.startSynchronization()
...@@ -187,19 +193,17 @@ class PublicationSynchronization(XMLSyncUtils): ...@@ -187,19 +193,17 @@ class PublicationSynchronization(XMLSyncUtils):
has been started from the server (forbiden)" has been started from the server (forbiden)"
# a synchronisation is always starded from a client and can't be from # a synchronisation is always starded from a client and can't be from
# a server ! # a server !
sync_body.append(Element('Final'))
xml(' <Final/>\n') xml_string = etree.tostring(xml, encoding='utf-8', pretty_print=True)
xml(' </SyncBody>\n')
xml('</SyncML>\n')
xml_a = ''.join(xml_list)
if publication.getSyncContentType() == self.CONTENT_TYPE['SYNCML_WBXML']: if publication.getSyncContentType() == self.CONTENT_TYPE['SYNCML_WBXML']:
xml_a = self.xml2wbxml(xml_a) xml_string = self.xml2wbxml(xml_string)
self.sendResponse(from_url=publication.getPublicationUrl(), self.sendResponse(from_url=publication.getPublicationUrl(),
to_url=subscriber.getSubscriptionUrl(), sync_id=publication.getTitle(), to_url=subscriber.getSubscriptionUrl(),
xml=xml_a, domain=publication, sync_id=publication.getTitle(),
xml=xml_string, domain=publication,
content_type=publication.getSyncContentType()) content_type=publication.getSyncContentType())
return {'has_response':1, 'xml':xml_a} return {'has_response':1, 'xml':xml_string}
def PubSyncModif(self, publication, xml_client): def PubSyncModif(self, publication, xml_client):
""" """
......
...@@ -34,6 +34,8 @@ from Conduit.ERP5Conduit import ERP5Conduit ...@@ -34,6 +34,8 @@ from Conduit.ERP5Conduit import ERP5Conduit
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from DateTime import DateTime from DateTime import DateTime
from zLOG import LOG, DEBUG, INFO from zLOG import LOG, DEBUG, INFO
from lxml.etree import Element, SubElement
from lxml import etree
class SubscriptionSynchronization(XMLSyncUtils): class SubscriptionSynchronization(XMLSyncUtils):
...@@ -51,54 +53,50 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -51,54 +53,50 @@ class SubscriptionSynchronization(XMLSyncUtils):
subscription.setZopeUser(user) subscription.setZopeUser(user)
subscription.setAuthenticated(True) subscription.setAuthenticated(True)
xml_list = [] xml = Element('SyncML')
xml = xml_list.append
xml('<SyncML>\n')
# syncml header # syncml header
xml(self.SyncMLHeader(subscription.incrementSessionId(), xml.append(self.SyncMLHeader(subscription.incrementSessionId(),
subscription.incrementMessageId(), subscription.getPublicationUrl(), subscription.incrementMessageId(), subscription.getPublicationUrl(),
subscription.getSubscriptionUrl(), source_name=subscription.getLogin())) subscription.getSubscriptionUrl(), source_name=subscription.getLogin()))
# syncml body # syncml body
xml(' <SyncBody>\n') sync_body = SubElement(xml, 'SyncBody')
# 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(), sync_body.append(self.SyncMLAlert(cmd_id, subscription.getSynchronizationType(),
subscription.getTargetURI(), subscription.getTargetURI(),
subscription.getSourceURI(), subscription.getSourceURI(),
subscription.getLastAnchor(), subscription.getLastAnchor(),
subscription.getNextAnchor())) subscription.getNextAnchor()))
cmd_id += 1 cmd_id += 1
syncml_put = self.SyncMLPut(cmd_id, subscription) syncml_put = self.SyncMLPut(cmd_id, subscription)
if syncml_put not in ('', None): if syncml_put is not None:
xml(syncml_put) sync_body.append(syncml_put)
cmd_id += 1 cmd_id += 1
xml(' </SyncBody>\n')
xml('</SyncML>\n')
xml_a = ''.join(xml_list)
xml_string = etree.tostring(xml, encoding='utf-8', xml_declaration=True,
pretty_print=True)
self.sendResponse(from_url=subscription.subscription_url, self.sendResponse(from_url=subscription.subscription_url,
to_url=subscription.publication_url, sync_id=subscription.getTitle(), to_url=subscription.publication_url,
xml=xml_a,domain=subscription, sync_id=subscription.getTitle(),
xml=xml_string, domain=subscription,
content_type=subscription.getSyncContentType()) content_type=subscription.getSyncContentType())
return {'has_response':1,'xml':xml_a} return {'has_response':1, 'xml':xml_string}
def SubSyncCred (self, subscription, msg=None, RESPONSE=None): def SubSyncCred (self, subscription, msg=None, RESPONSE=None):
""" """
This method send crendentials This method send crendentials
""" """
cmd_id = 1 # specifies a SyncML message-unique command identifier cmd_id = 1 # specifies a SyncML message-unique command identifier
xml_list = [] xml = Element('SyncML')
xml = xml_list.append
xml('<SyncML>\n')
# syncml header # syncml header
data = "%s:%s" % (subscription.getLogin(), subscription.getPassword()) data = "%s:%s" % (subscription.getLogin(), subscription.getPassword())
data=subscription.encode(subscription.getAuthenticationFormat(), data) data = subscription.encode(subscription.getAuthenticationFormat(), data)
xml(self.SyncMLHeader( xml.append(self.SyncMLHeader(
subscription.incrementSessionId(), subscription.incrementSessionId(),
subscription.incrementMessageId(), subscription.incrementMessageId(),
subscription.getPublicationUrl(), subscription.getPublicationUrl(),
...@@ -109,31 +107,32 @@ class SubscriptionSynchronization(XMLSyncUtils): ...@@ -109,31 +107,32 @@ class SubscriptionSynchronization(XMLSyncUtils):
authentication_type=subscription.getAuthenticationType())) authentication_type=subscription.getAuthenticationType()))
# syncml body # syncml body
xml(' <SyncBody>\n') sync_body = SubElement(xml, 'SyncBody')
# 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(), sync_body.append(self.SyncMLAlert(cmd_id, subscription.getSynchronizationType(),
subscription.getTargetURI(), subscription.getTargetURI(),
subscription.getSourceURI(), subscription.getSourceURI(),
subscription.getLastAnchor(), subscription.getLastAnchor(),
subscription.getNextAnchor())) subscription.getNextAnchor()))
cmd_id += 1 cmd_id += 1
xml(self.SyncMLPut(cmd_id, subscription)) syncml_put = self.SyncMLPut(cmd_id, subscription)
if syncml_put is not None:
sync_body.append(syncml_put)
cmd_id += 1 cmd_id += 1
xml(' <Final/>\n') sync_body.append(Element('Final'))
xml(' </SyncBody>\n') xml_string = etree.tostring(xml, encoding='utf-8', xml_declaration=True,
xml('</SyncML>\n') pretty_print=True)
xml_a = ''.join(xml_list)
self.sendResponse(from_url=subscription.subscription_url, self.sendResponse(from_url=subscription.subscription_url,
to_url=subscription.publication_url, sync_id=subscription.getTitle(), to_url=subscription.publication_url,
xml=xml_a, domain=subscription, sync_id=subscription.getTitle(),
xml=xml_string, domain=subscription,
content_type=subscription.getSyncContentType()) content_type=subscription.getSyncContentType())
return {'has_response':1, 'xml':xml_a} return {'has_response':1, 'xml':xml_string}
def SubSyncModif(self, subscription, xml_client): def SubSyncModif(self, subscription, xml_client):
""" """
......
...@@ -41,7 +41,7 @@ class SyncCode(Persistent): ...@@ -41,7 +41,7 @@ class SyncCode(Persistent):
ONE_WAY_FROM_SERVER = 204 ONE_WAY_FROM_SERVER = 204
WAITING_DATA = 214 WAITING_DATA = 214
REFRESH_REQUIRED = 508 REFRESH_REQUIRED = 508
CODE_LIST = ( TWO_WAY, ONE_WAY_FROM_SERVER ) CODE_LIST = ( TWO_WAY, ONE_WAY_FROM_SERVER, )
# SyncML Status Codes # SyncML Status Codes
SUCCESS = 200 SUCCESS = 200
......
...@@ -712,12 +712,12 @@ class SynchronizationTool( SubscriptionSynchronization, ...@@ -712,12 +712,12 @@ class SynchronizationTool( SubscriptionSynchronization,
if solve_conflict: if solve_conflict:
copy_path = conflict.getCopyPath() copy_path = conflict.getCopyPath()
signature.delConflict(conflict) signature.delConflict(conflict)
if signature.getConflictList() == []: if not signature.getConflictList():
if copy_path is not None: if copy_path is not None:
# Delete the copy of the object if the there is one # Delete the copy of the object if the there is one
directory = object.aq_parent directory = object.aq_parent
copy_id = copy_path[-1] copy_id = copy_path[-1]
if hasattr(directory.aq_base, 'hasObject'): if getattr(directory.aq_base, 'hasObject', None) is not None:
# optimize the case of a BTree folder # optimize the case of a BTree folder
if directory.hasObject(id): if directory.hasObject(id):
directory._delObject(copy_id) directory._delObject(copy_id)
...@@ -828,8 +828,6 @@ class SynchronizationTool( SubscriptionSynchronization, ...@@ -828,8 +828,6 @@ class SynchronizationTool( SubscriptionSynchronization,
if content_type == self.CONTENT_TYPE['SYNCML_WBXML']: if content_type == self.CONTENT_TYPE['SYNCML_WBXML']:
xml = self.xml2wbxml(xml) xml = self.xml2wbxml(xml)
#LOG('sendHttpResponse, xml after wbxml: \n', DEBUG, 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: 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):
...@@ -868,7 +866,7 @@ class SynchronizationTool( SubscriptionSynchronization, ...@@ -868,7 +866,7 @@ class SynchronizationTool( SubscriptionSynchronization,
content_type=content_type) content_type=content_type)
elif to_url.find('file://') == 0: elif to_url.find('file://') == 0:
filename = to_url[len('file:/'):] filename = to_url[len('file:/'):]
stream = file(filename,'w') stream = file(filename, 'w')
stream.write(xml) stream.write(xml)
stream.close() stream.close()
# we have to use local files (unit testing for example # we have to use local files (unit testing for example
......
...@@ -34,7 +34,7 @@ from ERP5Diff import ERP5Diff ...@@ -34,7 +34,7 @@ from ERP5Diff import ERP5Diff
from zLOG import LOG, INFO from zLOG import LOG, INFO
from lxml import etree from lxml import etree
from lxml.etree import Element from lxml.etree import Element, SubElement
from lxml.builder import E from lxml.builder import E
parser = etree.XMLParser(remove_blank_text=True) parser = etree.XMLParser(remove_blank_text=True)
...@@ -74,8 +74,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -74,8 +74,7 @@ class XMLSyncUtilsMixin(SyncCode):
E.Type(authentication_type, xmlns='syncml:metinf'),), E.Type(authentication_type, xmlns='syncml:metinf'),),
E.Data(dataCred) E.Data(dataCred)
)) ))
return etree.tostring(xml, encoding='utf-8', return xml
xml_declaration=False, pretty_print=False)
def SyncMLAlert(self, cmd_id, sync_code, target, source, last_anchor, def SyncMLAlert(self, cmd_id, sync_code, target, source, last_anchor,
next_anchor): next_anchor):
...@@ -101,8 +100,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -101,8 +100,7 @@ class XMLSyncUtilsMixin(SyncCode):
) )
) )
)) ))
return etree.tostring(xml, encoding='utf-8', return xml
xml_declaration=False, pretty_print=False)
def SyncMLStatus(self, remote_xml, data_code, cmd_id, next_anchor, def SyncMLStatus(self, remote_xml, data_code, cmd_id, next_anchor,
subscription=None): subscription=None):
...@@ -114,58 +112,47 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -114,58 +112,47 @@ class XMLSyncUtilsMixin(SyncCode):
#list of element in the SyncBody bloc #list of element in the SyncBody bloc
sub_syncbody_element_list = remote_xml.xpath('/SyncML/SyncBody/*') sub_syncbody_element_list = remote_xml.xpath('/SyncML/SyncBody/*')
message_id = self.getMessageIdFromXml(remote_xml) message_id = self.getMessageIdFromXml(remote_xml)
xml_list = [] status_list = []
xml = xml_list.append target_uri = '%s' % remote_xml.xpath('string(/SyncML/SyncHdr/Target/LocURI)')
source_uri = '%s' % remote_xml.xpath('string(/SyncML/SyncHdr/Source/LocURI)')
if data_code != self.AUTH_REQUIRED:#because for AUTH_REQUIRED, SyncMLChal is #called if data_code != self.AUTH_REQUIRED:
# status for SyncHdr xml = (E.Status(
xml(' <Status>\n') E.CmdID('%s' % cmd_id),
xml(' <CmdID>%s</CmdID>\n' % cmd_id) E.MsgRef('%s' % message_id),
E.CmdRef('0'),
E.Cmd('SyncHdr'),
E.TargetRef(target_uri),
E.SourceRef(source_uri),
E.Data('%s' % data_code),
))
cmd_id += 1 cmd_id += 1
xml(' <MsgRef>%s</MsgRef>\n' % message_id) status_list.append(xml)
xml(' <CmdRef>0</CmdRef>\n') #to make reference to the SyncHdr, it's 0
xml(' <Cmd>SyncHdr</Cmd>\n')
target_uri = remote_xml.xpath('string(/SyncML/SyncHdr/Target/LocURI)')
xml(' <TargetRef>%s</TargetRef>\n' % (target_uri))
source_uri = remote_xml.xpath('string(/SyncML/SyncHdr/Source/LocURI)')
xml(' <SourceRef>%s</SourceRef>\n' % (source_uri))
xml(' <Data>%s</Data>\n' % (data_code))
xml(' </Status>\n')
#add the status bloc corresponding to the receive command
for sub_syncbody_element in sub_syncbody_element_list: for sub_syncbody_element in sub_syncbody_element_list:
#LOG('SyncMLStatus : ', DEBUG, "command:%s, subscription:%s" % (str(syncbody_element.tag), subscription))
if sub_syncbody_element.tag not in ('Status', 'Final', 'Get'): if sub_syncbody_element.tag not in ('Status', 'Final', 'Get'):
xml(' <Status>\n') xml = (E.Status(
xml(' <CmdID>%s</CmdID>\n' % cmd_id) E.CmdID('%s' % cmd_id),
E.MsgRef('%s' % message_id),
E.CmdRef('%s' % sub_syncbody_element.xpath('string(.//CmdID)')),
E.Cmd(sub_syncbody_element.tag)
))
cmd_id += 1 cmd_id += 1
xml(' <MsgRef>%s</MsgRef>\n' % message_id)
xml(' <CmdRef>%s</CmdRef>\n' \
% sub_syncbody_element.xpath('string(.//CmdID)'))
xml(' <Cmd>%s</Cmd>\n' % sub_syncbody_element.tag)
target_ref = sub_syncbody_element.xpath('string(.//Target/LocURI)') target_ref = sub_syncbody_element.xpath('string(.//Target/LocURI)')
if target_ref: if target_ref:
xml(' <TargetRef>%s</TargetRef>\n' % target_ref ) xml.append(E.TargetRef('%s' % target_ref))
source_ref = sub_syncbody_element.xpath('string(.//Source/LocURI)') source_ref = sub_syncbody_element.xpath('string(.//Source/LocURI)')
if source_ref: if source_ref:
xml(' <SourceRef>%s</SourceRef>\n' % source_ref ) xml.append(E.SourceRef('%s' % source_ref))
if sub_syncbody_element.tag == 'Add': if sub_syncbody_element.tag == 'Add':
xml(' <Data>%s</Data>\n' % self.ITEM_ADDED) xml.append(E.Data('%s' % self.ITEM_ADDED))
elif sub_syncbody_element.tag == 'Alert' and \ elif sub_syncbody_element.tag == 'Alert' and \
sub_syncbody_element.xpath('string(.//Data)') == \ sub_syncbody_element.xpath('string(.//Data)') == \
str(self.SLOW_SYNC): str(self.SLOW_SYNC):
xml(' <Data>%s</Data>\n' % self.REFRESH_REQUIRED) xml.append(E.Data('%s' % self.REFRESH_REQUIRED))
elif sub_syncbody_element.tag == 'Alert': elif sub_syncbody_element.tag == 'Alert':
xml(' <Item>\n') xml.append(E.Item(E.Data(E.Anchor(E.Next(next_anchor)))))
xml(' <Data>\n')
xml(' <Anchor>\n')
xml(' <Next>%s</Next>\n' % next_anchor)
xml(' </Anchor>\n')
xml(' </Data>\n')
xml(' </Item>\n')
else: else:
xml(' <Data>%s</Data>\n' % self.SUCCESS) xml.append(E.Data('%s' % self.SUCCESS))
xml(' </Status>\n') status_list.append(xml)
if sub_syncbody_element.tag == 'Get' and subscription is not None: if sub_syncbody_element.tag == 'Get' and subscription is not None:
cmd_ref = '%s' % sub_syncbody_element.xpath('string(.//CmdID)') cmd_ref = '%s' % sub_syncbody_element.xpath('string(.//CmdID)')
...@@ -175,10 +162,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -175,10 +162,11 @@ class XMLSyncUtilsMixin(SyncCode):
markup='Results', markup='Results',
cmd_ref=cmd_ref, cmd_ref=cmd_ref,
message_id=message_id) message_id=message_id)
xml(syncml_result) if syncml_result is not None:
status_list.append(syncml_result)
cmd_id += 1 cmd_id += 1
xml_a = ''.join(xml_list)
return {'xml':xml_a, 'cmd_id':cmd_id} return status_list, cmd_id
def SyncMLConfirmation(self, cmd_id=None, target_ref=None, cmd=None, def SyncMLConfirmation(self, cmd_id=None, target_ref=None, cmd=None,
sync_code=None, msg_ref=None, cmd_ref=None, source_ref=None, sync_code=None, msg_ref=None, cmd_ref=None, source_ref=None,
...@@ -192,7 +180,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -192,7 +180,7 @@ class XMLSyncUtilsMixin(SyncCode):
cmd_ref = '%s' % remote_xml.xpath("string(.//CmdID)") cmd_ref = '%s' % remote_xml.xpath("string(.//CmdID)")
target_ref = '%s' % remote_xml.xpath("string(.//Target/LocURI)") target_ref = '%s' % remote_xml.xpath("string(.//Target/LocURI)")
source_ref = '%s' % remote_xml.xpath("string(.//Source/LocURI)") source_ref = '%s' % remote_xml.xpath("string(.//Source/LocURI)")
xml = (E.Status()) xml = Element('Status')
if cmd_id: if cmd_id:
xml.append(E.CmdID('%s' % cmd_id)) xml.append(E.CmdID('%s' % cmd_id))
if msg_ref: if msg_ref:
...@@ -207,12 +195,10 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -207,12 +195,10 @@ class XMLSyncUtilsMixin(SyncCode):
xml.append(E.SourceRef(source_ref)) xml.append(E.SourceRef(source_ref))
if sync_code: if sync_code:
xml.append(E.Data('%s'% sync_code)) xml.append(E.Data('%s'% sync_code))
return xml
return etree.tostring(xml, encoding='utf-8',
xml_declaration=False, pretty_print=False)
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): auth_type, auth_code):
""" """
This is used in order to ask crendentials This is used in order to ask crendentials
""" """
...@@ -229,10 +215,9 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -229,10 +215,9 @@ class XMLSyncUtilsMixin(SyncCode):
E.Type(auth_type, xmlns='syncml:metinf') E.Type(auth_type, xmlns='syncml:metinf')
) )
), ),
E.Data('%s' % data_code) E.Data('%s' % auth_code)
)) ))
return etree.tostring(xml, encoding='utf-8', return xml
xml_declaration=False, pretty_print=False)
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): message_id=None):
...@@ -243,81 +228,59 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -243,81 +228,59 @@ class XMLSyncUtilsMixin(SyncCode):
""" """
conduit_name = subscription.getConduit() conduit_name = subscription.getConduit()
conduit = self.getConduitByName(conduit_name) conduit = self.getConduitByName(conduit_name)
xml = None
#if the conduit support the SyncMLPut : #if the conduit support the SyncMLPut :
if getattr(conduit, 'getCapabilitiesCTTypeList', None) is not None and \ if getattr(conduit, 'getCapabilitiesCTTypeList', None) is not None and \
getattr(conduit, 'getCapabilitiesVerCTList', None) is not None and \ getattr(conduit, 'getCapabilitiesVerCTList', None) is not None and \
getattr(conduit, 'getPreferedCapabilitieVerCT', None) is not None: getattr(conduit, 'getPreferedCapabilitieVerCT', None) is not None:
xml_list = [] xml = Element(markup)
xml = xml_list.append xml.append(E.CmdID('%s' % cmd_id))
xml(' <%s>\n' % markup)
xml(' <CmdID>%s</CmdID>\n' % cmd_id)
if message_id: if message_id:
xml(' <MsgRef>%s</MsgRef>\n' % message_id) xml.append(E.MsgRef('%s' % message_id))
if cmd_ref: if cmd_ref:
xml(' <CmdRef>%s</CmdRef>\n' % cmd_ref) xml.append(E.CmdRef('%s' % cmd_ref))
xml(' <Meta>\n') xml.append(E.Meta(E.Type('application/vnd.syncml-devinf+xml')),
xml(' <Type>application/vnd.syncml-devinf+xml</Type>\n'); E.Item(E.Source(E.LocURI('./devinf11')),
xml(' </Meta>\n') E.Data(E.DevInf(
xml(' <Item>\n') E.VerDTD('1.1'),
xml(' <Source>\n') E.Man('Nexedi'),
xml(' <LocURI>./devinf11</LocURI>\n') E.Mod('ERP5SyncML'),
xml(' </Source>\n') E.OEM('Open Source'),
xml(' <Data>\n') E.SwV('0.1'),
xml(' <DevInf>\n') E.DevID(subscription.getSubscriptionUrl()),
xml(' <VerDTD>1.1</VerDTD>\n') E.DevTyp('workstation'),
xml(' <Man>Nexedi</Man>\n') E.UTC(),
xml(' <Mod>ERP5SyncML</Mod>\n') E.DataStore(
xml(' <OEM>Open Source</OEM>\n') E.SourceRef(subscription.getSourceURI()),
xml(' <SwV>0.1</SwV>\n') Element('E.Rx-Pref').append(
xml(' <DevID>%s</DevID>\n' % subscription.getSubscriptionUrl()) (E.CTType(conduit.getPreferedCapabilitieCTType()),
xml(' <DevTyp>workstation</DevTyp>\n') E.VerCT(conduit.getPreferedCapabilitieVerCT()))
xml(' <UTC/>\n') )
xml(' <DataStore>\n') )
xml(' <SourceRef>%s</SourceRef>\n' % subscription.getSourceURI()) )
xml(' <Rx-Pref>\n') )
xml(' <CTType>%s</CTType>\n' % \ ))
conduit.getPreferedCapabilitieCTType()) data_store = xml.find('DataStore')
xml(' <VerCT>%s</VerCT>\n' % \ tx_element_list = []
conduit.getPreferedCapabilitieVerCT()) rx_element_list = []
xml(' </Rx-Pref>\n')
for type in conduit.getCapabilitiesCTTypeList():
if type != self.MEDIA_TYPE['TEXT_XML']:
for rx_version in conduit.getCapabilitiesVerCTList(type):
xml(' <Rx>\n')
xml(' <CTType>%s</CTType>\n' % type)
xml(' <VerCT>%s</VerCT>\n' % rx_version)
xml(' </Rx>\n')
xml(' <Tx-Pref>\n')
xml(' <CTType>%s</CTType>\n' % \
conduit.getPreferedCapabilitieCTType())
xml(' <VerCT>%s</VerCT>\n' % \
conduit.getPreferedCapabilitieVerCT())
xml(' </Tx-Pref>\n')
for type in conduit.getCapabilitiesCTTypeList(): for type in conduit.getCapabilitiesCTTypeList():
if type != self.MEDIA_TYPE['TEXT_XML']: if type != self.MEDIA_TYPE['TEXT_XML']:
for tx_version in conduit.getCapabilitiesVerCTList(type): for tx_version in conduit.getCapabilitiesVerCTList(type):
xml(' <Tx>\n') rx_element_list.append(E.Rx(E.CTType(type), E.VerCT(rx_version)))
xml(' <CTType>%s</CTType>\n' % type) tx_element_list.append(E.Tx(E.CTType(type), E.VerCT(rx_version)))
xml(' <VerCT>%s</VerCT>\n' % tx_version) data_store.extend(rx_element_list)
xml(' </Tx>\n') data_store.append(Element('Tx-Pref').extend(
(E.CTType(conduit.getPreferedCapabilitieCTType()),
xml(' <SyncCap>\n') E.VerCT(conduit.getPreferedCapabilitieVerCT()))
xml(' <SyncType>2</SyncType>\n') ))
xml(' <SyncType>1</SyncType>\n') data_store.extend(tx_element_list)
xml(' <SyncType>4</SyncType>\n') data_store.append(E.SyncCap(
xml(' <SyncType>6</SyncType>\n') E.SyncType('2'),
xml(' </SyncCap>\n') E.SyncType('1'),
E.SyncType('4'),
xml(' </DataStore>\n') E.SyncType('6')
xml(' </DevInf>\n') ))
xml(' </Data>\n') return xml
xml(' </Item>\n')
xml(' </%s>\n' % markup)
xml_a = ''.join(xml_list)
return xml_a
return ''
def sendMail(self, fromaddr, toaddr, id_sync, msg): def sendMail(self, fromaddr, toaddr, id_sync, msg):
""" """
...@@ -365,8 +328,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -365,8 +328,7 @@ class XMLSyncUtilsMixin(SyncCode):
if more_data: if more_data:
item_node = xml.find('Item') item_node = xml.find('Item')
item_node.append(Element('MoreData')) item_node.append(Element('MoreData'))
return etree.tostring(xml, encoding='utf-8', return etree.tostring(xml, encoding='utf-8', pretty_print=True)
xml_declaration=False, pretty_print=False)
def deleteXMLObject(self, cmd_id=0, object_gid=None, rid=None, xml_object=''): def deleteXMLObject(self, cmd_id=0, object_gid=None, rid=None, xml_object=''):
""" """
...@@ -382,8 +344,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -382,8 +344,7 @@ class XMLSyncUtilsMixin(SyncCode):
elem_to_append elem_to_append
) )
)) ))
return etree.tostring(xml, encoding='utf-8', return etree.tostring(xml, encoding='utf-8', pretty_print=True)
xml_declaration=False, pretty_print=False)
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, rid=None, media_type=None): more_data=0, gid=None, rid=None, media_type=None):
...@@ -412,8 +373,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -412,8 +373,7 @@ class XMLSyncUtilsMixin(SyncCode):
if more_data: if more_data:
item_node = xml.find('Item') item_node = xml.find('Item')
item_node.append(Element('MoreData')) item_node.append(Element('MoreData'))
return etree.tostring(xml, encoding='utf-8', return etree.tostring(xml, encoding='utf-8', pretty_print=True)
xml_declaration=False, pretty_print=False)
def getXupdateObject(self, object_xml=None, old_xml=None): def getXupdateObject(self, object_xml=None, old_xml=None):
""" """
...@@ -509,7 +469,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -509,7 +469,7 @@ class XMLSyncUtilsMixin(SyncCode):
""" """
cmd = None cmd = None
if xml.tag == 'Status': if xml.tag == 'Status':
cmd = '%s' % xml.xpath('string(//Status/Cmd)') cmd = '%s' % xml.xpath('string(Cmd)')
return cmd return cmd
def getCred(self, xml): def getCred(self, xml):
...@@ -658,7 +618,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -658,7 +618,7 @@ class XMLSyncUtilsMixin(SyncCode):
return xml_string, rest_string return xml_string, rest_string
def getSyncMLData(self, domain=None, remote_xml=None, cmd_id=0, def getSyncMLData(self, domain=None, remote_xml=None, cmd_id=0,
subscriber=None, xml_confirmation=None, conduit=None, subscriber=None, xml_confirmation_list=None, conduit=None,
max=None, **kw): max=None, **kw):
""" """
This generate the syncml data message. This returns a string This generate the syncml data message. This returns a string
...@@ -670,8 +630,10 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -670,8 +630,10 @@ class XMLSyncUtilsMixin(SyncCode):
#LOG('getSyncMLData starting...', DEBUG, domain.getId()) #LOG('getSyncMLData starting...', DEBUG, domain.getId())
if isinstance(conduit, str): if isinstance(conduit, str):
conduit = self.getConduitByName(conduit) conduit = self.getConduitByName(conduit)
if xml_confirmation_list is None:
xml_confirmation_list = []
local_gid_list = [] local_gid_list = []
syncml_data = kw.get('syncml_data','') syncml_data_list = kw.get('syncml_data_list', [])
result = {'finished':1} result = {'finished':1}
if isinstance(remote_xml, (str, unicode)): if isinstance(remote_xml, (str, unicode)):
remote_xml = etree.XML(remote_xml, parser=parser) remote_xml = etree.XML(remote_xml, parser=parser)
...@@ -714,11 +676,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -714,11 +676,11 @@ class XMLSyncUtilsMixin(SyncCode):
# we were not able to create # we were not able to create
rid = signature.getRid() rid = signature.getRid()
object_gid_deleted.append(object_gid) object_gid_deleted.append(object_gid)
syncml_data += self.deleteXMLObject( syncml_data_list.append(self.deleteXMLObject(
xml_object=signature.getXML() or '', xml_object=signature.getXML() or '',
object_gid=object_gid, object_gid=object_gid,
rid=rid, rid=rid,
cmd_id=cmd_id) cmd_id=cmd_id))
cmd_id += 1 cmd_id += 1
#delete Signature if object does not exist anymore #delete Signature if object does not exist anymore
for known_gid in subscriber.getGidList(): for known_gid in subscriber.getGidList():
...@@ -738,7 +700,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -738,7 +700,7 @@ class XMLSyncUtilsMixin(SyncCode):
continue continue
local_gid_list += [object_gid] local_gid_list += [object_gid]
force = 0 force = 0
if syncml_data.count('\n') < self.MAX_LINES and not \ if ''.join(syncml_data_list).count('\n') < self.MAX_LINES and not \
object.id.startswith('.'): object.id.startswith('.'):
# If not we have to cut # If not we have to cut
#LOG('getSyncMLData', 0, 'object_path: %s' % '/'.join(object_path)) #LOG('getSyncMLData', 0, 'object_path: %s' % '/'.join(object_path))
...@@ -774,13 +736,13 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -774,13 +736,13 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setAction('Add') signature.setAction('Add')
#in fisrt, we try with rid if there is one #in fisrt, we try with rid if there is one
gid = signature.getRid() or signature.getGid() gid = signature.getRid() or signature.getGid()
syncml_data += self.addXMLObject( syncml_data_list.append(self.addXMLObject(
cmd_id=cmd_id, cmd_id=cmd_id,
object=object, object=object,
gid=gid, gid=gid,
xml_string=xml_string, xml_string=xml_string,
more_data=more_data, more_data=more_data,
media_type=subscriber.getMediaType()) media_type=subscriber.getMediaType()))
cmd_id += 1 cmd_id += 1
signature.setStatus(status) signature.setStatus(status)
subscriber.addSignature(signature) subscriber.addSignature(signature)
...@@ -791,11 +753,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -791,11 +753,11 @@ class XMLSyncUtilsMixin(SyncCode):
#LOG('getSyncMLData', DEBUG, 'checkMD5: %s' % str(signature.checkMD5(xml_object))) #LOG('getSyncMLData', DEBUG, 'checkMD5: %s' % str(signature.checkMD5(xml_object)))
#LOG('getSyncMLData', DEBUG, 'getStatus: %s' % str(signature.getStatus())) #LOG('getSyncMLData', DEBUG, 'getStatus: %s' % str(signature.getStatus()))
if signature.getStatus() == self.PUB_CONFLICT_MERGE: if signature.getStatus() == self.PUB_CONFLICT_MERGE:
xml_confirmation += self.SyncMLConfirmation( xml_confirmation_list.append(self.SyncMLConfirmation(
cmd_id=cmd_id, cmd_id=cmd_id,
source_ref=signature.getGid(), source_ref=signature.getGid(),
sync_code=self.CONFLICT_MERGE, sync_code=self.CONFLICT_MERGE,
cmd='Replace') cmd='Replace'))
set_synchronized = 1 set_synchronized = 1
if not signature.checkMD5(xml_object): if not signature.checkMD5(xml_object):
set_synchronized = 0 set_synchronized = 0
...@@ -816,12 +778,12 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -816,12 +778,12 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setStatus(status) signature.setStatus(status)
rid = signature.getRid()#in fisrt, we try with rid if there is one rid = signature.getRid()#in fisrt, we try with rid if there is one
gid = signature.getGid() gid = signature.getGid()
syncml_data += self.replaceXMLObject( syncml_data_list.append(self.replaceXMLObject(
cmd_id=cmd_id, object=object, cmd_id=cmd_id, object=object,
gid=gid, rid=rid, gid=gid, rid=rid,
xml_string=xml_string, xml_string=xml_string,
more_data=more_data, more_data=more_data,
media_type=subscriber.getMediaType()) media_type=subscriber.getMediaType()))
cmd_id += 1 cmd_id += 1
signature.setTempXML(xml_object) signature.setTempXML(xml_object)
# Now we can apply the xupdate from the subscriber # Now we can apply the xupdate from the subscriber
...@@ -851,11 +813,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -851,11 +813,11 @@ class XMLSyncUtilsMixin(SyncCode):
object=object, object=object,
previous_xml=signature.getXML(), previous_xml=signature.getXML(),
force=1) force=1)
xml_confirmation += self.SyncMLConfirmation( xml_confirmation_list.append(self.SyncMLConfirmation(
cmd_id=cmd_id, cmd_id=cmd_id,
target_ref=object_gid, target_ref=object_gid,
sync_code=self.CONFLICT_CLIENT_WIN, sync_code=self.CONFLICT_CLIENT_WIN,
cmd='Replace') cmd='Replace'))
signature.setStatus(self.SYNCHRONIZED) signature.setStatus(self.SYNCHRONIZED)
elif signature.getStatus() == self.PARTIAL: elif signature.getStatus() == self.PARTIAL:
xml_string = signature.getPartialXML() xml_string = signature.getPartialXML()
...@@ -872,32 +834,32 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -872,32 +834,32 @@ class XMLSyncUtilsMixin(SyncCode):
if signature.getAction() == 'Replace': if signature.getAction() == 'Replace':
rid = signature.getRid()#in fisrt, we try with rid if there is one rid = signature.getRid()#in fisrt, we try with rid if there is one
gid = signature.getGid() gid = signature.getGid()
syncml_data += self.replaceXMLObject( syncml_data_list.append(self.replaceXMLObject(
cmd_id=cmd_id, cmd_id=cmd_id,
object=object, object=object,
gid=gid, gid=gid,
rid=rid, rid=rid,
xml_string=xml_to_send, xml_string=xml_to_send,
more_data=more_data, more_data=more_data,
media_type=subscriber.getMediaType()) media_type=subscriber.getMediaType()))
elif signature.getAction() == 'Add': elif signature.getAction() == 'Add':
#in fisrt, we try with rid if there is one #in fisrt, we try with rid if there is one
gid = signature.getRid() or signature.getGid() gid = signature.getRid() or signature.getGid()
syncml_data += self.addXMLObject( syncml_data_list.append(self.addXMLObject(
cmd_id=cmd_id, cmd_id=cmd_id,
object=object, object=object,
gid=gid, gid=gid,
xml_string=xml_to_send, xml_string=xml_to_send,
more_data=more_data, more_data=more_data,
media_type=subscriber.getMediaType()) media_type=subscriber.getMediaType()))
if not more_data: if not more_data:
subscriber.removeRemainingObjectPath(object_path) subscriber.removeRemainingObjectPath(object_path)
else: else:
result['finished'] = 1 result['finished'] = 1
break break
loop += 1 loop += 1
result['syncml_data'] = syncml_data result['syncml_data_list'] = syncml_data_list
result['xml_confirmation'] = xml_confirmation result['xml_confirmation_list'] = xml_confirmation_list
result['cmd_id'] = cmd_id result['cmd_id'] = cmd_id
return result return result
...@@ -907,7 +869,7 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -907,7 +869,7 @@ class XMLSyncUtilsMixin(SyncCode):
This just look to a list of action to do, then id applies This just look to a list of action to do, then id applies
each action one by one, thanks to a conduit each action one by one, thanks to a conduit
""" """
xml_confirmation = '' xml_confirmation_list = []
has_next_action = 0 has_next_action = 0
gid_from_xml_list = [] gid_from_xml_list = []
destination = self.unrestrictedTraverse(domain.getDestinationPath()) destination = self.unrestrictedTraverse(domain.getDestinationPath())
...@@ -998,12 +960,12 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -998,12 +960,12 @@ class XMLSyncUtilsMixin(SyncCode):
xml_string = etree.tostring(data_subnode, encoding='utf-8') xml_string = etree.tostring(data_subnode, encoding='utf-8')
actual_xml = subscriber.getXMLFromObject(object=object, force=1) actual_xml = subscriber.getXMLFromObject(object=object, force=1)
data_subnode = self.getXupdateObject(xml_string, actual_xml) data_subnode = self.getXupdateObject(xml_string, actual_xml)
conflict_list += conduit.updateNode( conflict_list.extend(conduit.updateNode(
xml=data_subnode, xml=data_subnode,
object=object, object=object,
previous_xml=signature.getXML(), previous_xml=signature.getXML(),
force=force, force=force,
simulate=simulate) simulate=simulate))
xml_object = domain.getXMLFromObject(object) xml_object = domain.getXMLFromObject(object)
signature.setTempXML(xml_object) signature.setTempXML(xml_object)
if object is not None: if object is not None:
...@@ -1012,7 +974,8 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -1012,7 +974,8 @@ class XMLSyncUtilsMixin(SyncCode):
#After a reset we want copy the LAST XML view on Signature. #After a reset we want copy the LAST XML view on Signature.
#this implementation is not sufficient, need to be improved. #this implementation is not sufficient, need to be improved.
if not isinstance(data_subnode, str): if not isinstance(data_subnode, str):
xml_object = etree.tostring(data_subnode, encoding='utf-8') xml_object = etree.tostring(data_subnode, encoding='utf-8',
pretty_print=True)
else: else:
xml_object = data_subnode xml_object = data_subnode
else: else:
...@@ -1021,11 +984,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -1021,11 +984,11 @@ class XMLSyncUtilsMixin(SyncCode):
#signature.setId(object.getId()) #signature.setId(object.getId())
signature.setPath(object.getPhysicalPath()) signature.setPath(object.getPhysicalPath())
signature.setXML(xml_object) signature.setXML(xml_object)
xml_confirmation += self.SyncMLConfirmation( xml_confirmation_list.append(self.SyncMLConfirmation(
cmd_id=cmd_id, cmd_id=cmd_id,
cmd='Add', cmd='Add',
sync_code=self.ITEM_ADDED, sync_code=self.ITEM_ADDED,
remote_xml=action) remote_xml=action))
cmd_id +=1 cmd_id +=1
elif action.tag == 'Replace': elif action.tag == 'Replace':
#LOG('applyActionList', DEBUG, 'object: %s will be updated...' % str(object)) #LOG('applyActionList', DEBUG, 'object: %s will be updated...' % str(object))
...@@ -1052,11 +1015,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -1052,11 +1015,11 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setPartialXML(data_subnode_string) signature.setPartialXML(data_subnode_string)
elif not simulate: elif not simulate:
signature.setStatus(self.SYNCHRONIZED) signature.setStatus(self.SYNCHRONIZED)
xml_confirmation += self.SyncMLConfirmation( xml_confirmation_list.append(self.SyncMLConfirmation(
cmd_id=cmd_id, cmd_id=cmd_id,
cmd='Replace', cmd='Replace',
sync_code=status_code, sync_code=status_code,
remote_xml=action) remote_xml=action))
cmd_id +=1 cmd_id +=1
if simulate: if simulate:
# This means we are on the publisher side and we want to store # This means we are on the publisher side and we want to store
...@@ -1081,11 +1044,11 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -1081,11 +1044,11 @@ class XMLSyncUtilsMixin(SyncCode):
object=destination, object=destination,
object_id=subscriber.getObjectFromGid(object_id).getId()) object_id=subscriber.getObjectFromGid(object_id).getId())
subscriber.delSignature(gid) subscriber.delSignature(gid)
xml_confirmation += self.SyncMLConfirmation( xml_confirmation_list.append(self.SyncMLConfirmation(
cmd_id=cmd_id, cmd_id=cmd_id,
cmd='Delete', cmd='Delete',
sync_code=status_code, sync_code=status_code,
remote_xml=action) remote_xml=action))
else: # We want to retrieve more data else: # We want to retrieve more data
signature.setStatus(self.PARTIAL) signature.setStatus(self.PARTIAL)
previous_partial = signature.getPartialXML() or '' previous_partial = signature.getPartialXML() or ''
...@@ -1094,16 +1057,16 @@ class XMLSyncUtilsMixin(SyncCode): ...@@ -1094,16 +1057,16 @@ class XMLSyncUtilsMixin(SyncCode):
signature.setPartialXML(previous_partial) signature.setPartialXML(previous_partial)
#LOG('applyActionList', DEBUG, 'previous_partial: %s' % str(previous_partial)) #LOG('applyActionList', DEBUG, 'previous_partial: %s' % str(previous_partial))
#LOG('applyActionList', DEBUG, 'waiting more data for :%s' % signature.getId()) #LOG('applyActionList', DEBUG, 'waiting more data for :%s' % signature.getId())
xml_confirmation += self.SyncMLConfirmation( xml_confirmation_list.append(self.SyncMLConfirmation(
cmd_id=cmd_id, cmd_id=cmd_id,
cmd=action.tag, cmd=action.tag,
sync_code=self.WAITING_DATA, sync_code=self.WAITING_DATA,
remote_xml=action) remote_xml=action))
if conflict_list and signature is not None: if conflict_list and signature is not None:
# We had a conflict # We had a conflict
signature.setStatus(self.CONFLICT) signature.setStatus(self.CONFLICT)
return (xml_confirmation, has_next_action, cmd_id) return (xml_confirmation_list, has_next_action, cmd_id)
def applyStatusList(self, subscriber=None, remote_xml=None): def applyStatusList(self, subscriber=None, remote_xml=None):
""" """
...@@ -1243,7 +1206,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1243,7 +1206,7 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
subscriber.setLastSentMessage('') subscriber.setLastSentMessage('')
# First apply the list of status codes # First apply the list of status codes
(destination_waiting_more_data,has_status_list) = self.applyStatusList( (destination_waiting_more_data, has_status_list) = self.applyStatusList(
subscriber=subscriber, subscriber=subscriber,
remote_xml=remote_xml) remote_xml=remote_xml)
...@@ -1251,46 +1214,42 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1251,46 +1214,42 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
# Import the conduit and get it # Import the conduit and get it
conduit = self.getConduitByName(subscriber.getConduit()) conduit = self.getConduitByName(subscriber.getConduit())
# Then apply the list of actions # Then apply the list of actions
(xml_confirmation, has_next_action, cmd_id) = self.applyActionList( (xml_confirmation_list, has_next_action, cmd_id) = self.applyActionList(
cmd_id=cmd_id, cmd_id=cmd_id,
domain=domain, domain=domain,
subscriber=subscriber, subscriber=subscriber,
remote_xml=remote_xml, remote_xml=remote_xml,
conduit=conduit, simulate=simulate) conduit=conduit, simulate=simulate)
xml_list = [] xml = Element('SyncML')
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( xml.append(self.SyncMLHeader(
subscriber.getSessionId(), subscriber.getSessionId(),
subscriber.incrementMessageId(), subscriber.incrementMessageId(),
subscriber.getSubscriptionUrl(), subscriber.getSubscriptionUrl(),
domain.getPublicationUrl())) domain.getPublicationUrl()))
elif domain.domain_type == self.SUB: elif domain.domain_type == self.SUB:
xml(self.SyncMLHeader( xml.append(self.SyncMLHeader(
domain.getSessionId(), domain.incrementMessageId(), domain.getSessionId(), domain.incrementMessageId(),
domain.getPublicationUrl(), domain.getPublicationUrl(),
domain.getSubscriptionUrl())) domain.getSubscriptionUrl()))
# Add or replace objects
syncml_data = ''
# syncml body # syncml body
xml(' <SyncBody>\n') sync_body = SubElement(xml, 'SyncBody')
xml_status, cmd_id = self.SyncMLStatus( xml_status, cmd_id = self.SyncMLStatus(
remote_xml, remote_xml,
self.SUCCESS, self.SUCCESS,
cmd_id, cmd_id,
subscriber.getNextAnchor(), subscriber.getNextAnchor(),
subscription=subscriber).values() subscription=subscriber)
xml(xml_status) sync_body.extend(xml_status)
destination_url = '' destination_url = ''
# alert message if we want more data # alert message if we want more data
if destination_waiting_more_data: if destination_waiting_more_data:
xml(self.SyncMLAlert( sync_body.append(self.SyncMLAlert(
cmd_id, cmd_id,
self.WAITING_DATA, self.WAITING_DATA,
subscriber.getTargetURI(), subscriber.getTargetURI(),
...@@ -1302,20 +1261,21 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1302,20 +1261,21 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
cmd_id = cmd_id+1 cmd_id = cmd_id+1
if domain.getActivityEnabled(): if domain.getActivityEnabled():
#use activities to get SyncML data. #use activities to get SyncML data.
if not isinstance(remote_xml, (str, unicode)):
remote_xml = etree.tostring(remote_xml, encoding='utf-8', remote_xml = etree.tostring(remote_xml, encoding='utf-8',
xml_declaration=True, pretty_print=False) xml_declaration=True, pretty_print=False)
xml_tree = etree.tostring(xml, encoding='utf-8', xml_declaration=True,
pretty_print=False)
domain.activate(activity='SQLQueue', domain.activate(activity='SQLQueue',
tag=domain.getId(), tag=domain.getId(),
priority=self.PRIORITY).activateSyncModif( priority=self.PRIORITY).activateSyncModif(
domain_relative_url=domain.getRelativeUrl(), domain_relative_url=domain.getRelativeUrl(),
remote_xml=remote_xml, remote_xml=remote_xml,
xml_tree=xml_tree,
subscriber_relative_url=subscriber.getRelativeUrl(), subscriber_relative_url=subscriber.getRelativeUrl(),
cmd_id=cmd_id, cmd_id=cmd_id,
xml_confirmation=xml_confirmation, xml_confirmation_list=xml_confirmation_list,
syncml_data='', syncml_data_list=[],
cmd_id_before_getsyncmldata=cmd_id_before_getsyncmldata, cmd_id_before_getsyncmldata=cmd_id_before_getsyncmldata,
xml_list=xml_list,
has_status_list=has_status_list, has_status_list=has_status_list,
has_response=has_response ) has_response=has_response )
return {'has_response':1, 'xml':''} return {'has_response':1, 'xml':''}
...@@ -1324,15 +1284,15 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1324,15 +1284,15 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
remote_xml=remote_xml, remote_xml=remote_xml,
subscriber=subscriber, subscriber=subscriber,
cmd_id=cmd_id, cmd_id=cmd_id,
xml_confirmation=xml_confirmation, xml_confirmation_list=xml_confirmation_list,
conduit=conduit, conduit=conduit,
max=None) max=None)
syncml_data = result['syncml_data'] syncml_data_list = result['syncml_data_list']
xml_confirmation = result['xml_confirmation'] xml_confirmation_list = result['xml_confirmation_list']
cmd_id = result['cmd_id'] cmd_id = result['cmd_id']
return self.sendSyncModif(syncml_data, cmd_id_before_getsyncmldata, return self.sendSyncModif(syncml_data_list, cmd_id_before_getsyncmldata,
subscriber, domain, xml_confirmation, subscriber, domain, xml_confirmation_list,
remote_xml, xml_list, has_status_list, remote_xml, xml, has_status_list,
has_response) has_response)
def deleteRemainObjectList(self, domain, subscriber): def deleteRemainObjectList(self, domain, subscriber):
...@@ -1373,9 +1333,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1373,9 +1333,9 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
conduit = subscriber.getConduit() conduit = subscriber.getConduit()
result = self.getSyncMLData(domain=domain, subscriber=subscriber, result = self.getSyncMLData(domain=domain, subscriber=subscriber,
conduit=conduit, max=self.MAX_OBJECTS, **kw) conduit=conduit, max=self.MAX_OBJECTS, **kw)
syncml_data = result['syncml_data'] syncml_data_list = result['syncml_data_list']
cmd_id = result['cmd_id'] cmd_id = result['cmd_id']
kw['syncml_data'] = syncml_data kw['syncml_data_list'] = syncml_data_list
kw['cmd_id'] = cmd_id kw['cmd_id'] = cmd_id
finished = result['finished'] finished = result['finished']
if not finished: if not finished:
...@@ -1383,79 +1343,74 @@ class XMLSyncUtils(XMLSyncUtilsMixin): ...@@ -1383,79 +1343,74 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
tag=domain.getId(), tag=domain.getId(),
priority=self.PRIORITY).activateSyncModif(**kw) priority=self.PRIORITY).activateSyncModif(**kw)
else: else:
xml_confirmation = result['xml_confirmation']
cmd_id = result['cmd_id'] cmd_id = result['cmd_id']
cmd_id_before_getsyncmldata = kw['cmd_id_before_getsyncmldata'] cmd_id_before_getsyncmldata = kw['cmd_id_before_getsyncmldata']
remote_xml = etree.XML(kw['remote_xml'], parser=parser) remote_xml = etree.XML(kw['remote_xml'], parser=parser)
xml_list = kw['xml_list'] xml_tree = etree.XML(kw['xml_tree'], parser=parser)
xml_confirmation_list = kw['xml_confirmation_list']
has_status_list = kw['has_status_list'] has_status_list = kw['has_status_list']
has_response = kw['has_response'] has_response = kw['has_response']
return self.sendSyncModif( return self.sendSyncModif(
syncml_data, syncml_data_list,
cmd_id_before_getsyncmldata, cmd_id_before_getsyncmldata,
subscriber, subscriber,
domain, domain,
xml_confirmation, xml_confirmation_list,
remote_xml, remote_xml,
xml_list, xml_tree,
has_status_list, has_status_list,
has_response) has_response)
def sendSyncModif(self, syncml_data, cmd_id_before_getsyncmldata, subscriber, def sendSyncModif(self, syncml_data_list, cmd_id_before_getsyncmldata,
domain, xml_confirmation, remote_xml, xml_list, subscriber, domain, xml_confirmation_list, remote_xml,
has_status_list, has_response): xml_tree, has_status_list, has_response):
sync_body = xml_tree.find('SyncBody')
xml = xml_list.append if syncml_data_list:
if syncml_data != '': sync_node = SubElement(sync_body, 'Sync')
xml(' <Sync>\n') cmd_id_node = SubElement(sync_node, 'CmdID')
xml(' <CmdID>%s</CmdID>\n' % cmd_id_before_getsyncmldata) cmd_id_node.text = '%s' % cmd_id_before_getsyncmldata
if subscriber.getTargetURI() not in ('', None): target_uri = subscriber.getTargetURI()
xml(' <Target>\n') if target_uri:
xml(' <LocURI>%s</LocURI>\n' % subscriber.getTargetURI()) sync_node.append(E.Target(E.LocURI(target_uri)))
xml(' </Target>\n') source_uri = subscriber.getSourceURI()
if subscriber.getSourceURI() not in ('', None): if source_uri:
xml(' <Source>\n') sync_node.append(E.Source(E.LocURI(source_uri)))
xml(' <LocURI>%s</LocURI>\n' % subscriber.getSourceURI()) for syncml_data in syncml_data_list:
xml(' </Source>\n') sync_node.append(etree.XML(syncml_data, parser=parser))
xml(syncml_data) sync_body.extend(xml_confirmation_list)
xml(' </Sync>\n') sync_body.append(Element('Final'))
xml(xml_confirmation) xml_string = etree.tostring(xml_tree, encoding='utf-8', pretty_print=True)
xml(' <Final/>\n')
xml(' </SyncBody>\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_a) subscriber.setLastSentMessage(xml_string)
self.sendResponse( self.sendResponse(
from_url=domain.publication_url, from_url=domain.publication_url,
to_url=subscriber.subscription_url, to_url=subscriber.subscription_url,
sync_id=domain.getTitle(), sync_id=domain.getTitle(),
xml=xml_a, xml=xml_string,
domain=domain, domain=domain,
content_type=domain.getSyncContentType()) content_type=domain.getSyncContentType())
if not syncml_data: if not syncml_data_list:
LOG('this is the end of the synchronisation session !!!', INFO, domain.getId()) LOG('this is the end of the synchronisation session from PUB !!!', INFO, domain.getId())
subscriber.setAuthenticated(False) subscriber.setAuthenticated(False)
domain.setAuthenticated(False) domain.setAuthenticated(False)
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_list or syncml_data_list:
(xml_confirmation, syncml_data) != ('', ''): subscriber.setLastSentMessage(xml_string)
subscriber.setLastSentMessage(xml_a)
self.sendResponse( self.sendResponse(
from_url=domain.subscription_url, from_url=domain.subscription_url,
to_url=domain.publication_url, to_url=domain.publication_url,
sync_id=domain.getTitle(), sync_id=domain.getTitle(),
xml=xml_a, domain=domain, xml=xml_string, domain=domain,
content_type=domain.getSyncContentType()) content_type=domain.getSyncContentType())
has_response = 1 has_response = 1
else: else:
if domain.isOneWayFromServer(): if domain.isOneWayFromServer():
self.deleteRemainObjectList(domain, subscriber) self.deleteRemainObjectList(domain, subscriber)
LOG('this is the end of the synchronisation session !!!', INFO, domain.getId()) LOG('this is the end of the synchronisation session from SUB !!!', INFO, domain.getId())
domain.setAuthenticated(False) domain.setAuthenticated(False)
return {'has_response':has_response, 'xml':xml_a} return {'has_response':has_response, 'xml':xml_string}
def xml2wbxml(self, xml): def xml2wbxml(self, xml):
""" """
......
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