aliyun.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on 2021/3/18 12:39 上午
  4. ---------
  5. @summary: 阿里云附件上传
  6. ---------
  7. @author: Boris
  8. @email: boris_liu@foxmail.com
  9. """
  10. import hashlib
  11. import os
  12. import traceback
  13. import oss2
  14. import requests
  15. from feapder import setting
  16. import time
  17. class UploadOSS:
  18. """阿里云 oss"""
  19. def __init__(self):
  20. oss_conf = setting.oss_
  21. self.file_path: str = ""
  22. self.file_stream: bytes = b''
  23. self.__acc_key_id = oss_conf['key_id']
  24. self.__acc_key_secret = oss_conf['key_secret']
  25. self.__endpoint = oss_conf['endpoint']
  26. self.__bucket_name = oss_conf['bucket_name']
  27. @property
  28. def fid(self):
  29. """
  30. 文本摘要值
  31. @return: 十六进制摘要值
  32. """
  33. sha1 = hashlib.sha1()
  34. sha1.update(str(self.file_stream).encode("utf-8"))
  35. return sha1.hexdigest()
  36. @property
  37. def file_size(self):
  38. """
  39. 文件的大小,将字节(bytes)转化(kb/M/G单位)
  40. @return: 文件大小
  41. """
  42. try:
  43. size = os.path.getsize(self.file_path)
  44. except Exception:
  45. traceback.print_exc()
  46. else:
  47. try:
  48. _kb = float(size) / 1024
  49. except:
  50. return "Error"
  51. else:
  52. if _kb >= 1024:
  53. _M = _kb / 1024
  54. if _M >= 1024:
  55. _G = _M / 1024
  56. return "{:.1f} G".format(_G)
  57. else:
  58. return "{:.1f} M".format(_M)
  59. else:
  60. return "{:.1f} kb".format(_kb)
  61. def get_state(self, attachment,count=0, **kwargs):
  62. """
  63. 下载附件并上传阿里oss
  64. @param attachment: 附件
  65. @return: 附件处理结果
  66. """
  67. request_params = {
  68. 'headers': setting.headers,
  69. 'timeout': 20,
  70. 'stream': True,
  71. **kwargs
  72. }
  73. with requests.get(attachment["org_url"], **request_params) as req:
  74. if req.status_code == 200:
  75. self.file_stream = req.content
  76. # img_dir = "file"
  77. img_dir = f"file/{attachment['channel']}"
  78. # 文件夹不存在则创建文件夹
  79. if not os.path.exists(img_dir):
  80. os.makedirs(img_dir, mode=0o777, exist_ok=True)
  81. # 打开目录,放入下载的附件
  82. filname = hashlib.md5(attachment["filename"].encode("utf-8"))
  83. filname = filname.hexdigest() #加密1次
  84. types = attachment["ftype"]
  85. self.file_path = "{}/{}".format(img_dir, filname+'.'+types)
  86. with open(self.file_path, 'wb') as f:
  87. f.write(self.file_stream)
  88. # 上传附件
  89. self.put_oss_from_local()
  90. file_state = self.file_state(attachment)
  91. # 删除附件
  92. os.remove(self.file_path)
  93. # 返回附件上传处理信息
  94. return file_state
  95. else:
  96. if count<3:
  97. self.post_state(attachment,count=count+1, **kwargs)
  98. else:
  99. # attachment["ftype"] = str(attachment["filename"]).split(".")[1]
  100. attachment["url"] = 'oss'
  101. attachment["fid"] = self.fid + "." + attachment["ftype"]
  102. attachment["size"] = '0kb'
  103. attachment["false"] = True
  104. return attachment
  105. def post_state(self, attachment,count=0, **kwargs):
  106. """
  107. 下载附件并上传阿里oss
  108. @param attachment: 附件
  109. @return: 附件处理结果
  110. """
  111. request_params = {
  112. 'headers': setting.headers,
  113. 'timeout': 20,
  114. 'stream': True,
  115. **kwargs
  116. }
  117. with requests.post(attachment["org_url"], **request_params) as req:
  118. if req.status_code == 200:
  119. self.file_stream = req.content
  120. img_dir = f"file/{attachment['channel']}"
  121. # 文件夹不存在则创建文件夹
  122. if not os.path.exists(img_dir):
  123. os.makedirs(img_dir, mode=0o777, exist_ok=True)
  124. # 打开目录,放入下载的附件
  125. filname = hashlib.md5(attachment["filename"].encode("utf-8"))
  126. filname = filname.hexdigest() # 加密1次
  127. types = attachment["ftype"]
  128. self.file_path = "{}/{}".format(img_dir, filname + '.' + types)
  129. with open(self.file_path, 'wb') as f:
  130. f.write(self.file_stream)
  131. # 上传附件
  132. self.put_oss_from_local()
  133. file_state = self.file_state(attachment)
  134. # 删除附件
  135. # os.remove(self.file_path)
  136. # 返回附件上传处理信息
  137. return file_state
  138. else:
  139. if count<3:
  140. self.post_state(attachment,count=count+1, **kwargs)
  141. else:
  142. attachment["url"] = 'oss'
  143. attachment["fid"] = self.fid + "." + attachment["ftype"]
  144. attachment["size"] = '0kb'
  145. attachment["false"] = True
  146. return attachment
  147. def put_oss_from_local(self):
  148. """上传一个本地文件到阿里OSS的普通文件"""
  149. auth = oss2.Auth(self.__acc_key_id, self.__acc_key_secret)
  150. bucket = oss2.Bucket(auth, self.__endpoint, self.__bucket_name)
  151. bucket.put_object_from_file(self.fid, self.file_path)
  152. def file_state(self, attachment):
  153. """
  154. 文件信息
  155. @param attachment: 附件
  156. @return: 附件上传处理信息
  157. """
  158. # attachment["ftype"] = str(attachment["filename"]).split(".")[1]
  159. attachment["url"] = 'oss'
  160. attachment["fid"] = self.fid + "." + attachment["ftype"]
  161. attachment["size"] = self.file_size
  162. return attachment