Skip to content

Commit 741cc4a

Browse files
Merge branch 'master' into release
2 parents b457d03 + ebb8330 commit 741cc4a

File tree

332 files changed

+2689
-1201
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

332 files changed

+2689
-1201
lines changed

Examples/AcceptAllRevisionsOnline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
request_document = open(file_name, 'rb')
66
request = asposewordscloud.models.requests.AcceptAllRevisionsOnlineRequest(document=request_document)
77
accept_all_revisions_online_result = words_api.accept_all_revisions_online(request)
8-
copyfile(accept_all_revisions_online_result.document, 'test_result.docx')
8+
open('test_result.docx','wb').write(list(accept_all_revisions_online_result.document.values())[0])

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ Python Cloud SDK wraps Aspose.Words Cloud API so you could seamlessly integrate
1616
- [Convert a document to desired file format](https://docs.aspose.cloud/display/wordscloud/Convert+Document+to+Destination+Format+with+Detailed+Settings+and+Save+Result+to+Storage) along with detailed settings.
1717
- Convert an encrypted PDF document into Word document format.
1818

19+
## Enhancements in Version 22.3
20+
21+
- Online methods returns the dictionary of files with included original filename as key instead of single file content in responses.
22+
- Parameters contained sensitive data should be passed in encrypted form. Names of the parameters have 'encrypted' prefix.
23+
- Added Encrypt method to encrypt data on the API public key. Use it to prepare values for parameters required encrypted data.
24+
- GetPublicKey method is not billable.
25+
26+
1927
## Enhancements in Version 22.2
2028

2129
- Made 'SaveOprionsData.SaveFormat' property readonly with default value.

asposewordscloud/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@
169169
from asposewordscloud.models.pcl_save_options_data import PclSaveOptionsData
170170
from asposewordscloud.models.pdf_digital_signature_details_data import PdfDigitalSignatureDetailsData
171171
from asposewordscloud.models.pdf_encryption_details_data import PdfEncryptionDetailsData
172+
from asposewordscloud.models.pdf_permissions import PdfPermissions
172173
from asposewordscloud.models.pdf_save_options_data import PdfSaveOptionsData
173174
from asposewordscloud.models.png_save_options_data import PngSaveOptionsData
174175
from asposewordscloud.models.preferred_width import PreferredWidth

asposewordscloud/api_client.py

Lines changed: 67 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@
3636
import os
3737
import re
3838
import tempfile
39+
import uuid
3940

4041
# python 2 and python 3 compatibility library
4142
from urllib.parse import urlencode
4243
from six.moves.urllib.parse import quote
4344
import six
4445
from urllib3 import encode_multipart_formdata
45-
from base64 import b64encode
4646

4747
from asposewordscloud.configuration import Configuration
4848
import asposewordscloud.models
@@ -83,12 +83,12 @@ def __init__(self, configuration=None, header_name=None, header_value=None,
8383

8484
self.pool = None
8585
self.rest_client = rest.RESTClientObject(configuration)
86-
self.default_headers = {'x-aspose-client': 'python sdk', 'x-aspose-version': '22.2'}
86+
self.default_headers = {'x-aspose-client': 'python sdk', 'x-aspose-version': '22.3'}
8787
if header_name is not None:
8888
self.default_headers[header_name] = header_value
8989
self.cookie = cookie
9090
# Set default User-Agent.
91-
self.user_agent = 'python sdk 22.2'
91+
self.user_agent = 'python sdk 22.3'
9292

9393
def __del__(self):
9494
if not self.pool is None:
@@ -254,6 +254,41 @@ def sanitize_for_serialization(self, obj):
254254
return {key: self.sanitize_for_serialization(val)
255255
for key, val in six.iteritems(obj_dict)}
256256

257+
def getFilenameFromHeaders(self, headers):
258+
disposition = ""
259+
if b'Content-Disposition' in headers:
260+
disposition = headers[b'Content-Disposition']
261+
if type(disposition) != str:
262+
disposition = disposition.decode("utf-8")
263+
elif "Content-Disposition" in headers:
264+
disposition = headers["Content-Disposition"]
265+
else:
266+
return ""
267+
268+
dispparts = disposition.split(";")
269+
for dispart in dispparts:
270+
subparts = dispart.split("=")
271+
if len(subparts) == 2 and subparts[0].strip(" \"") == "filename":
272+
return subparts[1].strip(" \"")
273+
return ""
274+
275+
def findMultipartByName(self, multipart, name):
276+
for part in multipart:
277+
disposition = ""
278+
if b'Content-Disposition' in part.headers:
279+
disposition = part.headers[b'Content-Disposition']
280+
if type(disposition) != str:
281+
disposition = disposition.decode("utf-8")
282+
elif "Content-Disposition" in part.headers:
283+
disposition = part.headers["Content-Disposition"]
284+
285+
dispparts = disposition.split(";")
286+
for dispart in dispparts:
287+
subparts = dispart.split("=")
288+
if len(subparts) == 2 and subparts[0].strip(" \"") == "name" and subparts[1].strip(" \"") == name:
289+
return part
290+
return None
291+
257292
def deserialize_multipart(self, without_intermediate_results, multipart, requests):
258293
if without_intermediate_results:
259294
if len(multipart.parts) != 1:
@@ -297,6 +332,21 @@ def deserialize_multipart(self, without_intermediate_results, multipart, request
297332

298333
return results
299334

335+
def deserialize_files_collection(self, data, headers):
336+
result = {}
337+
if b'Content-Type' in headers.keys() and headers[b'Content-Type'].decode("utf-8").startswith("multipart/mixed"):
338+
parts = decoder.MultipartDecoder(data, headers[b'Content-Type'].decode("utf-8"), 'UTF-8').parts
339+
for part in parts:
340+
result[self.getFilenameFromHeaders(part.headers)] = self.deserialize_file(part.content, part.headers)
341+
elif "Content-Type" in headers.keys() and headers["Content-Type"].startswith("multipart/mixed"):
342+
parts = decoder.MultipartDecoder(data, headers["Content-Type"], 'UTF-8').parts
343+
for part in parts:
344+
result[self.getFilenameFromHeaders(part.headers)] = self.deserialize_file(part.content, part.headers)
345+
else:
346+
result[self.getFilenameFromHeaders(headers)] = self.deserialize_file(data, headers)
347+
348+
return result
349+
300350
def deserialize(self, data, headers, response_type):
301351
"""Deserializes response into an object.
302352
@@ -309,10 +359,16 @@ def deserialize(self, data, headers, response_type):
309359
# handle file downloading
310360
# save response body into a tmp file and return the instance
311361
if response_type == "file":
312-
return self.__deserialize_file(data, headers)
362+
return self.deserialize_file(data, headers)
363+
364+
if response_type == "files_collection":
365+
return self.deserialize_files_collection(data, headers)
313366

314367
if response_type == "multipart":
315-
return decoder.MultipartDecoder(data, headers['Content-Type'], 'UTF-8')
368+
if b'Content-Type' in headers:
369+
return decoder.MultipartDecoder(data, headers[b'Content-Type'], 'UTF-8')
370+
if "Content-Type" in headers:
371+
return decoder.MultipartDecoder(data, headers["Content-Type"], 'UTF-8')
316372

317373
# fetch data from response object
318374
if six.PY3:
@@ -600,30 +656,8 @@ def update_params_for_auth(self, headers, querys, auth_settings):
600656
'Authentication token must be in `query` or `header`'
601657
)
602658

603-
def __deserialize_file(self, data, headers):
604-
"""Deserializes body to file
605-
606-
Saves response body into a file in a temporary folder,
607-
using the filename from the `Content-Disposition` header if provided.
608-
609-
:param response: RESTResponse.
610-
:return: file path.
611-
"""
612-
fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)
613-
os.close(fd)
614-
os.remove(path)
615-
616-
if 'Content-Disposition' in headers.keys():
617-
content_disposition = headers["Content-Disposition"]
618-
filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?',
619-
content_disposition).group(1)
620-
filename = filename.replace('/', '_')
621-
path = os.path.join(os.path.dirname(path), filename)
622-
623-
with open(path, "wb") as f:
624-
f.write(data)
625-
626-
return path
659+
def deserialize_file(self, data, headers):
660+
return data
627661

628662
def __deserialize_primitive(self, data, klass):
629663
"""Deserializes string to primitive type.
@@ -719,12 +753,12 @@ def __deserialize_model(self, data, klass):
719753
instance = self.__deserialize(data, klass_name)
720754
return instance
721755

722-
def request_to_batch_part(self, request, rsa_key):
756+
def request_to_batch_part(self, request, encryptor):
723757
http_request = request.create_http_request(self)
724758
if http_request['form_params'] and http_request['body']:
725759
raise ValueError("body parameter cannot be used with post_params parameter.")
726760

727-
self.handle_password(http_request, rsa_key)
761+
self.handle_password(http_request, encryptor)
728762

729763
url = http_request['path'][len('/v4.0/words/'):]
730764
if http_request['query_params']:
@@ -761,10 +795,7 @@ def request_to_batch_part(self, request, rsa_key):
761795

762796
return [None, result, 'multipart']
763797

764-
def handle_password(self, http_params, rsa_key):
765-
766-
if rsa_key is None:
767-
return
798+
def handle_password(self, http_params, encryptor):
768799

769800
index = -1
770801
for i in range(len(http_params['query_params'])):
@@ -775,4 +806,4 @@ def handle_password(self, http_params, rsa_key):
775806

776807
if index > -1:
777808
k,v = http_params['query_params'].pop(index)
778-
http_params['query_params'].append(('encryptedPassword', b64encode(rsa_key.encrypt(v.encode('utf-8')))))
809+
http_params['query_params'].append(('encryptedPassword', encryptor.encrypt(v)))

0 commit comments

Comments
 (0)