cos_request.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """the request type in tencent qcloud cos"""
  4. from cos_params_check import ParamCheck
  5. import collections
  6. class BaseRequest(object):
  7. """BaseRequest基本类型的请求"""
  8. def __init__(self, bucket_name, cos_path):
  9. """ 类初始化
  10. :param bucket_name: bucket的名称
  11. :param cos_path: cos的绝对路径, 即从bucket下的根/开始
  12. """
  13. self._bucket_name = bucket_name.strip()
  14. self._cos_path = cos_path.strip()
  15. self._param_check = ParamCheck()
  16. def set_bucket_name(self, bucket_name=u''):
  17. """设置bucket_name
  18. :param bucket_name:
  19. :return:
  20. """
  21. self._bucket_name = bucket_name.strip()
  22. def get_bucket_name(self):
  23. """获取bucket_name
  24. :return:
  25. """
  26. return self._bucket_name
  27. def set_cos_path(self, cos_path=u''):
  28. """设置cos_path
  29. :param cos_path:
  30. :return:
  31. """
  32. self._cos_path = cos_path.strip()
  33. def get_cos_path(self):
  34. """获取cos_path
  35. :return:
  36. """
  37. return self._cos_path
  38. def get_err_tips(self):
  39. """获取错误信息
  40. :return:
  41. """
  42. return self._param_check.get_err_tips()
  43. def check_params_valid(self):
  44. """检查参数是否合法
  45. :return:
  46. """
  47. if not self._param_check.check_param_unicode('bucket', self._bucket_name):
  48. return False
  49. return self._param_check.check_param_unicode('cos_path', self._cos_path)
  50. class CreateFolderRequest(BaseRequest):
  51. """CreateFolderRequest 创建目录类型的请求"""
  52. def __init__(self, bucket_name, cos_path, biz_attr=u''):
  53. """
  54. :param bucket_name: bucket的名称
  55. :param cos_path: cos的绝对路径, 从bucket根/开始
  56. :param biz_attr: 目录的属性
  57. """
  58. super(CreateFolderRequest, self).__init__(bucket_name, cos_path)
  59. self._biz_attr = biz_attr
  60. def set_biz_attr(self, biz_attr):
  61. """设置biz_attr
  62. :param biz_attr:
  63. :return:
  64. """
  65. self._biz_attr = biz_attr
  66. def get_biz_attr(self):
  67. """ 获取biz_attr
  68. :return:
  69. """
  70. return self._biz_attr
  71. def check_params_valid(self):
  72. """检查参数是否合法
  73. :return:
  74. """
  75. if not super(CreateFolderRequest, self).check_params_valid():
  76. return False
  77. if not self._param_check.check_param_unicode('biz_attr', self._biz_attr):
  78. return False
  79. if not self._param_check.check_cos_path_valid(self._cos_path, is_file_path=False):
  80. return False
  81. return self._param_check.check_not_cos_root(self._cos_path)
  82. class UploadFileRequest(BaseRequest):
  83. """
  84. UploadFileRequest 单文件上传请求
  85. """
  86. def __init__(self, bucket_name, cos_path, local_path, biz_attr=u'', insert_only=1):
  87. """
  88. :param bucket_name: bucket的名称
  89. :param cos_path: cos的绝对路径(目的路径), 从bucket根/开始
  90. :param local_path: 上传的本地文件路径(源路径)
  91. :param biz_attr: 文件的属性
  92. :param insert_only: 是否覆盖写, 0覆盖, 1不覆盖,返回错误
  93. """
  94. super(UploadFileRequest, self).__init__(bucket_name, cos_path)
  95. self._local_path = local_path.strip()
  96. self._biz_attr = biz_attr
  97. self._insert_only = insert_only
  98. def set_local_path(self, local_path):
  99. """设置local_path
  100. :param local_path:
  101. :return:
  102. """
  103. self._local_path = local_path.strip()
  104. def get_local_path(self):
  105. """获取local_path
  106. :return:
  107. """
  108. return self._local_path
  109. def set_biz_attr(self, biz_attr):
  110. """设置biz_attr
  111. :param biz_attr:
  112. :return:
  113. """
  114. self._biz_attr = biz_attr
  115. def get_biz_attr(self):
  116. """获取biz_attr
  117. :return:
  118. """
  119. return self._biz_attr
  120. def set_insert_only(self, insert_only):
  121. """设置insert_only,0表示如果文件存在, 则覆盖
  122. :param insert_only:
  123. :return:
  124. """
  125. self._insert_only = insert_only
  126. def get_insert_only(self):
  127. """获取insert_only
  128. :return:
  129. """
  130. return self._insert_only
  131. def check_params_valid(self):
  132. """检查参数是否有效
  133. :return:
  134. """
  135. if not super(UploadFileRequest, self).check_params_valid():
  136. return False
  137. if not self._param_check.check_cos_path_valid(self._cos_path, is_file_path=True):
  138. return False
  139. if not self._param_check.check_param_unicode('biz_attr', self._biz_attr):
  140. return False
  141. if not self._param_check.check_param_unicode('local_path', self._local_path):
  142. return False
  143. if not self._param_check.check_local_file_valid(self._local_path):
  144. return False
  145. if not self._param_check.check_param_int('insert_only', self._insert_only):
  146. return False
  147. return self._param_check.check_insert_only(self._insert_only)
  148. class UploadSliceFileRequest(UploadFileRequest):
  149. """
  150. UploadSliceFileRequest 分片文件上传请求
  151. """
  152. def __init__(self, bucket_name, cos_path, local_path, slice_size=1024*1024, biz_attr=u'', enable_sha1=False, max_con=1):
  153. """
  154. :param bucket_name: bucket的名称
  155. :param cos_path: cos的绝对路径(目的路径), 从bucket根/开始
  156. :param local_path: 上传的本地文件路径(源路径)
  157. :param slice_size: 文件的属性
  158. :param biz_attr: 分片大小(字节, 默认1MB)
  159. :param enable_sha1: 是否启用sha1校验
  160. """
  161. super(UploadSliceFileRequest, self).__init__(bucket_name, cos_path, local_path, biz_attr)
  162. self._slice_size = slice_size
  163. self._enable_sha1 = enable_sha1
  164. self._max_con = max_con
  165. @property
  166. def enable_sha1(self):
  167. return self._enable_sha1
  168. @enable_sha1.setter
  169. def enable_sha1(self, val):
  170. if val in (True, False):
  171. self._enable_sha1 = val
  172. else:
  173. raise ValueError("enable_sha1 should be True/False")
  174. def set_slice_size(self, slice_size):
  175. """设置分片大小
  176. :param slice_size:
  177. :return:
  178. """
  179. self._slice_size = slice_size
  180. def get_slice_size(self):
  181. """获取分片大小
  182. :return:
  183. """
  184. return self._slice_size
  185. def check_params_valid(self):
  186. """检查参数是否有效
  187. :return:
  188. """
  189. if not super(UploadSliceFileRequest, self).check_params_valid():
  190. return False
  191. if self._enable_sha1 and self._slice_size != 1024*1024:
  192. self._param_check._err_tips = 'slice_size is invalid, slice must be 1MB with enable_sha1'
  193. return False
  194. return self._param_check.check_slice_size(self._slice_size)
  195. class UpdateFolderRequest(BaseRequest):
  196. """UpdateFolderRequest 更新目录请求"""
  197. def __init__(self, bucket_name, cos_path, biz_attr=u''):
  198. """
  199. :param bucket_name: bucket name
  200. :param cos_path: the path on cos
  201. :param biz_attr: biz attributes
  202. """
  203. super(UpdateFolderRequest, self).__init__(bucket_name, cos_path)
  204. self._biz_attr = biz_attr
  205. def set_biz_attr(self, biz_attr):
  206. """设置biz_attr
  207. :param biz_attr:
  208. :return:
  209. """
  210. self._biz_attr = biz_attr
  211. def get_biz_attr(self):
  212. """获取biz_attr
  213. :return:
  214. """
  215. return self._biz_attr
  216. def check_params_valid(self):
  217. """检查参数是否有效
  218. :return:
  219. """
  220. if not super(UpdateFolderRequest, self).check_params_valid():
  221. return False
  222. if not self._param_check.check_cos_path_valid(self._cos_path, is_file_path=False):
  223. return False
  224. if not self._param_check.check_not_cos_root(self._cos_path):
  225. return False
  226. return self._param_check.check_param_unicode('biz_attr', self._biz_attr)
  227. class UpdateFileRequest(BaseRequest):
  228. """UpdateFileRequest 更新文件请求 """
  229. def __init__(self, bucket_name, cos_path):
  230. """ 初始化类
  231. biz_attr: 要更新的文件的属性
  232. authority: 文件权限:
  233. eInvalid(继承bucket),
  234. eWRPrivate(私有读写),
  235. eWPrivateRPublic(私有写, 公有读)
  236. customer_header: 用户自定义的HTTP请求头,包括以下成员
  237. cache_control: 文件的缓存机制,参见HTTP的Cache-Control
  238. content_type: 文件的MIME信息,参见HTTP的Content-Type
  239. content_disposition: MIME协议的扩展,参见HTTP的Content-Disposition
  240. content_language: 文件的语言, 参见HTTP的Content-Language
  241. content_encoding: body的编码, 参见HTTP的Content-Encoding
  242. _x_cos_meta_dict: 用户自定义的属性, key是以x-cos-meta-开头,value为属性值
  243. :param bucket_name: bucket的名称
  244. :param cos_path: cos的绝对路径, 从bucket根/开始
  245. """
  246. super(UpdateFileRequest, self).__init__(bucket_name, cos_path)
  247. self._biz_attr = None
  248. self._custom_headers = {}
  249. self._authority = None
  250. self._cache_control = None
  251. self._content_type = None
  252. self._content_disposition = None
  253. self._content_language = None
  254. self._content_encoding = None
  255. self._x_cos_meta_dict = dict()
  256. def set_biz_attr(self, biz_attr):
  257. """设置biz_attr"""
  258. self._biz_attr = biz_attr
  259. def get_biz_attr(self):
  260. """获取biz_attr"""
  261. return self._biz_attr
  262. # 设置authority, 合法取值如下所示
  263. # eInvalid(继承bucket),
  264. # eWRPrivate(私有读写),
  265. # eWPrivateRPublic(私有写, 公有读)
  266. def set_authority(self, authority):
  267. """设置authority,
  268. 合法取值:eInvalid(继承bucket),eWRPrivate(私有读写),eWPrivateRPublic(私有写, 公有读)
  269. :param authority:
  270. :return:
  271. """
  272. self._authority = authority
  273. def get_authority(self):
  274. """获取authority"""
  275. return self._authority
  276. def set_cache_control(self, cache_control):
  277. """设置缓存机制Cache-Control"""
  278. self._cache_control = cache_control
  279. self._custom_headers[u'Cache-Control'] = cache_control
  280. def set_content_type(self, content_type):
  281. """设置Content-Type"""
  282. self._content_type = content_type
  283. self._custom_headers['Content-Type'] = content_type
  284. def set_content_disposition(self, content_disposition):
  285. """设置Content-Disposition"""
  286. self._content_disposition = content_disposition
  287. self._custom_headers['Content-Disposition'] = content_disposition
  288. def set_content_language(self, content_language):
  289. """设置Content-Language"""
  290. self._content_language = content_language
  291. self._custom_headers['Content-Language'] = content_language
  292. def set_content_encoding(self, content_encoding):
  293. """设置Content-Encoding"""
  294. self._content_encoding = content_encoding
  295. self._custom_headers['Content-Encoding'] = content_encoding
  296. def set_x_cos_meta(self, key, value):
  297. """设置自定义的x-cos-meta
  298. key以x-cos-meta-开头,例如自定义key为u'x-cos-meta-len', value为u'1024'
  299. :param key:
  300. :param value:
  301. :return:
  302. """
  303. self._x_cos_meta_dict[key] = value
  304. self._custom_headers[key] = value
  305. def _convert_dict(self, data):
  306. """convert a dict's keys & values from `unicode` to `str`
  307. :param data:
  308. :return:
  309. """
  310. if isinstance(data, basestring):
  311. return str(data)
  312. elif isinstance(data, collections.Mapping):
  313. return dict(map(self._convert_dict, data.iteritems()))
  314. elif isinstance(data, collections.Iterable):
  315. return type(data)(map(self._convert_dict, data))
  316. else:
  317. return data
  318. def get_custom_headers(self):
  319. """ 获取自定义的HTTP头"""
  320. return self._convert_dict(self._custom_headers)
  321. def check_params_valid(self):
  322. """ 检查参数是否合法"""
  323. if not super(UpdateFileRequest, self).check_params_valid():
  324. return False
  325. if not self._param_check.check_cos_path_valid(self._cos_path, is_file_path=True):
  326. return False
  327. if self._biz_attr is not None:
  328. if not self._param_check.check_param_unicode('biz_attr', self._biz_attr):
  329. return False
  330. if self._authority is not None:
  331. if not self._param_check.check_param_unicode('authority', self._authority):
  332. return False
  333. if self._authority is not None:
  334. if not self._param_check.check_file_authority(self._authority):
  335. return False
  336. if self._cache_control is not None:
  337. if not self._param_check.check_param_unicode('cache_control', self._cache_control):
  338. return False
  339. if self._content_type is not None:
  340. if not self._param_check.check_param_unicode('content_type', self._content_type):
  341. return False
  342. if self._content_disposition is not None:
  343. if not self._param_check.check_param_unicode('content_disposition', self._content_disposition):
  344. return False
  345. if self._content_language is not None:
  346. if not self._param_check.check_param_unicode('content_language', self._content_language):
  347. return False
  348. if self._content_encoding is not None:
  349. if not self._param_check.check_param_unicode('content_encoding', self._content_encoding):
  350. return False
  351. return self._param_check.check_x_cos_meta_dict(self._x_cos_meta_dict)
  352. class StatFileRequest(BaseRequest):
  353. """StatRequest 获取文件属性请求"""
  354. def __init__(self, bucket_name, cos_path):
  355. """
  356. :param bucket_name: bucket的名称
  357. :param cos_path: cos的文件路径, 从bucket根/开始, 不以/结束
  358. """
  359. super(StatFileRequest, self).__init__(bucket_name, cos_path)
  360. def check_params_valid(self):
  361. """检查参数是否合法"""
  362. if not super(StatFileRequest, self).check_params_valid():
  363. return False
  364. return self._param_check.check_cos_path_valid(self._cos_path, is_file_path=True)
  365. class StatFolderRequest(BaseRequest):
  366. """StatRequest 获取目录属性请求 """
  367. def __init__(self, bucket_name, cos_path):
  368. """
  369. :param bucket_name: bucket的名称
  370. :param cos_path: cos的目录路径, 从bucket根/开始, 以/结束
  371. """
  372. super(StatFolderRequest, self).__init__(bucket_name, cos_path)
  373. def check_params_valid(self):
  374. """检查参数是否合法"""
  375. if not super(StatFolderRequest, self).check_params_valid():
  376. return False
  377. return self._param_check.check_cos_path_valid(self._cos_path, is_file_path=False)
  378. class DelFileRequest(BaseRequest):
  379. """ DelFileRequest 删除文件请求 """
  380. def __init__(self, bucket_name, cos_path):
  381. """
  382. :param bucket_name: bucket的名称
  383. :param cos_path: cos的文件路径, 从bucket根/开始, 不以/结束
  384. """
  385. super(DelFileRequest, self).__init__(bucket_name, cos_path)
  386. def check_params_valid(self):
  387. """检查参数是否合法"""
  388. if not super(DelFileRequest, self).check_params_valid():
  389. return False
  390. return self._param_check.check_cos_path_valid(self._cos_path, is_file_path=True)
  391. class DelFolderRequest(BaseRequest):
  392. """DelFolderRequest 删除目录请求"""
  393. def __init__(self, bucket_name, cos_path):
  394. """
  395. :param bucket_name: bucket的名称
  396. :param cos_path: cos的目录路径, 从bucket根/开始, 以/结束
  397. """
  398. super(DelFolderRequest, self).__init__(bucket_name, cos_path)
  399. def check_params_valid(self):
  400. """ 检查参数合法"""
  401. if not super(DelFolderRequest, self).check_params_valid():
  402. return False
  403. if not self._param_check.check_cos_path_valid(self._cos_path, is_file_path=False):
  404. return False
  405. return self._param_check.check_not_cos_root(self._cos_path)
  406. class ListFolderRequest(BaseRequest):
  407. """ListFolderRequest 获取目录列表的请求"""
  408. def __init__(self, bucket_name, cos_path, num=199, prefix=u'', context=u''):
  409. """
  410. :param bucket_name: bucket的名称
  411. :param cos_path: cos的绝对路径, 从bucket根/开始
  412. :param num: 搜索数量
  413. :param prefix: 搜索前缀
  414. :param context: 搜索上下文
  415. """
  416. super(ListFolderRequest, self).__init__(bucket_name, cos_path)
  417. self._num = num
  418. self._prefix = prefix
  419. self._context = context
  420. def set_num(self, num):
  421. """设置List数量
  422. :param num:
  423. :return:
  424. """
  425. self._num = num
  426. def get_num(self):
  427. """获取List数量
  428. :return:
  429. """
  430. """
  431. :return:
  432. """
  433. return self._num
  434. def set_prefix(self, prefix):
  435. """设置前缀"""
  436. self._prefix = prefix
  437. def get_prefix(self):
  438. """获取前缀"""
  439. return self._prefix
  440. def set_context(self, context):
  441. """设置搜索上下文"""
  442. self._context = context
  443. def get_context(self):
  444. """获取搜索上下文"""
  445. return self._context
  446. def check_params_valid(self):
  447. """检查参数是否有效"""
  448. if not super(ListFolderRequest, self).check_params_valid():
  449. return False
  450. if not self._param_check.check_cos_path_valid(self._cos_path, is_file_path=False):
  451. return False
  452. if not self._param_check.check_param_unicode('prefix', self._prefix):
  453. return False
  454. return self._param_check.check_param_unicode('context', self._context)
  455. class DownloadFileRequest(BaseRequest):
  456. def __init__(self, bucket_name, cos_path, local_filename, range_start=None, range_end=None, *args, **kwargs):
  457. super(DownloadFileRequest, self).__init__(bucket_name, cos_path)
  458. self._local_filename = local_filename
  459. self._range_start = range_start
  460. self._range_end = range_end
  461. def check_params_valid(self):
  462. if not super(DownloadFileRequest, self).check_params_valid():
  463. return False
  464. from os import path
  465. if path.exists(self._local_filename):
  466. return False
  467. class MoveFileRequest(BaseRequest):
  468. def __init__(self, bucket_name, cos_path, dest_path, overwrite=False):
  469. super(MoveFileRequest, self).__init__(bucket_name, cos_path)
  470. self._dest_path = dest_path
  471. if isinstance(overwrite, bool):
  472. if overwrite:
  473. self._overwrite = 1
  474. else:
  475. self._overwrite = 0
  476. else:
  477. raise ValueError("overwrite must be an instance of Boolean")
  478. @property
  479. def dest_path(self):
  480. return self._dest_path
  481. @property
  482. def overwrite(self):
  483. return self._overwrite