photo_upload_qcloud2.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. # -*- coding=utf-8
  2. # appid 已在配置中移除,请在参数 Bucket 中带上 appid。Bucket 由 BucketName-APPID 组成
  3. # 1. 设置用户配置, 包括 secretId,secretKey 以及 Region
  4. import os
  5. import re
  6. import time
  7. import datetime
  8. import random
  9. import hashlib
  10. from qcloud_cos import CosConfig
  11. from qcloud_cos import CosS3Client
  12. from qcloud_cos import CosServiceError
  13. from qcloud_cos import CosClientError
  14. import sys
  15. import logging
  16. # 日志
  17. image_upload_log = './logs/image_log2.txt' # 图片上传日志
  18. logging.basicConfig(level=logging.INFO,
  19. # stream=sys.stdout,
  20. filename = image_upload_log)
  21. # 腾讯云文件存储,存储桶,测试环境用户配置
  22. bucket = 'zxhx-pro-1302712961' # 桶名称
  23. APPID = '1302712961'
  24. secret_id = "AKIDC9pETRbZfWBbmhoglkT4PUJGzRjmj3Ia" # "云 API 密钥 SecretId";
  25. secret_key = "C6jlX4LKfleGdmfQvGNgj74lESRpBIEJ" # "云 API 密钥 SecretKey";
  26. TIMEOUT = 30
  27. token = None # 使用临时密钥需要传入Token,默认为空,可不填
  28. # region = "sh" # 设置一个默认的存储桶地域
  29. region = "ap-beijing" # ap-beijing
  30. cos_config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token) # 获取配置对象
  31. client = CosS3Client(cos_config) # 获取客户端对象
  32. # 创建存储桶
  33. # response = client.create_bucket(
  34. # Bucket=bucket
  35. # )
  36. def upload_img_to_qcloud(param_qcloud):
  37. put_key, localfile = param_qcloud
  38. # 高级上传接口(推荐)
  39. # 根据文件大小自动选择简单上传或分块上传,分块上传具备断点续传功能。
  40. response = client.upload_file(
  41. Bucket=bucket,
  42. LocalFilePath=localfile, # 本地文件的路径
  43. Key=put_key, # 上传到桶之后的文件名
  44. # PartSize=10,
  45. PartSize=1, # 上传分成几部分
  46. MAXThread=10, # 支持最多的线程数
  47. EnableMD5=False # 是否支持MD5
  48. )
  49. # print(response['ETag'])
  50. def upload_replace_image(filename_root, sid, html):
  51. return_error = {"errcode": 1,
  52. "errmsg": "word图片上传失败。"}
  53. daytime = datetime.datetime.now().strftime('/%Y/%m/%d/')
  54. image_path = filename_root + "/files"
  55. # todo 判断试卷是否含有图片,如果有就替换上传,没有就不处理
  56. local2online_dict = {}
  57. judge_file = os.path.isdir(image_path)
  58. if judge_file: # 可以不用判断
  59. image_number = re.findall(r'<img\s*src\s*=\s*"files/image', str(html))
  60. local_images_path_list = os.listdir(image_path) # 本地图片文件名
  61. local_images_path_list = list(filter(
  62. lambda x: str(x).endswith(".png") or str(x).endswith(".gif") or str(x).endswith(".jpeg") or str(x).endswith(
  63. ".jpg"), local_images_path_list)) # 只允许特定后缀名的图片
  64. if len(image_number) != len(local_images_path_list):
  65. return return_error
  66. else:
  67. # 從大到小把圖片进行排序
  68. try:
  69. local_images_path_list.sort(key=lambda x: int(re.search(r"image(\d+)\.[pngifje]+", str(x)).group(1)))
  70. except:
  71. return return_error
  72. # logger.info("local_images_path_list==>{}".format(str(local_images_path_list)))
  73. put_key_list = [] # 线上图片地址
  74. localfile_list = [] # 本地图片地址
  75. rawpic_list = []
  76. online_image_url_list = []
  77. if local_images_path_list:
  78. try:
  79. for i, img in enumerate(local_images_path_list, start=1): # 所有的图片【image1.png,image2.png,。。。】
  80. src_pat2 = re.compile(r'<img\s*src\s*=\s*"files/image{}\.png"'.format(i))
  81. src_pat3 = re.compile(r'<img\s*src\s*=\s*"files/image{}\.gif"'.format(i))
  82. src_pat4 = re.compile(r'<img\s*src\s*=\s*"files/image{}\.jpeg"'.format(i))
  83. src_pat5 = re.compile(r'<img\s*src\s*=\s*"files/image{}\.jpg"'.format(i))
  84. if str(img).endswith("png"):
  85. pat = src_pat2
  86. # re_list.append(src_pat2)
  87. elif str(img).endswith("gif"):
  88. pat = src_pat3
  89. # re_list.append(src_pat3)
  90. elif str(img).endswith("jpeg"):
  91. pat = src_pat4
  92. # re_list.append(src_pat4)
  93. elif str(img).endswith("jpg"):
  94. pat = src_pat5
  95. # re_list.append(src_pat5)
  96. # todo 上传线上,并替换线上图片
  97. localfile = image_path + "/{}".format(img)
  98. rawfile = '<img src="files'+ "/{}".format(img)
  99. localfile_list.append(localfile)
  100. rawpic_list.append(rawfile)
  101. # todo 图片压缩
  102. # resize_img(localfile, localfile)
  103. hash_img = get_md5(img)
  104. # 上传文件在空间中的名称
  105. put_key = "teacher/uploadfiles/wording/" + str(sid) + str(daytime) + str(hash_img)
  106. put_key_list.append(put_key)
  107. # html替换为线上的地址
  108. # online_image_url = "http://" + str(public_bucket) + str(addr) + "/" + str(put_key)
  109. online_image_url = "http://" + str(bucket) + ".cos." + region + ".myqcloud.com/" + str(put_key)
  110. # html = pat.sub(r'<img src={}'.format(online_image_url), str(html))
  111. online_image_url='<img src="{}'.format(online_image_url)
  112. online_image_url_list.append(online_image_url)
  113. local2online_dict = dict(zip(rawpic_list,online_image_url_list))
  114. return local2online_dict, put_key_list, localfile_list
  115. except:
  116. return return_error
  117. else:
  118. return return_error
  119. else:
  120. return local2online_dict, [], []
  121. def upload_replace_image2(filename_root, sid, html):
  122. """
  123. 图片的本地文件名整体替换
  124. :param filename_root:
  125. :param sid:
  126. :param html:
  127. :return:
  128. """
  129. return_error = {"errcode": 1,
  130. "errmsg": "word图片上传失败。"}
  131. daytime = datetime.datetime.now().strftime('/%Y/%m/%d/')
  132. image_path = filename_root + "/files"
  133. # todo 判断试卷是否含有图片,如果有就替换上传,没有就不处理
  134. judge_file = os.path.isdir(image_path)
  135. if judge_file:
  136. image_number = re.findall(r'<img\s*src\s*=\s*"files/image', str(html))
  137. local_images_path_list = os.listdir(image_path) # 本地图片文件名
  138. local_images_path_list = list(filter(
  139. lambda x: str(x).endswith(".png") or str(x).endswith(".gif") or str(x).endswith(".jpeg") or str(x).endswith(
  140. ".jpg"), local_images_path_list))
  141. if len(image_number) != len(local_images_path_list): # file文件夹中的图片数量是否与html中一致
  142. return return_error
  143. else:
  144. # 從大到小把圖片进行排序
  145. try:
  146. local_images_path_list.sort(key=lambda x: int(re.search(r"image(\d+)\.[pngifje]+", str(x)).group(1)))
  147. except:
  148. return return_error
  149. # logger.info("local_images_path_list==>{}".format(str(local_images_path_list)))
  150. put_key_list = []
  151. localfile_list = []
  152. if local_images_path_list:
  153. try:
  154. for i, img in enumerate(local_images_path_list, start=1): # 所有的图片【image1.png,image2.png,。。。】
  155. src_pat2 = re.compile(r'<img\s*src\s*=\s*"files/image{}\.png"'.format(i))
  156. src_pat3 = re.compile(r'<img\s*src\s*=\s*"files/image{}\.gif"'.format(i))
  157. src_pat4 = re.compile(r'<img\s*src\s*=\s*"files/image{}\.jpeg"'.format(i))
  158. src_pat5 = re.compile(r'<img\s*src\s*=\s*"files/image{}\.jpg"'.format(i))
  159. if str(img).endswith("png"):
  160. pat = src_pat2
  161. # re_list.append(src_pat2)
  162. elif str(img).endswith("gif"):
  163. pat = src_pat3
  164. # re_list.append(src_pat3)
  165. elif str(img).endswith("jpeg"):
  166. pat = src_pat4
  167. # re_list.append(src_pat4)
  168. elif str(img).endswith("jpg"):
  169. pat = src_pat5
  170. # re_list.append(src_pat5)
  171. # todo 上传线上,并替换线上图片
  172. localfile = image_path + "/{}".format(img)
  173. localfile_list.append(localfile)
  174. # todo 图片压缩
  175. # resize_img(localfile, localfile)
  176. hash_img = get_md5(img)
  177. # 上传文件在空间中的名称
  178. put_key = "teacher/uploadfiles/wording/" + str(sid) + str(daytime) + str(hash_img)
  179. put_key_list.append(put_key)
  180. # html替换为线上的地址
  181. online_image_url = "http://" + str(bucket) + ".cos." + region +".myqcloud.com/" + str(put_key)
  182. html = pat.sub(r'<img src={}'.format(online_image_url), str(html))
  183. return html, put_key_list, localfile_list
  184. except:
  185. return return_error
  186. else:
  187. return return_error
  188. else:
  189. return html, [], []
  190. def get_md5(image):
  191. """
  192. 由于hash不处理unicode编码的字符串(python3默认字符串是unicode)
  193. 所以这里判断是否字符串,如果是则进行转码
  194. 初始化md5、将image_name进行加密、然后返回加密字串
  195. """
  196. image_name, image_type = str(image).split(".")
  197. image_name = str(image_name) + str(time.time()) + str(random.random())
  198. if isinstance(image_name, str):
  199. image_name = image_name.encode("utf-8")
  200. md = hashlib.md5()
  201. md.update(image_name)
  202. # a = time.time()
  203. # b = random.random()
  204. return str(md.hexdigest()) + "." + str(image_type)
  205. if __name__ == "__main__":
  206. localfile1 = r"D:\zwj\word_uploads\5820\files\image1.png"
  207. put_key2 = "teacher/uploadfiles/wording/320/2021/01/28/573c04ef54beb46f14b4aa1d0f3ghiho.png"
  208. # pic_name = "99.png"
  209. # put_key1 = "https://" + str(bucket) + ".cos." +region+ ".myqcloud.com/" + pic_name
  210. # put_key2 = "http://zxhx-pro-1302712961.cos.ap-beijing.myqcloud.com/" + pic_name
  211. response = client.upload_file(
  212. Bucket=bucket,
  213. LocalFilePath=localfile1, # 本地文件的路径
  214. Key=put_key2, # 上传到桶之后的文件名
  215. PartSize=1,
  216. MAXThread=10,
  217. EnableMD5=False
  218. )
  219. print(response)
  220. print("http://{0}.cos.{1}.myqcloud.com/{2}".format(bucket, region, put_key2))
  221. # print(response['ETag']) # 可以与Web资源关联的记号
  222. #### 字节流简单上传
  223. # response = client.put_object(
  224. # Bucket=bucket,
  225. # Body=b'bytes',
  226. # Key='picture.jpg',
  227. # EnableMD5=False
  228. # )
  229. # print(response['ETag'])