import os import json import time import shutil import requests import zipstream import uuid from datetime import datetime from rest_framework.views import APIView from rest_framework.response import Response from django.http import HttpResponse, JsonResponse, StreamingHttpResponse from django.views.generic.base import View from kedong.settings import MEDIA_ROOT from django.conf import settings from smartfarming.models.worm_forecast import MongoCBDphoto JsonResponse = lambda x: HttpResponse(json.dumps(x, indent=True),content_type="application/json") config = settings.CONFIG server_web = config.get("server_web") def down_image(image_name,url): content = requests.get(url).content with open("%s"%image_name,"wb") as f: f.write(content) return image_name class ZipUtilities(object): """ 将文件或者文件夹打包成ZIP格式的文件,然后下载,在后台可以通过response完成下载 """ zip_file = None def __init__(self): self.zip_file = zipstream.ZipFile(mode='w', compression=zipstream.ZIP_DEFLATED) def to_zip(self, file, name): if os.path.isfile(file): self.zip_file.write(file, arcname=os.path.basename(file)) else: self.add_folder_to_zip(file, name) def add_folder_to_zip(self, folder, name): for file in os.listdir(folder): full_path = os.path.join(folder, file) if os.path.isfile(full_path): self.zip_file.write( full_path,arcname=os.path.join(name, os.path.basename(full_path))) elif os.path.isdir(full_path): self.add_folder_to_zip( full_path,os.path.join(name, os.path.basename(full_path))) def close(self): if self.zip_file: self.zip_file.close() class FileUploadView(APIView): # 上传图片 def post(self, request): path = request.data.get("model", "others") local_path = os.path.join(MEDIA_ROOT, path) os.mkdir(local_path) if not os.path.exists(local_path) else None file_obj = request.data['file'] if file_obj.size > 1024 * 1024 * 200: return Response({"code": 2, "msg": "请上传小于200M文件"}) try: stamp = int(datetime.now().timestamp()) unique_id = uuid.uuid4() combined_id = str(stamp) + "-" + str(unique_id) file_name = combined_id + "." + ((file_obj.name).split("."))[-1] with open(f"{local_path}/{file_name}", 'wb') as f: for chunk in file_obj.chunks(): f.write(chunk) return Response({"url": f'{server_web}/media/{path}/{file_name}', "code": 0, "msg": "success"}) except Exception as e: return Response({"code": 2, "msg": "图片保存失败,请检查或重试"}) class ImaggeDownloadView(View): """ 测报灯图片下载 """ def post(self, request): img_id = request.POST.get("img_id") device_type = request.POST.get("device_type") if not img_id: return JsonResponse({"msg":"参数缺失","code":"10004"}) img_id_list = img_id.split(",") if device_type == "5": models = MongoCBDphoto else: return JsonResponse({"msg":"参数超出范围","code":"10001"}) path = config.get("img_download") os.mkdir(path) if not os.path.exists(path) else None # 先删除,然后在保存 try: shutil.rmtree(path) except : pass cbd_img_query = models.objects.filter(id__in=img_id_list) if not cbd_img_query: return JsonResponse({"msg":"未找到图片","code":"10003"}) for x in cbd_img_query: img_name = x.addr.split("/")[-1] if not os.path.exists(path): os.makedirs(path) now_time = str(int(time.time())) paths = path + "/" + now_time+"_"+img_name down_image(paths, server_web + x.addr) utilities = ZipUtilities() folder_name = "img" utilities.add_folder_to_zip(path, folder_name) try: response = StreamingHttpResponse(utilities.zip_file) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename="{0}"'.format(folder_name) except Exception as e: return JsonResponse({"msg":"下载失败","error":e,"code":"10002"}) return response