Laurent Mignon created CMIS-1002: ------------------------------------ Summary: Allow access to the repository from a CmisObject instance Key: CMIS-1002 URL: https://issues.apache.org/jira/browse/CMIS-1002 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)