AiController.py 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. @Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
  5. @AUTHOR: ASJRD018
  6. @NAME: AnsjerFormal
  7. @software: PyCharm
  8. @DATE: 2018/12/5 9:30
  9. @Version: python3.6
  10. @MODIFY DECORD:ansjer dev
  11. @file: cloudstorage.py
  12. @Contact: chanjunkai@163.com
  13. """
  14. import base64
  15. import json
  16. import os
  17. import time
  18. import urllib
  19. from urllib.parse import quote, parse_qs, unquote
  20. import apns2
  21. import boto3
  22. import jpush
  23. import oss2
  24. import paypalrestsdk
  25. import threading
  26. import calendar
  27. import datetime
  28. import logging
  29. import sys
  30. from aliyunsdkcore import client
  31. from aliyunsdksts.request.v20150401 import AssumeRoleRequest
  32. from boto3.session import Session
  33. from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
  34. from django.db import transaction
  35. from django.views.generic.base import View
  36. import jwt
  37. from Object.ETkObject import ETkObject
  38. from pyfcm import FCMNotification
  39. from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
  40. SERVER_DOMAIN_SSL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN, APNS_MODE, APNS_CONFIG, BASE_DIR, \
  41. JPUSH_CONFIG, FCM_CONFIG, OAUTH_ACCESS_TOKEN_SECRET
  42. from Controller.CheckUserData import DataValid
  43. from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
  44. ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMassModel, SysMsgModel, UidPushModel, \
  45. Unused_Uid_Meal, UIDMainUser, UserModel, PromotionRuleModel, VideoPlaybackTimeModel, CloudLogModel, CouponModel, \
  46. AiStoreMeal, AiService, UidSetModel, Ai_Push_Info
  47. from Object.AWS.S3Email import S3Email
  48. from Object.AliPayObject import AliPayObject
  49. from Object.AliSmsObject import AliSmsObject
  50. from Object.RedisObject import RedisObject
  51. from Object.ResponseObject import ResponseObject
  52. from Object.TokenObject import TokenObject
  53. from Object.UidTokenObject import UidTokenObject
  54. from Service.CommonService import CommonService
  55. from Object.m3u8generate import PlaylistGenerator
  56. from Object.WechatPayObject import WechatPayObject
  57. from django.db.models import Q, F, Count
  58. from Controller.PaymentCycle import Paypal
  59. from decimal import Decimal
  60. from Ansjer.config import SERVER_TYPE
  61. from Service.ModelService import ModelService
  62. from Object import MergePic
  63. import boto3
  64. import botocore
  65. from botocore import client
  66. # AI服务
  67. class AiView(View):
  68. def get(self, request, *args, **kwargs):
  69. request.encoding = 'utf-8'
  70. operation = kwargs.get('operation')
  71. return self.validation(request.GET, request, operation)
  72. def post(self, request, *args, **kwargs):
  73. request.encoding = 'utf-8'
  74. operation = kwargs.get('operation')
  75. return self.validation(request.POST, request, operation)
  76. def validation(self, request_dict, request, operation):
  77. response = ResponseObject()
  78. if operation is None:
  79. return response.json(444, 'error path')
  80. elif operation == 'identification': # ai识别
  81. return self.do_ai_identification(request.POST, response)
  82. else:
  83. token = request_dict.get('token', None)
  84. # 设备主键uid
  85. tko = TokenObject(token)
  86. response.lang = tko.lang
  87. if tko.code != 0:
  88. return response.json(tko.code)
  89. userID = tko.userID
  90. if operation == 'createpayorder': # 创建支付订单
  91. ip = CommonService.get_ip_address(request)
  92. return self.do_create_pay_order(request_dict, userID, ip, response)
  93. elif operation == 'changeaistatus': # 修改云存状态,传送两个url,即getsignsts接口和storeplaylist接口
  94. return self.do_change_ai_status(userID, request_dict, response)
  95. elif operation == 'commoditylist': # 修改云存状态,传送两个url,即getsignsts接口和storeplaylist接口
  96. return self.do_commodity_list(userID, request_dict, response)
  97. elif operation == 'identification': # ai识别
  98. return self.do_ai_identification(request_dict, response)
  99. else:
  100. return response.json(414)
  101. def do_change_ai_status(self, userID, request_dict, response):
  102. token_val = request_dict.get('token_val', None)
  103. appBundleId = request_dict.get('appBundleId', None)
  104. app_type = request_dict.get('app_type', None)
  105. push_type = request_dict.get('push_type', None)
  106. status = request_dict.get('status', None)
  107. m_code = request_dict.get('m_code', None)
  108. uid = request_dict.get('uid', None)
  109. # 设备语言
  110. lang = request_dict.get('lang', 'en')
  111. tz = request_dict.get('tz', '0')
  112. # 消息提醒功能新增
  113. # 如果传空上来,就默认为0
  114. if tz == '':
  115. tz = 0
  116. else:
  117. tz = tz.replace("GMT", "")
  118. detect_group = request_dict.get('detect_group', None)
  119. interval = request_dict.get('interval', None)
  120. if not status:
  121. return response.json(444, 'status')
  122. # 关闭推送
  123. if not all([appBundleId, app_type, token_val, uid, m_code]):
  124. return response.json(444, 'appBundleId,app_type,token_val,uid,m_code')
  125. # 判断推送类型对应key是否存在
  126. print('push_type:', push_type)
  127. if push_type == '0':
  128. if appBundleId not in APNS_CONFIG.keys():
  129. return response.json(904)
  130. elif push_type == '1':
  131. if appBundleId not in FCM_CONFIG.keys():
  132. return response.json(904)
  133. elif push_type == '2':
  134. if appBundleId not in JPUSH_CONFIG.keys():
  135. return response.json(904)
  136. else:
  137. return response.json(173)
  138. hasAiService = AiService.objects.filter(uid=uid,use_status=1)
  139. if not hasAiService.exists():
  140. return response.json(10053)
  141. nowTime = int(time.time())
  142. endTime = hasAiService.values('endTime')[0]['endTime']
  143. if nowTime >endTime:
  144. return response.json(10054)
  145. dvqs = Device_Info.objects.filter(userID_id=userID, UID=uid)
  146. status = int(status)
  147. nowTime = int(time.time())
  148. if dvqs.exists():
  149. # 修改状态
  150. # dvqs.update(NotificationMode=status)
  151. uid_set_qs = UidSetModel.objects.filter(uid=uid)
  152. # uid配置信息是否存在
  153. if uid_set_qs.exists():
  154. uid_set_id = uid_set_qs[0].id
  155. qs_data = {
  156. 'detect_status': status,
  157. 'updTime': nowTime,
  158. }
  159. if interval:
  160. qs_data['detect_interval'] = int(interval)
  161. if detect_group:
  162. qs_data['detect_group'] = detect_group
  163. uid_set_qs.update(**qs_data)
  164. else:
  165. qs_data = {
  166. 'uid': uid,
  167. 'addTime': nowTime,
  168. 'updTime': nowTime,
  169. 'detect_status': status,
  170. }
  171. if interval:
  172. qs_data['detect_interval'] = int(interval)
  173. if detect_group:
  174. qs_data['detect_group'] = detect_group
  175. # 添加设备配置
  176. uid_set_qs = UidSetModel.objects.create(**qs_data)
  177. uid_set_id = uid_set_qs.id
  178. if status == 0:
  179. hasAiService.update(**qs_data)
  180. # UidPushModel.objects.filter(uid_set__uid=uid).delete()
  181. # 状态为0的时候删除redis缓存数据
  182. # self.do_delete_redis(uid)
  183. return response.json(0)
  184. elif status == 1:
  185. hasAiService.update(**qs_data)
  186. uid_push_qs = UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=uid)
  187. if uid_push_qs.exists():
  188. uid_push_update_dict = {
  189. 'appBundleId': appBundleId,
  190. 'app_type': app_type,
  191. 'push_type': push_type,
  192. 'token_val': token_val,
  193. 'updTime': nowTime,
  194. 'lang': lang,
  195. 'tz': tz
  196. }
  197. uid_push_qs.update(**uid_push_update_dict)
  198. else:
  199. # uid_set_id = uid_set_qs[0].id
  200. uid_push_create_dict = {
  201. 'uid_set_id': uid_set_id,
  202. 'userID_id': userID,
  203. 'appBundleId': appBundleId,
  204. 'app_type': app_type,
  205. 'push_type': push_type,
  206. 'token_val': token_val,
  207. 'm_code': m_code,
  208. 'addTime': nowTime,
  209. 'updTime': nowTime,
  210. 'lang': lang,
  211. 'tz': tz
  212. }
  213. # 绑定设备推送
  214. UidPushModel.objects.create(**uid_push_create_dict)
  215. # if interval:
  216. # self.do_delete_redis(uid, int(interval))
  217. # else:
  218. # self.do_delete_redis(uid)
  219. # utko = UidTokenObject()
  220. # # right
  221. # utko.generate(data={'uid': uid})
  222. etkObj = ETkObject(etk='')
  223. etk = etkObj.encrypt(uid)
  224. #只返回一个接口就行
  225. # detectUrl = "{DETECT_PUSH_DOMAIN}AiService/push?etk={etk}&endTime={endTime}". \
  226. # format(etk=etk, DETECT_PUSH_DOMAIN=SERVER_DOMAIN_SSL, endTime=endTime)
  227. aiIdentificationUrl = "{DETECT_PUSH_DOMAIN}AiService/identification".format(DETECT_PUSH_DOMAIN=SERVER_DOMAIN_SSL)
  228. return response.json(0, {'aiIdentificationUrl': aiIdentificationUrl, 'endTime': endTime, 'etk': etk})
  229. else:
  230. return response.json(14)
  231. def do_commodity_list(self, userID, request_dict, response): # 查询套餐列表
  232. uid = request_dict.get('uid', None)
  233. lang = request_dict.get('lang', 'en')
  234. nowTime = int(time.time())
  235. # DVR/NVR设备暂不返回云存套餐列表
  236. device_info_qs = Device_Info.objects.filter(Q(UID=uid), Q(Type__lte=4) | Q(Type=10001))
  237. if device_info_qs.exists():
  238. return response.json(0)
  239. qs = AiStoreMeal.objects
  240. qs = qs.filter(is_show=1) #过滤隐藏套餐
  241. qs = qs.annotate(ai_meal_id=F('id'))
  242. qs = qs.values("ai_meal_id", "title", "content", "price", "effective_day", "currency",
  243. "virtual_price", "symbol", "pay_type")
  244. if qs.exists():
  245. res = list(qs)
  246. for key, val in enumerate(res):
  247. pay_types = Pay_Type.objects.filter(aistoremeal=res[key]['ai_meal_id']).values("id", "payment")
  248. res[key]['pay_type'] = list(pay_types)
  249. result = {
  250. 'meals': res,
  251. }
  252. return response.json(0, result)
  253. else:
  254. return response.json(0)
  255. def do_create_pay_order(self, request_dict, userID, ip, response):
  256. uid = request_dict.get('uid', None)
  257. channel = request_dict.get('channel', None)
  258. pay_type = int(request_dict.get('pay_type', 1))
  259. ai_meal_id = request_dict.get('ai_meal_id', None)
  260. lang = request_dict.get('lang', 'en')
  261. if not uid or not channel or not pay_type or not ai_meal_id:
  262. return response.json(444)
  263. # dv_qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False, isExist=1).values(
  264. # 'vodPrimaryUserID',
  265. # 'vodPrimaryMaster')
  266. # if not dv_qs.exists():
  267. # return response.json(12)
  268. # dvq = Device_Info.objects.filter(UID=uid)
  269. # dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
  270. # if dvq.exists():
  271. # if dvq[0]['vodPrimaryUserID'] != userID:
  272. # return response.json(10033)
  273. nowTime = int(time.time())
  274. smqs = AiStoreMeal.objects.filter(id=ai_meal_id, pay_type=pay_type, is_show=1). \
  275. values('currency', 'price', 'content', 'effective_day', 'title')
  276. if not smqs.exists():
  277. return response.json(173)
  278. currency = smqs[0]['currency']
  279. price = smqs[0]['price']
  280. content = smqs[0]['content']
  281. day = smqs[0]['effective_day']
  282. orderID = CommonService.createOrderID()
  283. price = float(price)
  284. price = round(price, 2)
  285. if pay_type == 1:
  286. #正常扣款
  287. cal_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  288. if lang != 'cn':
  289. cal_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
  290. call_sub_url = "{SERVER_DOMAIN_SSL}cloudstorage/dopaypalcallback?orderID={orderID}&lang={lang}". \
  291. format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL, orderID=orderID, lang=lang)
  292. # call_sub_url = "http://binbin.uicp.vip/cloudstorage/dopaypalcallback?orderID={orderID}".format(
  293. # SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL, orderID=orderID)
  294. Order_Model.objects.create(orderID=orderID, UID=uid, channel=channel, userID_id=userID,
  295. desc=content, payType=pay_type, payTime=nowTime,
  296. price=price, currency=currency, addTime=nowTime, updTime=nowTime,
  297. pay_url='', commodity_code='', commodity_type=1,
  298. ai_rank_id=ai_meal_id, rank_id=1, order_type=1)
  299. has = AiService.objects.filter(uid=uid, channel=channel, use_status=1)
  300. if has.exists():
  301. use_status = 0
  302. else:
  303. use_status = 1
  304. # return response.json(0)
  305. AiService.objects.create(orders_id=orderID, uid=uid, channel=channel, detect_status=0,
  306. endTime=nowTime+(day*86400), addTime=nowTime, updTime=nowTime,
  307. use_status=use_status, detect_group='1')
  308. return response.json(0, {"orderID": orderID})
  309. return response.json(10, 'generate_order_false')
  310. def do_ai_identification(self, request_dict,response):
  311. etk = request_dict.get('etk', None)
  312. now_time = int(time.time())
  313. if etk:
  314. eto = ETkObject(etk)
  315. uid = eto.uid
  316. ##通过uid查出endTime是否过期,并且ai开关是否打开
  317. AiServiceQuery = AiService.objects.filter(uid=uid, detect_status=0, use_status=1, endTime__gt=now_time).\
  318. values('detect_group')
  319. if not AiServiceQuery.exists():
  320. return JsonResponse(status=500, data='ai_service_invalid', safe=False)
  321. detect_group = AiServiceQuery[0]['detect_group']
  322. #{}??
  323. #
  324. file_post_one = request_dict.get('fileOne', None)
  325. file_post_two = request_dict.get('fileTwo', None)
  326. file_post_three = request_dict.get('fileThree', None)
  327. file_post_one = file_post_one.replace(' ', '+')
  328. file_post_two = file_post_two.replace(' ', '+')
  329. file_post_three = file_post_three.replace(' ', '+')
  330. file_post_one = base64.b64decode(file_post_one)
  331. file_post_two = base64.b64decode(file_post_two)
  332. file_post_three = base64.b64decode(file_post_three)
  333. file_list = [file_post_one, file_post_two, file_post_three]
  334. del file_post_one, file_post_two, file_post_three
  335. dir_path = os.path.join(BASE_DIR, 'static/ai/' + uid + '/' + str(now_time))
  336. if not os.path.exists(dir_path):
  337. os.makedirs(dir_path)
  338. file_path_list = []
  339. i = 1
  340. for index in file_list:
  341. file_path = dir_path + '/' + str(i) + '.jpg'
  342. file_path_list.append(file_path)
  343. with open(file_path, 'wb') as f:
  344. f.write(index)
  345. f.close()
  346. i += 1
  347. image_size = 500 # 每张小图片的大小
  348. image_colnum = 1 # 合并成一张图后,一行有几个小图
  349. MergePic.merge_images(dir_path, image_size, image_colnum)
  350. photo = open(dir_path + '.jpg', 'rb') #打开合成图
  351. cover = dir_path + '/' + str(i-1) + '.jpg'
  352. desc = dir_path + '.jpg'
  353. # photo = open(r'E:\test---------------\test\snipaste20220121_215952.jpg', 'rb')
  354. #识别合成图片
  355. maxLabels = 50
  356. minConfidence = 96
  357. try:
  358. client = boto3.client(
  359. 'rekognition',
  360. aws_access_key_id='AKIA2E67UIMD6JD6TN3J',
  361. aws_secret_access_key='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',
  362. region_name='us-east-1')
  363. # doc:
  364. rekognition_res = client.detect_labels(
  365. Image={
  366. 'Bytes': photo.read()},
  367. MaxLabels=maxLabels,
  368. MinConfidence=minConfidence)
  369. if rekognition_res['ResponseMetadata']['HTTPStatusCode'] != 200:
  370. return response.json(173)
  371. labels =rekognition_res['Labels']
  372. label_name = []
  373. for label in labels:
  374. label_name.append(label['Name'])
  375. for Parents in label['Parents']:
  376. label_name.append(Parents['Name'])
  377. labels = self.checkLabels(detect_group, label_name) #检查标签是否符合用户选择的识别类型
  378. if len(labels['label_list']) == 0:
  379. return JsonResponse(status=500, data='label_list_none')
  380. event_type = ','.join(labels['label_type'])
  381. #存储消息以及推送
  382. channel = request_dict.get('channel', '1')
  383. n_time = now_time
  384. # event_type = request_dict.get('event_type', None)
  385. is_st = 1 #单图
  386. region = 1
  387. # uid = request_dict.get('uid', None) # 调试
  388. # 判断uid长度
  389. if len(uid) != 20 and len(uid) != 14:
  390. return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong uid'})
  391. # pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, channel=channel, event_type=event_type)
  392. # redisObj = RedisObject(db=6)
  393. # have_pkey = redisObj.get_data(key=pkey) # 一分钟限制key
  394. #
  395. # # 一分钟内不推送
  396. # if have_pkey:
  397. # return JsonResponse(status=200, data={'code': 0, 'msg': 'Push again in one minute'})
  398. # redisObj.set_data(key=pkey, val=1, expire=60)
  399. # 查询推送数据
  400. uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid). \
  401. values('token_val', 'app_type', 'appBundleId', 'm_code', 'push_type', 'userID_id',
  402. 'userID__NickName',
  403. 'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval',
  404. 'uid_set__detect_group',
  405. 'uid_set__channel')
  406. if not uid_push_qs.exists():
  407. return JsonResponse(status=200, data={'code': 176, 'msg': 'no uid_push data'})
  408. redis_list = []
  409. for qs in uid_push_qs:
  410. redis_list.append(qs)
  411. nickname = redis_list[0]['uid_set__nickname']
  412. if not nickname:
  413. nickname = uid
  414. kwag_args = {
  415. 'uid': uid,
  416. 'channel': channel,
  417. 'event_type': event_type,
  418. 'n_time': n_time,
  419. }
  420. eq_list = []
  421. userID_ids = []
  422. do_apns_code = ''
  423. do_fcm_code = ''
  424. do_jpush_code = ''
  425. for up in redis_list:
  426. # push_type = up['push_type']
  427. # appBundleId = up['appBundleId']
  428. # token_val = up['token_val']
  429. # lang = up['lang']
  430. # tz = up['tz']
  431. # if tz is None or tz == '':
  432. # tz = 0
  433. # 发送标题
  434. # msg_title = self.get_msg_title(appBundleId=appBundleId, nickname=nickname)
  435. # # 发送内容
  436. # msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
  437. # event_type=event_type)
  438. # kwag_args['appBundleId'] = appBundleId
  439. # kwag_args['token_val'] = token_val
  440. # kwag_args['msg_title'] = msg_title
  441. # kwag_args['msg_text'] = msg_text
  442. # 推送消息
  443. # if push_type == 0: # ios apns
  444. # do_apns_code = self.do_apns(**kwag_args)
  445. # elif push_type == 1: # android gcm
  446. # do_fcm_code = self.do_fcm(**kwag_args)
  447. # elif push_type == 2: # android jpush
  448. # do_jpush_code = self.do_jpush(**kwag_args)
  449. # 以下是存库
  450. userID_id = up["userID_id"]
  451. if userID_id not in userID_ids:
  452. now_time = int(time.time())
  453. eq_list.append(Ai_Push_Info(
  454. userID_id=userID_id,
  455. eventTime=n_time,
  456. eventType=event_type,
  457. devUid=uid,
  458. devNickName=nickname,
  459. Channel=channel,
  460. alarm='检查到{labels} \tChannel:{channel}'.format(labels=','.join(labels['label_list']), channel=channel),
  461. is_st=is_st,
  462. receiveTime=n_time,
  463. addTime=now_time,
  464. storage_location=2
  465. ))
  466. userID_ids.append(userID_id)
  467. Ai_Push_Info.objects.bulk_create(eq_list)
  468. #上传缩略图到s3
  469. upload_cover_path = "{uid}/{channel}/cover{n_time}.jpg".format(uid=uid, channel=channel, n_time=n_time) #封面图
  470. upload_desc_path = "{uid}/{channel}/desc{n_time}.jpg".format(uid=uid, channel=channel, n_time=n_time) #详情内容图
  471. c_res = self.upload_s3(cover, upload_cover_path)
  472. d_res = self.upload_s3(desc, upload_desc_path)
  473. if c_res and d_res:
  474. return JsonResponse(status=200, data='success', safe=False)
  475. return JsonResponse(status=500, data='fail', safe=False)
  476. except Exception as e:
  477. print(e)
  478. return response.json(500, repr(e))
  479. else:
  480. return HttpResponse("fail")
  481. ## 检查是否有符合条件的标签
  482. def checkLabels(self, user_detect_group, labels):
  483. labels_type = {
  484. '1': ['Person', 'Human'], #人
  485. '2': ['Dog', 'Pet', 'Canine', 'Animal'], #动物
  486. '3': ['Car', '', 'Vehicle', 'Transportation', 'Automobile'] #车
  487. }
  488. user_detect_list = user_detect_group.split(',')
  489. user_labels_type = {}
  490. for user_detect in user_detect_list:
  491. if user_detect in labels_type.keys():
  492. user_labels_type[user_detect] = labels_type[user_detect]
  493. label_list = []
  494. for k, labels_type in user_labels_type.items():
  495. for label in labels_type:
  496. if label in labels:
  497. label_list.append(label)
  498. return {'label_type': user_labels_type.keys(), 'label_list': label_list}
  499. def upload_s3(self, file_path, upload_path):
  500. try:
  501. aws_key = "AKIA2MMWBR4DSFG67DTG" #【你的 aws_access_key】
  502. aws_secret = "aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL" # 【你的 aws_secret_key】
  503. session = Session(aws_access_key_id=aws_key,
  504. aws_secret_access_key=aws_secret,
  505. region_name="cn-northwest-1")
  506. s3 = session.resource("s3")
  507. # client = session.client("s3")
  508. bucket = "aipush" # 【你 bucket 的名字】 # 首先需要保.证 s3 上已经存在该存储桶,否则报错
  509. upload_data = open(file_path, "rb")
  510. # upload_key = "test"
  511. s3.Bucket(bucket).put_object(Key=upload_path, Body=upload_data)
  512. return True
  513. except Exception as e:
  514. print(repr(e))
  515. return False
  516. def get_msg_title(self, appBundleId, nickname):
  517. package_title_config = {
  518. 'com.ansjer.customizedd_a': 'DVS',
  519. 'com.ansjer.zccloud_a': 'ZosiSmart',
  520. 'com.ansjer.zccloud_ab': '周视',
  521. 'com.ansjer.adcloud_a': 'ADCloud',
  522. 'com.ansjer.adcloud_ab': 'ADCloud',
  523. 'com.ansjer.accloud_a': 'ACCloud',
  524. 'com.ansjer.loocamccloud_a': 'Loocam',
  525. 'com.ansjer.loocamdcloud_a': 'Anlapus',
  526. 'com.ansjer.customizedb_a': 'COCOONHD',
  527. 'com.ansjer.customizeda_a': 'Guardian365',
  528. 'com.ansjer.customizedc_a': 'PatrolSecure',
  529. }
  530. if appBundleId in package_title_config.keys():
  531. return package_title_config[appBundleId] + '(' + nickname + ')'
  532. else:
  533. return nickname
  534. def is_sys_msg(self, event_type):
  535. event_type_list = [702, 703, 704]
  536. if event_type in event_type_list:
  537. return True
  538. return False
  539. def get_msg_text(self, channel, n_time, lang, tz, event_type, is_sys=0):
  540. n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz,lang=lang)
  541. etype = int(event_type)
  542. if lang == 'cn':
  543. if etype == 704:
  544. msg_type = '电量过低'
  545. elif etype == 702:
  546. msg_type = '摄像头休眠'
  547. elif etype == 703:
  548. msg_type = '摄像头唤醒'
  549. else:
  550. msg_type = ''
  551. if is_sys:
  552. send_text = '{msg_type} 通道:{channel}'.format(msg_type=msg_type, channel=channel)
  553. else:
  554. send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
  555. # send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
  556. else:
  557. if etype == 704:
  558. msg_type = 'Low battery'
  559. elif etype == 702:
  560. msg_type = 'Camera sleep'
  561. elif etype == 703:
  562. msg_type = 'Camera wake'
  563. else:
  564. msg_type = ''
  565. if is_sys:
  566. send_text = '{msg_type} channel:{channel}'. \
  567. format(msg_type=msg_type, channel=channel)
  568. else:
  569. send_text = '{msg_type} channel:{channel} date:{date}'. \
  570. format(msg_type=msg_type, channel=channel, date=n_date)
  571. return send_text
  572. def do_jpush(self, uid, channel, appBundleId, token_val, event_type, n_time,
  573. msg_title, msg_text):
  574. app_key = JPUSH_CONFIG[appBundleId]['Key']
  575. master_secret = JPUSH_CONFIG[appBundleId]['Secret']
  576. # 此处换成各自的app_key和master_secre
  577. _jpush = jpush.JPush(app_key, master_secret)
  578. push = _jpush.create_push()
  579. # if you set the logging level to "DEBUG",it will show the debug logging.
  580. # _jpush.set_logging("DEBUG")
  581. # push.audience = jpush.all_
  582. push.audience = jpush.registration_id(token_val)
  583. push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
  584. "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
  585. android = jpush.android(alert=msg_text, priority=1, style=1, alert_type=7,
  586. big_text=msg_text, title=msg_title,
  587. extras=push_data)
  588. push.notification = jpush.notification(android=android)
  589. push.platform = jpush.all_
  590. res = push.send()
  591. print(res)
  592. return res.status_code
  593. # try:
  594. # res = push.send()
  595. # print(res)
  596. # except Exception as e:
  597. # print("jpush fail")
  598. # print("Exception")
  599. # print(repr(e))
  600. # return
  601. # else:
  602. # print("jpush success")
  603. # return
  604. def do_fcm(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title, msg_text):
  605. try:
  606. serverKey = FCM_CONFIG[appBundleId]
  607. except Exception as e:
  608. return 'serverKey abnormal'
  609. push_service = FCMNotification(api_key=serverKey)
  610. data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
  611. "received_at": n_time, "sound": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
  612. result = push_service.notify_single_device(registration_id=token_val, message_title=msg_title,
  613. message_body=msg_text, data_message=data,
  614. extra_kwargs={
  615. 'default_vibrate_timings': True,
  616. 'default_sound': True,
  617. 'default_light_settings': True
  618. })
  619. print('fcm push ing')
  620. print(result)
  621. return result
  622. def do_apns(self, uid, channel, appBundleId, token_val, event_type, n_time, msg_title,
  623. msg_text):
  624. logger = logging.getLogger('info')
  625. logger.info("进来do_apns函数了")
  626. logger.info(token_val)
  627. logger.info(APNS_MODE)
  628. logger.info(os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
  629. try:
  630. cli = apns2.APNSClient(mode=APNS_MODE,
  631. client_cert=os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
  632. push_data = {"alert": "Motion ", "event_time": n_time, "event_type": event_type, "msg": "",
  633. "received_at": n_time, "sound": "", "uid": uid, "zpush": "1", "channel": channel}
  634. alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
  635. payload = apns2.Payload(alert=alert, custom=push_data, sound="default")
  636. # return uid, channel, appBundleId, str(token_val), event_type, n_time, msg_title,msg_text
  637. n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
  638. res = cli.push(n=n, device_token=token_val, topic=appBundleId)
  639. print(res.status_code)
  640. logger.info("推送状态:")
  641. logger.info(res.status_code)
  642. # 200, 推送成功。
  643. #   400, 请求有问题。
  644. #   403, 证书或Token有问题。
  645. #   405, 请求方式不正确, 只支持POST请求
  646. #   410, 设备的Token与证书不一致
  647. if res.status_code == 200:
  648. return res.status_code
  649. else:
  650. print('apns push fail')
  651. print(res.reason)
  652. logger.info('apns push fail')
  653. logger.info(res.reason)
  654. return res.status_code
  655. except (ValueError, ArithmeticError):
  656. return 'The program has a numeric format exception, one of the arithmetic exceptions'
  657. except Exception as e:
  658. print(repr(e))
  659. logger.info(repr(e))
  660. return repr(e)