import json import logging import os import time import apns2 import jpush as jpush import oss2 from django.db import transaction from django.http import JsonResponse from django.views.generic.base import View from pyfcm import FCMNotification from AnsjerPush.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, JPUSH_CONFIG, FCM_CONFIG, \ APNS_CONFIG, BASE_DIR, APNS_MODE from AnsjerPush.config import SERVER_TYPE from Model.models import UidPushModel, SysMsgModel from Object.ETkObject import ETkObject from Object.RedisObject import RedisObject from Object.UidTokenObject import UidTokenObject from Object.utils import LocalDateTimeUtil from Service.CommonService import CommonService from Service.DevicePushService import DevicePushService from Service.EquipmentInfoService import EquipmentInfoService # 旧移动侦测接口 class NotificationView(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): """ 设备触发报警消息推送 @param request_dict:uidToken 加密uid @param request_dict:etk 加密uid @param request_dict:channel 设备通道号 @param request_dict:n_time 设备触发报警时间 @param request_dict:event_type 设备事件类型 @param request_dict:is_st 文件类型(0:无,1:图片,2:视频) """ logger = logging.getLogger('info') logger.info("旧移动侦测接口参数:{}".format(request_dict)) uidToken = request_dict.get('uidToken', None) etk = request_dict.get('etk', None) channel = request_dict.get('channel', '1') n_time = request_dict.get('n_time', None) event_type = request_dict.get('event_type', None) is_st = request_dict.get('is_st', None) if not all([channel, n_time]): return JsonResponse(status=200, data={'code': 444, 'msg': 'error channel or n_time'}) try: with transaction.atomic(): uid = DevicePushService.decode_uid(etk, uidToken) # 解密uid if len(uid) != 20 and len(uid) != 14: return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong uid'}) logger.info("旧移动侦测接口的uid:{}".format(uid)) pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, event_type=event_type, channel=channel) ykey = '{uid}_redis_qs'.format(uid=uid) is_sys_msg = self.is_sys_msg(int(event_type)) if is_sys_msg is True: dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel) else: dkey = '{uid}_{channel}_flag'.format(uid=uid, channel=channel) redisObj = RedisObject(db=6) have_ykey = redisObj.get_data(key=ykey) # uid_set 数据库缓存 have_pkey = redisObj.get_data(key=pkey) # 一分钟限制key have_dkey = redisObj.get_data(key=dkey) # 推送类型限制 # 一分钟外,推送开启状态 detect_med_type = 0 # 0推送旧机制 1存库不推送,2推送存库 # 暂时注销 if have_pkey: res_data = {'code': 0, 'msg': 'Push it once a minute'} return JsonResponse(status=200, data=res_data) # 数据库读取数据 if have_ykey: uid_push_list = eval(redisObj.get_data(key=ykey)) else: # 从数据库查询出来 uid_push_qs = DevicePushService.query_uid_push(uid) if not uid_push_qs.exists(): logger.info('消息推送-uid_push 数据不存在') return JsonResponse(status=200, data={'code': 176, 'msg': 'no uid_push data'}) # 修改redis数据,并设置过期时间为10分钟 uid_push_list = DevicePushService.cache_uid_push(uid_push_qs) redisObj.set_data(key=ykey, val=str(uid_push_list), expire=600) if not uid_push_list: res_data = {'code': 404, 'msg': 'error !'} return JsonResponse(status=200, data=res_data) if not uid_push_list: res_data = {'code': 0, 'msg': 'uid_push_list not exist'} return JsonResponse(status=200, data=res_data) nickname = uid_push_list[0]['uid_set__nickname'] detect_interval = uid_push_list[0]['uid_set__detect_interval'] detect_group = uid_push_list[0]['uid_set__detect_group'] if not nickname: nickname = uid if detect_group is not None: if have_dkey: detect_med_type = 1 # 1为存库不推送 else: detect_med_type = 2 # 为2的话,既推送,又存库 if SERVER_TYPE != 'Ansjer.cn_config.cn_formal_settings': new_detect_interval = uid_push_list[0]['uid_set__new_detect_interval'] detect_interval = new_detect_interval if new_detect_interval > 0 else detect_interval detect_interval = 60 if detect_interval < 60 else detect_interval redisObj.set_data(key=dkey, val=1, expire=detect_interval - 5) redisObj.set_data(key=pkey, val=1, expire=60) logger.info('APP消息推送V1接口,是否进行APP推送:{},1为不推送,间隔:{}'.format(detect_med_type, detect_interval)) # 旧模式并且没有pkey,重新创建一个 if not detect_group and not have_pkey: redisObj.set_data(key=pkey, val=1, expire=60) auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET) bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg') kwag_args = { 'uid': uid, 'channel': channel, 'event_type': event_type, 'n_time': n_time, } params = {'nickname': nickname, 'uid': uid, 'kwag_args': kwag_args, 'is_st': is_st, 'is_sys_msg': is_sys_msg, 'channel': channel, 'event_type': event_type, 'n_time': n_time, 'electricity': '', 'bucket': bucket, 'app_push': ''} # 推送以及报警消息存库 result = DevicePushService.save_msg_push(uid_set_push_list=uid_push_list, **params) if result['code_date'] is None: result['code_date'] = {'do_apns_code': '', 'do_fcm_code': '', 'do_jpush_code': ''} if detect_med_type == 1: result['code_date']['do_apns_code'] = '只存库不推送' result['code_date']['do_fcm_code'] = '只存库不推送' result['code_date']['do_jpush_code'] = '只存库不推送' if is_sys_msg: SysMsgModel.objects.bulk_create(result['sys_msg_list']) else: if result['new_device_info_list'] and len(result['new_device_info_list']) > 0: # 根据日期获得星期几 week = LocalDateTimeUtil.date_to_week(result['local_date_time']) EquipmentInfoService.equipment_info_bulk_create(week, result['new_device_info_list']) logger.info('----《旧接口》设备信息分表批量保存end') if is_st == '0' or is_st == '2': print("is_st=0or2") for up in uid_push_list: if up['push_type'] == 0: # ios apns up['do_apns_code'] = result['code_date']['do_apns_code'] elif up['push_type'] == 1: # android gcm up['do_fcm_code'] = result['code_date']['do_fcm_code'] elif up['push_type'] == 2: # android jpush up['do_jpush_code'] = result['code_date']['do_jpush_code'] del up['push_type'] del up['userID_id'] del up['userID__NickName'] del up['lang'] del up['tz'] del up['uid_set__nickname'] del up['uid_set__detect_interval'] del up['uid_set__detect_group'] return JsonResponse(status=200, data={'code': 0, 'msg': 'success 0 or 2'}) elif is_st == '1': print("is_st=1") # Endpoint以杭州为例,其它Region请按实际情况填写。 obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time) # 设置此签名URL在60秒内有效。 url = bucket.sign_url('PUT', obj, 7200) for up in uid_push_list: up['do_apns_code'] = result['code_date']['do_apns_code'] up['do_fcm_code'] = result['code_date']['do_fcm_code'] up['do_jpush_code'] = result['code_date']['do_jpush_code'] del up['push_type'] del up['userID_id'] del up['userID__NickName'] del up['lang'] del up['tz'] del up['uid_set__nickname'] del up['uid_set__detect_interval'] del up['uid_set__detect_group'] res_data = {'code': 0, 'img_push': url, 'msg': 'success'} return JsonResponse(status=200, data=res_data) elif is_st == '3': print("is_st=3") # 人形检测带动图 # Endpoint以杭州为例,其它Region请按实际情况填写。 img_url_list = [] for i in range(int(is_st)): obj = '{uid}/{channel}/{filename}_{st}.jpeg'. \ format(uid=uid, channel=channel, filename=n_time, st=i) # 设置此签名URL在60秒内有效。 url = bucket.sign_url('PUT', obj, 7200) img_url_list.append(url) for up in uid_push_list: up['do_apns_code'] = result['code_date']['do_apns_code'] up['do_fcm_code'] = result['code_date']['do_fcm_code'] up['do_jpush_code'] = result['code_date']['do_jpush_code'] del up['push_type'] del up['userID_id'] del up['userID__NickName'] del up['lang'] del up['tz'] del up['uid_set__nickname'] del up['uid_set__detect_interval'] del up['uid_set__detect_group'] res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'} return JsonResponse(status=200, data=res_data) except Exception as e: logger.info('消息推送-异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e))) data = { 'errLine': e.__traceback__.tb_lineno, 'errMsg': repr(e), } return JsonResponse(status=200, data=json.dumps(data), safe=False) def is_sys_msg(self, event_type): event_type_list = [702, 703, 704] if event_type in event_type_list: return True return False