DetectController.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import json
  2. import logging
  3. import os
  4. import time
  5. import apns2
  6. import jpush as jpush
  7. import oss2
  8. from django.db import transaction
  9. from django.http import JsonResponse
  10. from django.views.generic.base import View
  11. from pyfcm import FCMNotification
  12. from AnsjerPush.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, JPUSH_CONFIG, FCM_CONFIG, \
  13. APNS_CONFIG, BASE_DIR, APNS_MODE
  14. from AnsjerPush.config import SERVER_TYPE
  15. from Model.models import UidPushModel, SysMsgModel
  16. from Object.ETkObject import ETkObject
  17. from Object.RedisObject import RedisObject
  18. from Object.UidTokenObject import UidTokenObject
  19. from Object.utils import LocalDateTimeUtil
  20. from Service.CommonService import CommonService
  21. from Service.DevicePushService import DevicePushService
  22. from Service.EquipmentInfoService import EquipmentInfoService
  23. # 旧移动侦测接口
  24. class NotificationView(View):
  25. def get(self, request, *args, **kwargs):
  26. request.encoding = 'utf-8'
  27. return self.validation(request.GET)
  28. def post(self, request, *args, **kwargs):
  29. request.encoding = 'utf-8'
  30. return self.validation(request.POST)
  31. def validation(self, request_dict):
  32. """
  33. 设备触发报警消息推送
  34. @param request_dict:uidToken 加密uid
  35. @param request_dict:etk 加密uid
  36. @param request_dict:channel 设备通道号
  37. @param request_dict:n_time 设备触发报警时间
  38. @param request_dict:event_type 设备事件类型
  39. @param request_dict:is_st 文件类型(0:无,1:图片,2:视频)
  40. """
  41. logger = logging.getLogger('info')
  42. logger.info("旧移动侦测接口参数:{}".format(request_dict))
  43. uidToken = request_dict.get('uidToken', None)
  44. etk = request_dict.get('etk', None)
  45. channel = request_dict.get('channel', '1')
  46. n_time = request_dict.get('n_time', None)
  47. event_type = request_dict.get('event_type', None)
  48. is_st = request_dict.get('is_st', None)
  49. if not all([channel, n_time]):
  50. return JsonResponse(status=200, data={'code': 444, 'msg': 'error channel or n_time'})
  51. try:
  52. with transaction.atomic():
  53. uid = DevicePushService.decode_uid(etk, uidToken) # 解密uid
  54. if len(uid) != 20 and len(uid) != 14:
  55. return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong uid'})
  56. logger.info("旧移动侦测接口的uid:{}".format(uid))
  57. pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, event_type=event_type, channel=channel)
  58. ykey = '{uid}_redis_qs'.format(uid=uid)
  59. is_sys_msg = self.is_sys_msg(int(event_type))
  60. if is_sys_msg is True:
  61. dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
  62. else:
  63. dkey = '{uid}_{channel}_flag'.format(uid=uid, channel=channel)
  64. redisObj = RedisObject(db=6)
  65. have_ykey = redisObj.get_data(key=ykey) # uid_set 数据库缓存
  66. have_pkey = redisObj.get_data(key=pkey) # 一分钟限制key
  67. have_dkey = redisObj.get_data(key=dkey) # 推送类型限制
  68. # 一分钟外,推送开启状态
  69. detect_med_type = 0 # 0推送旧机制 1存库不推送,2推送存库
  70. # 暂时注销
  71. if have_pkey:
  72. res_data = {'code': 0, 'msg': 'Push it once a minute'}
  73. return JsonResponse(status=200, data=res_data)
  74. # 数据库读取数据
  75. if have_ykey:
  76. uid_push_list = eval(redisObj.get_data(key=ykey))
  77. else:
  78. # 从数据库查询出来
  79. uid_push_qs = DevicePushService.query_uid_push(uid)
  80. if not uid_push_qs.exists():
  81. logger.info('消息推送-uid_push 数据不存在')
  82. return JsonResponse(status=200, data={'code': 176, 'msg': 'no uid_push data'})
  83. # 修改redis数据,并设置过期时间为10分钟
  84. uid_push_list = DevicePushService.cache_uid_push(uid_push_qs)
  85. redisObj.set_data(key=ykey, val=str(uid_push_list), expire=600)
  86. if not uid_push_list:
  87. res_data = {'code': 404, 'msg': 'error !'}
  88. return JsonResponse(status=200, data=res_data)
  89. if not uid_push_list:
  90. res_data = {'code': 0, 'msg': 'uid_push_list not exist'}
  91. return JsonResponse(status=200, data=res_data)
  92. nickname = uid_push_list[0]['uid_set__nickname']
  93. detect_interval = uid_push_list[0]['uid_set__detect_interval']
  94. detect_group = uid_push_list[0]['uid_set__detect_group']
  95. if not nickname:
  96. nickname = uid
  97. if detect_group is not None:
  98. if have_dkey:
  99. detect_med_type = 1 # 1为存库不推送
  100. else:
  101. detect_med_type = 2 # 为2的话,既推送,又存库
  102. if SERVER_TYPE != 'Ansjer.cn_config.cn_formal_settings':
  103. new_detect_interval = uid_push_list[0]['uid_set__new_detect_interval']
  104. detect_interval = new_detect_interval if new_detect_interval > 0 else detect_interval
  105. detect_interval = 60 if detect_interval < 60 else detect_interval
  106. redisObj.set_data(key=dkey, val=1, expire=detect_interval - 5)
  107. redisObj.set_data(key=pkey, val=1, expire=60)
  108. logger.info('APP消息推送V1接口,是否进行APP推送:{},1为不推送,间隔:{}'.format(detect_med_type, detect_interval))
  109. # 旧模式并且没有pkey,重新创建一个
  110. if not detect_group and not have_pkey:
  111. redisObj.set_data(key=pkey, val=1, expire=60)
  112. auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
  113. bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
  114. kwag_args = {
  115. 'uid': uid,
  116. 'channel': channel,
  117. 'event_type': event_type,
  118. 'n_time': n_time,
  119. }
  120. params = {'nickname': nickname, 'uid': uid, 'kwag_args': kwag_args, 'is_st': is_st,
  121. 'is_sys_msg': is_sys_msg, 'channel': channel, 'event_type': event_type, 'n_time': n_time,
  122. 'electricity': '', 'bucket': bucket, 'app_push': ''}
  123. # 推送以及报警消息存库
  124. result = DevicePushService.save_msg_push(uid_set_push_list=uid_push_list, **params)
  125. if result['code_date'] is None:
  126. result['code_date'] = {'do_apns_code': '', 'do_fcm_code': '', 'do_jpush_code': ''}
  127. if detect_med_type == 1:
  128. result['code_date']['do_apns_code'] = '只存库不推送'
  129. result['code_date']['do_fcm_code'] = '只存库不推送'
  130. result['code_date']['do_jpush_code'] = '只存库不推送'
  131. if is_sys_msg:
  132. SysMsgModel.objects.bulk_create(result['sys_msg_list'])
  133. else:
  134. if result['new_device_info_list'] and len(result['new_device_info_list']) > 0:
  135. # 根据日期获得星期几
  136. week = LocalDateTimeUtil.date_to_week(result['local_date_time'])
  137. EquipmentInfoService.equipment_info_bulk_create(week, result['new_device_info_list'])
  138. logger.info('----《旧接口》设备信息分表批量保存end')
  139. if is_st == '0' or is_st == '2':
  140. print("is_st=0or2")
  141. for up in uid_push_list:
  142. if up['push_type'] == 0: # ios apns
  143. up['do_apns_code'] = result['code_date']['do_apns_code']
  144. elif up['push_type'] == 1: # android gcm
  145. up['do_fcm_code'] = result['code_date']['do_fcm_code']
  146. elif up['push_type'] == 2: # android jpush
  147. up['do_jpush_code'] = result['code_date']['do_jpush_code']
  148. del up['push_type']
  149. del up['userID_id']
  150. del up['userID__NickName']
  151. del up['lang']
  152. del up['tz']
  153. del up['uid_set__nickname']
  154. del up['uid_set__detect_interval']
  155. del up['uid_set__detect_group']
  156. return JsonResponse(status=200, data={'code': 0, 'msg': 'success 0 or 2'})
  157. elif is_st == '1':
  158. print("is_st=1")
  159. # Endpoint以杭州为例,其它Region请按实际情况填写。
  160. obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
  161. # 设置此签名URL在60秒内有效。
  162. url = bucket.sign_url('PUT', obj, 7200)
  163. for up in uid_push_list:
  164. up['do_apns_code'] = result['code_date']['do_apns_code']
  165. up['do_fcm_code'] = result['code_date']['do_fcm_code']
  166. up['do_jpush_code'] = result['code_date']['do_jpush_code']
  167. del up['push_type']
  168. del up['userID_id']
  169. del up['userID__NickName']
  170. del up['lang']
  171. del up['tz']
  172. del up['uid_set__nickname']
  173. del up['uid_set__detect_interval']
  174. del up['uid_set__detect_group']
  175. res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
  176. return JsonResponse(status=200, data=res_data)
  177. elif is_st == '3':
  178. print("is_st=3")
  179. # 人形检测带动图
  180. # Endpoint以杭州为例,其它Region请按实际情况填写。
  181. img_url_list = []
  182. for i in range(int(is_st)):
  183. obj = '{uid}/{channel}/{filename}_{st}.jpeg'. \
  184. format(uid=uid, channel=channel, filename=n_time, st=i)
  185. # 设置此签名URL在60秒内有效。
  186. url = bucket.sign_url('PUT', obj, 7200)
  187. img_url_list.append(url)
  188. for up in uid_push_list:
  189. up['do_apns_code'] = result['code_date']['do_apns_code']
  190. up['do_fcm_code'] = result['code_date']['do_fcm_code']
  191. up['do_jpush_code'] = result['code_date']['do_jpush_code']
  192. del up['push_type']
  193. del up['userID_id']
  194. del up['userID__NickName']
  195. del up['lang']
  196. del up['tz']
  197. del up['uid_set__nickname']
  198. del up['uid_set__detect_interval']
  199. del up['uid_set__detect_group']
  200. res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
  201. return JsonResponse(status=200, data=res_data)
  202. except Exception as e:
  203. logger.info('消息推送-异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  204. data = {
  205. 'errLine': e.__traceback__.tb_lineno,
  206. 'errMsg': repr(e),
  207. }
  208. return JsonResponse(status=200, data=json.dumps(data), safe=False)
  209. def is_sys_msg(self, event_type):
  210. event_type_list = [702, 703, 704]
  211. if event_type in event_type_list:
  212. return True
  213. return False