chemistry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Laurent Mignon (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (CMIS-996) BrowserBinding getObjecyByPath: unicode is not supported by urllib.quote
Date Sat, 10 Sep 2016 10:44:20 GMT

     [ https://issues.apache.org/jira/browse/CMIS-996?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Laurent Mignon updated CMIS-996:
--------------------------------
    Description: 
The function getObjectByPath use urllib.quote to quote the path into the url. urllib.quote
doesn't support unicode values. 
see https://github.com/apache/chemistry-cmislib/pull/4
{code}
>From 26e824b255acb0721516067ffc53093696acb191 Mon Sep 17 00:00:00 2001
From: Laurent Mignon <laurent.mignon@acsone.eu>
Date: Fri, 9 Sep 2016 19:52:30 +0200
Subject: [PATCH] Fix UnicodeEncodeError when calling urllib.quote whith value
 containing accented chars In the same time ensure that all the sources files
 are in the same encoding as python itself (utf-8) by adding an encoding
 declaration at first line of any files.

---
 src/cmislib/atompub/binding.py |  1 +
 src/cmislib/browser/binding.py | 38 +++++++++++++++++++++--------
 src/cmislib/cmis_services.py   |  1 +
 src/cmislib/domain.py          |  1 +
 src/cmislib/exceptions.py      |  1 +
 src/cmislib/messages.py        |  1 +
 src/cmislib/model.py           |  1 +
 src/cmislib/net.py             |  1 +
 src/cmislib/util.py            |  1 +
 src/tests/cmislibtest.py       | 55 +++++++++++++++++++++---------------------
 10 files changed, 64 insertions(+), 37 deletions(-)

diff --git a/src/cmislib/atompub/binding.py b/src/cmislib/atompub/binding.py
index f1a629f..55a066a 100644
--- a/src/cmislib/atompub/binding.py
+++ b/src/cmislib/atompub/binding.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding.py
index 7d7d758..c148a0c 100644
--- a/src/cmislib/browser/binding.py
+++ b/src/cmislib/browser/binding.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
@@ -715,7 +716,7 @@ def getObjectByPath(self, path, **kwargs):
          - includeAllowableActions
         """
 
-        byPathUrl = self.getRootFolderUrl() + quote(path) + "?cmisselector=object"
+        byPathUrl = self.getRootFolderUrl() + safe_quote(path) + "?cmisselector=object"
         result = self._cmisClient.binding.get(byPathUrl.encode('utf-8'),
                                               self._cmisClient.username,
                                               self._cmisClient.password,
@@ -926,7 +927,7 @@ def getTypeChildren(self,
         typesUrl = self.getRepositoryUrl() + "?cmisselector=typeChildren"
 
         if typeId is not None:
-            typesUrl += "&typeId=%s" % (quote(typeId))
+            typesUrl += "&typeId=%s" % (safe_quote(typeId))
 
         result = self._cmisClient.binding.get(typesUrl,
                                               self._cmisClient.username,
@@ -986,7 +987,7 @@ def getTypeDescendants(self, typeId=None, depth=None, **kwargs):
         typesUrl = self.getRepositoryUrl() + "?cmisselector=typeDescendants"
 
         if typeId is not None:
-            typesUrl += "&typeId=%s" % (quote(typeId))
+            typesUrl += "&typeId=%s" % (safe_quote(typeId))
         if depth is not None:
             typesUrl += "&depth=%s" % (depth)
         print typesUrl
@@ -1180,7 +1181,7 @@ def query(self, statement, **kwargs):
         """
 
         # build the CMIS query XML that we're going to POST
-        queryUrl = self.getRepositoryUrl() + "?cmisaction=query&q=" + quote(statement)
+        queryUrl = self.getRepositoryUrl() + "?cmisaction=query&q=" + safe_quote(statement)
 
         # do the POST
         result = self._cmisClient.binding.post(queryUrl.encode('utf-8'),
@@ -3161,6 +3162,18 @@ def encode_multipart_formdata(fields, contentFile, contentType):
     return content_type, body
 
 
+def to_utf8(value):
+
+    """ Safe encodng of value to utf-8 taking care of unicode values
+    """
+    if isinstance(value, unicode):
+        value = value.encode('utf8')
+    elif isinstance(value, str):
+        # Must be encoded in UTF-8
+        value.decode('utf8')
+    return value
+
+
 def safe_urlencode(in_dict):
 
     """
@@ -3171,17 +3184,22 @@ def safe_urlencode(in_dict):
     def encoded_dict(in_dict):
         out_dict = {}
         for k, v in in_dict.iteritems():
-            if isinstance(v, unicode):
-                v = v.encode('utf8')
-            elif isinstance(v, str):
-                # Must be encoded in UTF-8
-                v.decode('utf8')
-            out_dict[k] = v
+            out_dict[k] = to_utf8(v)
         return out_dict
 
     return urlencode(encoded_dict(in_dict))
 
 
+def safe_quote(value):
+
+    """
+    Safe encoding of value taking care of unicode value
+    urllib.quote doesn't like unicode values
+    """
+
+    return quote(to_utf8(value))
+
+
 class ResultsSerializer(object):
 
     """
diff --git a/src/cmislib/cmis_services.py b/src/cmislib/cmis_services.py
index 8c59cdb..4659d02 100644
--- a/src/cmislib/cmis_services.py
+++ b/src/cmislib/cmis_services.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/domain.py b/src/cmislib/domain.py
index a2f7a25..a362339 100644
--- a/src/cmislib/domain.py
+++ b/src/cmislib/domain.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/exceptions.py b/src/cmislib/exceptions.py
index 207280d..58d601d 100644
--- a/src/cmislib/exceptions.py
+++ b/src/cmislib/exceptions.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/messages.py b/src/cmislib/messages.py
index 2df8e45..0d49756 100644
--- a/src/cmislib/messages.py
+++ b/src/cmislib/messages.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/model.py b/src/cmislib/model.py
index 0a04c09..03ede82 100644
--- a/src/cmislib/model.py
+++ b/src/cmislib/model.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/net.py b/src/cmislib/net.py
index 3984918..e5124a9 100644
--- a/src/cmislib/net.py
+++ b/src/cmislib/net.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/util.py b/src/cmislib/util.py
index 7b6855f..0a2ff6a 100644
--- a/src/cmislib/util.py
+++ b/src/cmislib/util.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py
index a81be56..70f9415 100644
--- a/src/tests/cmislibtest.py
+++ b/src/tests/cmislibtest.py
@@ -346,33 +346,34 @@ def testGetFolder(self):
     def testGetObjectByPath(self):
         """Create test objects (one folder, one document) then try to get
         them by path"""
-        # names of folders and test docs
-        parentFolderName = 'testGetObjectByPath folder'
-        subFolderName = 'subfolder'
-        docName = 'testdoc'
-
-        # create the folder structure
-        parentFolder = self._testFolder.createFolder(parentFolderName)
-        subFolder = parentFolder.createFolder(subFolderName)
-        # use the subfolder path to get the folder by path
-        subFolderPath = subFolder.getProperties().get("cmis:path")
-        searchFolder = self._repo.getObjectByPath(subFolderPath)
-        self.assertEquals(subFolder.getObjectId(), searchFolder.getObjectId())
-
-        # create a test doc
-        doc = subFolder.createDocument(docName)
-        # ask the doc for its paths
-        searchDocPaths = doc.getPaths()
-        # for each path in the list, try to get the object by path
-        # this is better than building a path with the doc's name b/c the name
-        # isn't guaranteed to be used as the path segment (see CMIS-232)
-        for path in searchDocPaths:
-            searchDoc = self._repo.getObjectByPath(path)
-            self.assertEquals(doc.getObjectId(), searchDoc.getObjectId())
-
-        # get the subfolder by path, then ask for its children
-        subFolder = self._repo.getObjectByPath(subFolderPath)
-        self.assertEquals(len(subFolder.getChildren().getResults()), 1)
+        # names of folders and test docs (without and with unicode char)
+        for suffix in ['', u'_éà€$']:
+            parentFolderName = 'testGetObjectByPath folder' + suffix
+            subFolderName = 'subfolder' + suffix
+            docName = 'testdoc' + suffix
+
+            # create the folder structure
+            parentFolder = self._testFolder.createFolder(parentFolderName)
+            subFolder = parentFolder.createFolder(subFolderName)
+            # use the subfolder path to get the folder by path
+            subFolderPath = subFolder.getProperties().get("cmis:path")
+            searchFolder = self._repo.getObjectByPath(subFolderPath)
+            self.assertEquals(subFolder.getObjectId(), searchFolder.getObjectId())
+
+            # create a test doc
+            doc = subFolder.createDocument(docName)
+            # ask the doc for its paths
+            searchDocPaths = doc.getPaths()
+            # for each path in the list, try to get the object by path
+            # this is better than building a path with the doc's name b/c the name
+            # isn't guaranteed to be used as the path segment (see CMIS-232)
+            for path in searchDocPaths:
+                searchDoc = self._repo.getObjectByPath(path)
+                self.assertEquals(doc.getObjectId(), searchDoc.getObjectId())
+
+            # get the subfolder by path, then ask for its children
+            subFolder = self._repo.getObjectByPath(subFolderPath)
+            self.assertEquals(len(subFolder.getChildren().getResults()), 1)
 
     # getting unfiled documents may work for the atom pub binding for some servers
     # but it isn't part of the spec so removing this test for now
{code}


  was:
The function getObjectByPath use urllib.quote to quote the path into the url. urllib.quote
doesn't support unicode values. 
see https://github.com/apache/chemistry-cmislib/pull/4
{code}
>From 144475d56aa4a8547f8c5a869f75697e6f653d99 Mon Sep 17 00:00:00 2001
From: Laurent Mignon <laurent.mignon@acsone.eu>
Date: Fri, 9 Sep 2016 19:52:30 +0200
Subject: [PATCH] Fix UnicodeEncodeError when calling urllib.quote whith value
 containing accented chars In the same time ensure that all the sources files
 are in the same encoding as python itself (utf-8) by adding an encoding
 declaration at first line of any files.

---
 src/cmislib/atompub/binding.py |  1 +
 src/cmislib/browser/binding.py | 38 ++++++++++++++++++++++--------
 src/cmislib/cmis_services.py   |  1 +
 src/cmislib/domain.py          |  1 +
 src/cmislib/exceptions.py      |  1 +
 src/cmislib/messages.py        |  1 +
 src/cmislib/model.py           |  1 +
 src/cmislib/net.py             |  1 +
 src/cmislib/util.py            |  1 +
 src/tests/cmislibtest.py       | 53 +++++++++++++++++++++---------------------
 10 files changed, 63 insertions(+), 36 deletions(-)

diff --git a/src/cmislib/atompub/binding.py b/src/cmislib/atompub/binding.py
index f1a629f..55a066a 100644
--- a/src/cmislib/atompub/binding.py
+++ b/src/cmislib/atompub/binding.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding.py
index 7d7d758..c148a0c 100644
--- a/src/cmislib/browser/binding.py
+++ b/src/cmislib/browser/binding.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
@@ -715,7 +716,7 @@ def getObjectByPath(self, path, **kwargs):
          - includeAllowableActions
         """
 
-        byPathUrl = self.getRootFolderUrl() + quote(path) + "?cmisselector=object"
+        byPathUrl = self.getRootFolderUrl() + safe_quote(path) + "?cmisselector=object"
         result = self._cmisClient.binding.get(byPathUrl.encode('utf-8'),
                                               self._cmisClient.username,
                                               self._cmisClient.password,
@@ -926,7 +927,7 @@ def getTypeChildren(self,
         typesUrl = self.getRepositoryUrl() + "?cmisselector=typeChildren"
 
         if typeId is not None:
-            typesUrl += "&typeId=%s" % (quote(typeId))
+            typesUrl += "&typeId=%s" % (safe_quote(typeId))
 
         result = self._cmisClient.binding.get(typesUrl,
                                               self._cmisClient.username,
@@ -986,7 +987,7 @@ def getTypeDescendants(self, typeId=None, depth=None, **kwargs):
         typesUrl = self.getRepositoryUrl() + "?cmisselector=typeDescendants"
 
         if typeId is not None:
-            typesUrl += "&typeId=%s" % (quote(typeId))
+            typesUrl += "&typeId=%s" % (safe_quote(typeId))
         if depth is not None:
             typesUrl += "&depth=%s" % (depth)
         print typesUrl
@@ -1180,7 +1181,7 @@ def query(self, statement, **kwargs):
         """
 
         # build the CMIS query XML that we're going to POST
-        queryUrl = self.getRepositoryUrl() + "?cmisaction=query&q=" + quote(statement)
+        queryUrl = self.getRepositoryUrl() + "?cmisaction=query&q=" + safe_quote(statement)
 
         # do the POST
         result = self._cmisClient.binding.post(queryUrl.encode('utf-8'),
@@ -3161,6 +3162,18 @@ def encode_multipart_formdata(fields, contentFile, contentType):
     return content_type, body
 
 
+def to_utf8(value):
+
+    """ Safe encodng of value to utf-8 taking care of unicode values
+    """
+    if isinstance(value, unicode):
+        value = value.encode('utf8')
+    elif isinstance(value, str):
+        # Must be encoded in UTF-8
+        value.decode('utf8')
+    return value
+
+
 def safe_urlencode(in_dict):
 
     """
@@ -3171,17 +3184,22 @@ def safe_urlencode(in_dict):
     def encoded_dict(in_dict):
         out_dict = {}
         for k, v in in_dict.iteritems():
-            if isinstance(v, unicode):
-                v = v.encode('utf8')
-            elif isinstance(v, str):
-                # Must be encoded in UTF-8
-                v.decode('utf8')
-            out_dict[k] = v
+            out_dict[k] = to_utf8(v)
         return out_dict
 
     return urlencode(encoded_dict(in_dict))
 
 
+def safe_quote(value):
+
+    """
+    Safe encoding of value taking care of unicode value
+    urllib.quote doesn't like unicode values
+    """
+
+    return quote(to_utf8(value))
+
+
 class ResultsSerializer(object):
 
     """
diff --git a/src/cmislib/cmis_services.py b/src/cmislib/cmis_services.py
index 8c59cdb..4659d02 100644
--- a/src/cmislib/cmis_services.py
+++ b/src/cmislib/cmis_services.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/domain.py b/src/cmislib/domain.py
index a2f7a25..a362339 100644
--- a/src/cmislib/domain.py
+++ b/src/cmislib/domain.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/exceptions.py b/src/cmislib/exceptions.py
index 207280d..58d601d 100644
--- a/src/cmislib/exceptions.py
+++ b/src/cmislib/exceptions.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/messages.py b/src/cmislib/messages.py
index 2df8e45..0d49756 100644
--- a/src/cmislib/messages.py
+++ b/src/cmislib/messages.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/model.py b/src/cmislib/model.py
index 0a04c09..03ede82 100644
--- a/src/cmislib/model.py
+++ b/src/cmislib/model.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/net.py b/src/cmislib/net.py
index 3984918..e5124a9 100644
--- a/src/cmislib/net.py
+++ b/src/cmislib/net.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/cmislib/util.py b/src/cmislib/util.py
index 7b6855f..0a2ff6a 100644
--- a/src/cmislib/util.py
+++ b/src/cmislib/util.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 #
 #      Licensed to the Apache Software Foundation (ASF) under one
 #      or more contributor license agreements.  See the NOTICE file
diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py
index a81be56..c524bcf 100644
--- a/src/tests/cmislibtest.py
+++ b/src/tests/cmislibtest.py
@@ -346,32 +346,33 @@ def testGetFolder(self):
     def testGetObjectByPath(self):
         """Create test objects (one folder, one document) then try to get
         them by path"""
-        # names of folders and test docs
-        parentFolderName = 'testGetObjectByPath folder'
-        subFolderName = 'subfolder'
-        docName = 'testdoc'
-
-        # create the folder structure
-        parentFolder = self._testFolder.createFolder(parentFolderName)
-        subFolder = parentFolder.createFolder(subFolderName)
-        # use the subfolder path to get the folder by path
-        subFolderPath = subFolder.getProperties().get("cmis:path")
-        searchFolder = self._repo.getObjectByPath(subFolderPath)
-        self.assertEquals(subFolder.getObjectId(), searchFolder.getObjectId())
-
-        # create a test doc
-        doc = subFolder.createDocument(docName)
-        # ask the doc for its paths
-        searchDocPaths = doc.getPaths()
-        # for each path in the list, try to get the object by path
-        # this is better than building a path with the doc's name b/c the name
-        # isn't guaranteed to be used as the path segment (see CMIS-232)
-        for path in searchDocPaths:
-            searchDoc = self._repo.getObjectByPath(path)
-            self.assertEquals(doc.getObjectId(), searchDoc.getObjectId())
-
-        # get the subfolder by path, then ask for its children
-        subFolder = self._repo.getObjectByPath(subFolderPath)
+        # names of folders and test docs (without and with unicode char)
+        for suffix in ['', u'_éà€$']:
+            parentFolderName = 'testGetObjectByPath folder' + suffix
+            subFolderName = 'subfolder' + suffix
+            docName = 'testdoc' + suffix
+    
+            # create the folder structure
+            parentFolder = self._testFolder.createFolder(parentFolderName)
+            subFolder = parentFolder.createFolder(subFolderName)
+            # use the subfolder path to get the folder by path
+            subFolderPath = subFolder.getProperties().get("cmis:path")
+            searchFolder = self._repo.getObjectByPath(subFolderPath)
+            self.assertEquals(subFolder.getObjectId(), searchFolder.getObjectId())
+    
+            # create a test doc
+            doc = subFolder.createDocument(docName)
+            # ask the doc for its paths
+            searchDocPaths = doc.getPaths()
+            # for each path in the list, try to get the object by path
+            # this is better than building a path with the doc's name b/c the name
+            # isn't guaranteed to be used as the path segment (see CMIS-232)
+            for path in searchDocPaths:
+                searchDoc = self._repo.getObjectByPath(path)
+                self.assertEquals(doc.getObjectId(), searchDoc.getObjectId())
+    
+            # get the subfolder by path, then ask for its children
+            subFolder = self._repo.getObjectByPath(subFolderPath)
         self.assertEquals(len(subFolder.getChildren().getResults()), 1)
 
     # getting unfiled documents may work for the atom pub binding for some servers
{code}



> BrowserBinding getObjecyByPath: unicode is not supported by urllib.quote
> ------------------------------------------------------------------------
>
>                 Key: CMIS-996
>                 URL: https://issues.apache.org/jira/browse/CMIS-996
>             Project: Chemistry
>          Issue Type: Bug
>          Components: python-cmislib
>            Reporter: Laurent Mignon
>            Assignee: Jeff Potts
>
> The function getObjectByPath use urllib.quote to quote the path into the url. urllib.quote
doesn't support unicode values. 
> see https://github.com/apache/chemistry-cmislib/pull/4
> {code}
> From 26e824b255acb0721516067ffc53093696acb191 Mon Sep 17 00:00:00 2001
> From: Laurent Mignon <laurent.mignon@acsone.eu>
> Date: Fri, 9 Sep 2016 19:52:30 +0200
> Subject: [PATCH] Fix UnicodeEncodeError when calling urllib.quote whith value
>  containing accented chars In the same time ensure that all the sources files
>  are in the same encoding as python itself (utf-8) by adding an encoding
>  declaration at first line of any files.
> ---
>  src/cmislib/atompub/binding.py |  1 +
>  src/cmislib/browser/binding.py | 38 +++++++++++++++++++++--------
>  src/cmislib/cmis_services.py   |  1 +
>  src/cmislib/domain.py          |  1 +
>  src/cmislib/exceptions.py      |  1 +
>  src/cmislib/messages.py        |  1 +
>  src/cmislib/model.py           |  1 +
>  src/cmislib/net.py             |  1 +
>  src/cmislib/util.py            |  1 +
>  src/tests/cmislibtest.py       | 55 +++++++++++++++++++++---------------------
>  10 files changed, 64 insertions(+), 37 deletions(-)
> diff --git a/src/cmislib/atompub/binding.py b/src/cmislib/atompub/binding.py
> index f1a629f..55a066a 100644
> --- a/src/cmislib/atompub/binding.py
> +++ b/src/cmislib/atompub/binding.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding.py
> index 7d7d758..c148a0c 100644
> --- a/src/cmislib/browser/binding.py
> +++ b/src/cmislib/browser/binding.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> @@ -715,7 +716,7 @@ def getObjectByPath(self, path, **kwargs):
>           - includeAllowableActions
>          """
>  
> -        byPathUrl = self.getRootFolderUrl() + quote(path) + "?cmisselector=object"
> +        byPathUrl = self.getRootFolderUrl() + safe_quote(path) + "?cmisselector=object"
>          result = self._cmisClient.binding.get(byPathUrl.encode('utf-8'),
>                                                self._cmisClient.username,
>                                                self._cmisClient.password,
> @@ -926,7 +927,7 @@ def getTypeChildren(self,
>          typesUrl = self.getRepositoryUrl() + "?cmisselector=typeChildren"
>  
>          if typeId is not None:
> -            typesUrl += "&typeId=%s" % (quote(typeId))
> +            typesUrl += "&typeId=%s" % (safe_quote(typeId))
>  
>          result = self._cmisClient.binding.get(typesUrl,
>                                                self._cmisClient.username,
> @@ -986,7 +987,7 @@ def getTypeDescendants(self, typeId=None, depth=None, **kwargs):
>          typesUrl = self.getRepositoryUrl() + "?cmisselector=typeDescendants"
>  
>          if typeId is not None:
> -            typesUrl += "&typeId=%s" % (quote(typeId))
> +            typesUrl += "&typeId=%s" % (safe_quote(typeId))
>          if depth is not None:
>              typesUrl += "&depth=%s" % (depth)
>          print typesUrl
> @@ -1180,7 +1181,7 @@ def query(self, statement, **kwargs):
>          """
>  
>          # build the CMIS query XML that we're going to POST
> -        queryUrl = self.getRepositoryUrl() + "?cmisaction=query&q=" + quote(statement)
> +        queryUrl = self.getRepositoryUrl() + "?cmisaction=query&q=" + safe_quote(statement)
>  
>          # do the POST
>          result = self._cmisClient.binding.post(queryUrl.encode('utf-8'),
> @@ -3161,6 +3162,18 @@ def encode_multipart_formdata(fields, contentFile, contentType):
>      return content_type, body
>  
>  
> +def to_utf8(value):
> +
> +    """ Safe encodng of value to utf-8 taking care of unicode values
> +    """
> +    if isinstance(value, unicode):
> +        value = value.encode('utf8')
> +    elif isinstance(value, str):
> +        # Must be encoded in UTF-8
> +        value.decode('utf8')
> +    return value
> +
> +
>  def safe_urlencode(in_dict):
>  
>      """
> @@ -3171,17 +3184,22 @@ def safe_urlencode(in_dict):
>      def encoded_dict(in_dict):
>          out_dict = {}
>          for k, v in in_dict.iteritems():
> -            if isinstance(v, unicode):
> -                v = v.encode('utf8')
> -            elif isinstance(v, str):
> -                # Must be encoded in UTF-8
> -                v.decode('utf8')
> -            out_dict[k] = v
> +            out_dict[k] = to_utf8(v)
>          return out_dict
>  
>      return urlencode(encoded_dict(in_dict))
>  
>  
> +def safe_quote(value):
> +
> +    """
> +    Safe encoding of value taking care of unicode value
> +    urllib.quote doesn't like unicode values
> +    """
> +
> +    return quote(to_utf8(value))
> +
> +
>  class ResultsSerializer(object):
>  
>      """
> diff --git a/src/cmislib/cmis_services.py b/src/cmislib/cmis_services.py
> index 8c59cdb..4659d02 100644
> --- a/src/cmislib/cmis_services.py
> +++ b/src/cmislib/cmis_services.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> diff --git a/src/cmislib/domain.py b/src/cmislib/domain.py
> index a2f7a25..a362339 100644
> --- a/src/cmislib/domain.py
> +++ b/src/cmislib/domain.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> diff --git a/src/cmislib/exceptions.py b/src/cmislib/exceptions.py
> index 207280d..58d601d 100644
> --- a/src/cmislib/exceptions.py
> +++ b/src/cmislib/exceptions.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> diff --git a/src/cmislib/messages.py b/src/cmislib/messages.py
> index 2df8e45..0d49756 100644
> --- a/src/cmislib/messages.py
> +++ b/src/cmislib/messages.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> diff --git a/src/cmislib/model.py b/src/cmislib/model.py
> index 0a04c09..03ede82 100644
> --- a/src/cmislib/model.py
> +++ b/src/cmislib/model.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> diff --git a/src/cmislib/net.py b/src/cmislib/net.py
> index 3984918..e5124a9 100644
> --- a/src/cmislib/net.py
> +++ b/src/cmislib/net.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> diff --git a/src/cmislib/util.py b/src/cmislib/util.py
> index 7b6855f..0a2ff6a 100644
> --- a/src/cmislib/util.py
> +++ b/src/cmislib/util.py
> @@ -1,3 +1,4 @@
> +# -*- coding: utf-8 -*-
>  #
>  #      Licensed to the Apache Software Foundation (ASF) under one
>  #      or more contributor license agreements.  See the NOTICE file
> diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py
> index a81be56..70f9415 100644
> --- a/src/tests/cmislibtest.py
> +++ b/src/tests/cmislibtest.py
> @@ -346,33 +346,34 @@ def testGetFolder(self):
>      def testGetObjectByPath(self):
>          """Create test objects (one folder, one document) then try to get
>          them by path"""
> -        # names of folders and test docs
> -        parentFolderName = 'testGetObjectByPath folder'
> -        subFolderName = 'subfolder'
> -        docName = 'testdoc'
> -
> -        # create the folder structure
> -        parentFolder = self._testFolder.createFolder(parentFolderName)
> -        subFolder = parentFolder.createFolder(subFolderName)
> -        # use the subfolder path to get the folder by path
> -        subFolderPath = subFolder.getProperties().get("cmis:path")
> -        searchFolder = self._repo.getObjectByPath(subFolderPath)
> -        self.assertEquals(subFolder.getObjectId(), searchFolder.getObjectId())
> -
> -        # create a test doc
> -        doc = subFolder.createDocument(docName)
> -        # ask the doc for its paths
> -        searchDocPaths = doc.getPaths()
> -        # for each path in the list, try to get the object by path
> -        # this is better than building a path with the doc's name b/c the name
> -        # isn't guaranteed to be used as the path segment (see CMIS-232)
> -        for path in searchDocPaths:
> -            searchDoc = self._repo.getObjectByPath(path)
> -            self.assertEquals(doc.getObjectId(), searchDoc.getObjectId())
> -
> -        # get the subfolder by path, then ask for its children
> -        subFolder = self._repo.getObjectByPath(subFolderPath)
> -        self.assertEquals(len(subFolder.getChildren().getResults()), 1)
> +        # names of folders and test docs (without and with unicode char)
> +        for suffix in ['', u'_éà€$']:
> +            parentFolderName = 'testGetObjectByPath folder' + suffix
> +            subFolderName = 'subfolder' + suffix
> +            docName = 'testdoc' + suffix
> +
> +            # create the folder structure
> +            parentFolder = self._testFolder.createFolder(parentFolderName)
> +            subFolder = parentFolder.createFolder(subFolderName)
> +            # use the subfolder path to get the folder by path
> +            subFolderPath = subFolder.getProperties().get("cmis:path")
> +            searchFolder = self._repo.getObjectByPath(subFolderPath)
> +            self.assertEquals(subFolder.getObjectId(), searchFolder.getObjectId())
> +
> +            # create a test doc
> +            doc = subFolder.createDocument(docName)
> +            # ask the doc for its paths
> +            searchDocPaths = doc.getPaths()
> +            # for each path in the list, try to get the object by path
> +            # this is better than building a path with the doc's name b/c the name
> +            # isn't guaranteed to be used as the path segment (see CMIS-232)
> +            for path in searchDocPaths:
> +                searchDoc = self._repo.getObjectByPath(path)
> +                self.assertEquals(doc.getObjectId(), searchDoc.getObjectId())
> +
> +            # get the subfolder by path, then ask for its children
> +            subFolder = self._repo.getObjectByPath(subFolderPath)
> +            self.assertEquals(len(subFolder.getChildren().getResults()), 1)
>  
>      # getting unfiled documents may work for the atom pub binding for some servers
>      # but it isn't part of the spec so removing this test for now
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message