88import xml .dom .minidom
99import xml .etree .ElementTree
1010from urllib import quote
11+ from urllib import unquote
1112from xml2dict import Xml2Dict
1213from dicttoxml import dicttoxml
1314from cos_exception import CosClientError
1415from cos_exception import CosServiceError
1516
1617SINGLE_UPLOAD_LENGTH = 5 * 1024 * 1024 * 1024 # 单次上传文件最大为5G
18+ LOGGING_UIN = 'id="qcs::cam::uin/100001001014:uin/100001001014"'
1719# kwargs中params到http headers的映射
1820maplist = {
1921 'ContentLength' : 'Content-Length' ,
4547 'CopySourceIfNoneMatch' : 'x-cos-copy-source-If-None-Match' ,
4648 'CopySourceIfModifiedSince' : 'x-cos-copy-source-If-Modified-Since' ,
4749 'CopySourceIfUnmodifiedSince' : 'x-cos-copy-source-If-Unmodified-Since' ,
48- 'VersionId' : 'x-cos-version-id' ,
50+ 'VersionId' : 'versionId' ,
51+ 'ServerSideEncryption' : 'x-cos-server-side-encryption' ,
52+ 'SSECustomerAlgorithm' : 'x-cos-server-side-encryption-customer-algorithm' ,
53+ 'SSECustomerKey' : 'x-cos-server-side-encryption-customer-key' ,
54+ 'SSECustomerKeyMD5' : 'x-cos-server-side-encryption-customer-key-MD5' ,
55+ 'SSEKMSKeyId' : 'x-cos-server-side-encryption-cos-kms-key-id'
4956 }
5057
5158
@@ -62,6 +69,21 @@ def get_md5(data):
6269 return MD5
6370
6471
72+ def get_content_md5 (body ):
73+ body_type = type (body )
74+ if body_type == str :
75+ return get_md5 (body )
76+ elif body_type == file :
77+ if hasattr (body , 'tell' ) and hasattr (body , 'seek' ) and hasattr (body , 'read' ):
78+ file_position = body .tell () # 记录文件当前位置
79+ md5_str = get_md5 (body .read ())
80+ body .seek (file_position ) # 恢复初始的文件位置
81+ return md5_str
82+ else :
83+ raise CosClientError ('can not get md5 digest for file without necessary attrs, including tell, seek and read' )
84+ return None
85+
86+
6587def dict_to_xml (data ):
6688 """V5使用xml格式,将输入的dict转换为xml"""
6789 doc = xml .dom .minidom .Document ()
@@ -98,6 +120,8 @@ def xml_to_dict(data, origin_str="", replace_str=""):
98120 xmldict = Xml2Dict (root )
99121 xmlstr = str (xmldict )
100122 xmlstr = xmlstr .replace ("{http://www.qcloud.com/document/product/436/7751}" , "" )
123+ xmlstr = xmlstr .replace ("{https://cloud.tencent.com/document/product/436}" , "" )
124+ xmlstr = xmlstr .replace ("{http://doc.s3.amazonaws.com/2006-03-01}" , "" )
101125 xmlstr = xmlstr .replace ("{http://www.w3.org/2001/XMLSchema-instance}" , "" )
102126 if origin_str :
103127 xmlstr = xmlstr .replace (origin_str , replace_str )
@@ -193,6 +217,7 @@ def format_path(path):
193217def get_copy_source_info (CopySource ):
194218 """获取拷贝源的所有信息"""
195219 appid = ""
220+ versionid = ""
196221 if 'Appid' in CopySource .keys ():
197222 appid = CopySource ['Appid' ]
198223 if 'Bucket' in CopySource .keys ():
@@ -209,13 +234,17 @@ def get_copy_source_info(CopySource):
209234 path = CopySource ['Key' ]
210235 else :
211236 raise CosClientError ('CopySource Need Parameter Key' )
212- return bucket , path , region
237+ if 'VersionId' in CopySource .keys ():
238+ versionid = CopySource ['VersionId' ]
239+ return bucket , path , region , versionid
213240
214241
215242def gen_copy_source_url (CopySource ):
216243 """拼接拷贝源url"""
217- bucket , path , region = get_copy_source_info (CopySource )
244+ bucket , path , region , versionid = get_copy_source_info (CopySource )
218245 path = format_path (path )
246+ if versionid != '' :
247+ path = path + '?versionId=' + versionid
219248 url = "{bucket}.{region}.myqcloud.com/{path}" .format (
220249 bucket = bucket ,
221250 region = region ,
@@ -245,3 +274,27 @@ def deal_with_empty_file_stream(data):
245274 except io .UnsupportedOperation :
246275 return ""
247276 return data
277+
278+
279+ def format_dict (data , key_lst ):
280+ """转换返回dict中的可重复字段为list"""
281+ for key in key_lst :
282+ # 将dict转为list,保持一致
283+ if key in data .keys () and isinstance (data [key ], dict ):
284+ lst = []
285+ lst .append (data [key ])
286+ data [key ] = lst
287+ return data
288+
289+
290+ def decode_result (data , key_lst , multi_key_list ):
291+ """decode结果中的字段"""
292+ for key in key_lst :
293+ if key in data .keys () and data [key ]:
294+ data [key ] = unquote (data [key ])
295+ for multi_key in multi_key_list :
296+ if multi_key [0 ] in data .keys ():
297+ for item in data [multi_key [0 ]]:
298+ if multi_key [1 ] in item .keys () and item [multi_key [1 ]]:
299+ item [multi_key [1 ]] = unquote (item [multi_key [1 ]])
300+ return data
0 commit comments