# -*- coding: utf-8 -*- """ @Author : Rocky @Time : 2022/9/16 10:39 @File :PowerWarningController.py """ import logging import os import time import apns2 import jpush as jpush from django.http import JsonResponse from django.views.generic.base import View from pyfcm import FCMNotification from AnsjerPush.config import JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE from Model.models import UidPushModel, SysMsgModel from Object.RedisObject import RedisObject from Service.CommonService import CommonService # 低电量推送接口 class PowerWarningView(View): def get(self, request, *args, **kwargs): request.encoding = 'utf-8' return self.validation(request.GET) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' return self.validation(request.POST) def validation(self, request_dict): logger = logging.getLogger('info') uid = request_dict.get('uid', None) # 限制每6小时推一次 redisObj = RedisObject() is_limit = redisObj.CONN.setnx(uid+'limit_power_warning', 1) redisObj.CONN.expire(uid+'limit_power_warning', 6*60*60) if not is_limit: return JsonResponse(status=200, data={'code': 0, 'msg': 'push limited!'}) channel = request_dict.get('channel', None) electricity = request_dict.get('electricity', None) logger.info('调用低电量推送接口的uid: {},electricity: {}'.format(uid, electricity)) try: 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(): res_data = {'code': 173, 'msg': 'uid push data not exit!'} return JsonResponse(status=200, data=res_data) # 新建一个list接收数据 redis_list = [] # 把数据库数据追加进redis_list for qs in uid_push_qs: redis_list.append(qs) if not redis_list: res_data = {'code': 0, 'msg': 'no redis_list success!'} return JsonResponse(status=200, data=res_data) nickname = redis_list[0]['uid_set__nickname'] if not nickname: nickname = uid now_time = int(time.time()) channel = channel event_type = 704 sys_msg_list = [] userID_ids = [] kwag_args = { 'uid': uid, 'channel': channel, 'event_type': event_type, 'n_time': now_time, } for up in redis_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 # 发送标题 msg_title = self.get_msg_title(appBundleId=appBundleId, nickname=nickname) # 发送内容 msg_text = self.get_msg_text(channel=channel, n_time=now_time, lang=lang, tz=tz, event_type=event_type, electricity=electricity) kwag_args['appBundleId'] = appBundleId kwag_args['token_val'] = token_val kwag_args['msg_title'] = msg_title kwag_args['msg_text'] = msg_text if push_type == 0: # ios apns self.do_apns(**kwag_args) elif push_type == 1: # android gcm self.do_fcm(**kwag_args) elif push_type == 2: # android jpush self.do_jpush(**kwag_args) # 以下是存库 userID_id = up["userID_id"] if userID_id not in userID_ids: sys_msg_text = self.get_msg_text(channel=channel, n_time=now_time, lang=lang, tz=tz, event_type=event_type, is_sys=1, electricity=electricity) sys_msg_list.append(SysMsgModel( userID_id=userID_id, msg=sys_msg_text, addTime=now_time, updTime=now_time, uid=uid, eventType=event_type, )) userID_ids.append(userID_id) SysMsgModel.objects.bulk_create(sys_msg_list) return JsonResponse(status=200, data={'code': 0}) except Exception as e: logger.info('低电量推送接口异常: {}'.format(e)) return JsonResponse(status=500, data={'msg': 'power warning error'}) 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 is_sys_msg(self, event_type): event_type_list = [702, 703, 704] if event_type in event_type_list: return True return False def get_msg_text(self, channel, n_time, lang, tz, event_type, electricity, is_sys=0): n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz, lang=lang) etype = int(event_type) if lang == 'cn': if etype == 704: msg_type = '剩余电量:' + electricity elif etype == 702: msg_type = '摄像头休眠' elif etype == 703: msg_type = '摄像头唤醒' else: msg_type = '' if is_sys: send_text = '{msg_type} 通道:{channel}'.format(msg_type=msg_type, channel=channel) else: send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date) else: if etype == 704: msg_type = 'Battery remaining:' + electricity elif etype == 702: msg_type = 'Camera sleep' elif etype == 703: msg_type = 'Camera wake' else: msg_type = '' if is_sys: send_text = '{msg_type} channel:{channel}'. \ format(msg_type=msg_type, channel=channel) else: send_text = '{msg_type} channel:{channel} date:{date}'. \ format(msg_type=msg_type, 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'] _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() 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] except Exception as e: return 'serverKey abnormal' 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 }) return result def do_apns(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text): 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: return res.status_code except (ValueError, ArithmeticError): return 'The program has a numeric format exception, one of the arithmetic exceptions' except Exception as e: return repr(e)