#!/usr/bin/env python3 # -*- coding: utf-8 -*- import base64 import json import logging import os import time import zipfile import xlwt from django.http import StreamingHttpResponse, HttpResponse, QueryDict from django.utils.decorators import method_decorator from django.views import View from django.views.decorators.csrf import csrf_exempt from django.db import transaction from AnsjerUIDManage.config import BASE_DIR from Model.models import UIDModel, UserUIDModel, UserModel, LogModel, MacModel, OrderTaskModel, OrderUIDModel from Object.RedisObject import RedisObject from Object.TokenObject import TokenObject from Object.ResponseObject import ResponseObject from Service.CommonService import CommonService class UploadUIDFileView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(UploadUIDFileView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.GET fileName = request.FILES.get('fileName', None) return self.validate(fileName, request_dict, request) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST fileName = request.FILES.get('fileName', None) return self.validate(fileName, request_dict, request) def validate(self, fileName, request_dict, request): token = request_dict.get('token', None) area = request_dict.get('area', None) isReset = request_dict.get('isReset', 0) content = request_dict.get('fileName', None) print('content') print(content) content = base64.b64decode(content).decode().strip() content = content[3:(len(content) - 3)] uids = content.split('\n') # print(uids) # print(len(uids)) response = ResponseObject() tko = TokenObject(token) if tko.code != 0: return response.json(tko.code) # if not fileName and not area: # return response.json(444, 'fileName,area') data = {} duplicate = [] for line in uids: if len(line) < 20: continue if data.__contains__(line): duplicate.append(line) else: data[line] = '' if isReset == 0: return self.do_insert(data, duplicate, area, response, request, tko) else: return self.do_reset(data, response, area, request, tko) @transaction.atomic def do_insert(self, data, duplicate, area, response, request, token): bulk = [] count = 0 add_time = int(time.time()) update_time = int(time.time()) keys = data.keys() # 获取最新的mac mac = MacModel.objects.filter().values('id', 'value', 'is_active')[0] if not mac['is_active']: return response.json(175) # redisObject = RedisObject(db=3) key = '' tmpMac = mac['value'] savePoint = None for item in keys: key = item.strip() # value = redisObject.get_data(key) # if value is False: # # redisObject.set_data(key, '1', 600) # else: # duplicate.append(key) # continue bulk.append(UIDModel( uid=item.strip(), uid_extra='', status=0, add_time=add_time, update_time=update_time, area=area, mac=mac['value'] )) try: try: if (count % 5000) == 0: savePoint = transaction.savepoint() UIDModel.objects.bulk_create(bulk) bulk.clear() data = { 'value': mac['value'], 'is_active': tmpMac is not None } MacModel.objects.filter().update(**data) except Exception as e: # print('--------------------------error 5000') # print(repr(e)) if savePoint: transaction.rollback(savePoint) djangoLogger = logging.getLogger('django') djangoLogger.exception(repr(e)) return response.json(174, str(e)) else: savePoint = None except Exception as e: # print('--------------------------error 5001') # print(repr(e)) return response.json(174, str(e)) count += 1 tmpMac = CommonService.updateMac(mac['value']) if tmpMac is None: # 能分配的mac已用完 break else: mac['value'] = tmpMac # 当bulk不足5000时,还有数据要插入 try: try: savePoint = transaction.savepoint() # 事务保存点 if len(bulk) > 0: UIDModel.objects.bulk_create(bulk) bulk.clear() except Exception as e: # print('--------------------------error') # print(repr(e)) if savePoint: transaction.rollback(savePoint) return response.json(174) else: del data del bulk data = { 'value': mac['value'], 'is_active': tmpMac is not None } MacModel.objects.filter().update(**data) except Exception as e: # print('--------------------------error 1111') # print(repr(e)) return response.json(174) # print('重复:') # print(duplicate) operation = self.formatOperation(operation='上传', quantity=int(count), area=int(area)) print(operation) self.add_log(request, operation, token) if tmpMac is None: return response.json(175, {'last_uid': key}) return response.json(0, {'count': count, 'duplicate_count': len(duplicate), 'data': duplicate}) def do_reset(self, data, response, area, request, token): keys = data.keys() uids = [] count = 0 for key in keys: uids.append(key.strip()) if len(uids) % 5000 == 0: count += self.do_update_uid_status(uids, area) uids.clear() if len(uids) > 0: count += self.do_update_uid_status(uids, area) uids.clear() operation = self.formatOperation('重置', int(count), int(area)) self.add_log(request, operation, token) return response.json(0) def do_update_uid_status(self, uids, area): uid_qs = UIDModel.objects.filter(uid__in=uids, area=area, status=2) if uid_qs.exists(): uid_ids = [] for uid in uid_qs: if uid.status == 2: uid.status = 1 uid_ids.append(uid.id) UIDModel.objects.bulk_update(uid_qs, fields=['status']) try: OrderUIDModel.objects.filter(uid__id__in=tuple(uid_ids)).delete() except Exception as e: print(e) return uid_qs.count() return 0 def add_log(self, request, operation, token): ip = CommonService.get_ip_address(request) now_time = time.time() content = json.loads(json.dumps(request.POST)) user_qs = UserModel.objects.filter(id=token.userID) if content.__contains__('fileName'): del content['fileName'] log = { 'status': 200, 'content': json.dumps(content), 'ip': ip, 'time': now_time, 'url': 'upload', 'operation': operation, 'user': user_qs[0] } try: LogModel.objects.create(**log) except Exception as e: print('出错') print(repr(e)) def formatOperation(self, operation, quantity, area): str = '{operation}{quantity}个{area}UID' if area == 0: return str.format(operation=operation, quantity=quantity, area='国内') else: return str.format(operation=operation, quantity=quantity, area='国外') class DownloadUIDFileView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(DownloadUIDFileView, self).dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.GET return self.validate(request_dict) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' request_dict = request.POST return self.validate(request_dict) def validate(self, request_dict): token = request_dict.get('token', None) area = request_dict.get('area', None) quantity = int(request_dict.get('quantity', None)) fileType = request_dict.get('fileType', None) order_number = request_dict.get('order_number', None) board = request_dict.get('board', None) plan = request_dict.get('plan', None) checksum = request_dict.get('checksum', None) ic_model = request_dict.get('ic_model', None) order_quantity = request_dict.get('order_quantity', None) response = ResponseObject() # print(area) # print(quantity) token = TokenObject(token) if token.code != 0: return response.json(token.code) if not area or not order_number or not board or not plan or not checksum or not ic_model or not order_quantity or not fileType: return response.json(444) area = int(area) if area >= 0 and quantity > 0: # 保存订单信息 now_time = int(time.time()) order = { 'order_number': order_number, 'board': board, 'plan': plan, 'checksum': checksum, 'ic_model': ic_model, 'quantity': order_quantity, 'add_time': now_time } tmp = OrderTaskModel.objects.create(**order) print(tmp) order = OrderTaskModel.objects.filter(order_number=order_number).order_by('-add_time')[0] uid_qs = UserUIDModel.objects.filter(user__id=token.userID, uid__status=1, uid__area=area) uid_values = uid_qs.values('uid__id', 'uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__add_time', 'uid__update_time', 'uid__area') count = uid_values.count() if count < quantity: return response.json(444, '设备UID不足') if uid_values.exists(): uid_values = uid_values[0:quantity] uid_qs = uid_qs[0: quantity] if fileType == 'txt': # return self.download_txt(uid_values, uid_qs, order) # return self.download_excel(uid_values, order) return self.download_zip(uid_values, order) elif fileType == 'excel': return self.download_excel(uid_values, order) else: return response.json(444, 'fileType') else: return response.json(444, '111') else: return response.json(444, '222') def download_txt(self, uid_values, uid_qs, order): updates = [] updates_uid = [] content = '' now_time = int(time.time()) for i in range(len(uid_values)): # print(item) item = uid_values[i] mac: str = item['uid__mac'] index = mac.rfind(':') tmp = mac[0:index] + '\t' + mac[index:] content += tmp + '\t' content += item['uid__uid'].strip() content += '\r\n' uidModel = UIDModel( id=item['uid__id'], uid=item['uid__uid'], mac=item['uid__mac'], uid_extra=item['uid__uid_extra'], status=2, add_time=item['uid__add_time'], update_time=now_time, area=item['uid__area'] ) updates.append(uidModel) order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time) updates_uid.append(order_uid) if len(updates) % 5000 == 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() # print(item['uid__uid']) if len(updates) > 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() del updates del updates_uid content = content[0:len(content) - 1] response = StreamingHttpResponse(content) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename=UID'+time.strftime('-%Y-%m-%d-%H-%M-%S', time.localtime()) + '.txt' return response def download_excel(self, uid_qs, order): response = HttpResponse(content_type='application/vnd.ms-excel') response['Content-Disposition'] = 'attachment; filename=UID' + time.strftime('-%Y-%m-%d-%H-%M-%S', time.localtime()) + '.xls' workbook = xlwt.Workbook(encoding='utf-8') sheet1 = workbook.add_sheet('UID') # row1 = [u'设备UID'] # for i in range(0, len(row1)): # sheet1.write(0, i, row1[i]) num = 1 updates = [] updates_uid = [] now_time = int(time.time()) for item in uid_qs: uid = item['uid__uid'] mac = item['uid__mac'] index = mac.rfind(':') sheet1.write(num, 0, mac[0:index]) sheet1.write(num, 1, mac[index:]) sheet1.write(num, 2, uid) num += 1 uidModel = UIDModel( id=item['uid__id'], uid=item['uid__uid'], mac=item['uid__mac'], uid_extra=item['uid__uid_extra'], status=2, add_time=item['uid__add_time'], update_time=now_time, area=item['uid__area'] ) updates.append(uidModel) order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time) updates_uid.append(order_uid) if len(updates) % 5000 == 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() # print(item['uid__uid']) if len(updates) > 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() UIDModel.objects.bulk_update(updates, fields=["status"]) workbook.save(response) return response def download_zip(self, uid_qs, order): dir_name = 'static/' + time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime()) path = '/'.join((BASE_DIR, dir_name)).replace('\\', '/') + '/' if not os.path.exists(path): os.mkdir(path) filename = time.strftime('_%Y_%m_%d_%H_%M_%S', time.localtime()) txt_filename = 'UID' + filename + '.txt' excel_filename = 'UID' + filename + '.xls' txt_file = open(path + txt_filename, 'w+') workbook = xlwt.Workbook(encoding='utf-8') sheet1 = workbook.add_sheet('UID') num = 1 updates = [] updates_uid = [] content = '' now_time = int(time.time()) for i in range(len(uid_qs)): # print(item) item = uid_qs[i] uid = item['uid__uid'] mac = item['uid__mac'] index = mac.rfind(':') tmp = mac[0:index] + '\t' + mac[index:] content += tmp + '\t' content += item['uid__uid'].strip() content += '\r\n' sheet1.write(num, 0, mac[0:index]) sheet1.write(num, 1, mac[index:]) sheet1.write(num, 2, uid) num += 1 uidModel = UIDModel( id=item['uid__id'], uid=item['uid__uid'], mac=item['uid__mac'], uid_extra=item['uid__uid_extra'], status=2, add_time=item['uid__add_time'], update_time=now_time, area=item['uid__area'] ) updates.append(uidModel) order_uid = OrderUIDModel(uid=uidModel, order=order, add_time=now_time, update_time=now_time) updates_uid.append(order_uid) if len(updates) % 5000 == 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() # print(item['uid__uid']) if len(updates) > 0: UIDModel.objects.bulk_update(updates, fields=["status"]) OrderUIDModel.objects.bulk_create(updates_uid) updates.clear() updates_uid.clear() del updates del updates_uid content = content[0:len(content) - 1] txt_file.write(content) txt_file.close() workbook.save(path + excel_filename) zip_name = path[0:path.rfind('/')] + '.zip' return self.get_zip(path, os.listdir(path), zip_name) def get_zip(self, path, files, zip_name): zp = zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) for file in files: zp.write(filename=(path + file), arcname=str(file)) zp.close() response = StreamingHttpResponse(open(zip_name, 'rb')) response['content_type'] = "application/octet-stream" response['Content-Disposition'] = 'attachment; filename=UID' + time.strftime('_%Y_%m_%d_%H_%M_%S', time.localtime()) + '.zip' return response