123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- import base64
- import json
- import logging
- import os
- import threading
- import time
- import boto3
- from django.views.generic.base import View
- from AnsjerPush.config import BASE_DIR
- from Model.models import UidPushModel, AiService, Device_Info
- from Object.ETkObject import ETkObject
- from Object.AiImageObject import ImageProcessingObject
- from Object.ResponseObject import ResponseObject
- from Object.utils import LocalDateTimeUtil
- from Service.CommonService import CommonService
- from Service.EquipmentInfoService import EquipmentInfoService
- from Service.PushService import PushObject
- class AiView(View):
- def get(self, request, *args, **kwargs):
- request.encoding = 'utf-8'
- operation = kwargs.get('operation')
- return self.validation(request.GET, operation)
- def post(self, request, *args, **kwargs):
- request.encoding = 'utf-8'
- operation = kwargs.get('operation')
- return self.validation(request.POST, operation)
- def validation(self, request_dict, operation):
- response = ResponseObject()
- if operation == 'identification': # ai识别推送
- return self.identification(request_dict, response)
- else:
- return response.json(414)
- def identification(self, request_dict, response):
- """
- ai识别推送
- @param request_dict: 请求数据
- @request_dict etk: uid token
- @request_dict n_time: 设备的当前时间
- @request_dict channel: 通道
- @request_dict fileOne: 图片一
- @request_dict fileTwo: 图片二
- @request_dict fileThree: 图片三
- @param response: 响应
- @return: response
- """
- etk = request_dict.get('etk', None)
- n_time = request_dict.get('n_time', None)
- channel = request_dict.get('channel', '1')
- file_one = request_dict.get('fileOne', None)
- file_two = request_dict.get('fileTwo', None)
- file_three = request_dict.get('fileThree', None)
- if not all([etk, n_time]):
- return response.json(444)
- # 解密etk并判断uid长度
- eto = ETkObject(etk)
- uid = eto.uid
- logger = logging.getLogger('info')
- logger.info('---进入ai识别推送接口--- etk:{}, uid:{}'.format(etk, uid))
- receive_time = int(time.time())
- file_list = [file_one, file_two, file_three]
- # 查询设备是否有使用中的ai服务
- ai_service_qs = AiService.objects.filter(uid=uid, detect_status=1, use_status=1, endTime__gt=receive_time). \
- values('detect_group')
- if not ai_service_qs.exists():
- return response.json(173)
- # 查询推送相关数据
- uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid). \
- values('push_type', 'appBundleId', 'token_val', 'm_code', 'lang', 'tz', 'userID_id')
- if not uid_push_qs.exists():
- return response.json(173)
- # 查询设备数据
- device_info_qs = Device_Info.objects.filter(UID=uid).first()
- nickname = uid if device_info_qs is None else device_info_qs.NickName
- now_time = int(time.time())
- detect_group = ai_service_qs[0]['detect_group']
- try:
- dir_path = os.path.join(BASE_DIR, 'static/ai/' + uid + '/' + str(n_time))
- if not os.path.exists(dir_path):
- os.makedirs(dir_path)
- file_path_list = []
- for i, val in enumerate(file_list):
- val = val.replace(' ', '+')
- val = base64.b64decode(val)
- file_path = "{dir_path}/{n_time}_{i}.jpg".format(dir_path=dir_path, n_time=n_time, i=i)
- file_path_list.append(file_path)
- with open(file_path, 'wb') as f:
- f.write(val)
- f.close()
- image_size = 0 # 每张小图片的大小,等于0是按原图大小进行合并
- image_row = 1 # 合并成一张图后,一行有几个小图
- image_processing_obj = ImageProcessingObject(dir_path, image_size, image_row)
- image_processing_obj.merge_images()
- photo = open(dir_path + '.jpg', 'rb') # 打开合成图
- # 识别合成图片
- maxLabels = 50 # 最大标签
- minConfidence = 80 # 置信度
- client = boto3.client(
- 'rekognition',
- aws_access_key_id='AKIA2E67UIMD6JD6TN3J',
- aws_secret_access_key='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',
- region_name='us-east-1')
- # doc: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rekognition.html#Rekognition.Client.detect_labels
- rekognition_res = client.detect_labels(
- Image={'Bytes': photo.read()},
- MaxLabels=maxLabels,
- MinConfidence=minConfidence)
- photo.close()
- if rekognition_res['ResponseMetadata']['HTTPStatusCode'] != 200:
- return response.json(5)
- label_dict = image_processing_obj.handle_rekognition_res(detect_group, rekognition_res)
- if not label_dict['label_list']:
- # 需要删除图片
- # photo.close()
- # self.del_path(os.path.join(BASE_DIR, 'static/ai/' + uid))
- return response.json(0)
- event_type = label_dict['event_type']
- label_str = ','.join(label_dict['label_list'])
- new_bounding_box_dict = label_dict['new_bounding_box_dict']
- # 上传缩略图到s3
- file_dict = {}
- for i, val in enumerate(file_path_list):
- # 封面图
- file_dict[val] = '{}/{}/{}_{}.jpeg'.format(uid, channel, n_time, i)
- upload_images_thread = threading.Thread(target=CommonService.upload_images, args=(file_dict, dir_path))
- upload_images_thread.start()
- # 存储消息以及推送
- uid_push_list = [uid_push for uid_push in uid_push_qs]
- eq_list = []
- user_id_list = []
- local_date_time = ''
- for up in uid_push_list:
- # 保存推送数据
- tz = up['tz']
- if tz is None or tz == '':
- tz = 0
- local_date_time = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang='cn')[:10]
- user_id = up['userID_id']
- if user_id not in user_id_list:
- eq_list.append(EquipmentInfoService.get_equipment_info_obj(
- local_date_time,
- device_user_id=user_id,
- event_time=n_time,
- event_type=event_type,
- device_uid=uid,
- device_nick_name=nickname,
- channel=channel,
- alarm='检查到{} \tChannel:{}'.format(label_str, channel),
- is_st=3,
- receive_time=receive_time,
- add_time=now_time,
- storage_location=2,
- border_coords=json.dumps(new_bounding_box_dict)
- ))
- user_id_list.append(user_id)
- # 推送
- push_type = up['push_type']
- appBundleId = up['appBundleId']
- token_val = up['token_val']
- lang = up['lang']
- # 推送标题和推送内容
- msg_title = PushObject.get_msg_title(app_bundle_id=appBundleId, nickname=nickname)
- msg_text = PushObject.get_ai_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz, label=label_str)
- kwargs = {
- 'nickname': nickname,
- 'app_bundle_id': appBundleId,
- 'token_val': token_val,
- 'n_time': n_time,
- 'event_type': event_type,
- 'msg_title': msg_title,
- 'msg_text': msg_text,
- 'uid': uid,
- 'channel': channel,
- }
- try:
- # 推送消息
- if push_type == 0: # ios apns
- PushObject.ios_apns_push(**kwargs)
- elif push_type == 1: # android gcm
- PushObject.android_fcm_push(**kwargs)
- elif push_type == 2: # android jpush
- PushObject.android_jpush(**kwargs)
- except Exception as e:
- logger.info('ai推送消息异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
- continue
- week = LocalDateTimeUtil.date_to_week(local_date_time)
- EquipmentInfoService.equipment_info_bulk_create(week, eq_list)
- return response.json(0)
- except Exception as e:
- logger.info('---ai识别推送异常---:{}'.format(repr(e)))
- data = {
- 'errLine': e.__traceback__.tb_lineno,
- 'errMsg': repr(e)
- }
- return response.json(48, data)
|