DetectController.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import json
  2. import logging
  3. import threading
  4. import oss2
  5. from django.http import JsonResponse
  6. from django.views.generic.base import View
  7. from AnsjerPush.config import CONFIG_INFO, CONFIG_CN
  8. from Object.RedisObject import RedisObject
  9. from Service.DevicePushService import DevicePushService
  10. from django.conf import settings
  11. ALICLOUD_AK = settings.ALICLOUD_AK
  12. ALICLOUD_SK = settings.ALICLOUD_SK
  13. V1_PUSH_LOGGER = logging.getLogger('v1_push')
  14. # 旧移动侦测接口
  15. class NotificationView(View):
  16. def get(self, request, *args, **kwargs):
  17. request.encoding = 'utf-8'
  18. return self.validation(request.GET)
  19. def post(self, request, *args, **kwargs):
  20. request.encoding = 'utf-8'
  21. return self.validation(request.POST)
  22. @staticmethod
  23. def validation(request_dict):
  24. """
  25. 设备触发报警消息推送
  26. @param request_dict:uidToken 加密uid
  27. @param request_dict:etk 加密uid
  28. @param request_dict:channel 设备通道号
  29. @param request_dict:n_time 设备触发报警时间
  30. @param request_dict:event_type 设备事件类型
  31. @param request_dict:is_st 文件类型(0:无,1:图片,2:视频)
  32. """
  33. uidToken = request_dict.get('uidToken', None)
  34. etk = request_dict.get('etk', None)
  35. channel = request_dict.get('channel', '1')
  36. n_time = request_dict.get('n_time', None)
  37. event_type = request_dict.get('event_type', None)
  38. is_st = request_dict.get('is_st', None)
  39. if not all([channel, n_time]):
  40. return JsonResponse(status=200, data={'code': 444, 'msg': 'error channel or n_time'})
  41. redis_obj = RedisObject()
  42. try:
  43. uid = DevicePushService.decode_uid(etk, uidToken) # 解密uid
  44. if len(uid) != 20 and len(uid) != 14:
  45. return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong uid'})
  46. V1_PUSH_LOGGER.info('旧移动侦测接口uid:{},时间戳:{},事件类型:{}'.format(uid, n_time, event_type))
  47. event_type = int(event_type)
  48. pkey = '{}_{}_{}_ptl'.format(uid, event_type, channel)
  49. ykey = '{}_redis_qs'.format(uid)
  50. is_sys_msg = DevicePushService.judge_sys_msg(event_type)
  51. if is_sys_msg:
  52. dkey = '{}_{}_{}_flag'.format(uid, event_type, channel)
  53. else:
  54. dkey = '{}_{}_flag'.format(uid, channel)
  55. have_ykey = redis_obj.get_data(key=ykey) # uid_set 数据库缓存
  56. have_pkey = redis_obj.get_data(key=pkey) # 一分钟限制key
  57. have_dkey = redis_obj.get_data(key=dkey) # 推送类型限制
  58. # 一分钟外,推送开启状态
  59. detect_med_type = 0 # 0推送旧机制 1存库不推送,2推送存库
  60. if event_type not in [606, 607]:
  61. if have_pkey:
  62. res_data = {'code': 0, 'msg': 'Push it once a minute'}
  63. return JsonResponse(status=200, data=res_data)
  64. # 数据库读取数据
  65. if have_ykey:
  66. uid_push_list = eval(redis_obj.get_data(key=ykey))
  67. else:
  68. # 从数据库查询出来
  69. uid_push_qs = DevicePushService.query_uid_push(uid, event_type)
  70. if not uid_push_qs.exists():
  71. V1_PUSH_LOGGER.info('{}uid_push数据不存在'.format(uid))
  72. return JsonResponse(status=200, data={'code': 176, 'msg': 'no uid_push data'})
  73. # 修改redis数据,并设置过期时间为10分钟
  74. uid_push_list = DevicePushService.qs_to_list(uid_push_qs)
  75. redis_obj.set_data(key=ykey, val=str(uid_push_list), expire=600)
  76. if not uid_push_list:
  77. res_data = {'code': 404, 'msg': 'error !'}
  78. return JsonResponse(status=200, data=res_data)
  79. if not uid_push_list:
  80. res_data = {'code': 0, 'msg': 'uid_push_list not exist'}
  81. return JsonResponse(status=200, data=res_data)
  82. nickname = uid_push_list[0]['uid_set__nickname']
  83. detect_interval = uid_push_list[0]['uid_set__detect_interval']
  84. detect_group = uid_push_list[0]['uid_set__detect_group']
  85. if not nickname:
  86. nickname = uid
  87. if detect_group is not None:
  88. if have_dkey:
  89. detect_med_type = 1 # 1为存库不推送
  90. else:
  91. detect_med_type = 2 # 为2的话,既推送,又存库
  92. if CONFIG_INFO != CONFIG_CN:
  93. new_detect_interval = uid_push_list[0]['uid_set__new_detect_interval']
  94. detect_interval = new_detect_interval if new_detect_interval > 0 else detect_interval
  95. detect_interval = 60 if detect_interval < 60 else detect_interval
  96. redis_obj.set_data(key=dkey, val=1, expire=detect_interval - 5)
  97. redis_obj.set_data(key=pkey, val=1, expire=60)
  98. # 旧模式并且没有pkey,重新创建一个
  99. if not detect_group and not have_pkey:
  100. redis_obj.set_data(key=pkey, val=1, expire=60)
  101. auth = oss2.Auth(ALICLOUD_AK, ALICLOUD_SK)
  102. bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
  103. # 推送相关参数
  104. push_kwargs = {
  105. 'uid': uid,
  106. 'channel': channel,
  107. 'event_type': event_type,
  108. 'n_time': n_time,
  109. }
  110. params = {'nickname': nickname, 'uid': uid, 'push_kwargs': push_kwargs, 'is_st': is_st,
  111. 'is_sys_msg': is_sys_msg, 'channel': channel, 'event_type': event_type, 'n_time': n_time,
  112. 'electricity': '', 'bucket': bucket, 'app_push': have_dkey, 'storage_location': 1, 'ai_type': 0,
  113. 'dealings_type': 0, 'detection': 0, 'device_type': 1, 'app_push_config': '',
  114. 'uid_set_push_list': uid_push_list, 'redis_obj': redis_obj}
  115. # 异步推送消息和保存数据
  116. push_thread = threading.Thread(
  117. target=push_and_save_data,
  118. kwargs=params)
  119. push_thread.start()
  120. res_data = {}
  121. if is_st == '0' or is_st == '2':
  122. res_data = {'code': 0, 'msg': 'success 0 or 2'}
  123. return JsonResponse(status=200, data=res_data)
  124. elif is_st == '1':
  125. obj = '{}/{}/{}.jpeg'.format(uid, channel, n_time)
  126. url = bucket.sign_url('PUT', obj, 3600)
  127. res_data = {'code': 0, 'img_push': url, 'msg': 'success 1'}
  128. elif is_st == '3':
  129. img_url_list = []
  130. for i in range(int(is_st)):
  131. obj = '{}/{}/{}_{}.jpeg'.format(uid, channel, n_time, i)
  132. url = bucket.sign_url('PUT', obj, 3600)
  133. img_url_list.append(url)
  134. res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
  135. V1_PUSH_LOGGER.info('旧推送接口响应,uid:{},n_time:{},事件类型:{},响应:{}'.
  136. format(uid, n_time, event_type, json.dumps(res_data)))
  137. return JsonResponse(status=200, data=res_data)
  138. except Exception as e:
  139. V1_PUSH_LOGGER.info('旧推送接口异常,error_line:{},error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  140. data = {
  141. 'error_line': e.__traceback__.tb_lineno,
  142. 'error_msg': repr(e)
  143. }
  144. return JsonResponse(status=200, data=json.dumps(data), safe=False)
  145. def push_and_save_data(**params):
  146. uid = params['uid']
  147. V1_PUSH_LOGGER.info('{}开始异步存表和推送'.format(uid))
  148. # 异步推送消息
  149. push_thread = threading.Thread(
  150. target=DevicePushService.push_msg,
  151. kwargs=params)
  152. push_thread.start()
  153. # 保存推送数据
  154. result = DevicePushService.save_msg_push(**params)
  155. V1_PUSH_LOGGER.info('{}存表结果:{}'.format(uid, result))