#!/usr/bin/env python3 # -*- coding: utf-8 -*- import base64 import json import time 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 Model.models import UIDModel, UserUIDModel, UserModel, LogModel, MacModel 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 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) 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: result = UIDModel.objects.bulk_create(bulk) print('result is ') print(result) print() print() print('bulk is ') print(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)) 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) 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(): for uid in uid_qs: if uid.status == 2: uid.status = 1 UIDModel.objects.bulk_update(uid_qs, fields=['status']) 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.dumps(request.POST) user_qs = UserModel.objects.filter(id=token.userID) log = { 'status': 200, 'content': content, 'ip': ip, 'time': now_time, 'url': 'upload', 'operation': operation, 'user': user_qs[0] } try: LogModel.objects.create(**log) except Exception as e: 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) response = ResponseObject() # print(area) # print(quantity) token = TokenObject(token) if token.code != 0: return response.json(token.code) if not area: return response.json(444, 'area') area = int(area) if area >= 0 and quantity > 0: uid_qs = UserUIDModel.objects.filter(user__id=token.userID, uid__status=1, uid__area=area). \ values('uid__id', 'uid__uid', 'uid__mac', 'uid__uid_extra', 'uid__add_time', 'uid__update_time', 'uid__area') count = uid_qs.count() if count < quantity: return response.json(444, '设备UID不足') if uid_qs.exists(): uid_qs = uid_qs[0:quantity] if fileType == 'txt': return self.download_txt(uid_qs) elif fileType == 'excel': return self.download_excel(uid_qs) else: return response.json(444, 'fileType') else: return response.json(444, '111') else: return response.json(444, '222') def download_txt(self, uid_qs): updates = [] content = '' for item in uid_qs: # print(item) mac: str = item['uid__mac'] index = mac.rfind(':') tmp = mac[0:index] + '\t' + mac[index:] content += tmp + '\t' content += item['uid__uid'] content += '\r\n' updates.append(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=item['uid__update_time'], area=item['uid__area'] )) if len(updates) % 5000 == 0: UIDModel.objects.bulk_update(updates, fields=["status"]) updates.clear() # print(item['uid__uid']) if len(updates) > 0: UIDModel.objects.bulk_update(updates, fields=["status"]) updates.clear() del updates 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): 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 = [] for item in uid_qs: uid = item['uid'] sheet1.write(num, 0, uid) num += 1 updates.append(UIDModel( id=item['id'], uid=item['uid'], uid_extra=item['uid_extra'], status=1, add_time=item['add_time'], update_time=item['update_time'], area=item['area'] )) UIDModel.objects.bulk_update(updates, fields=["status"]) workbook.save(response) return response