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

Laurent Mignon updated CMIS-972:
--------------------------------
    Description: 
I've improved the checkin method to allow to update the content stream and the 
properties

{code}
>From cbca562e4cfce685c2cc60ee2ad0d73182d3cb5f Mon Sep 17 00:00:00 2001
From: Laurent Mignon <laurent.mig...@acsone.eu>
Date: Fri, 9 Sep 2016 18:53:05 +0200
Subject: [PATCH] Support content and properties paramaters on method checkin

---
 src/cmislib/atompub/binding.py | 23 ++++++++++++++++-------
 src/cmislib/browser/binding.py | 34 ++++++++++++++++++++--------------
 src/cmislib/domain.py          |  9 +++------
 src/tests/cmislibtest.py       | 42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 81 insertions(+), 27 deletions(-)

diff --git a/src/cmislib/atompub/binding.py b/src/cmislib/atompub/binding.py
index f1a629f..2eee222 100644
--- a/src/cmislib/atompub/binding.py
+++ b/src/cmislib/atompub/binding.py
@@ -2362,7 +2362,8 @@ def getCheckedOutBy(self):
         self.reload()
         return self.getProperties()['cmis:versionSeriesCheckedOutBy']
 
-    def checkin(self, checkinComment=None, **kwargs):
+    def checkin(self, checkinComment=None, contentFile=None, contentType=None,
+                properties=None, **kwargs):
 
         """
         Checks in this :class:`Document` which must be a private
@@ -2378,10 +2379,7 @@ def checkin(self, checkinComment=None, **kwargs):
         >>> doc.isCheckedOut()
         False
 
-        The following optional arguments are supported:
-         - major
-         - properties
-         - contentStream
+        The following optional arguments are NOT supported:
          - policies
          - addACEs
          - removeACEs
@@ -2395,8 +2393,19 @@ def checkin(self, checkinComment=None, **kwargs):
         kwargs['checkin'] = 'true'
         kwargs['checkinComment'] = checkinComment
 
-        # Build an empty ATOM entry
-        entryXmlDoc = getEmptyXmlDoc()
+        if not properties and not contentFile:
+            # Build an empty ATOM entry
+            entryXmlDoc = getEmptyXmlDoc()
+        else:
+            # the getEntryXmlDoc function may need the object type
+            objectTypeId = None
+            if self.properties.has_key('cmis:objectTypeId') and not 
properties.has_key('cmis:objectTypeId'):
+                objectTypeId = self.properties['cmis:objectTypeId']
+                self.logger.debug('This object type is:%s', objectTypeId)
+
+            # build the entry based on the properties provided
+            entryXmlDoc = getEntryXmlDoc(
+                self._repository, objectTypeId, properties, contentFile, 
contentType)
 
         # Get the self link
         # Do a PUT of the empty ATOM to the self link
diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding.py
index 7d7d758..c300e5e 100644
--- a/src/cmislib/browser/binding.py
+++ b/src/cmislib/browser/binding.py
@@ -1755,7 +1755,8 @@ def getCheckedOutBy(self):
         self.reload()
         return self.getProperties()['cmis:versionSeriesCheckedOutBy']
 
-    def checkin(self, checkinComment=None, **kwargs):
+    def checkin(self, checkinComment=None, contentFile=None, contentType=None,
+                properties=None, **kwargs):
 
         """
         Checks in this :class:`Document` which must be a private
@@ -1772,9 +1773,6 @@ def checkin(self, checkinComment=None, **kwargs):
         False
 
         The following optional arguments are NOT supported:
-         - major
-         - properties
-         - contentStream
          - policies
          - addACEs
          - removeACEs
@@ -1784,21 +1782,29 @@ def checkin(self, checkinComment=None, **kwargs):
         if not kwargs.has_key('major'):
             kwargs['major'] = 'true'
 
-        kwargs['checkinComment'] = checkinComment
-
-        ciUrl = self._repository.getRootFolderUrl()
+        else:
+            kwargs['major'] = 'false'
+        props = {
+            'checkinComment': checkinComment or "",
+        }
+        props.update(kwargs)
+        propCount = 0
+        properties = properties or {}
+        for key, value in properties.iteritems():
+            props["propertyId[%s]" % propCount] = key
+            props["propertyValue[%s]" % propCount] = value
+            propCount += 1
+
+        ciUrl = self._repository.getRootFolderUrl() + "?objectId=" + self.id + 
"&cmisaction=checkin"
 
-        # TODO don't hardcode major flag
-        props = {"objectId": self.id,
-                 "cmisaction": "checkIn"}
+        contentType, body = encode_multipart_formdata(props, contentFile, 
contentType)
 
         # invoke the URL
         result = self._cmisClient.binding.post(ciUrl.encode('utf-8'),
-                                               safe_urlencode(props),
-                                               
'application/x-www-form-urlencoded',
+                                               body,
+                                               contentType,
                                                self._cmisClient.username,
-                                               self._cmisClient.password,
-                                               **kwargs)
+                                               self._cmisClient.password)
 
         return getSpecializedObject(BrowserCmisObject(self._cmisClient, 
self._repository, data=result))
 
diff --git a/src/cmislib/domain.py b/src/cmislib/domain.py
index a2f7a25..3b4175c 100644
--- a/src/cmislib/domain.py
+++ b/src/cmislib/domain.py
@@ -1240,7 +1240,8 @@ def getCheckedOutBy(self):
 
         pass
 
-    def checkin(self, checkinComment=None, **kwargs):
+    def checkin(self, checkinComment=None, contentFile=None, contentType=None,
+                properties=None, **kwargs):
 
         """
         Checks in this :class:`Document` which must be a private
@@ -1256,15 +1257,11 @@ def checkin(self, checkinComment=None, **kwargs):
         >>> doc.isCheckedOut()
         False
 
-        The following optional arguments are supported:
-         - major
-         - properties
-         - contentStream
+        The following optional arguments are NOT supported:
          - policies
          - addACEs
          - removeACEs
         """
-
         pass
 
     def getLatestVersion(self, **kwargs):
diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py
index a81be56..4ad13a4 100644
--- a/src/tests/cmislibtest.py
+++ b/src/tests/cmislibtest.py
@@ -898,6 +898,48 @@ def testCheckinComment(self):
             if testDoc.isCheckedOut():
                 pwcDoc.delete()
 
+    def testCheckinContentAndProperties(self):
+        """Checkin a document with a new content a modifed properties"""
+        testFilename = settings.TEST_BINARY_1.split('/')[-1]
+        contentFile = open(testFilename, 'rb')
+        props = {'cmis:objectTypeId': settings.VERSIONABLE_TYPE_ID}
+        testDoc = self._testFolder.createDocument(testFilename, 
contentFile=contentFile, properties=props)
+        contentFile.close()
+        self.assertEquals(testFilename, testDoc.getName())
+        if not 'canCheckOut' in testDoc.allowableActions.keys():
+            print 'The test doc cannot be checked out...skipping'
+            return
+        pwcDoc = testDoc.checkout()
+
+        try:
+            self.assertTrue(testDoc.isCheckedOut())
+            testFile2 = settings.TEST_BINARY_2
+            testFile2Size = os.path.getsize(testFile2)
+            exportFile2 = testFile2.replace('.', 'export.')
+            contentFile2 = open(testFile2, 'rb')
+            props = {'cmis:name': 'testDocument2'}
+            testDoc = pwcDoc.checkin(
+                contentFile=contentFile2,
+                properties=props)
+            contentFile2.close()
+            self.assertFalse(testDoc.isCheckedOut())
+            self.assertEqual('testDocument2', testDoc.getName())
+
+            # expport the result
+            result = testDoc.getContentStream()
+            outfile = open(exportFile2, 'wb')
+            outfile.write(result.read())
+            result.close()
+            outfile.close()
+
+            # the file we exported should be the same size as the file we
+            # originally created
+            self.assertEquals(testFile2Size, os.path.getsize(exportFile2))
+
+        finally:
+            if testDoc.isCheckedOut():
+                pwcDoc.delete()
+
     def testCheckinAfterGetPWC(self):
         """Create a document in a test folder, check it out, call getPWC, then 
checkin"""
         if not self._repo.getCapabilities()['PWCUpdatable'] == True:
{code}
https://github.com/apache/chemistry-cmislib/pull/5


  was:
I've improved the checkin method to allow to update the content stream and the 
properties

{code}
diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding.py
index c9cc8a3..b340eda 100644
--- a/src/cmislib/browser/binding.py
+++ b/src/cmislib/browser/binding.py
@@ -1743,7 +1743,8 @@ class BrowserDocument(BrowserCmisObject):
         self.reload()
         return self.getProperties()['cmis:versionSeriesCheckedOutBy']
 
-    def checkin(self, checkinComment=None, **kwargs):
+    def checkin(self, checkinComment=None, contentFile=None, 
contentType=None,ntStream
          - policies
          - addACEs
          - removeACEs
         """
-        # TODO implement optional arguments
-        # major = true is supposed to be the default but inmemory 0.9 is 
throwing an error 500 without it
         if not kwargs.has_key('major'):
             kwargs['major'] = 'true'
+        else:
+            kwargs['major'] = 'false'
+        props = {
+            'checkinComment': checkinComment,
+        }
+        props.update(kwargs)
+        propCount = 0
+        properties = properties or {}
+        for key, value in properties.iteritems():
+            props["propertyId[%s]" % propCount] = key
+            props["propertyValue[%s]" % propCount] = value
+            propCount += 1
 
-        kwargs['checkinComment'] = checkinComment
-
-        ciUrl = self._repository.getRootFolderUrl()
+        ciUrl = self._repository.getRootFolderUrl() + "?objectId=" + self.id + 
"&cmisaction=checkin"
 
-        # TODO don't hardcode major flag
-        props = {"objectId": self.id,
-                 "cmisaction": "checkIn"}
+        contentType, body = encode_multipart_formdata(props, contentFile, 
contentType)
 
         # invoke the URL
         result = self._cmisClient.binding.post(ciUrl.encode('utf-8'),
-                                               urlencode(props),
-                                               
'application/x-www-form-urlencoded',
+                                               body,
+                                               contentType,
                                                self._cmisClient.username,
-                                               self._cmisClient.password,
-                                               **kwargs)
+                                               self._cmisClient.password)
 
         return getSpecializedObject(BrowserCmisObject(self._cmisClient, 
self._repository, data=result))
{code}
https://github.com/lmignon/python-cmislib/commit/c1ff31b82c6768148e18e766a9cbc5d62bfb5b23?diff=unified



> Implement contentStream and properties update in BrowserDocument.checkin 
> method
> -------------------------------------------------------------------------------
>
>                 Key: CMIS-972
>                 URL: https://issues.apache.org/jira/browse/CMIS-972
>             Project: Chemistry
>          Issue Type: Improvement
>          Components: python-cmislib
>         Environment: Linux, python 2.7.x, Alfresco 5.0.x
>            Reporter: Laurent Mignon
>            Assignee: Jeff Potts
>
> I've improved the checkin method to allow to update the content stream and 
> the properties
> {code}
> From cbca562e4cfce685c2cc60ee2ad0d73182d3cb5f Mon Sep 17 00:00:00 2001
> From: Laurent Mignon <laurent.mig...@acsone.eu>
> Date: Fri, 9 Sep 2016 18:53:05 +0200
> Subject: [PATCH] Support content and properties paramaters on method checkin
> ---
>  src/cmislib/atompub/binding.py | 23 ++++++++++++++++-------
>  src/cmislib/browser/binding.py | 34 ++++++++++++++++++++--------------
>  src/cmislib/domain.py          |  9 +++------
>  src/tests/cmislibtest.py       | 42 
> ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 81 insertions(+), 27 deletions(-)
> diff --git a/src/cmislib/atompub/binding.py b/src/cmislib/atompub/binding.py
> index f1a629f..2eee222 100644
> --- a/src/cmislib/atompub/binding.py
> +++ b/src/cmislib/atompub/binding.py
> @@ -2362,7 +2362,8 @@ def getCheckedOutBy(self):
>          self.reload()
>          return self.getProperties()['cmis:versionSeriesCheckedOutBy']
>  
> -    def checkin(self, checkinComment=None, **kwargs):
> +    def checkin(self, checkinComment=None, contentFile=None, 
> contentType=None,
> +                properties=None, **kwargs):
>  
>          """
>          Checks in this :class:`Document` which must be a private
> @@ -2378,10 +2379,7 @@ def checkin(self, checkinComment=None, **kwargs):
>          >>> doc.isCheckedOut()
>          False
>  
> -        The following optional arguments are supported:
> -         - major
> -         - properties
> -         - contentStream
> +        The following optional arguments are NOT supported:
>           - policies
>           - addACEs
>           - removeACEs
> @@ -2395,8 +2393,19 @@ def checkin(self, checkinComment=None, **kwargs):
>          kwargs['checkin'] = 'true'
>          kwargs['checkinComment'] = checkinComment
>  
> -        # Build an empty ATOM entry
> -        entryXmlDoc = getEmptyXmlDoc()
> +        if not properties and not contentFile:
> +            # Build an empty ATOM entry
> +            entryXmlDoc = getEmptyXmlDoc()
> +        else:
> +            # the getEntryXmlDoc function may need the object type
> +            objectTypeId = None
> +            if self.properties.has_key('cmis:objectTypeId') and not 
> properties.has_key('cmis:objectTypeId'):
> +                objectTypeId = self.properties['cmis:objectTypeId']
> +                self.logger.debug('This object type is:%s', objectTypeId)
> +
> +            # build the entry based on the properties provided
> +            entryXmlDoc = getEntryXmlDoc(
> +                self._repository, objectTypeId, properties, contentFile, 
> contentType)
>  
>          # Get the self link
>          # Do a PUT of the empty ATOM to the self link
> diff --git a/src/cmislib/browser/binding.py b/src/cmislib/browser/binding.py
> index 7d7d758..c300e5e 100644
> --- a/src/cmislib/browser/binding.py
> +++ b/src/cmislib/browser/binding.py
> @@ -1755,7 +1755,8 @@ def getCheckedOutBy(self):
>          self.reload()
>          return self.getProperties()['cmis:versionSeriesCheckedOutBy']
>  
> -    def checkin(self, checkinComment=None, **kwargs):
> +    def checkin(self, checkinComment=None, contentFile=None, 
> contentType=None,
> +                properties=None, **kwargs):
>  
>          """
>          Checks in this :class:`Document` which must be a private
> @@ -1772,9 +1773,6 @@ def checkin(self, checkinComment=None, **kwargs):
>          False
>  
>          The following optional arguments are NOT supported:
> -         - major
> -         - properties
> -         - contentStream
>           - policies
>           - addACEs
>           - removeACEs
> @@ -1784,21 +1782,29 @@ def checkin(self, checkinComment=None, **kwargs):
>          if not kwargs.has_key('major'):
>              kwargs['major'] = 'true'
>  
> -        kwargs['checkinComment'] = checkinComment
> -
> -        ciUrl = self._repository.getRootFolderUrl()
> +        else:
> +            kwargs['major'] = 'false'
> +        props = {
> +            'checkinComment': checkinComment or "",
> +        }
> +        props.update(kwargs)
> +        propCount = 0
> +        properties = properties or {}
> +        for key, value in properties.iteritems():
> +            props["propertyId[%s]" % propCount] = key
> +            props["propertyValue[%s]" % propCount] = value
> +            propCount += 1
> +
> +        ciUrl = self._repository.getRootFolderUrl() + "?objectId=" + self.id 
> + "&cmisaction=checkin"
>  
> -        # TODO don't hardcode major flag
> -        props = {"objectId": self.id,
> -                 "cmisaction": "checkIn"}
> +        contentType, body = encode_multipart_formdata(props, contentFile, 
> contentType)
>  
>          # invoke the URL
>          result = self._cmisClient.binding.post(ciUrl.encode('utf-8'),
> -                                               safe_urlencode(props),
> -                                               
> 'application/x-www-form-urlencoded',
> +                                               body,
> +                                               contentType,
>                                                 self._cmisClient.username,
> -                                               self._cmisClient.password,
> -                                               **kwargs)
> +                                               self._cmisClient.password)
>  
>          return getSpecializedObject(BrowserCmisObject(self._cmisClient, 
> self._repository, data=result))
>  
> diff --git a/src/cmislib/domain.py b/src/cmislib/domain.py
> index a2f7a25..3b4175c 100644
> --- a/src/cmislib/domain.py
> +++ b/src/cmislib/domain.py
> @@ -1240,7 +1240,8 @@ def getCheckedOutBy(self):
>  
>          pass
>  
> -    def checkin(self, checkinComment=None, **kwargs):
> +    def checkin(self, checkinComment=None, contentFile=None, 
> contentType=None,
> +                properties=None, **kwargs):
>  
>          """
>          Checks in this :class:`Document` which must be a private
> @@ -1256,15 +1257,11 @@ def checkin(self, checkinComment=None, **kwargs):
>          >>> doc.isCheckedOut()
>          False
>  
> -        The following optional arguments are supported:
> -         - major
> -         - properties
> -         - contentStream
> +        The following optional arguments are NOT supported:
>           - policies
>           - addACEs
>           - removeACEs
>          """
> -
>          pass
>  
>      def getLatestVersion(self, **kwargs):
> diff --git a/src/tests/cmislibtest.py b/src/tests/cmislibtest.py
> index a81be56..4ad13a4 100644
> --- a/src/tests/cmislibtest.py
> +++ b/src/tests/cmislibtest.py
> @@ -898,6 +898,48 @@ def testCheckinComment(self):
>              if testDoc.isCheckedOut():
>                  pwcDoc.delete()
>  
> +    def testCheckinContentAndProperties(self):
> +        """Checkin a document with a new content a modifed properties"""
> +        testFilename = settings.TEST_BINARY_1.split('/')[-1]
> +        contentFile = open(testFilename, 'rb')
> +        props = {'cmis:objectTypeId': settings.VERSIONABLE_TYPE_ID}
> +        testDoc = self._testFolder.createDocument(testFilename, 
> contentFile=contentFile, properties=props)
> +        contentFile.close()
> +        self.assertEquals(testFilename, testDoc.getName())
> +        if not 'canCheckOut' in testDoc.allowableActions.keys():
> +            print 'The test doc cannot be checked out...skipping'
> +            return
> +        pwcDoc = testDoc.checkout()
> +
> +        try:
> +            self.assertTrue(testDoc.isCheckedOut())
> +            testFile2 = settings.TEST_BINARY_2
> +            testFile2Size = os.path.getsize(testFile2)
> +            exportFile2 = testFile2.replace('.', 'export.')
> +            contentFile2 = open(testFile2, 'rb')
> +            props = {'cmis:name': 'testDocument2'}
> +            testDoc = pwcDoc.checkin(
> +                contentFile=contentFile2,
> +                properties=props)
> +            contentFile2.close()
> +            self.assertFalse(testDoc.isCheckedOut())
> +            self.assertEqual('testDocument2', testDoc.getName())
> +
> +            # expport the result
> +            result = testDoc.getContentStream()
> +            outfile = open(exportFile2, 'wb')
> +            outfile.write(result.read())
> +            result.close()
> +            outfile.close()
> +
> +            # the file we exported should be the same size as the file we
> +            # originally created
> +            self.assertEquals(testFile2Size, os.path.getsize(exportFile2))
> +
> +        finally:
> +            if testDoc.isCheckedOut():
> +                pwcDoc.delete()
> +
>      def testCheckinAfterGetPWC(self):
>          """Create a document in a test folder, check it out, call getPWC, 
> then checkin"""
>          if not self._repo.getCapabilities()['PWCUpdatable'] == True:
> {code}
> https://github.com/apache/chemistry-cmislib/pull/5



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

Reply via email to