소스 검색

优化AI推送代码-封装图片加工类函数,推送函数

locky 2 년 전
부모
커밋
6230b4a02c

+ 51 - 282
Controller/AiController.py

@@ -5,23 +5,18 @@ import os
 import threading
 import time
 
-import apns2
 import boto3
-import jpush
-from boto3.session import Session
 from django.views.generic.base import View
-from pyfcm import FCMNotification
 
-from AnsjerPush.Config.aiConfig import LABEL_DICT, AI_IDENTIFICATION_TAGS_DICT
-from AnsjerPush.config import APNS_MODE, APNS_CONFIG, BASE_DIR, \
-    JPUSH_CONFIG, FCM_CONFIG, ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, PUSH_BUCKET
-from Model.models import UidPushModel, AiService
+from AnsjerPush.config import BASE_DIR
+from Model.models import UidPushModel, AiService, Device_Info
 from Object.ETkObject import ETkObject
-from Object.MergePic import ImageProcessing
+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):
@@ -81,6 +76,17 @@ class AiView(View):
         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:
@@ -100,8 +106,8 @@ class AiView(View):
 
             image_size = 0  # 每张小图片的大小,等于0是按原图大小进行合并
             image_row = 1  # 合并成一张图后,一行有几个小图
-            ImageProcessingObj = ImageProcessing(dir_path, image_size, image_row)
-            image_info_dict = ImageProcessing.merge_images(ImageProcessingObj)
+            image_processing_obj = ImageProcessingObject(dir_path, image_size, image_row)
+            image_processing_obj.merge_images()
             photo = open(dir_path + '.jpg', 'rb')  # 打开合成图
 
             # 识别合成图片
@@ -122,7 +128,7 @@ class AiView(View):
             if rekognition_res['ResponseMetadata']['HTTPStatusCode'] != 200:
                 return response.json(5)
 
-            label_dict = self.handle_rekognition_res(detect_group, rekognition_res, image_info_dict)
+            label_dict = image_processing_obj.handle_rekognition_res(detect_group, rekognition_res)
             if not label_dict['label_list']:
                 # 需要删除图片
                 # photo.close()
@@ -138,317 +144,80 @@ class AiView(View):
             for i, val in enumerate(file_path_list):
                 # 封面图
                 file_dict[val] = '{}/{}/{}_{}.jpeg'.format(uid, channel, n_time, i)
-            upload_images_thread = threading.Thread(target=self.upload_images, args=(file_dict, dir_path))
+            upload_images_thread = threading.Thread(target=CommonService.upload_images, args=(file_dict, dir_path))
             upload_images_thread.start()
 
             # 存储消息以及推送
-            is_st = 3  # 多图
-            # 查询推送数据
-            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid). \
-                values('token_val', 'app_type', 'appBundleId', 'm_code', 'push_type', 'userID_id',
-                       'userID__NickName',
-                       'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval',
-                       'uid_set__detect_group',
-                       'uid_set__channel')
-            if not uid_push_qs.exists():
-                return response.json(173)
-            uid_push_list = []
-            for qs in uid_push_qs:
-                uid_push_list.append(qs)
-
-            nickname = uid_push_list[0]['uid_set__nickname']
-            if not nickname:
-                nickname = uid
+            uid_push_list = [uid_push for uid_push in uid_push_qs]
 
             eq_list = []
-            userID_ids = []
+            user_id_list = []
             local_date_time = ''
             for up in uid_push_list:
-                push_type = up['push_type']
-                appBundleId = up['appBundleId']
-                token_val = up['token_val']
-                lang = up['lang']
+                # 保存推送数据
                 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')
-                logger.info('----AI消息存库{},{},{}'.format(uid, local_date_time, tz))
-                local_date_time = local_date_time[0:10]
-                # 以下是存库
-                userID_id = up["userID_id"]
-                if userID_id not in userID_ids:
-                    now_time = int(time.time())
+                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=userID_id,
+                        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=is_st,
+                        is_st=3,
                         receive_time=receive_time,
                         add_time=now_time,
                         storage_location=2,
                         border_coords=json.dumps(new_bounding_box_dict)
                     ))
-                    userID_ids.append(userID_id)
+                    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)
 
-                # 推送标题
-                msg_title = self.get_msg_title(appBundleId=appBundleId, nickname=nickname)
-                # 推送内容
-                msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz, label_list=label_str)
                 kwargs = {
-                    'uid': uid,
-                    'channel': channel,
-                    'event_type': event_type,
-                    'n_time': n_time,
-                    'appBundleId': appBundleId,
+                    '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
-                        self.do_apns(**kwargs)
+                        PushObject.ios_apns_push(**kwargs)
                     elif push_type == 1:  # android gcm
-                        self.do_fcm(**kwargs)
+                        PushObject.android_fcm_push(**kwargs)
                     elif push_type == 2:  # android jpush
-                        self.do_jpush(**kwargs)
+                        PushObject.android_jpush(**kwargs)
                 except Exception as e:
-                    logger.info(
-                        "errLine={errLine}, errMsg={errMsg}".format(errLine=e.__traceback__.tb_lineno, errMsg=repr(e)))
+                    logger.info('ai推送消息异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                     continue
-            # 分表批量存储
-            if eq_list and len(eq_list) > 0:
-                logger.info("AI存库中........")
-                week = LocalDateTimeUtil.date_to_week(local_date_time)
-                result = EquipmentInfoService.equipment_info_bulk_create(week, eq_list)
-                logger.info("-.-存库结果{}".format(result))
+
+            week = LocalDateTimeUtil.date_to_week(local_date_time)
+            EquipmentInfoService.equipment_info_bulk_create(week, eq_list)
             return response.json(0)
 
         except Exception as e:
-            print(e)
+            logger.info('---ai识别推送异常---:{}'.format(repr(e)))
             data = {
                 'errLine': e.__traceback__.tb_lineno,
                 'errMsg': repr(e)
             }
             return response.json(48, data)
-
-    @staticmethod
-    def handle_rekognition_res(detect_group, rekognition_res, image_info_dict):
-        """
-        处理识别结果,匹配检测类型,并且返回标签坐标位置信息
-        @param detect_group: 检测类型
-        @param rekognition_res: 识别响应
-        @param image_info_dict: 合成的图片信息
-        @return: label_dict
-        """
-        logger = logging.getLogger('info')
-        labels = rekognition_res['Labels']
-        logger.info('--------识别到的标签-------:{}'.format(labels))
-
-        label_name = []
-        label_list = []
-
-        # 找出识别的所有标签
-        for label in labels:
-            label_name.append(label['Name'])
-            for Parents in label['Parents']:
-                label_name.append(Parents['Name'])
-
-        logger.info('------标签名------:{}'.format(label_name))
-
-        # 删除用户没有选择的ai识别类型, 并且得出最终识别结果
-        user_detect_list = detect_group.split(',')
-        user_detect_list = [i.strip() for i in user_detect_list]
-        conform_label_list = []
-        conform_detect_group = set()
-        for key, label_type_val in LABEL_DICT.items():
-            if key in user_detect_list:
-                for label in label_type_val:
-                    if label in label_name:
-                        conform_detect_group.add(key)
-                        conform_label_list.append(label)
-
-        # 找出标签边框线位置信息
-        bounding_box_list = []
-        for label in labels:
-            if label['Name'] in conform_label_list:
-                for label_instance in label['Instances']:
-                    bounding_box_list.append(label_instance['BoundingBox'])
-
-        # 找出边框位置信息对应的单图位置并重新计算位置比
-        merge_image_height = image_info_dict['height']
-        single_height = merge_image_height // image_info_dict['num']
-        new_bounding_box_dict = {
-            'file_0': [],
-            'file_1': [],
-            'file_2': []
-        }
-
-        for k, val in enumerate(bounding_box_list):
-            bounding_box_top = merge_image_height * val['Top']
-            # 找出当前边框属于哪张图片范围
-            box_dict = {}
-            for i in range(image_info_dict['num']):
-                top_min = i * single_height
-                top_max = (i + 1) * single_height
-                if bounding_box_top >= top_min and bounding_box_top <= top_max:
-                    box_dict['Width'] = val['Width']
-                    box_dict['Height'] = merge_image_height * val['Height'] / single_height
-                    # 减去前i张图片的高度
-                    box_dict['Top'] = ((merge_image_height * val['Top']) - (i * single_height)) / single_height
-                    box_dict['Left'] = val['Left']
-                    new_bounding_box_dict['file_{i}'.format(i=i)].append(box_dict)
-
-        # 组织返回数据
-        if not conform_detect_group:    # 没有识别到符合的标签
-            event_type = ''
-            label_list = []
-        else:
-            conform_detect_group = list(conform_detect_group)
-            if len(conform_detect_group) > 1:
-                conform_detect_group.sort()
-                # 集成识别标签
-                for label_key in conform_detect_group:
-                    label_list.append(AI_IDENTIFICATION_TAGS_DICT[label_key])
-                event_type = ''.join(conform_detect_group)  # 组合类型
-            else:
-                label_list.append(AI_IDENTIFICATION_TAGS_DICT[conform_detect_group[0]])
-                event_type = conform_detect_group[0]
-
-        logger.info('------conform_detect_group------ {}'.format(conform_detect_group))
-
-        label_dict = {
-            'event_type': event_type,
-            'label_list': label_list,
-            'new_bounding_box_dict': new_bounding_box_dict
-        }
-        logger.info('------label_dict------ {}'.format(label_dict))
-        return label_dict
-
-    @staticmethod
-    def upload_images(file_dict, dir_path):
-        """
-        上传图片
-        @param file_dict: S3图片路径
-        @param dir_path: 本地图片路径
-        @return: boolean
-        """
-        try:
-            s3 = Session(
-                aws_access_key_id=ACCESS_KEY_ID,
-                aws_secret_access_key=SECRET_ACCESS_KEY,
-                region_name=REGION_NAME
-            ).resource('s3')
-
-            for file_path, upload_path in file_dict.items():
-                upload_data = open(file_path, 'rb')
-                s3.Bucket(PUSH_BUCKET).put_object(Key=upload_path, Body=upload_data)
-
-            # 删除图片
-            CommonService.del_path(dir_path)
-            CommonService.del_path(dir_path + '.jpg')
-            return True
-        except Exception as e:
-            print(repr(e))
-            return False
-
-    def get_msg_title(self, appBundleId, nickname):
-        package_title_config = {
-            'com.ansjer.customizedd_a': 'DVS',
-            'com.ansjer.zccloud_a': 'ZosiSmart',
-            'com.ansjer.zccloud_ab': '周视',
-            'com.ansjer.adcloud_a': 'ADCloud',
-            'com.ansjer.adcloud_ab': 'ADCloud',
-            'com.ansjer.accloud_a': 'ACCloud',
-            'com.ansjer.loocamccloud_a': 'Loocam',
-            'com.ansjer.loocamdcloud_a': 'Anlapus',
-            'com.ansjer.customizedb_a': 'COCOONHD',
-            'com.ansjer.customizeda_a': 'Guardian365',
-            'com.ansjer.customizedc_a': 'PatrolSecure',
-        }
-        if appBundleId in package_title_config.keys():
-            return package_title_config[appBundleId] + '(' + nickname + ')'
-        else:
-            return nickname
-
-    def get_msg_text(self, channel, n_time, lang, tz, label_list):
-        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang=lang)
-        if lang == 'cn':
-            msg = '摄像头AI识别到了{}'.format(label_list)
-            send_text = '{msg} 通道:{channel} 日期:{date}'.format(msg=msg, channel=channel, date=n_date)
-        else:
-            msg = 'Camera AI recognizes {}'.format(label_list)
-            send_text = '{msg} channel:{channel} date:{date}'.format(msg=msg, channel=channel, date=n_date)
-        return send_text
-
-    def do_jpush(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text):
-        app_key = JPUSH_CONFIG[appBundleId]['Key']
-        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
-        # 此处换成各自的app_key和master_secre
-        _jpush = jpush.JPush(app_key, master_secret)
-        push = _jpush.create_push()
-        push.audience = jpush.registration_id(token_val)
-        push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                     "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
-        android = jpush.android(alert=msg_text, priority=1, style=1, alert_type=7,
-                                big_text=msg_text, title=msg_title,
-                                extras=push_data)
-        push.notification = jpush.notification(android=android)
-        push.platform = jpush.all_
-        res = push.send()
-        print(res)
-        return res.status_code
-
-    def do_fcm(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text):
-        try:
-
-            serverKey = FCM_CONFIG[appBundleId]
-            push_service = FCMNotification(api_key=serverKey)
-            data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                    "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
-            result = push_service.notify_single_device(registration_id=token_val, message_title=msg_title,
-                                                       message_body=msg_text, data_message=data,
-                                                       extra_kwargs={
-                                                           'default_vibrate_timings': True,
-                                                           'default_sound': True,
-                                                           'default_light_settings': True
-                                                       })
-            print('fcm push ing')
-            print(result)
-            return result
-        except Exception as e:
-            return 'serverKey abnormal'
-
-    def do_apns(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text):
-        logger = logging.getLogger('info')
-        logger.info("进来do_apns函数了")
-        logger.info(token_val)
-        logger.info(APNS_MODE)
-        logger.info(os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
-        try:
-            cli = apns2.APNSClient(mode=APNS_MODE,
-                                   client_cert=os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
-            push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
-                         "received_at": n_time, "sound": "", "uid": uid, "zpush": "1", "channel": channel}
-            alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
-            payload = apns2.Payload(alert=alert, custom=push_data, sound="default")
-            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
-            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
-
-            if res.status_code == 200:
-                return res.status_code
-            else:
-                logger.info('apns push fail')
-                logger.info(res.reason)
-                return res.status_code
-        except (ValueError, ArithmeticError):
-            return 'The program has a numeric format exception, one of the arithmetic exceptions'
-        except Exception as e:
-            print(repr(e))
-            logger.info(repr(e))
-            return repr(e)

+ 6 - 6
Controller/ComboCron/ComboCronPushController.py

@@ -16,7 +16,7 @@ from django.views import View
 from Model.models import UnicomComboOrderInfo, UnicomDeviceInfo, GatewayPush, SysMsgModel, UnicomFlowPush, Device_User
 from Object.AliyunSmsObject import AliyunSmsObject
 from Object.ResponseObject import ResponseObject
-from Service.GatewayService import GatewayPushService
+from Service.PushService import PushObject
 
 
 class ComboCronPushView(View):
@@ -102,7 +102,7 @@ class ComboCronPushView(View):
                 app_bundle_id = push_vo['app_bundle_id']
 
                 # 获取推送所需数据
-                msg_title = GatewayPushService.get_msg_title(app_bundle_id, nickname)
+                msg_title = PushObject.get_msg_title(app_bundle_id, nickname)
                 if lang == 'cn':
                     sys_msg_text = "温馨提示:尊敬的客户,您" + nickname + "设备4G流量套餐将在" + time.strftime("%Y-%m-%d", time.localtime(
                         item['expire_time'])) + "到期"
@@ -183,7 +183,7 @@ class ComboCronPushView(View):
                     app_bundle_id = push_vo['app_bundle_id']
 
                     # 获取推送所需数据
-                    msg_title = GatewayPushService.get_msg_title(app_bundle_id, item.serial_no)
+                    msg_title = PushObject.get_msg_title(app_bundle_id, item.serial_no)
                     sys_msg_text = sys_msg if msg else cls.get_msg_text(item.serial_no, lang, total, usage, usable)
                     kwargs['app_bundle_id'] = app_bundle_id
                     kwargs['token_val'] = token_val
@@ -222,13 +222,13 @@ class ComboCronPushView(View):
         try:
             # ios apns
             if push_type == 0:
-                GatewayPushService.ios_apns_push(**kwargs)
+                PushObject.ios_apns_push(**kwargs)
             # android gcm
             elif push_type == 1:
-                GatewayPushService.android_fcm_push(**kwargs)
+                PushObject.android_fcm_push(**kwargs)
             # android 极光推送
             elif push_type == 2:
-                GatewayPushService.android_jpush(**kwargs)
+                PushObject.android_jpush(**kwargs)
             return True
         except Exception as e:
             logger.info('流量预警推送异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

+ 5 - 5
Controller/DetectControllerV2.py

@@ -17,7 +17,7 @@ from AnsjerPush.config import JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, BASE_DIR, A
 from Object.RedisObject import RedisObject
 from Service.CommonService import CommonService
 from Service.DevicePushService import DevicePushService
-from Service.GatewayService import GatewayPushService
+from Service.PushService import PushObject
 
 
 # 移动侦测V2接口
@@ -186,11 +186,11 @@ class NotificationV2View(View):
                                                              ExpiresIn=300)
             logger.info('推送图片url:{}'.format(image_url))
             if push_type == 0:
-                GatewayPushService.ios_apns_push(uid, appBundleId, token_val, n_time, event_type, msg_title, msg_text,
-                                                 uid, channel, image_url)
+                PushObject.ios_apns_push(uid, appBundleId, token_val, n_time, event_type, msg_title, msg_text,
+                                         uid, channel, image_url)
             elif push_type == 1:
-                GatewayPushService.android_fcm_push(uid, appBundleId, token_val, n_time, event_type, msg_title,
-                                                    msg_text, uid, channel, image_url)
+                PushObject.android_fcm_push(uid, appBundleId, token_val, n_time, event_type, msg_title,
+                                            msg_text, uid, channel, image_url)
         except Exception as e:
             logger.info('推送图片测试异常:{}'.format(e))
 

+ 9 - 11
Controller/gatewayController.py

@@ -15,7 +15,7 @@ from Object.ResponseObject import ResponseObject
 from Object.utils import LocalDateTimeUtil
 from Service.CommonService import CommonService
 from Service.EquipmentInfoService import EquipmentInfoService
-from Service.GatewayService import GatewayPushService
+from Service.PushService import PushObject
 
 
 class GatewayView(View):
@@ -157,8 +157,8 @@ class GatewayView(View):
                     tz = gateway_push['tz'] if gateway_push['tz'] else 0
 
                     # 获取推送所需数据
-                    msg_title = GatewayPushService.get_msg_title(app_bundle_id, nickname)
-                    msg_text = GatewayPushService.get_msg_text(n_time, tz, lang, alarm)
+                    msg_title = PushObject.get_msg_title(app_bundle_id, nickname)
+                    msg_text = PushObject.get_gateway_msg_text(n_time, tz, lang, alarm)
 
                     kwargs['msg_title'] = msg_title
                     kwargs['msg_text'] = msg_text
@@ -168,11 +168,11 @@ class GatewayView(View):
                     try:
                         # 推送消息
                         if push_type == 0:  # ios apns
-                            GatewayPushService.ios_apns_push(**kwargs)
+                            PushObject.ios_apns_push(**kwargs)
                         elif push_type == 1:  # android gcm
-                            GatewayPushService.android_fcm_push(**kwargs)
+                            PushObject.android_fcm_push(**kwargs)
                         elif push_type == 2:  # android 极光推送
-                            GatewayPushService.android_jpush(**kwargs)
+                            PushObject.android_jpush(**kwargs)
                     except Exception as e:
                         logger.info('网关推送消息异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                         continue
@@ -244,8 +244,6 @@ class GatewayView(View):
                         app_bundle_id = gateway_push['app_bundle_id']
                         push_type = gateway_push['push_type']
                         token_val = gateway_push['token_val']
-                        lang = gateway_push['lang']
-                        tz = gateway_push['tz'] if gateway_push['tz'] else 0
 
                         kwargs['msg_title'] = nickname
                         kwargs['msg_text'] = event_info
@@ -255,11 +253,11 @@ class GatewayView(View):
                         try:
                             # 推送消息
                             if push_type == 0:  # ios apns
-                                GatewayPushService.ios_apns_push(**kwargs)
+                                PushObject.ios_apns_push(**kwargs)
                             elif push_type == 1:  # android gcm
-                                GatewayPushService.android_fcm_push(**kwargs)
+                                PushObject.android_fcm_push(**kwargs)
                             elif push_type == 2:  # android 极光推送
-                                GatewayPushService.android_jpush(**kwargs)
+                                PushObject.android_jpush(**kwargs)
                         except Exception as e:
                             logger.info('场景日志推送消息异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                             continue

+ 98 - 7
Object/MergePic.py → Object/AiImageObject.py

@@ -1,21 +1,22 @@
+import logging
 import os
 import PIL.Image as Image
 
+from AnsjerPush.Config.aiConfig import LABEL_DICT, AI_IDENTIFICATION_TAGS_DICT
 
-class ImageProcessing:
-    """
-    图片加工类
-    """
+
+# 图片加工类
+class ImageProcessingObject:
 
     def __init__(self, image_dir_path, image_size, image_row):
         self.image_dir_path = image_dir_path
         self.image_size = image_size
         self.image_row = image_row
+        self.image_info_dict = {}
 
     def merge_images(self):
         """
         合并图片
-        @return: image_info_dict
         """
 
         # 获取图片集地址下的所有图片名称
@@ -41,8 +42,7 @@ class ImageProcessing:
         self.composite_images(self.image_row, self.image_size, image_row_num, image_full_path_list, image_save_path,
                               x_new, y_new)
 
-        image_info_dict = {'width': x_list[0], 'height': sum(y_list), 'num': len(y_list)}
-        return image_info_dict
+        self.image_info_dict = {'width': x_list[0], 'height': sum(y_list), 'num': len(y_list)}
 
     def get_image_full_path_list(self, image_dir_path):
         """
@@ -121,3 +121,94 @@ class ImageProcessing:
             print("x_s", x_s, y_s)
             out = im.resize((x_s, y_s), Image.ANTIALIAS)
             return out
+
+    def handle_rekognition_res(self, detect_group, rekognition_res):
+        """
+        处理识别结果,匹配检测类型,并且返回标签坐标位置信息
+        @param detect_group: 检测类型
+        @param rekognition_res: 识别响应
+        @return: label_dict
+        """
+        logger = logging.getLogger('info')
+        labels = rekognition_res['Labels']
+        logger.info('--------识别到的标签-------:{}'.format(labels))
+
+        label_name = []
+        label_list = []
+
+        # 找出识别的所有标签
+        for label in labels:
+            label_name.append(label['Name'])
+            for Parents in label['Parents']:
+                label_name.append(Parents['Name'])
+
+        logger.info('------标签名------:{}'.format(label_name))
+
+        # 删除用户没有选择的ai识别类型, 并且得出最终识别结果
+        user_detect_list = detect_group.split(',')
+        user_detect_list = [i.strip() for i in user_detect_list]
+        conform_label_list = []
+        conform_detect_group = set()
+        for key, label_type_val in LABEL_DICT.items():
+            if key in user_detect_list:
+                for label in label_type_val:
+                    if label in label_name:
+                        conform_detect_group.add(key)
+                        conform_label_list.append(label)
+
+        # 找出标签边框线位置信息
+        bounding_box_list = []
+        for label in labels:
+            if label['Name'] in conform_label_list:
+                for label_instance in label['Instances']:
+                    bounding_box_list.append(label_instance['BoundingBox'])
+
+        # 找出边框位置信息对应的单图位置并重新计算位置比
+        merge_image_height = self.image_info_dict['height']
+        single_height = merge_image_height // self.image_info_dict['num']
+        new_bounding_box_dict = {
+            'file_0': [],
+            'file_1': [],
+            'file_2': []
+        }
+
+        for k, val in enumerate(bounding_box_list):
+            bounding_box_top = merge_image_height * val['Top']
+            # 找出当前边框属于哪张图片范围
+            box_dict = {}
+            for i in range(self.image_info_dict['num']):
+                top_min = i * single_height
+                top_max = (i + 1) * single_height
+                if top_min <= bounding_box_top <= top_max:
+                    box_dict['Width'] = val['Width']
+                    box_dict['Height'] = merge_image_height * val['Height'] / single_height
+                    # 减去前i张图片的高度
+                    box_dict['Top'] = ((merge_image_height * val['Top']) - (i * single_height)) / single_height
+                    box_dict['Left'] = val['Left']
+                    new_bounding_box_dict['file_{i}'.format(i=i)].append(box_dict)
+
+        # 组织返回数据
+        if not conform_detect_group:  # 没有识别到符合的标签
+            event_type = ''
+            label_list = []
+        else:
+            conform_detect_group = list(conform_detect_group)
+            if len(conform_detect_group) > 1:
+                conform_detect_group.sort()
+                # 集成识别标签
+                for label_key in conform_detect_group:
+                    label_list.append(AI_IDENTIFICATION_TAGS_DICT[label_key])
+                event_type = ''.join(conform_detect_group)  # 组合类型
+            else:
+                label_list.append(AI_IDENTIFICATION_TAGS_DICT[conform_detect_group[0]])
+                event_type = conform_detect_group[0]
+
+        logger.info('------conform_detect_group------ {}'.format(conform_detect_group))
+
+        label_dict = {
+            'event_type': event_type,
+            'label_list': label_list,
+            'new_bounding_box_dict': new_bounding_box_dict
+        }
+        logger.info('------label_dict------ {}'.format(label_dict))
+        return label_dict

+ 29 - 1
Service/CommonService.py

@@ -6,11 +6,12 @@ from pathlib import Path
 from random import Random
 import ipdb
 import simplejson as json
+from boto3 import Session
 from django.core import serializers
 from django.utils import timezone
 from pyipip import IPIPDatabase
 
-from AnsjerPush.config import BASE_DIR
+from AnsjerPush.config import BASE_DIR, ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, PUSH_BUCKET
 
 
 # 复用性且公用较高封装代码在这
@@ -220,6 +221,33 @@ class CommonService:
         file.flush()
         file.close()
 
+    @classmethod
+    def upload_images(cls, file_dict, dir_path):
+        """
+        上传图片到S3,并删除本地图片
+        @param file_dict: S3图片路径
+        @param dir_path: 本地图片路径
+        @return: boolean
+        """
+        try:
+            s3 = Session(
+                aws_access_key_id=ACCESS_KEY_ID,
+                aws_secret_access_key=SECRET_ACCESS_KEY,
+                region_name=REGION_NAME
+            ).resource('s3')
+
+            for file_path, upload_path in file_dict.items():
+                upload_data = open(file_path, 'rb')
+                s3.Bucket(PUSH_BUCKET).put_object(Key=upload_path, Body=upload_data)
+
+            # 删除图片
+            cls.del_path(dir_path)
+            cls.del_path(dir_path + '.jpg')
+            return True
+        except Exception as e:
+            print(repr(e))
+            return False
+
     @classmethod
     def del_path(cls, path):
         """

+ 8 - 21
Service/DevicePushService.py

@@ -15,7 +15,7 @@ import apns2
 import jpush as jpush
 from pyfcm import FCMNotification
 
-from AnsjerPush.config import JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE
+from AnsjerPush.config import JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE, APP_BUNDLE_DICT
 from AnsjerPush.config import SERVER_TYPE
 from Model.models import UidPushModel, SysMsgModel
 from Object.ETkObject import ETkObject
@@ -23,7 +23,7 @@ from Object.UidTokenObject import UidTokenObject
 from Object.utils import LocalDateTimeUtil
 from Service.CommonService import CommonService
 from Service.EquipmentInfoService import EquipmentInfoService
-from Service.GatewayService import GatewayPushService
+from Service.PushService import PushObject
 
 LOGGING = logging.getLogger('info')
 
@@ -221,21 +221,8 @@ class DevicePushService:
         """
         获取消息标题
         """""
-        package_title_config = {
-            'com.ansjer.customizedd_a': 'DVS',
-            'com.ansjer.zccloud_a': 'ZosiSmart',
-            'com.ansjer.zccloud_ab': '周视',
-            'com.ansjer.adcloud_a': 'ADCloud',
-            'com.ansjer.adcloud_ab': 'ADCloud',
-            'com.ansjer.accloud_a': 'ACCloud',
-            'com.ansjer.loocamccloud_a': 'Loocam',
-            'com.ansjer.loocamdcloud_a': 'Anlapus',
-            'com.ansjer.customizedb_a': 'COCOONHD',
-            'com.ansjer.customizeda_a': 'Guardian365',
-            'com.ansjer.customizedc_a': 'PatrolSecure',
-        }
-        if appBundleId in package_title_config.keys():
-            return package_title_config[appBundleId] + '(' + nickname + ')'
+        if appBundleId in APP_BUNDLE_DICT.keys():
+            return APP_BUNDLE_DICT[appBundleId] + '(' + nickname + ')'
         else:
             return nickname
 
@@ -374,11 +361,11 @@ class DevicePushService:
                                                              ExpiresIn=300)
             LOGGING.info('推送图片url:{}'.format(image_url))
             if push_type == 0:
-                GatewayPushService.ios_apns_push(uid, appBundleId, token_val, n_time, event_type, msg_title, msg_text,
-                                                 uid, channel, image_url)
+                PushObject.ios_apns_push(uid, appBundleId, token_val, n_time, event_type, msg_title, msg_text,
+                                         uid, channel, image_url)
             elif push_type == 1:
-                GatewayPushService.android_fcm_push(uid, appBundleId, token_val, n_time, event_type, msg_title,
-                                                    msg_text, uid, channel, image_url)
+                PushObject.android_fcm_push(uid, appBundleId, token_val, n_time, event_type, msg_title,
+                                            msg_text, uid, channel, image_url)
         except Exception as e:
             LOGGING.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 

+ 42 - 8
Service/GatewayService.py → Service/PushService.py

@@ -2,7 +2,7 @@
 """
 @Time : 2022/5/19 11:43
 @Auth : Locky
-@File :GatewayService.py
+@File :PushService.py
 @IDE :PyCharm
 """
 import logging
@@ -13,22 +13,36 @@ import jpush
 from pyfcm import FCMNotification
 
 from AnsjerPush.config import APP_BUNDLE_DICT, APNS_MODE, BASE_DIR, APNS_CONFIG, FCM_CONFIG, JPUSH_CONFIG
-# 网关推送类
 from Service.CommonService import CommonService
 
 
-class GatewayPushService:
-    # 获取推送消息标题
+# 推送对象
+class PushObject:
+
     @staticmethod
     def get_msg_title(app_bundle_id, nickname):
+        """
+        获取推送消息标题
+        @param app_bundle_id: app包id
+        @param nickname: 设备名
+        @return: msg_title
+        """
         if app_bundle_id in APP_BUNDLE_DICT.keys():
-            return APP_BUNDLE_DICT[app_bundle_id] + '(' + nickname + ')'
+            msg_title = APP_BUNDLE_DICT[app_bundle_id] + '(' + nickname + ')'
         else:
-            return nickname
+            msg_title = nickname
+        return msg_title
 
-    # 获取推送消息内容
     @staticmethod
-    def get_msg_text(n_time, tz, lang, alarm):
+    def get_gateway_msg_text(n_time, tz, lang, alarm):
+        """
+        获取网关推送消息内容
+        @param n_time: 当前时间
+        @param tz: 时区
+        @param lang: 语言
+        @param alarm: 警报
+        @return: msg_text
+        """
         n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang=lang)
         if lang == 'cn':
             msg_text = '{} 日期:{}'.format(alarm, n_date)
@@ -36,6 +50,26 @@ class GatewayPushService:
             msg_text = '{} date:{}'.format(alarm, n_date)
         return msg_text
 
+    @staticmethod
+    def get_ai_msg_text(channel, n_time, lang, tz, label):
+        """
+        获取AI推送内容
+        @param channel: 通道
+        @param n_time: 当前时间
+        @param lang: 语言
+        @param tz: 时区
+        @param label: 识别到的标签
+        @return: ai_msg_text
+        """
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang=lang)
+        if lang == 'cn':
+            msg = '摄像头AI识别到了{}'.format(label)
+            ai_msg_text = '{msg} 通道:{channel} 日期:{date}'.format(msg=msg, channel=channel, date=n_date)
+        else:
+            msg = 'Camera AI recognizes {}'.format(label)
+            ai_msg_text = '{msg} channel:{channel} date:{date}'.format(msg=msg, channel=channel, date=n_date)
+        return ai_msg_text
+
     # ios apns 推送
     @staticmethod
     def ios_apns_push(nickname, app_bundle_id, token_val, n_time, event_type, msg_title, msg_text,