import hashlib import logging import shutil import time import traceback import os from urllib import request, parse import requests from django.http import HttpResponse from django.views.generic.base import View from Model.models import Pc_Info from Object.ResponseObject import ResponseObject from Object.TokenObject import TokenObject from Service.CommonService import CommonService from Ansjer.config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN, BASE_DIR import boto3 import botocore from botocore import client from wsgiref.util import FileWrapper from zlib import crc32 class PcInfo(View): def dispatch(self, requset, *args, **kwargs): return super(PcInfo, self).dispatch(requset, *args, **kwargs) def get(self, request, *args, **kwargs): operation = kwargs.get('operation') request.encoding = 'utf-8' return self.validation(request.GET, request, operation) def post(self, request, *args, **kwargs): operation = kwargs.get('operation') request.encoding = 'utf-8' return self.validation(request.POST, request, operation) def validation(self, request_dict, request, operation): response = ResponseObject() if not operation: return response.json(444, 'operation') else: if operation == 'query': # pc端查询 return self.query(request_dict, response) elif operation == 'queryall': # 后台查询 return self.queryall(request_dict, response) elif operation == 'getnewversion': # 获取当前软件的最新版本 return self.getnewversion(request_dict, response) elif operation == 'addandupload': # 上传到服务器 return self.addandupload(request_dict, response, request) elif operation == 'download': # 服务器下载 return self.download(request_dict, response) elif operation == 'delete': return self.delete(request_dict, response) elif operation == 's3addandupload': return self.s3addandupload(request_dict, response, request) elif operation == 's3download': return self.s3download(request_dict, response) elif operation == 's3delete': return self.s3delete(request_dict, response) else: return response.json(414) def getnewversion(self, request_dict, response, ): pc_name = request_dict.get('pc_name', None) bundle_version = request_dict.get('bundle_version', None) pc_version = request_dict.get('pc_version', None) pc_test = request_dict.get('pc_test', None) param_flag = CommonService.get_param_flag( data=[pc_name, bundle_version, pc_version, pc_test]) if param_flag is not True: return response.json(444) file = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_version=pc_version, pc_test=pc_test) if not file: return response.json(173) app_list = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_test=pc_test) new_version = app_list.order_by('-add_time')[0].pc_version if pc_version == new_version: return response.json(10045) else: path = app_list.order_by('-add_time')[0].download_link print('path', path) aws_s3_guonei = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[0], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0], config=botocore.client.Config(signature_version='s3v4'), region_name='cn-northwest-1') response_url = aws_s3_guonei.generate_presigned_url( ClientMethod='get_object', Params={'Bucket': 'pc-package', 'Key': path}, ExpiresIn=3600) res = {'new_version': new_version, 'path': path, 'response_url': response_url} return response.json(0, res) def addandupload(self, request_dict, response, request): token = request_dict.get('token', None) tko = TokenObject(token) response.lang = tko.lang if tko.code != 0: return response.json(tko.code) userID = tko.userID if not userID: return response.json(104) pc_name = request_dict.get('pc_name', None) bundle_version = request_dict.get('bundle_version', None) pc_version = request_dict.get('pc_version', None) pc_test = request_dict.get('pc_test', None) lang = request_dict.get('lang', None) file_name = request.FILES.get('file_name', None) param_flag = CommonService.get_param_flag( data=[pc_name, bundle_version, pc_version, pc_test, lang, file_name]) if param_flag is not True: return response.json(444) else: file = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_version=pc_version, pc_test=pc_test) if file: return response.json(174) try: # 安装包上传到服务器本地 file_path = 'static/pc/' + pc_name if not os.path.exists(file_path): os.makedirs(os.path.join(BASE_DIR, file_path)) a = os.path.splitext(str(file_name))[-1] if not a: return response.json(444, "文件无后缀") name = pc_version + '_' + bundle_version + '_' + pc_test + str(a) file_path = file_path + '/' + str(name) upload_path = os.path.join(BASE_DIR, file_path) print('upload_path:', upload_path) with open(upload_path, 'wb+') as destination: for chunk in file_name.chunks(): destination.write(chunk) add_time = time.time() create_dict = { 'pc_name': pc_name, 'bundle_version': bundle_version, 'pc_version': pc_version, 'pc_test': pc_test, 'lang': lang, 'download_link': file_path, 'add_time': add_time, 'update_time': add_time } pc_Info = Pc_Info(**create_dict) pc_Info.save() except Exception: errorInfo = traceback.format_exc() print(errorInfo) return response.json(700, {'details': errorInfo}) else: if pc_Info.id: res = {'pc_name': pc_Info.pc_name, 'bundle_version': pc_Info.bundle_version, 'pc_version': pc_Info.pc_version, 'pc_test': pc_Info.pc_test, 'download_link': pc_Info.download_link, 'lang': pc_Info.lang, 'add_time': pc_Info.add_time, 'update_time': pc_Info.update_time } return response.json(0, res) else: return response.json(500) def query(self, request_dict, response): pc_name = request_dict.get('pc_name', None) if pc_name is None: queryset = Pc_Info.objects.all() else: queryset = Pc_Info.objects.filter(pc_name=pc_name) if queryset.exists(): count = queryset.count() res = queryset send_json = CommonService.qs_to_dict(res) send_json['count'] = count return response.json(0, send_json) else: return response.json(173) def queryall(self, request_dict, response): token = request_dict.get('token', None) tko = TokenObject(token) response.lang = tko.lang if tko.code != 0: return response.json(tko.code) userID = tko.userID if not userID: return response.json(104) page = int(request_dict.get('page', None)) line = int(request_dict.get('line', None)) if page is None or line is None: return response.json(444, 'page,line') queryset = Pc_Info.objects.all() if queryset.exists(): count = queryset.count() res = queryset[(page - 1) * line:page * line] send_json = CommonService.qs_to_dict(res) send_json['count'] = count return response.json(0, send_json) else: return response.json(173) def download(self, request_dict, response): pc_name = request_dict.get('pc_name', None) bundle_version = request_dict.get('bundle_version', None) pc_version = request_dict.get('pc_version', None) pc_test = request_dict.get('pc_test', None) param_flag = CommonService.get_param_flag( data=[pc_name, bundle_version, pc_version, pc_test]) if param_flag is not True: return response.json(444) path = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_version=pc_version, pc_test=pc_test).values('download_link') if not path: return response.json(173) filepath = path[0]['download_link'] fullPath = os.path.join(BASE_DIR, filepath) fullPath.replace('\\', '/') res = ResponseObject() print('fullPath:') print(fullPath) print(os.path.basename(fullPath)) if fullPath: if os.path.isfile(fullPath): try: wrapper = FileWrapper(open(fullPath, 'rb')) response = HttpResponse(wrapper, content_type="application/octet-stream") response['Content-Length'] = os.path.getsize(fullPath) response['Content-Disposition'] = 'attachment; filename={}'.format(parse.quote_plus(os.path.basename(fullPath), encoding="utf-8")) response['Content-MD5'] = getMD5orSHA265(fullPath) # 校验文件md5值 response['Content-SHA265'] = getMD5orSHA265(fullPath, 'SHA265') response['Content-CRC32'] = getMD5orSHA265(fullPath, 'CRC32') response['Content-Error'] = res.formal(0) return response except Exception as e: return res.json(906, repr(e)) else: return res.json(907) else: return res.json(444, 'fullPath') def delete(self, request_dict, response): token = request_dict.get('token', None) tko = TokenObject(token) response.lang = tko.lang if tko.code != 0: return response.json(tko.code) userID = tko.userID if not userID: return response.json(104) id = request_dict.get('id', None) param_flag = CommonService.get_param_flag(data=[id]) if param_flag is not True: return response.json(444) file = Pc_Info.objects.filter(id=id) if not file.exists(): return response.json(173) try: # 删除文件,文件夹和数据库里的相应数据 file_path = file[0].download_link file_path = os.path.join(BASE_DIR, file_path).replace('\\', '/') os.remove(file_path) # file_path = file_path.split("/") # file_path = [str(i) for i in file_path][:-1] # file_path = "/".join(file_path) # shutil.rmtree(file_path) file.delete() except Exception as e: return response.json(176, repr(e)) else: return response.json(0) def s3addandupload(self, request_dict, response, request): logger = logging.getLogger('info') logger.info('s3方式上传参数:') logger.info(request_dict) token = request_dict.get('token', None) tko = TokenObject(token) response.lang = tko.lang if tko.code != 0: return response.json(tko.code) userID = tko.userID if not userID: return response.json(104) pc_name = request_dict.get('pc_name', None) bundle_version = request_dict.get('bundle_version', None) pc_version = request_dict.get('pc_version', None) pc_test = request_dict.get('pc_test', None) lang = request_dict.get('lang', None) file_name = request.FILES.get('file_name', None) logger.info('文件名字:') logger.info(file_name) param_flag = CommonService.get_param_flag( data=[pc_name, bundle_version, pc_version, pc_test, lang, file_name]) if param_flag is not True: return response.json(444) else: file = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_version=pc_version, pc_test=pc_test) if file: return response.json(174) try: logger.info('开始上传') # 把安装包上传到s3 aws_s3_guonei = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[0], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0], config=botocore.client.Config(signature_version='s3v4'), region_name='cn-northwest-1' ) download_link = '{pc_name}/{pc_version}_{bundle_version}_{pc_test}_{file_s}'.format( pc_name=pc_name, pc_version=pc_version, bundle_version=bundle_version, pc_test=pc_test, file_s=str(file_name)) response_url = aws_s3_guonei.generate_presigned_url( ClientMethod='put_object', Params={ 'Bucket': 'pc-package', 'Key': download_link }, ExpiresIn=3600 ) requests.put(response_url, data=file_name) logger.info('上传完成') add_time = time.time() create_dict = { 'pc_name': pc_name, 'bundle_version': bundle_version, 'pc_version': pc_version, 'pc_test': pc_test, 'lang': lang, 'download_link': download_link, 'add_time': add_time, 'update_time': add_time } pc_Info = Pc_Info(**create_dict) pc_Info.save() except Exception: errorInfo = traceback.format_exc() print(errorInfo) return response.json(500, {'details': errorInfo}) else: if pc_Info.id: res = {'pc_name': pc_Info.pc_name, 'bundle_version': pc_Info.bundle_version, 'pc_version': pc_Info.pc_version, 'pc_test': pc_Info.pc_test, 'download_link': pc_Info.download_link, 'lang': pc_Info.lang, 'add_time': pc_Info.add_time, 'update_time': pc_Info.update_time, 'response_url': response_url } return response.json(0, res) else: return response.json(500) def s3download(self, request_dict, response): pc_name = request_dict.get('pc_name', None) bundle_version = request_dict.get('bundle_version', None) pc_version = request_dict.get('pc_version', None) pc_test = request_dict.get('pc_test', None) param_flag = CommonService.get_param_flag( data=[pc_name, bundle_version, pc_version, pc_test]) if param_flag is not True: return response.json(444) path = Pc_Info.objects.filter(pc_name=pc_name, bundle_version=bundle_version, pc_version=pc_version, pc_test=pc_test).values('download_link') if not path: return response.json(173) path = path[0]['download_link'] aws_s3_guonei = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[0], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0], config=botocore.client.Config(signature_version='s3v4'), region_name='cn-northwest-1' ) response_url = aws_s3_guonei.generate_presigned_url( ClientMethod='get_object', Params={ 'Bucket': 'pc-package', 'Key': path }, ExpiresIn=3600 ) res = {'path': path, 'response_url': response_url } return response.json(0, res) def s3delete(self, request_dict, response): token = request_dict.get('token', None) tko = TokenObject(token) response.lang = tko.lang if tko.code != 0: return response.json(tko.code) userID = tko.userID if not userID: return response.json(104) id = request_dict.get('id', None) param_flag = CommonService.get_param_flag(data=[id]) if param_flag is not True: return response.json(444) file = Pc_Info.objects.filter(id=id) if not file.exists(): return response.json(173) try: # 删除s3和数据库里的相应数据 file_path = file[0].download_link print(file_path) aws_s3_guonei = boto3.client( 's3', aws_access_key_id=AWS_ACCESS_KEY_ID[0], aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0], config=botocore.client.Config(signature_version='s3v4'), region_name='cn-northwest-1' ) aws_s3_guonei.delete_object(Bucket='pc-package', Key=file_path) file.delete() except Exception as e: return response.json(176, repr(e)) else: return response.json(0) def getMD5orSHA265(fileName, encryptionType='MD5'): """ :param filePath: :param encryptionType: :return: """ if not os.path.isfile(fileName): return '' else: if encryptionType == 'MD5': encryption = hashlib.md5() elif encryptionType == 'SHA265': encryption = hashlib.sha256() elif encryptionType == 'CRC32': f = open(fileName, 'rb') chunk = f.read() return crc32(chunk) f = open(fileName, 'rb') block_size = 8192 # why is 8192 | 8192 is fast than 2048 while True: chunk = f.read(block_size) if not chunk: break encryption.update(chunk) f.close() return encryption.hexdigest()