upload_file.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. import os
  2. import json
  3. import time
  4. import shutil
  5. import requests
  6. import zipstream
  7. import uuid
  8. from datetime import datetime
  9. from rest_framework.views import APIView
  10. from rest_framework.response import Response
  11. from django.http import HttpResponse, JsonResponse, StreamingHttpResponse
  12. from django.views.generic.base import View
  13. from kedong.settings import MEDIA_ROOT
  14. from django.conf import settings
  15. from smartfarming.models.worm_forecast import MongoCBDphoto
  16. JsonResponse = lambda x: HttpResponse(json.dumps(x, indent=True),content_type="application/json")
  17. config = settings.CONFIG
  18. server_web = config.get("server_web")
  19. def down_image(image_name,url):
  20. content = requests.get(url).content
  21. with open("%s"%image_name,"wb") as f:
  22. f.write(content)
  23. return image_name
  24. class ZipUtilities(object):
  25. """
  26. 将文件或者文件夹打包成ZIP格式的文件,然后下载,在后台可以通过response完成下载
  27. """
  28. zip_file = None
  29. def __init__(self):
  30. self.zip_file = zipstream.ZipFile(mode='w', compression=zipstream.ZIP_DEFLATED)
  31. def to_zip(self, file, name):
  32. if os.path.isfile(file):
  33. self.zip_file.write(file, arcname=os.path.basename(file))
  34. else:
  35. self.add_folder_to_zip(file, name)
  36. def add_folder_to_zip(self, folder, name):
  37. for file in os.listdir(folder):
  38. full_path = os.path.join(folder, file)
  39. if os.path.isfile(full_path):
  40. self.zip_file.write(
  41. full_path,arcname=os.path.join(name, os.path.basename(full_path)))
  42. elif os.path.isdir(full_path):
  43. self.add_folder_to_zip(
  44. full_path,os.path.join(name, os.path.basename(full_path)))
  45. def close(self):
  46. if self.zip_file:
  47. self.zip_file.close()
  48. class FileUploadView(APIView):
  49. # 上传图片
  50. def post(self, request):
  51. path = request.data.get("model", "others")
  52. local_path = os.path.join(MEDIA_ROOT, path)
  53. os.mkdir(local_path) if not os.path.exists(local_path) else None
  54. file_obj = request.data['file']
  55. if file_obj.size > 1024 * 1024 * 200:
  56. return Response({"code": 2, "msg": "请上传小于200M文件"})
  57. try:
  58. stamp = int(datetime.now().timestamp())
  59. unique_id = uuid.uuid4()
  60. combined_id = str(stamp) + "-" + str(unique_id)
  61. file_name = combined_id + "." + ((file_obj.name).split("."))[-1]
  62. with open(f"{local_path}/{file_name}", 'wb') as f:
  63. for chunk in file_obj.chunks():
  64. f.write(chunk)
  65. return Response({"url": f'{server_web}/media/{path}/{file_name}', "code": 0, "msg": "success"})
  66. except Exception as e:
  67. return Response({"code": 2, "msg": "图片保存失败,请检查或重试"})
  68. class ImaggeDownloadView(View):
  69. """
  70. 测报灯图片下载
  71. """
  72. def post(self, request):
  73. img_id = request.POST.get("img_id")
  74. device_type = request.POST.get("device_type")
  75. if not img_id:
  76. return JsonResponse({"msg":"参数缺失","code":"10004"})
  77. img_id_list = img_id.split(",")
  78. if device_type == "5":
  79. models = MongoCBDphoto
  80. else:
  81. return JsonResponse({"msg":"参数超出范围","code":"10001"})
  82. path = config.get("img_download")
  83. os.mkdir(path) if not os.path.exists(path) else None
  84. # 先删除,然后在保存
  85. try:
  86. shutil.rmtree(path)
  87. except :
  88. pass
  89. cbd_img_query = models.objects.filter(id__in=img_id_list)
  90. if not cbd_img_query:
  91. return JsonResponse({"msg":"未找到图片","code":"10003"})
  92. for x in cbd_img_query:
  93. img_name = x.addr.split("/")[-1]
  94. if not os.path.exists(path):
  95. os.makedirs(path)
  96. now_time = str(int(time.time()))
  97. paths = path + "/" + now_time+"_"+img_name
  98. down_image(paths, server_web + x.addr)
  99. utilities = ZipUtilities()
  100. folder_name = "img"
  101. utilities.add_folder_to_zip(path, folder_name)
  102. try:
  103. response = StreamingHttpResponse(utilities.zip_file)
  104. response['Content-Type'] = 'application/octet-stream'
  105. response['Content-Disposition'] = 'attachment;filename="{0}"'.format(folder_name)
  106. except Exception as e:
  107. return JsonResponse({"msg":"下载失败","error":e,"code":"10002"})
  108. return response