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