Commit 0e28e647 authored by Sebastien Robin's avatar Sebastien Robin

ERP5Syncml now support synchronization by :

- files
- email
- http


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@564 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 3f1855f5
......@@ -108,19 +108,9 @@ class PublicationSynchronization(XMLSyncUtils):
xml += ' </SyncBody>\n'
xml += '</SyncML>\n'
#file.write(xml)
#file.close()
else:
pass
if self.email is None:
file = open('/tmp/sync','w')
file.write(xml)
file.close()
else:
self.sendMail(publication.publication_url, subscriber.subscription_url,
publication.id, xml)
self.sendResponse(from_url=publication.getPublicationUrl(),
to_url=subscriber.getSubscriptionUrl(),sync_id=publication.id,xml=xml)
def PubSync(self, id, msg=None, RESPONSE=None, subscriber=None):
......@@ -128,19 +118,15 @@ class PublicationSynchronization(XMLSyncUtils):
This is the synchronization method for the server
"""
LOG('PubSync',0,'Starting... id: %s' % str(id))
LOG('PubSync',0,'Starting... msg: %s' % str(msg))
# Read the request from the client
xml_client = None
if self.email is None:
file = open('/tmp/sync_client','r')
xml_client = FromXmlStream(file)
file.seek(0)
LOG('PubSync',0,'Starting... msg: %s' % str(file.read()))
file.close()
elif msg is not None:
xml_client = FromXml(msg)
xml_client = msg
if xml_client is None:
xml_client = self.readResponse(from_url='file://tmp/sync_server')
LOG('PubSync',0,'Starting... msg: %s' % str(xml_client))
if xml_client is not None:
if type(xml_client) in (type('a'),type(u'a')):
xml_client = FromXml(xml_client)
first_node = xml_client.childNodes[1]
if first_node.nodeName != "SyncML":
......
......@@ -73,13 +73,8 @@ class SubscriptionSynchronization(XMLSyncUtils):
xml += '</SyncML>\n'
if self.email is None:
file = open('/tmp/sync_client','w')
file.write(xml)
file.close()
else:
self.sendMail(subscription.subscription_url, subscription.publication_url,
subscription.id, xml)
self.sendResponse(from_url=subscription.subscription_url, to_url=subscription.publication_url,
sync_id=subscription.id, xml=xml)
def SubSync(self, id, msg=None, RESPONSE=None):
"""
......@@ -89,26 +84,17 @@ class SubscriptionSynchronization(XMLSyncUtils):
LOG('SubSync',0,'starting... msg: %s' % str(msg))
has_response = 0 #check if subsync replies to this messages
subscription = self.getSubscription(id)
# first synchronization
if self.email is None:
file = open('/tmp/sync','r')
if file.readlines() == []:
self.SubSyncInit(self.getSubscription(id))
has_response = 1
else:
file.seek(0)
xml_client = FromXmlStream(file)
file.seek(0)
LOG('SubSync',0,'starting... msg: %s' % str(file.read()))
has_response = self.SubSyncModif(self.getSubscription(id),xml_client)
file.close()
else:
if msg==None:
msg = self.readResponse(sync_id=id,from_url=subscription.getSubscriptionUrl())
if msg==None:
self.SubSyncInit(self.getSubscription(id))
has_response = 1
else:
xml_client = FromXml(msg)
xml_client = msg
if type(xml_client) in (type('a'),type(u'a')):
xml_client = FromXml(xml_client)
has_response = self.SubSyncModif(self.getSubscription(id),xml_client)
......
......@@ -48,6 +48,7 @@ import urllib
import string
from zLOG import *
from Conduit.ERP5Conduit import ERP5Conduit
class SynchronizationError( Exception ):
......@@ -518,22 +519,95 @@ class SynchronizationTool( UniqueObject, SimpleItem,
else:
return context.getPhysicalPath()
def sendResponse(self,url=None, xml=None):
security.declarePublic('sendResponse')
def sendResponse(self, to_url=None, from_url=None, sync_id=None,xml=None):
"""
We will look at the url and we will see if we need to send mail, http
response, or just copy to a file.
"""
if type(url) is type('a'):
if url.find('http://')==0:
LOG('sendResponse, to_url: ',0,to_url)
LOG('sendResponse, from_url: ',0,from_url)
LOG('sendResponse, sync_id: ',0,sync_id)
LOG('sendResponse, xml: ',0,xml)
if type(to_url) is type('a'):
if to_url.find('http://')==0:
# we will send an http response
to_encode = (('file',xml))
encoded = urrlib.urlencode(to_encode)
urrlib.open(url, encoded).read()
elif url.find('file://')==0:
self.activate(activity='RAMQueue').sendHttpResponse(sync_id=sync_id,
to_url=to_url,
xml=xml)
return None
elif to_url.find('file://')==0:
filename = to_url[len('file:/'):]
stream = file(filename,'w')
LOG('sendResponse, filename: ',0,filename)
stream.write(xml)
stream.close()
# we have to use local files (unit testing for example
pass
elif url.find('mailto:')==0:
elif to_url.find('mailto:')==0:
# we will send an email
pass
to_address = to_url[len('mailto:'):]
from_address = from_url[len('mailto:'):]
self.sendMail(from_address,to_address,sync_id,xml)
security.declarePrivate('sendHttpResponse')
def sendHttpResponse(self, to_url=None, sync_id=None, xml=None):
to_encode = (('text',xml),('sync_id',sync_id))
LOG('sendResponse, before encoding, to encode: ',0,to_encode)
encoded = urllib.urlencode(to_encode)
LOG('sendResponse, before encoding, encoded: ',0,encoded)
to_url = to_url + '/portal_synchronizations/readResponse'
to_url
#result = urllib.urlopen(to_url, encoded).read()
result = urllib.urlopen(to_url, encoded).read()
LOG('sendResponse, stop: ',0,'stopped')
security.declarePublic('readResponse')
def readResponse(self, text=None, sync_id=None, to_url=None, from_url=None):
"""
We will look at the url and we will see if we need to send mail, http
response, or just copy to a file.
"""
LOG('readResponse, ',0,'starting')
LOG('readResponse, sync_id: ',0,sync_id)
if text is not None:
LOG('readResponse, message: ',0,text)
# Get the target and then find the corresponding publication or
# Subscription
xml = FromXml(text)
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':
url = subnode2.childNodes[0].data
LOG('readResponse, url: ',0,url)
for publication in self.getPublicationList():
if publication.getPublicationUrl()==url:
self.PubSync(sync_id,xml)
return None
for subscription in self.getSubscriptionList():
if subscription.getSubscriptionUrl()==url:
self.SubSync(sync_id,xml)
return None
# we use from only if we have a file
elif type(from_url) is type('a'):
if from_url.find('file://')==0:
try:
filename = from_url[len('file:/'):]
stream = file(filename,'r')
LOG('readResponse, filename: ',0,filename)
xml = stream.read()
#stream.seek(0)
#LOG('readResponse',0,'Starting... msg: %s' % str(stream.read()))
except IOError:
LOG('readResponse, cannot read file: ',0,filename)
xml = None
if xml is not None and len(xml)==0:
xml = None
return xml
InitializeClass( SynchronizationTool )
......@@ -32,10 +32,16 @@ from Products.ERP5SyncML.Subscription import Signature
from xml.dom.ext.reader.Sax2 import FromXml
from cStringIO import StringIO
from xml.dom.ext import PrettyPrint
try:
from Products.CMFActivity.ActiveObject import ActiveObject
except ImportError:
LOG('XMLSyncUtils',0,"Can't import ActiveObject")
class ActiveObject:
pass
import commands
from zLOG import LOG
class XMLSyncUtilsMixin(SyncCode):
class XMLSyncUtilsMixin(SyncCode, ActiveObject):
def SyncMLHeader(self, session_id, msg_id, target, source):
"""
......@@ -413,22 +419,6 @@ class XMLSyncUtilsMixin(SyncCode):
return subnode
return next_status
# def getActionObjectId(self, action):
# """
# XXX Deprecated
# Return the id of the object described by the action
# """
# for subnode in action.childNodes:
# if subnode.nodeType == subnode.ELEMENT_NODE and subnode.nodeName == 'Item':
# for subnode2 in subnode.childNodes:
# if subnode2.nodeType == subnode2.ELEMENT_NODE and subnode2.nodeName == 'Data':
# for subnode3 in subnode2.childNodes:
# if subnode3.nodeType == subnode3.ELEMENT_NODE and subnode3.nodeName == 'object':
# for subnode4 in subnode3.childNodes:
# if subnode4.nodeType == subnode4.ELEMENT_NODE and subnode4.nodeName == 'id':
# return str(subnode4.childNodes[0].data)
#return subnode4.childNodes[0].data
def getDataSubNode(self, action):
"""
Return the node starting with <object....> of the action
......@@ -971,34 +961,15 @@ class XMLSyncUtils(XMLSyncUtilsMixin):
xml += ' <Final/>\n'
xml += ' </SyncBody>\n'
xml += '</SyncML>\n'
if self.email is None:
# We do not want to use email
if domain.domain_type == self.PUB: # We always reply
#if (xml_confirmation,syncml_data)!=('','') or has_status_list:
if 1:
file = open('/tmp/sync','w')
file.write(xml)
file.close()
self.sendResponse(from_url=domain.publication_url, to_url=subscriber.subscription_url,
sync_id=domain.id, xml=xml)
has_response = 1
elif domain.domain_type == self.SUB :
if self.checkAlert(remote_xml) or \
(xml_confirmation,syncml_data)!=('','') or \
has_status_list:
file = open('/tmp/sync_client','w')
has_response = 1
file.write(xml)
file.close()
else:
# We use email
if domain.domain_type == self.PUB: # We always reply
#if (xml_confirmation,syncml_data)!=('','') or has_status_list:
if 1:
self.sendMail(domain.publication_url, subscriber.subscription_url,
domain.id, xml)
elif domain.domain_type == self.SUB:
if self.checkAlert(remote_xml) or \
(xml_confirmation,syncml_data)!=('','') or \
has_status_list:
self.sendMail(domain.subscription_url, domain.publication_url,
domain.id, xml)
self.sendResponse(from_url=domain.subscription_url, to_url=domain.publication_url,
sync_id=domain.id, xml=xml)
has_response = 1
return has_response
......@@ -31,7 +31,7 @@ Setting up Synchronization
the publication should looks like this ::
id : Repository
Publication Url : cps_server@localhost
Publication Url : mailto:cps_server@localhost
Destination Path : /cps/portal_repository
Query : objectValues (it will be completed automatically)
XML Mapping : asXML
......@@ -39,8 +39,8 @@ Setting up Synchronization
Inside the synchronization tool, the subscription should looks like this ::
id : Repository
Publication Url : cps_server@localhost
Subscription Url : cps_client@localhost
Publication Url : mailto:cps_server@localhost
Subscription Url : mailto:cps_client@localhost
Destination Path : /cps_client/portal_repository
Query : objectValues (it will be completed automatically)
XML Mapping : asXML
......
......@@ -81,8 +81,12 @@ class TestERP5SyncML(ERP5TypeTestCase):
nb_publication = 1
nb_synchronization = 3
nb_message_first_synchronization = 6
subscription_url1 = 'client1@localhost'
subscription_url2 = 'client2@localhost'
subscription_url1 = 'file://tmp/sync_client1'
subscription_url2 = 'file://tmp/sync_client2'
publication_url = 'file://tmp/sync_server'
#publication_url = 'server@localhost'
#subscription_url1 = 'client1@localhost'
#subscription_url2 = 'client2@localhost'
def getBusinessTemplateList(self):
"""
......@@ -128,7 +132,7 @@ class TestERP5SyncML(ERP5TypeTestCase):
LOG('Testing... ',0,'testAddPublication')
portal_id = self.getPortalName()
portal_sync = self.getSynchronizationTool()
portal_sync.manage_addPublication(self.pub_id,'server@localhost',
portal_sync.manage_addPublication(self.pub_id,self.publication_url,
'/%s/person_server' % portal_id,'',
self.xml_mapping)
pub = portal_sync.getPublication(self.pub_id)
......@@ -141,7 +145,7 @@ class TestERP5SyncML(ERP5TypeTestCase):
LOG('Testing... ',0,'testAddSubscription1')
portal_id = self.getPortalId()
portal_sync = self.getSynchronizationTool()
portal_sync.manage_addSubscription(self.sub_id1,'server@localhost',
portal_sync.manage_addSubscription(self.sub_id1,self.publication_url,
self.subscription_url1,'/%s/person_client1' % portal_id,'',
self.xml_mapping)
sub = portal_sync.getSubscription(self.sub_id1)
......@@ -154,7 +158,7 @@ class TestERP5SyncML(ERP5TypeTestCase):
LOG('Testing... ',0,'testAddSubscription2')
portal_id = self.getPortalId()
portal_sync = self.getSynchronizationTool()
portal_sync.manage_addSubscription(self.sub_id2,'server@localhost',
portal_sync.manage_addSubscription(self.sub_id2,self.publication_url,
self.subscription_url2,'/%s/person_client2' % portal_id,'',
self.xml_mapping)
sub = portal_sync.getSubscription(self.sub_id2)
......@@ -282,7 +286,7 @@ class TestERP5SyncML(ERP5TypeTestCase):
to define it here because it is specific to the unit testing
"""
portal_sync = self.getSynchronizationTool()
portal_sync.email = None
#portal_sync.email = None # XXX To be removed
subscription = portal_sync.getSubscription(id)
publication = None
for publication in portal_sync.getPublicationList():
......@@ -290,7 +294,10 @@ class TestERP5SyncML(ERP5TypeTestCase):
publication = publication
self.failUnless(publication is not None)
# reset files, because we do sync by files
file = open('/tmp/sync_client','w')
file = open('/tmp/sync_client1','w')
file.write('')
file.close()
file = open('/tmp/sync_client2','w')
file.write('')
file.close()
file = open('/tmp/sync','w')
......
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