Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
140
Merge Requests
140
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
erp5
Commits
20afa613
Commit
20afa613
authored
Jan 30, 2024
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
syncml: support python3
parent
41156e9a
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
190 additions
and
155 deletions
+190
-155
bt5/erp5_syncml/DocumentTemplateItem/portal_components/document.erp5.SyncMLSignature.py
...teItem/portal_components/document.erp5.SyncMLSignature.py
+10
-8
bt5/erp5_syncml/DocumentTemplateItem/portal_components/document.erp5.SyncMLSubscription.py
...tem/portal_components/document.erp5.SyncMLSubscription.py
+21
-18
bt5/erp5_syncml/MixinTemplateItem/portal_components/mixin.erp5.SyncMLEngineMixin.py
...ateItem/portal_components/mixin.erp5.SyncMLEngineMixin.py
+8
-4
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5Conduit.py
...TemplateItem/portal_components/module.erp5.ERP5Conduit.py
+31
-22
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5DocumentConduit.py
...Item/portal_components/module.erp5.ERP5DocumentConduit.py
+1
-1
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5ShopOrderConduit.py
...tem/portal_components/module.erp5.ERP5ShopOrderConduit.py
+1
-1
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLEngineAsynchronous.py
...portal_components/module.erp5.SyncMLEngineAsynchronous.py
+6
-5
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLEngineSynchronous.py
.../portal_components/module.erp5.SyncMLEngineSynchronous.py
+6
-5
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLMessage.py
...mplateItem/portal_components/module.erp5.SyncMLMessage.py
+13
-9
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLTransportFile.py
...Item/portal_components/module.erp5.SyncMLTransportFile.py
+2
-3
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLUtils.py
...TemplateItem/portal_components/module.erp5.SyncMLUtils.py
+14
-18
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.VCardConduit.py
...emplateItem/portal_components/module.erp5.VCardConduit.py
+11
-4
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.XMLSyncUtils.py
...emplateItem/portal_components/module.erp5.XMLSyncUtils.py
+8
-5
bt5/erp5_syncml/SkinTemplateItem/portal_skins/erp5_syncml/Person_exportAsVCard.py
...lateItem/portal_skins/erp5_syncml/Person_exportAsVCard.py
+0
-7
bt5/erp5_syncml/SkinTemplateItem/portal_skins/erp5_syncml/SQLCatalog_indexSyncMLDocumentList.py
...l_skins/erp5_syncml/SQLCatalog_indexSyncMLDocumentList.py
+2
-1
bt5/erp5_syncml/SkinTemplateItem/portal_skins/erp5_syncml/SynchronizationTool_activateCheckPointFixe.py
...erp5_syncml/SynchronizationTool_activateCheckPointFixe.py
+2
-1
bt5/erp5_syncml/TestTemplateItem/portal_components/test.erp5.testERP5DocumentSyncML.py
...tem/portal_components/test.erp5.testERP5DocumentSyncML.py
+3
-3
bt5/erp5_syncml/TestTemplateItem/portal_components/test.erp5.testERP5SyncML.py
...emplateItem/portal_components/test.erp5.testERP5SyncML.py
+22
-25
bt5/erp5_syncml/ToolComponentTemplateItem/portal_components/tool.erp5.SynchronizationTool.py
...teItem/portal_components/tool.erp5.SynchronizationTool.py
+11
-8
bt5/erp5_syncml_test_data/TestTemplateItem/portal_components/test.erp5.testSyncMLAsynchronousEngine.py
...rtal_components/test.erp5.testSyncMLAsynchronousEngine.py
+2
-1
product/ERP5Type/XMLExportImport/__init__.py
product/ERP5Type/XMLExportImport/__init__.py
+16
-6
No files found.
bt5/erp5_syncml/DocumentTemplateItem/portal_components/document.erp5.SyncMLSignature.py
View file @
20afa613
...
...
@@ -28,6 +28,7 @@
##############################################################################
from
hashlib
import
md5
import
six
from
AccessControl
import
ClassSecurityInfo
...
...
@@ -98,7 +99,8 @@ class SyncMLSignature(XMLObject):
Set the XML corresponding to the object
"""
if
value
:
# convert the string to Pdata
assert
isinstance
(
value
,
bytes
)
# convert the bytes to Pdata
pdata_wrapper
=
PdataHelper
(
self
.
getPortalObject
(),
value
)
self
.
_setData
(
pdata_wrapper
)
self
.
setTemporaryData
(
None
)
# We make sure that the data will not be erased
...
...
@@ -113,7 +115,7 @@ class SyncMLSignature(XMLObject):
Get the XML corresponding to the object
"""
if
self
.
hasData
():
return
str
(
self
.
_baseGetData
())
return
bytes
(
self
.
_baseGetData
())
elif
default
is
_MARKER
:
return
self
.
_baseGetData
()
else
:
...
...
@@ -139,7 +141,7 @@ class SyncMLSignature(XMLObject):
Return the temp xml as string
"""
if
self
.
hasTemporaryData
():
return
str
(
self
.
_baseGetTemporaryData
())
return
bytes
(
self
.
_baseGetTemporaryData
())
elif
default
is
_MARKER
:
return
self
.
_baseGetTemporaryData
()
else
:
...
...
@@ -153,7 +155,7 @@ class SyncMLSignature(XMLObject):
changed or not
Returns 1 if MD5 are equals, else it returns 0
"""
if
isinstance
(
xml_string
,
unicod
e
):
if
six
.
PY2
and
isinstance
(
xml_string
,
six
.
text_typ
e
):
xml_string
=
xml_string
.
encode
(
'utf-8'
)
return
md5
(
xml_string
).
hexdigest
()
==
self
.
getContentMd5
()
...
...
@@ -189,7 +191,7 @@ class SyncMLSignature(XMLObject):
Return the patial xml as string
"""
if
self
.
hasPartialData
():
return
str
(
self
.
_baseGetPartialData
())
return
bytes
(
self
.
_baseGetPartialData
())
elif
default
is
_MARKER
:
return
self
.
_baseGetPartialData
()
else
:
...
...
@@ -223,7 +225,7 @@ class SyncMLSignature(XMLObject):
rest_in_queue
=
partial_data
[
max_len
:]
if
rest_in_queue
is
not
None
:
self
.
setPartialData
(
rest_in_queue
)
return
str
(
chunk
)
return
bytes
(
chunk
)
security
.
declareProtected
(
Permissions
.
ModifyPortalContent
,
'setSubscriberXupdate'
)
...
...
@@ -244,7 +246,7 @@ class SyncMLSignature(XMLObject):
Return the patial xml as string
"""
if
self
.
hasSubscriberXupdate
():
return
str
(
self
.
_baseGetSubscriberXupdate
())
return
bytes
(
self
.
_baseGetSubscriberXupdate
())
elif
default
is
_MARKER
:
return
self
.
_baseGetSubscriberXupdate
()
else
:
...
...
@@ -269,7 +271,7 @@ class SyncMLSignature(XMLObject):
Return the partial xml as string
"""
if
self
.
hasPublisherXupdate
():
return
str
(
self
.
_baseGetPublisherXupdate
())
return
bytes
(
self
.
_baseGetPublisherXupdate
())
elif
default
is
_MARKER
:
return
self
.
_baseGetPublisherXupdate
()
else
:
...
...
bt5/erp5_syncml/DocumentTemplateItem/portal_components/document.erp5.SyncMLSubscription.py
View file @
20afa613
...
...
@@ -29,9 +29,10 @@
from
base64
import
b16encode
,
b16decode
from
logging
import
getLogger
from
url
parse
import
urlparse
from
six.moves.urllib.
parse
import
urlparse
from
lxml
import
etree
from
copy
import
deepcopy
import
six
from
AccessControl
import
ClassSecurityInfo
from
AccessControl.SecurityManagement
import
newSecurityManager
...
...
@@ -53,6 +54,7 @@ from erp5.component.module.SyncMLTransportERP5 import ERP5Transport
from
erp5.component.module.SyncMLConstant
import
MAX_LEN
,
ADD_ACTION
,
\
REPLACE_ACTION
from
erp5.component.module.XMLSyncUtils
import
cutXML
from
six.moves
import
range
transport_scheme_dict
=
{
"http"
:
HTTPTransport
(),
...
...
@@ -160,7 +162,7 @@ class SyncMLSubscription(XMLObject):
activate
=
self
.
activate
callback_method
=
getattr
(
activate
(
**
activate_kw
),
callback
)
if
generated_other_activity
:
for
i
in
x
range
(
0
,
result_count
,
packet_size
):
for
i
in
range
(
0
,
result_count
,
packet_size
):
syncml_logger
.
info
(
"-- getAndIndex : recursive call, generating for %s"
,
r
[
i
:
i
+
packet_size
])
callback_method
(
path_list
=
r
[
i
:
i
+
packet_size
],
...
...
@@ -168,7 +170,7 @@ class SyncMLSubscription(XMLObject):
**
method_kw
)
else
:
if
result_count
>
packet_size
and
limit
:
for
i
in
x
range
(
0
,
result_count
-
packet_size
,
packet_size
):
for
i
in
range
(
0
,
result_count
-
packet_size
,
packet_size
):
syncml_logger
.
info
(
"-- getAndIndex : i %s, call, generating for %s : %s"
,
i
,
r
[
i
:
i
+
packet_size
],
activate_kw
)
callback_method
(
path_list
=
r
[
i
:
i
+
packet_size
],
...
...
@@ -205,7 +207,7 @@ class SyncMLSubscription(XMLObject):
Return the path of the subscription that will be used in sql table
_ char must be escaped because of the LIKE behaviour
"""
return
"%s/%%"
%
(
self
.
getSourceValue
().
getPath
().
replace
(
"_"
,
"
\
_
"
),) # pylint: disable=anomalous-backslash-in-string
return
"%s/%%"
%
(
self
.
getSourceValue
().
getPath
().
replace
(
"_"
,
r"\
_
"),)
security.declarePrivate('sendSyncCommand')
def sendSyncCommand(self, min_gid, max_gid, message_id, activate_kw):
...
...
@@ -225,7 +227,7 @@ class SyncMLSubscription(XMLObject):
# transport failure
# activate_kw["
group_method_id
"] = None
# activate_kw["
group_method_cost
"] = .05
self.activate(**activate_kw).sendMessage(xml=
str
(syncml_response))
self.activate(**activate_kw).sendMessage(xml=
bytes
(syncml_response))
security.declarePrivate('applySyncCommand')
def applySyncCommand(self, response_message_id, activate_kw, **kw):
...
...
@@ -250,7 +252,7 @@ class SyncMLSubscription(XMLObject):
self.activate(activity="
SQLQueue
",
# group_method_id=None,
# group_method_cost=.05,
tag=activate_kw).sendMessage(xml=
str
(syncml_response))
tag=activate_kw).sendMessage(xml=
bytes
(syncml_response))
security.declarePrivate('getAndActivate')
...
...
@@ -310,7 +312,7 @@ class SyncMLSubscription(XMLObject):
if generated_other_activity:
# XXX Can be factorized with following code
# upper_limit of xrange + some check ???
for i in
x
range(0, result_count, packet_size):
for i in range(0, result_count, packet_size):
if first_call:
min_gid = None
first_call = False
...
...
@@ -330,7 +332,7 @@ class SyncMLSubscription(XMLObject):
else:
i = 0
if result_count > packet_size:
for i in
x
range(0, result_count-packet_size, packet_size):
for i in range(0, result_count-packet_size, packet_size):
if first_call:
min_gid = None
first_call = False
...
...
@@ -531,7 +533,7 @@ class SyncMLSubscription(XMLObject):
domain=self))
xml_document = incoming_data
if not isinstance(xml_document, b
asestring
):
if not isinstance(xml_document, b
ytes
):
# XXX using deepcopy to remove parent link - must be done elsewhere
xml_document = deepcopy(xml_document)
# Remove useless namespace
...
...
@@ -539,7 +541,7 @@ class SyncMLSubscription(XMLObject):
xml_document = etree.tostring(xml_document, encoding='utf-8',
pretty_print=True)
if isinstance(xml_document, unicode):
if
six.PY2 and
isinstance(xml_document, unicode):
xml_document = xml_document.encode('utf-8')
# Link the signature to the document
if signature:
...
...
@@ -603,12 +605,12 @@ class SyncMLSubscription(XMLObject):
signature.changeToConflict()
# Register the data received which generated the diff
# XXX Why ?
if not isinstance(incoming_data, b
asestring
):
if not isinstance(incoming_data, b
ytes
):
incoming_data = etree.tostring(incoming_data,
encoding='utf-8')
signature.setPartialData(incoming_data)
else:
signature.setData(
str
(xml_document))
signature.setData(
bytes
(xml_document))
signature.synchronize()
syncml_logger.info("
change
state
of
signature
to
%
s
with
%
s
",
signature.getValidationState(), signature.getData())
...
...
@@ -667,7 +669,7 @@ class SyncMLSubscription(XMLObject):
}
syncml_logger.info("
Sending
final
message
for
modificationson
on
%
s
",
self.getRelativeUrl())
self.activate(**final_activate_kw).sendMessage(xml=
str
(syncml_response))
self.activate(**final_activate_kw).sendMessage(xml=
bytes
(syncml_response))
security.declarePrivate('getDeletedSyncMLData')
...
...
@@ -700,11 +702,10 @@ class SyncMLSubscription(XMLObject):
}
syncml_logger.info("
Sending
final
message
for
modificationson
on
%
s
",
self.getRelativeUrl())
self.activate(**final_activate_kw).sendMessage(xml=
str
(syncml_response))
self.activate(**final_activate_kw).sendMessage(xml=
bytes
(syncml_response))
def getSearchablePath(self):
return "
%
s
%%
" %(self.getPath().replace('_', '
\
_
'
),) # pylint: disable=anomalous-backslash-in-string
return "
%
s
%%
" %(self.getPath().replace('_', r'
\
_
'
),)
def _generateSyncCommand(self, action, signature, data_diff ,document_data, gid,
conduit, syncml_response):
...
...
@@ -973,10 +974,12 @@ class SyncMLSubscription(XMLObject):
# old way using the conduit
conduit = self.getConduit()
raw_gid = conduit.getGidFromObject(object)
if isinstance(raw_gid,
unicod
e):
if isinstance(raw_gid,
six.text_typ
e):
raw_gid = raw_gid.encode('ascii', 'ignore')
if encoded:
gid = b16encode(raw_gid)
if six.PY3:
gid = gid.decode()
else:
gid = raw_gid
return gid
...
...
@@ -1146,7 +1149,7 @@ class SyncMLSubscription(XMLObject):
"""
object_id_list = list(self.getObjectIds())
object_list_len = len(object_id_list)
for i in
x
range(0, object_list_len, MAX_OBJECTS):
for i in range(0, object_list_len, MAX_OBJECTS):
current_id_list = object_id_list[i:i+MAX_OBJECTS]
self.activate(activity='SQLQueue',
priority=ACTIVITY_PRIORITY).manage_delObjects(current_id_list)
...
...
bt5/erp5_syncml/MixinTemplateItem/portal_components/mixin.erp5.SyncMLEngineMixin.py
View file @
20afa613
...
...
@@ -25,6 +25,7 @@
#
##############################################################################
import
six
from
logging
import
getLogger
from
AccessControl
import
ClassSecurityInfo
,
getSecurityManager
...
...
@@ -337,8 +338,11 @@ class SyncMLEngineMixin(object):
if
syncml_request
.
credentials
[
'type'
]
==
publication
.
getAuthenticationType
():
decoded
=
decode
(
syncml_request
.
credentials
[
'format'
],
syncml_request
.
credentials
[
'data'
])
if
decoded
and
':'
in
decoded
:
login
,
password
=
decoded
.
split
(
':'
)
if
decoded
and
b':'
in
decoded
:
login
,
password
=
decoded
.
split
(
b':'
)
if
six
.
PY3
:
login
=
login
.
decode
()
password
=
password
.
decode
()
# TODO: make it work for users existing anywhere
user_folder
=
publication
.
getPortalObject
().
acl_users
for
_
,
plugin
in
user_folder
.
_getOb
(
'plugins'
)
\
...
...
@@ -463,8 +467,8 @@ class SyncMLEngineMixin(object):
# Wait for all reset to be done
# before starting sync
priority
=
ACTIVITY_PRIORITY
,
tag
=
publication
.
getRelativeUrl
()).
sendMessage
(
xml
=
str
(
syncml_response
))
tag
=
publication
.
getRelativeUrl
()).
sendMessage
(
xml
=
bytes
(
syncml_response
))
else
:
subscriber
.
sendMessage
(
xml
=
str
(
syncml_response
))
subscriber
.
sendMessage
(
xml
=
bytes
(
syncml_response
))
return
syncml_response
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5Conduit.py
View file @
20afa613
...
...
@@ -42,12 +42,14 @@ from xml.sax.saxutils import unescape
import
re
from
lxml
import
etree
from
lxml.etree
import
Element
import
six
parser
=
etree
.
XMLParser
(
remove_blank_text
=
True
)
from
xml_marshaller.xml_marshaller
import
Unmarshaller
from
xupdate_processor
import
xuproc
from
base64
import
standard_b64decode
from
zope.interface
import
implementer
from
copy
import
deepcopy
from
six
import
string_types
as
basestring
import
logging
syncml_logger
=
logging
.
getLogger
(
'ERP5SyncML'
)
...
...
@@ -229,10 +231,10 @@ class ERP5Conduit(XMLSyncUtilsMixin):
# /erp5/object[@gid='
313730
']/../workflow_action[@id=SHA(TIME + ACTOR)]
wf_action_id = EXTRACT_ID_FROM_XPATH.findall(xpath_expression)[-1][-1]
def deleteWorkflowNode():
for wf_id, wf_history_tuple in
object.workflow_history.iteritems(
):
for wf_id, wf_history_tuple in
six.iteritems(object.workflow_history
):
for wf_history_index, wf_history in enumerate(wf_history_tuple):
if sha1(wf_id + str(wf_history['
time
']) +
wf_history['
actor
']).hexdigest() == wf_action_id:
if sha1(
(
wf_id + str(wf_history['
time
']) +
wf_history['
actor
']).
encode('
utf
-
8
')).
hexdigest() == wf_action_id:
object.workflow_history[wf_id] = (
object.workflow_history[wf_id][:wf_history_index] +
object.workflow_history[wf_id][wf_history_index + 1:])
...
...
@@ -426,21 +428,21 @@ class ERP5Conduit(XMLSyncUtilsMixin):
def getFormatedArgs(self, args=None):
"""
This lookd inside the args dictionnary and then
convert any unicode string to string
convert any unicode string to string
( on python 2 )
"""
new_args = {}
for keyword in args.keys():
data = args[keyword]
if
isinstance(keyword, unicod
e):
if
six.PY2 and isinstance(keyword, six.text_typ
e):
keyword = keyword.encode(self.getEncoding())
if isinstance(data, (tuple, list)):
new_data = []
for item in data:
if
isinstance(item, unicod
e):
if
six.PY2 and isinstance(item, six.text_typ
e):
item = item.encode(self.getEncoding())
new_data.append(item)
data = new_data
if
isinstance(data, unicod
e):
if
six.PY2 and isinstance(data, six.text_typ
e):
data = data.encode(self.getEncoding())
new_args[keyword] = data
return new_args
...
...
@@ -561,7 +563,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
XXX
name
of
method
is
not
good
,
because
content
is
not
necessarily
XML
return
a
xml
with
id
replaced
by
a
new
id
"""
if isinstance(xml,
str
):
if isinstance(xml,
bytes
):
xml = etree.XML(xml, parser=parser)
else:
# copy of xml object for modification
...
...
@@ -623,9 +625,10 @@ class ERP5Conduit(XMLSyncUtilsMixin):
"""
if
xml
is
a
string
,
convert
it
to
a
node
"""
if xml is None: return None
if isinstance(xml, (str, unicode)):
if isinstance(xml, unicode):
if xml is None:
return None
if isinstance(xml, six.string_types + (bytes, )):
if six.PY2 and isinstance(xml, six.text_type):
xml = xml.encode('utf-8')
xml = etree.XML(xml, parser=parser)
# If we have the xml from the node erp5, we just take the subnode
...
...
@@ -778,7 +781,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if data_type == NONE_TYPE:
return None
data = node.text
if data is not None and
isinstance(data, unicod
e):
if data is not None and
six.PY2 and isinstance(data, six.text_typ
e):
data = data.encode('utf-8')
elif data is None and data_type in TEXT_TYPE_LIST:
return ''
...
...
@@ -797,7 +800,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
elif data_type in DATA_TYPE_LIST:
if data is None:
# data is splitted inside block_data nodes
data = ''.join([standard_b64decode(block.text) for
\
data =
b
''.join([standard_b64decode(block.text) for
\
block in node.iterchildren()])
elif data_type == DATE_TYPE:
data = DateTime(data)
...
...
@@ -812,7 +815,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
Parse
the
xupdate
and
then
it
will
call
the
conduit
"""
conflict_list = []
if isinstance(xupdate,
(str, unicode
)):
if isinstance(xupdate,
six.string_types + (bytes,
)):
xupdate = etree.XML(xupdate, parser=parser)
#LOG("applyXupdate", INFO, etree.tostring(xupdate, pretty_print=True))
xupdate_builded = False
...
...
@@ -830,14 +833,16 @@ class ERP5Conduit(XMLSyncUtilsMixin):
xupdate_builded = True
# Find the prefix used by marshaller.
for prefix, namespace_uri in s
ubnode.nsmap.iteritems(
):
for prefix, namespace_uri in s
ix.iteritems(subnode.nsmap
):
if namespace_uri == MARSHALLER_NAMESPACE_URI:
break
# TODO add support of etree objects for xuproc to avoid
# serializing tree into string
if not isinstance(previous_xml, str):
previous_xml = etree.tostring(previous_xml)
xupdated_tree = xuproc.applyXUpdate(xml_xu_string=etree.tostring(xupdate),
if isinstance(previous_xml, bytes):
previous_xml = previous_xml.decode('utf-8')
if not isinstance(previous_xml, six.text_type):
previous_xml = etree.tostring(previous_xml, encoding='unicode')
xupdated_tree = xuproc.applyXUpdate(xml_xu_string=etree.tostring(xupdate, encoding='unicode'),
xml_doc_string=previous_xml)
if MARSHALLER_NAMESPACE_URI in subnode.nsmap.values():
xpath_expression = original_xpath_expression
...
...
@@ -888,7 +893,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
previous_xml=previous_xml, **kw)
# Now apply collected xupdated_node
for update_dict in
xpath_expression_update_dict.itervalues(
):
for update_dict in
six.itervalues(xpath_expression_update_dict
):
update_dict.update(kw)
conflict_list += self.updateNode(previous_xml=previous_xml,
**update_dict)
...
...
@@ -913,7 +918,7 @@ class ERP5Conduit(XMLSyncUtilsMixin):
if time <= action.get('time'):
# action in the past are not appended
addable = WORKFLOW_ACTION_INSERTABLE
key_list =
action.keys(
)
key_list =
list(action.keys()
)
key_list.remove("time")
for key in key_list:
if status[key] != action[key]:
...
...
@@ -1100,8 +1105,12 @@ class ERP5Conduit(XMLSyncUtilsMixin):
"""
# XXX xuproc does not support passing
# etree objetcs
if not isinstance(diff, basestring):
diff = etree.tostring(diff)
if isinstance(diff, bytes):
diff = diff.decode('utf-8')
elif not isinstance(diff, basestring):
diff = etree.tostring(diff, encoding='unicode')
if not isinstance(original_data, six.text_type):
original_data = six.text_type(original_data, 'utf-8')
return etree.tostring(xuproc.applyXUpdate(xml_xu_string=diff,
xml_doc_string=original_data),
encoding='utf-8')
...
...
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5DocumentConduit.py
View file @
20afa613
...
...
@@ -75,7 +75,7 @@ class ERP5DocumentConduit(ERP5Conduit):
# if time <= action.get('time'):
# # action in the past are not appended
# addable = WORKFLOW_ACTION_INSERTABLE
key_list
=
action
.
keys
(
)
key_list
=
list
(
action
.
keys
()
)
# key_list.remove("time")
# XXX-AUREL For document it seems that checking time != is required
# I don't know why ?
...
...
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.ERP5ShopOrderConduit.py
View file @
20afa613
...
...
@@ -29,7 +29,7 @@
from
xml.dom.ext
import
PrettyPrint
import
random
from
cStringIO
import
StringIO
from
six.moves
import
cStringIO
as
StringIO
from
AccessControl
import
ClassSecurityInfo
from
zLOG
import
LOG
...
...
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLEngineAsynchronous.py
View file @
20afa613
...
...
@@ -30,6 +30,7 @@ from logging import getLogger
from
erp5.component.mixin.SyncMLEngineMixin
import
SyncMLEngineMixin
from
erp5.component.module.SyncMLConstant
import
ACTIVITY_PRIORITY
from
Products.ERP5.ERP5Site
import
getSite
from
six.moves
import
range
syncml_logger
=
getLogger
(
'ERP5SyncML'
)
...
...
@@ -113,7 +114,7 @@ class SyncMLAsynchronousEngine(SyncMLEngineMixin):
(
subscription
.
getPath
(),
'applySyncCommand'
),
after_tag
=
tag
,).
sendMessage
(
xml
=
str
(
syncml_response
))
xml
=
bytes
(
syncml_response
))
# Synchronization process is now finished
syncml_logger
.
info
(
"
\
t
Client finished processing messages from server"
)
subscription
.
finish
()
...
...
@@ -137,7 +138,7 @@ class SyncMLAsynchronousEngine(SyncMLEngineMixin):
# transport failure
syncml_logger
.
info
(
"....client sending message...."
)
subscription
.
activate
(
activity
=
"SQLQueue"
).
sendMessage
(
xml
=
str
(
syncml_response
))
xml
=
bytes
(
syncml_response
))
def
processServerSynchronization
(
self
,
subscriber
,
syncml_request
):
...
...
@@ -241,7 +242,7 @@ class SyncMLAsynchronousEngine(SyncMLEngineMixin):
subscriber
.
activate
(
activity
=
"SQLQueue"
,
after_method_id
=
after_method_id
,
after_tag
=
tag
).
sendMessage
(
xml
=
str
(
syncml_response
))
xml
=
bytes
(
syncml_response
))
def
runGetAndActivate
(
self
,
subscription
,
tag
,
after_method_id
=
None
):
"""
...
...
@@ -282,7 +283,7 @@ class SyncMLAsynchronousEngine(SyncMLEngineMixin):
response_id_list
.
reverse
()
else
:
response_id_list
=
[
None
for
_
in
x
range
(
len
(
syncml_request
.
sync_command_list
))]
range
(
len
(
syncml_request
.
sync_command_list
))]
split
=
getSite
().
portal_preferences
.
getPreferredSyncActionPerActivityCount
()
if
not
split
:
# We do not use activities
if
send_response
:
...
...
@@ -294,7 +295,7 @@ class SyncMLAsynchronousEngine(SyncMLEngineMixin):
subscription
.
activate
(
activity
=
"SQLQueue"
,
priority
=
ACTIVITY_PRIORITY
,
tag
=
subscription
.
getRelativeUrl
()).
sendMessage
(
xml
=
str
(
syncml_response
))
tag
=
subscription
.
getRelativeUrl
()).
sendMessage
(
xml
=
bytes
(
syncml_response
))
else
:
# XXX For now always split by one
activate
=
subscription
.
activate
...
...
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLEngineSynchronous.py
View file @
20afa613
...
...
@@ -123,8 +123,9 @@ class SyncMLSynchronousEngine(SyncMLEngineMixin):
subscription
.
_edit
(
authenticated_user
=
None
)
# Send the message
subscription
.
sendMessage
(
xml
=
str
(
syncml_response
))
return
str
(
syncml_response
)
subscription
.
sendMessage
(
xml
=
bytes
(
syncml_response
))
return
bytes
(
syncml_response
)
def
processServerSynchronization
(
self
,
subscriber
,
syncml_request
):
...
...
@@ -222,10 +223,10 @@ class SyncMLSynchronousEngine(SyncMLEngineMixin):
subscriber
.
logout
()
subscriber
.
_edit
(
authenticated_user
=
None
,
remaining_object_path_list
=
None
)
syncml_response
=
""
# XXX This is expected by unit test only
syncml_response
=
b
""
# XXX This is expected by unit test only
# Body must be sent even when there is no data to notify client
subscriber
.
sendMessage
(
xml
=
str
(
syncml_response
))
subscriber
.
sendMessage
(
xml
=
bytes
(
syncml_response
))
# Return message for unit test purpose
return
str
(
syncml_response
)
return
bytes
(
syncml_response
)
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLMessage.py
View file @
20afa613
...
...
@@ -28,6 +28,7 @@
from
lxml.builder
import
ElementMaker
from
lxml.etree
import
Element
from
lxml
import
etree
import
six
from
erp5.component.module.XMLSyncUtils
import
resolveSyncmlStatusCode
,
\
encode
,
resolveSyncmlAlertCode
...
...
@@ -60,13 +61,13 @@ class SyncMLResponse(object):
def
__len__
(
self
):
# To check if it has to be done on whole message or only the body
return
len
(
etree
.
tostring
(
self
.
body
,
encoding
=
'utf-8'
,
xml_declaration
=
True
,
pretty_print
=
True
))
return
len
(
bytes
(
self
))
def
__
str
__
(
self
):
def
__
bytes
__
(
self
):
return
etree
.
tostring
(
self
.
data
,
encoding
=
'utf-8'
,
xml_declaration
=
True
,
pretty_print
=
True
)
if
six
.
PY2
:
__str__
=
__bytes__
def
_getNextCommandId
(
self
):
"""
...
...
@@ -117,7 +118,7 @@ class SyncMLResponse(object):
if
authentication_type
==
'syncml:auth-basic'
:
# base64 formating of "userid:password"
credential
=
"%s:%s"
%
(
user_id
,
password
)
credential
=
encode
(
authentication_format
,
credential
)
credential
=
encode
(
authentication_format
,
credential
)
.
decode
()
elif
authentication_type
==
"syncml:auth-md5"
:
# base64 coded md5 for user "XXX", password "XXX", nonce "XXX"
raise
NotImplementedError
(
"MD5 authentication not supported"
)
...
...
@@ -345,7 +346,7 @@ class SyncMLResponse(object):
data_node
=
E
.
Data
()
# XXX to be remove later to use only CDATA
if
media_type
==
'text/xml'
:
if
isinstance
(
data
,
b
asestring
):
if
isinstance
(
data
,
b
ytes
):
data_node
.
append
(
etree
.
XML
(
data
,
parser
=
parser
))
elif
isinstance
(
data
,
etree
.
CDATA
):
# data could be Data element if partial XML
...
...
@@ -421,7 +422,7 @@ class SyncMLRequest(object):
""" SyncMLRequest represent a message received by the client or server"""
def
__init__
(
self
,
xml
):
if
isinstance
(
xml
,
b
asestring
):
if
isinstance
(
xml
,
b
ytes
):
self
.
data
=
etree
.
XML
(
xml
,
parser
=
parser
)
else
:
raise
ValueError
(
"Do not know how to initialize message with data %r"
...
...
@@ -435,9 +436,11 @@ class SyncMLRequest(object):
self
.
isFinal
=
False
self
.
parse
()
def
__
str
__
(
self
):
def
__
bytes
__
(
self
):
return
etree
.
tostring
(
self
.
data
,
encoding
=
'utf-8'
,
xml_declaration
=
True
,
pretty_print
=
True
)
if
six
.
PY2
:
__str__
=
__bytes__
def
parse
(
self
):
"""
...
...
@@ -590,7 +593,8 @@ class SyncMLRequest(object):
parser_
=
etree
.
XMLParser
(
strip_cdata
=
False
)
cdata
=
etree
.
XML
(
data
,
parser_
)
data
=
cdata
.
text
# XXX this is unicode and can be a problem for activity
if
six
.
PY3
:
data
=
data
.
encode
()
sync_command_kw
[
"raw_data"
]
=
data
append
(
sync_command_kw
)
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLTransportFile.py
View file @
20afa613
...
...
@@ -32,8 +32,7 @@ class FileTransport:
def
send
(
self
,
to_url
,
data
,
sync_id
,
content_type
):
filename
=
to_url
[
len
(
'file:/'
):]
try
:
stream
=
open
(
filename
,
'w'
)
stream
.
write
(
data
)
stream
.
close
()
with
open
(
filename
,
'wb'
)
as
stream
:
stream
.
write
(
data
)
except
IOError
:
raise
ConnectionError
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.SyncMLUtils.py
View file @
20afa613
...
...
@@ -38,7 +38,7 @@ from hashlib import md5
from
ZPublisher.HTTPRequest
import
FileUpload
from
OFS.Image
import
Pdata
from
StringIO
import
String
IO
from
io
import
Bytes
IO
import
transaction
class
PdataHelper
(
persistent
.
Persistent
):
...
...
@@ -68,14 +68,14 @@ class PdataHelper(persistent.Persistent):
n
=
self
.
_max_len
if
isinstance
(
value
,
(
str
,
unicode
)):
if
isinstance
(
value
,
unicod
e
):
if
isinstance
(
value
,
six
.
string_types
+
(
six
.
binary_type
,
)):
if
not
isinstance
(
value
,
six
.
binary_typ
e
):
value
=
value
.
encode
(
'utf-8'
)
size
=
len
(
value
)
size
=
len
(
value
)
if
size
<
n
:
return
Pdata
(
value
),
size
# Big
string
: cut it into smaller chunks
value
=
String
IO
(
value
)
# Big
data
: cut it into smaller chunks
value
=
Bytes
IO
(
value
)
if
isinstance
(
value
,
FileUpload
)
and
not
value
:
raise
ValueError
(
'File not specified'
)
...
...
@@ -161,11 +161,13 @@ class PdataHelper(persistent.Persistent):
"""
return
self
.
size
def
__
str
__
(
self
):
def
__
bytes
__
(
self
):
"""Return string concatenation
of all Pdata parts
"""
return
str
(
self
.
_data
)
return
bytes
(
self
.
_data
)
if
six
.
PY2
:
__str__
=
__bytes__
def
getContentMd5
(
self
):
"""
...
...
@@ -176,26 +178,20 @@ class PdataHelper(persistent.Persistent):
self
.
md5sum
=
md5sum
return
md5sum
def
__get
slice__
(
self
,
i
,
j
):
def
__get
item__
(
self
,
i
):
"""XXX Could be improved to avoid loading
into memory all Pdata objects
"""
return
self
.
__
str__
()[
i
:
j
]
return
self
.
__
bytes__
()[
i
]
def
getLastPdata
(
self
):
"""return the last Pdata element
of a Pdata chains
"""
pdata
=
self
.
_data
if
six
.
PY2
:
next_
=
pdata
.
next
else
:
next_
=
pdata
.
__next__
next_
=
pdata
.
next
while
next_
is
not
None
:
pdata
=
next_
if
six
.
PY2
:
next_
=
pdata
.
next
else
:
next_
=
pdata
.
__next__
next_
=
pdata
.
next
return
pdata
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.VCardConduit.py
View file @
20afa613
...
...
@@ -31,6 +31,7 @@ from erp5.component.module.ERP5Conduit import ERP5Conduit
from
AccessControl
import
ClassSecurityInfo
from
Products.ERP5Type
import
Permissions
import
difflib
import
six
from
zLOG
import
LOG
...
...
@@ -56,7 +57,7 @@ class VCardConduit(ERP5Conduit):
"""
#LOG('VCardConduit',0,'addNode, object=%s, object_id=%s, sub_object:%s, \
#xml:\n%s' % (str(object), str(object_id), str(sub_object), xml))
if
not
isinstance
(
xml
,
str
):
if
not
isinstance
(
xml
,
bytes
):
xml
=
self
.
nodeToString
(
xml
)
portal_type
=
'Person'
#the VCard can just use Person
if
sub_object
is
None
:
...
...
@@ -161,7 +162,9 @@ class VCardConduit(ERP5Conduit):
convert_dict
[
'N'
]
=
'last_name'
convert_dict
[
'TEL'
]
=
'default_telephone_text'
edit_dict
=
{}
vcard_list
=
vcard
.
split
(
'
\
n
'
)
if
isinstance
(
vcard
,
bytes
):
vcard
=
vcard
.
decode
(
'utf-8'
)
vcard_list
=
vcard
.
splitlines
()
for
vcard_line
in
vcard_list
:
if
':'
in
vcard_line
:
property_
,
property_value
=
vcard_line
.
split
(
':'
)
...
...
@@ -192,12 +195,12 @@ class VCardConduit(ERP5Conduit):
else
:
property_name
=
property_
if
isinstance
(
property_name
,
unicod
e
):
if
six
.
PY2
and
isinstance
(
property_name
,
six
.
text_typ
e
):
property_name
=
property_name
.
encode
(
'utf-8'
)
tmp
=
[]
for
property_value
in
property_value_list
:
if
isinstance
(
property_value
,
unicod
e
):
if
six
.
PY2
and
isinstance
(
property_value
,
six
.
text_typ
e
):
property_value
=
property_value
.
encode
(
'utf-8'
)
tmp
.
append
(
property_value
)
property_value_list
=
tmp
...
...
@@ -226,6 +229,10 @@ class VCardConduit(ERP5Conduit):
def
generateDiff
(
self
,
new_data
,
former_data
):
"""return unified diff for plain-text documents
"""
if
isinstance
(
new_data
,
bytes
):
new_data
=
new_data
.
decode
(
'utf-8'
)
if
isinstance
(
former_data
,
bytes
):
former_data
=
former_data
.
decode
(
'utf-8'
)
diff
=
'
\
n
'
.
join
(
difflib
.
unified_diff
(
new_data
.
splitlines
(),
former_data
.
splitlines
()))
return
diff
...
...
bt5/erp5_syncml/ModuleComponentTemplateItem/portal_components/module.erp5.XMLSyncUtils.py
View file @
20afa613
...
...
@@ -29,6 +29,7 @@
import
smtplib
import
os
import
six
from
base64
import
b64encode
,
b64decode
from
lxml
import
etree
from
lxml.builder
import
ElementMaker
...
...
@@ -58,7 +59,10 @@ def encode(format, string_to_encode): # pylint: disable=redefined-builtin
if
not
format
:
return
string_to_encode
if
format
==
'b64'
:
return
b64encode
(
string_to_encode
)
if
not
isinstance
(
string_to_encode
,
six
.
binary_type
):
string_to_encode
=
string_to_encode
.
encode
()
encoded
=
b64encode
(
string_to_encode
)
return
encoded
#elif format is .... put here the other formats
else
:
#if there is no format corresponding with format, raise an error
LOG
(
'encode : unknown or not implemented format : '
,
INFO
,
format
)
...
...
@@ -180,11 +184,10 @@ def getXupdateObject(object_xml=None, old_xml=None):
"""
erp5diff
=
ERP5Diff
()
erp5diff
.
compare
(
old_xml
,
object_xml
)
#Upper version of ERP5Diff produce valid XML.
if
erp5diff
.
_getResultRoot
():
xupdate
=
erp5diff
.
output
String
(
)
#omit xml declaration
xupdate
=
xupdate
[
xupdate
.
find
(
'<xupdate:modifications'
):]
xupdate
=
erp5diff
.
output
Bytes
(
encoding
=
"utf-8"
)
#
omit xml declaration
xupdate
=
xupdate
[
xupdate
.
find
(
b
'<xupdate:modifications'
):]
return
xupdate
def
cutXML
(
xml_string
,
length
=
None
):
...
...
bt5/erp5_syncml/SkinTemplateItem/portal_skins/erp5_syncml/Person_exportAsVCard.py
View file @
20afa613
...
...
@@ -3,13 +3,6 @@ first_name = context.getFirstName()
last_name
=
context
.
getLastName
()
tel
=
context
.
getDefaultTelephoneTelephoneNumber
()
if
same_type
(
first_name
,
u'a'
):
first_name
=
first_name
.
encode
(
'utf-8'
)
if
same_type
(
last_name
,
u'a'
):
last_name
=
last_name
.
encode
(
'utf-8'
)
if
same_type
(
tel
,
u'a'
)
:
tel
=
tel
.
encode
(
'utf-8'
)
parameters_FN
=
''
parameters_N
=
''
...
...
bt5/erp5_syncml/SkinTemplateItem/portal_skins/erp5_syncml/SQLCatalog_indexSyncMLDocumentList.py
View file @
20afa613
from
six.moves
import
range
if
not
len
(
path_list
):
return
restrictedTraverse
=
context
.
getPortalObject
().
restrictedTraverse
...
...
@@ -35,7 +36,7 @@ for path in path_list:
object_list
=
obj
()
else
:
object_list
=
[
obj
,]
for
x
in
x
range
(
0
,
len
(
object_list
),
MAX_PER_QUERY
):
for
x
in
range
(
0
,
len
(
object_list
),
MAX_PER_QUERY
):
parameter_dict
,
parameter_append_list
=
generateParameterList
()
for
obj
in
object_list
[
x
:
x
+
MAX_PER_QUERY
]:
for
value_list
,
getter
in
parameter_append_list
:
...
...
bt5/erp5_syncml/SkinTemplateItem/portal_skins/erp5_syncml/SynchronizationTool_activateCheckPointFixe.py
View file @
20afa613
from
six.moves
import
range
sub_path
=
method_kw
.
get
(
"subscription_path"
)
sub
=
context
.
getPortalObject
().
restrictedTraverse
(
sub_path
)
search_kw
=
dict
(
kw
)
...
...
@@ -17,7 +18,7 @@ if result_count:
r
=
[
x
.
getId
()
for
x
in
r
]
callback_method
=
getattr
(
sub
.
activate
(
**
activate_kw
),
callback
)
for
i
in
x
range
(
0
,
result_count
,
packet_size
):
for
i
in
range
(
0
,
result_count
,
packet_size
):
callback_method
(
id_list
=
r
[
i
:
i
+
packet_size
],
**
method_kw
)
...
...
bt5/erp5_syncml/TestTemplateItem/portal_components/test.erp5.testERP5DocumentSyncML.py
View file @
20afa613
...
...
@@ -55,9 +55,9 @@ class TestERP5DocumentSyncMLMixin(TestERP5SyncMLMixin):
nb_objects
=
10
#for objects
ids
=
range
(
1
,
nb_objects
+
1
)
ids
=
list
(
range
(
1
,
nb_objects
+
1
)
)
#id_max_text : number of document text
id_max_text
=
nb_objects
/
2
id_max_text
=
nb_objects
//
2
id1
=
'2'
id2
=
'3'
#for documents (encoding in unicode for utf-8)
...
...
@@ -644,7 +644,7 @@ class TestERP5DocumentSyncML(TestERP5DocumentSyncMLMixin):
publication
=
portal_sync
[
self
.
pub_id
]
self
.
assertEqual
(
len
(
publication
[
'1'
]),
nb_document
)
gid
=
self
.
reference1
+
'-'
+
self
.
version1
+
'-'
+
self
.
language1
# ie the title ''
gid
=
b16encode
(
gid
)
gid
=
b16encode
(
gid
.
encode
()).
decode
(
)
document_c1
=
subscription1
.
getDocumentFromGid
(
gid
)
document_s
=
publication
.
getSubscriber
(
self
.
subscription_url
[
'two_way'
]).
getDocumentFromGid
(
gid
)
id_s
=
document_s
.
getId
()
...
...
bt5/erp5_syncml/TestTemplateItem/portal_components/test.erp5.testERP5SyncML.py
View file @
20afa613
...
...
@@ -31,6 +31,7 @@ import unittest
from
base64
import
b64encode
,
b64decode
,
b16encode
from
lxml
import
etree
from
unittest
import
expectedFailure
from
six
import
string_types
as
basestring
from
AccessControl.SecurityManagement
import
newSecurityManager
from
ERP5Diff
import
ERP5Diff
...
...
@@ -43,6 +44,7 @@ from erp5.component.module.SyncMLConstant import MAX_LEN
from
erp5.component.document
import
SyncMLSubscription
from
erp5.component.module.testERP5SyncMLMixin
import
TestERP5SyncMLMixin
\
as
TestMixin
from
six.moves
import
range
class
TestERP5SyncMLMixin
(
TestMixin
):
...
...
@@ -255,7 +257,7 @@ class TestERP5SyncMLMixin(TestMixin):
# only first call will return an answer
result
=
portal_sync
.
processServerSynchronization
(
publication
.
getPath
())
self
.
tic
()
for
_
in
x
range
(
2
):
for
_
in
range
(
2
):
portal_sync
.
processServerSynchronization
(
publication
.
getPath
())
self
.
tic
()
nb_message
+=
1
...
...
@@ -263,7 +265,7 @@ class TestERP5SyncMLMixin(TestMixin):
break
result
=
portal_sync
.
processClientSynchronization
(
subscription
.
getPath
())
self
.
tic
()
for
_
in
x
range
(
2
):
for
_
in
range
(
2
):
portal_sync
.
processClientSynchronization
(
subscription
.
getPath
())
self
.
tic
()
nb_message
+=
1
...
...
@@ -1095,7 +1097,7 @@ return [context[%r]]
publication
=
portal_sync
[
self
.
pub_id
]
self
.
assertEqual
(
len
(
publication
.
getDocumentList
()),
nb_person
)
gid
=
self
.
first_name1
+
' '
+
self
.
last_name1
# ie the title 'Sebastien Robin'
gid
=
b16encode
(
gid
)
gid
=
b16encode
(
gid
.
encode
()).
decode
(
)
person_c1
=
subscription1
.
getDocumentFromGid
(
gid
)
person_s
=
publication
.
getSubscriber
(
self
.
subscription_url1
).
getDocumentFromGid
(
gid
)
id_s
=
person_s
.
getId
()
...
...
@@ -1620,7 +1622,7 @@ return [context[%r]]
# Check same person on client & server side
client_person_module
=
self
.
getPersonClient1
()
server_person_module
=
self
.
getPersonServer
()
for
x
in
x
range
(
1
,
61
):
for
x
in
range
(
1
,
61
):
client_person
=
client_person_module
.
_getOb
(
str
(
x
))
server_person
=
server_person_module
.
_getOb
(
str
(
x
))
self
.
assertEqual
(
client_person
.
getFirstName
(),
self
.
first_name1
)
...
...
@@ -1643,7 +1645,7 @@ return [context[%r]]
self
.
assertEqual
(
len
(
subscription1
),
0
)
self
.
assertEqual
(
len
(
subscriber
),
0
)
for
x
in
x
range
(
1
,
61
):
for
x
in
range
(
1
,
61
):
client_person
=
client_person_module
.
_getOb
(
str
(
x
))
server_person
=
server_person_module
.
_getOb
(
str
(
x
))
self
.
assertEqual
(
client_person
.
getFirstName
(),
self
.
first_name2
)
...
...
@@ -1663,7 +1665,7 @@ return [context[%r]]
self
.
assertEqual
(
len
(
subscription1
),
0
)
self
.
assertEqual
(
len
(
subscriber
),
0
)
for
x
in
x
range
(
1
,
61
):
for
x
in
range
(
1
,
61
):
client_person
=
client_person_module
.
_getOb
(
str
(
x
))
server_person
=
server_person_module
.
_getOb
(
str
(
x
))
self
.
assertEqual
(
client_person
.
getLastName
(),
self
.
last_name2
)
...
...
@@ -1687,31 +1689,26 @@ return [context[%r]]
self
.
test_08_FirstSynchronization
()
#define some strings :
python
=
'www.python.org'
awaited_result_python
=
"d3d3LnB5dGhvbi5vcmc="
long_string
=
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO
\
PQRSTUVWXYZéèçà@^~µ&²0123456789!@#0^&*();:<>,. []{}
\
xc3
\
xa7
sdf__
\
sdf
\
xc3
\
xa7
\
xc3
\
xa7
\
xc3
\
xa7
_df___&&
\
xc3
\
xa9
]]]
\
xc2
\
xb0
\
xc2
\
xb0
\
xc2
\
\
xb0
\
xc2
\
xb0
\
xc2
\
xb0
\
xc2
\
xb0
"
#= "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZéèçà@^~µ&²012345
#6789!@#0^&*();:<>,. []{}çsdf__sdfççç_df___&&é]]]°°°°°°'"
awaited_result_long_string
=
"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZH
\
SElKS0xNTk9QUVJTVFVWV1hZWsOpw6jDp8OgQF5+wrUmwrIwMTIzNDU2Nzg5IUAjMF4mKigpOzo8Pi
\
wuIFtde33Dp3NkZl9fc2Rmw6fDp8OnX2RmX19fJibDqV1dXcKwwrDCsMKwwrDCsA=="
python
=
b'www.python.org'
awaited_result_python
=
b"d3d3LnB5dGhvbi5vcmc="
long_string
=
u"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZéèçà@^~µ&²0123456789"
\
u"!@#0^&*();:<>,. []{}çsdf__sdfççç_df___&&é]]]°°°°°°'"
.
encode
(
'utf-8'
)
awaited_result_long_string
=
b'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNERUZH'
\
b'SElKS0xNTk9QUVJTVFVWV1hZWsOpw6jDp8OgQF5+wrUmwrIwMTIzNDU2Nzg5IUAjMF4mKigpO'
\
b'zo8PiwuIFtde33Dp3NkZl9fc2Rmw6fDp8OnX2RmX19fJibDqV1dXcKwwrDCsMKwwrDCsCc='
#test just b64encode
self
.
assertEqual
(
b64encode
(
python
),
awaited_result_python
)
self
.
assertEqual
(
b64encode
(
""
),
""
)
self
.
assertEqual
(
b64encode
(
b""
),
b
""
)
self
.
assertEqual
(
b64encode
(
long_string
),
awaited_result_long_string
)
self
.
assertEqual
(
b64decode
(
awaited_result_python
),
python
)
self
.
assertEqual
(
b64decode
(
""
),
""
)
self
.
assertEqual
(
b64decode
(
b""
),
b
""
)
self
.
assertEqual
(
b64decode
(
awaited_result_long_string
),
long_string
)
# test with the ERP5 functions
string_encoded
=
encode
(
'b64'
,
python
)
self
.
assertEqual
(
string_encoded
,
awaited_result_python
)
string_decoded
=
decode
(
'b64'
,
awaited_result_python
)
string_decoded
=
decode
(
'b64'
,
awaited_result_python
.
decode
()
)
self
.
assertEqual
(
string_decoded
,
python
)
self
.
assertTrue
(
isDecodeEncodeTheSame
(
string_encoded
,
python
,
'b64'
))
...
...
@@ -1720,17 +1717,17 @@ wuIFtde33Dp3NkZl9fc2Rmw6fDp8OnX2RmX19fJibDqV1dXcKwwrDCsMKwwrDCsA=="
string_encoded
=
encode
(
'b64'
,
long_string
)
self
.
assertEqual
(
string_encoded
,
awaited_result_long_string
)
string_decoded
=
decode
(
'b64'
,
awaited_result_long_string
)
string_decoded
=
decode
(
'b64'
,
awaited_result_long_string
.
decode
()
)
self
.
assertEqual
(
string_decoded
,
long_string
)
self
.
assertTrue
(
isDecodeEncodeTheSame
(
string_encoded
,
long_string
,
'b64'
))
self
.
assertTrue
(
isDecodeEncodeTheSame
(
string_encoded
,
string_decoded
,
'b64'
))
self
.
assertEqual
(
encode
(
'b64'
,
''
),
''
)
self
.
assertEqual
(
decode
(
'b64'
,
''
),
''
)
self
.
assertEqual
(
encode
(
'b64'
,
b''
),
b
''
)
self
.
assertEqual
(
decode
(
'b64'
,
''
),
b
''
)
self
.
assertTrue
(
isDecodeEncodeTheSame
(
encode
(
'b64'
,
''
),
''
,
'b64'
))
encode
(
'b64'
,
''
),
b
''
,
'b64'
))
def
test_35_authentication
(
self
):
"""
...
...
bt5/erp5_syncml/ToolComponentTemplateItem/portal_components/tool.erp5.SynchronizationTool.py
View file @
20afa613
...
...
@@ -26,6 +26,7 @@
##############################################################################
from
logging
import
getLogger
import
six
from
AccessControl
import
ClassSecurityInfo
...
...
@@ -184,8 +185,7 @@ class SynchronizationTool(BaseTool):
#
security
.
declarePublic
(
'readResponse'
)
def
readResponse
(
self
,
text
=
''
,
sync_id
=
None
,
from_url
=
None
):
"""
We will look at the url and we will see if we need to send mail, http
"""We will look at the url and we will see if we need to send mail, http
response, or just copy to a file.
"""
syncml_logger
.
info
(
'readResponse sync_id %s, text %s'
,
sync_id
,
text
)
...
...
@@ -193,6 +193,9 @@ class SynchronizationTool(BaseTool):
# we are still anonymous at this time, use unrestrictedSearchResults
# to fetch the Subcribers
catalog_tool
=
self
.
getPortalObject
().
portal_catalog
.
unrestrictedSearchResults
if
isinstance
(
text
,
six
.
text_type
):
text
=
text
.
encode
(
'utf-8'
)
syncml_request
=
SyncMLRequest
(
text
)
# It is assumed that client & server does not share the same database ID
...
...
@@ -233,12 +236,12 @@ class SynchronizationTool(BaseTool):
%
(
sync_id
,
syncml_request
.
header
[
'target'
]))
# we use from only if we have a file
elif
isinstance
(
from_url
,
basestring
):
elif
isinstance
(
from_url
,
six
.
string_types
):
if
from_url
.
startswith
(
'file:'
):
filename
=
from_url
[
len
(
'file:'
):]
xml
=
None
try
:
stream
=
open
(
filename
,
'r'
)
stream
=
open
(
filename
,
'r
b
'
)
except
IOError
:
# XXX-Aurel : Why raising here make unit tests to fail ?
# raise ValueError("Impossible to read file %s, error is %s"
...
...
@@ -313,7 +316,7 @@ class SynchronizationTool(BaseTool):
raise
NotImplementedError
(
"Starting sync process from server is forbidden"
)
# Return message for unit test purpose
return
str
(
syncml_response
)
return
bytes
(
syncml_response
)
#
# Following methods are related to client (subscription)
...
...
@@ -362,10 +365,10 @@ class SynchronizationTool(BaseTool):
'getAndIndex'
,
'SQLCatalog_indexSyncMLDocumentList'
),
priority
=
ACTIVITY_PRIORITY
,
tag
=
subscription
.
getRelativeUrl
()).
sendMessage
(
str
(
syncml_response
))
tag
=
subscription
.
getRelativeUrl
()).
sendMessage
(
bytes
(
syncml_response
))
else
:
subscription
.
sendMessage
(
str
(
syncml_response
))
subscription
.
sendMessage
(
bytes
(
syncml_response
))
return
str
(
syncml_response
)
return
bytes
(
syncml_response
)
InitializeClass
(
SynchronizationTool
)
bt5/erp5_syncml_test_data/TestTemplateItem/portal_components/test.erp5.testSyncMLAsynchronousEngine.py
View file @
20afa613
...
...
@@ -27,6 +27,7 @@
from
erp5.component.module.testERP5SyncMLMixin
import
TestERP5SyncMLMixin
from
six.moves
import
range
class
testSyncMLAsynchronousEngine
(
TestERP5SyncMLMixin
):
...
...
@@ -100,7 +101,7 @@ class testSyncMLAsynchronousEngine(TestERP5SyncMLMixin):
def
_fillModule
(
self
,
module
,
nb_objects
):
self
.
title_list
=
[]
append
=
self
.
title_list
.
append
for
x
in
x
range
(
nb_objects
):
for
x
in
range
(
nb_objects
):
module
.
newContent
(
title
=
str
(
x
))
append
(
str
(
x
))
...
...
product/ERP5Type/XMLExportImport/__init__.py
View file @
20afa613
...
...
@@ -123,7 +123,7 @@ def Base_asXML(object, root=None):
# Create blocks to represent data
# <data><block>ZERD</block><block>OEJJM</block></data>
size_block
=
60
if
isinstance
(
value
,
str
):
if
isinstance
(
value
,
bytes
):
for
index
in
xrange
(
0
,
len
(
value
),
size_block
):
content
=
value
[
index
:
index
+
size_block
]
data_encoded
=
standard_b64encode
(
content
)
...
...
@@ -136,7 +136,10 @@ def Base_asXML(object, root=None):
for
word
in
value
]
sub_object
.
append
(
marshaller
(
value
))
elif
prop_type
in
(
'text'
,
'string'
,):
sub_object
.
text
=
six
.
text_type
(
escape
(
value
),
'utf-8'
)
value
=
escape
(
value
)
if
six
.
PY2
:
value
=
six
.
text_type
(
value
,
'utf-8'
)
sub_object
.
text
=
value
elif
prop_type
!=
'None'
:
sub_object
.
text
=
str
(
value
)
...
...
@@ -160,15 +163,22 @@ def Base_asXML(object, root=None):
variable_node
=
SubElement
(
workflow_node
,
workflow_variable
,
attrib
=
dict
(
type
=
variable_type
))
if
variable_type
!=
'None'
:
variable_node
.
text
=
six
.
text_type
(
str
(
variable_node_text
),
'utf-8'
)
variable_node_text
=
str
(
variable_node_text
)
if
six
.
PY2
:
variable_node_text
=
six
.
text_type
(
str
(
variable_node_text
),
'utf-8'
)
variable_node
.
text
=
variable_node_text
if
workflow_variable
==
'time'
:
time
=
variable_node
.
text
elif
workflow_variable
==
'actor'
:
actor
=
variable_node
.
text
workflow_node
.
attrib
[
'id'
]
=
sha1
(
workflow_id
+
time
+
str
(
actor
.
encode
(
'utf-8'
))).
hexdigest
()
if
six
.
PY2
and
isinstance
(
actor
,
six
.
text_type
):
actor
=
actor
.
encode
(
'utf-8'
)
workflow_transition_id
=
workflow_id
+
time
+
actor
if
six
.
PY3
:
workflow_transition_id
=
workflow_transition_id
.
encode
()
workflow_node
.
attrib
[
'id'
]
=
sha1
(
workflow_transition_id
).
hexdigest
()
# We should now describe security settings
for
user_role
in
self
.
get_local_roles
():
...
...
@@ -177,7 +187,7 @@ def Base_asXML(object, root=None):
#convert local_roles in string because marshaller can't do it
role_list
=
[]
for
role
in
user_role
[
1
]:
if
isinstance
(
role
,
six
.
text_type
):
if
six
.
PY2
and
isinstance
(
role
,
six
.
text_type
):
role
=
role
.
encode
(
'utf-8'
)
role_list
.
append
(
role
)
local_role_node
.
append
(
marshaller
(
tuple
(
role_list
)))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment