Explorar el Código

Merge branch 'master' of http://192.168.136.99:3000/SERVER/AnsjerServer

chenshibin hace 4 años
padre
commit
32913dad87

+ 110 - 52
Ansjer/config.py

@@ -81,58 +81,7 @@ elif SERVER_TYPE == 'Ansjer.test_settings':
     from Ansjer.config_test import *
 elif SERVER_TYPE == 'Ansjer.formal_settings':
     from Ansjer.config_formal import *
-# type =2
-JPUSH_CONFIG = {
-    'com.ansjer.accloud_ab': {
-        'Key': 'f0dc047e5e53fd14199de5b0',
-        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
-    'com.ansjer.adcloud_ab': {
-        'Key': '76d97b535185114985608234',
-        'Secret': 'c9a92b301043cc9c52778692'},
-    'com.ansjer.zccloud_ab': {
-        'Key': 'd9924f56d3cc7c6017965130',
-        'Secret': '869d832d126a232f158b5987'},
-    'com.ansjer.loocamccloud_ab': {
-        'Key': 'd1cc44797b4642b0e05304fe',
-        'Secret': 'c3e8b4ca8c576de61401e56a'},
-    'com.ansjer.loocamdcloud_ab': {
-        'Key': '76d97b535185114985608234',
-        'Secret': 'c9a92b301043cc9c52778692'},
-    'com.ansjer.zccloud_a': {
-        'Key': '57de2a80d68bf270fd6bdf5a',
-        'Secret': '3d354eb6a0b49c2610decf42'},
-    'com.ansjer.accloud_a': {
-        'Key': 'ff95ee685f49c0dc4013347b',
-        'Secret': 'de2c20959f5516fdeeafe78e'},
-    'com.ansjer.adcloud_a': {
-        'Key': '2e47eb1aee9b164460df3668',
-        'Secret': 'b9137d8d684bc248f1809b6d'},
-    'com.ansjer.loocamccloud_a': {
-        'Key': '23c9213215c7ca0ec945629b',
-        'Secret': '81e4b1e859cc8387e2e6c431'},
-    'com.ansjer.loocamdcloud_a': {
-        'Key': '1dbdd60a16e9892d6f68a073',
-        'Secret': '80a97690e7e043109059b403'},
-    'com.ansjer.customizedb_a': {
-        'Key': '9d79630aa49adfa291fe2568',
-        'Secret': '4d8ff52f88136561875a0212'},
-    'com.ansjer.customizedd_a': {
-        'Key': '8fc4f495685bde53341ee25d',
-        'Secret': 'f1da11fa466509fa2670fb66',
-    }
-}
-# type =1
-FCM_CONFIG = {
-    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
-    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
-    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
-    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
-    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
-    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
-    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
-    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
-    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
-}
+
 
 DEVICE_TYPE = {
     0: 'UNKOWN',
@@ -345,3 +294,112 @@ SALES = {
     ]
 
 }
+
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/lcc-dev.pem',
+    },
+    'com.ansjer.zosidcloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/zosidcloud-dev.pem',
+    },
+    'com.ansjer.customizedb': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizedb-dev.pem',
+    },
+    'com.ansjer.customizeda': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizeda-dev.pem',
+    },
+    'com.ansjer.zccloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/zccloud-dev.pem',
+    },
+    'com.ansjer.accloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizedc':{
+        'pem_path': 'AnsjerPush/file/apns_pem/customizedc.pem',
+    },
+    'com.ansjer.customizede': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizede.pem',
+    },
+}
+APNS_MODE = 'dev'
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+
+JPUSH_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '错误请求',
+    401: '没有验证信息或者验证失败',
+    403: '请求被拒绝',
+    404: '资源不存在,请求的用户的不存在,请求的格式不被支持',
+    405: '请求方法不合适',
+    410: '请求的资源已下线',
+    429: '请求超出了频率限制',
+    500: '极光内部服务错误',
+    502: '业务服务器下线了或者正在升级。请稍后重试',
+    503: '服务暂时失效',
+    504: '代理超时'
+}
+APNS_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '请求有问题',
+    403: '证书或Token有问题',
+    405: '请求方式不正确, 只支持POST请求',
+    410: '设备的Token与证书不一致'
+}
+APP_TYPE = {
+    1: 'ios',
+    2: 'android'
+}

+ 64 - 13
Ansjer/config_formal.py

@@ -11,6 +11,8 @@
 @file: config_formal.py
 @Contact: chanjunkai@163.com
 """
+import os
+
 NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
 SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
 SERVER_DOMAIN = 'http://www.dvema.com/'
@@ -35,38 +37,87 @@ DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 USER_BRAND = 'user_brand'
 USER_BRAND_ALL = 'user_brand_all'
 
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
 APNS_CONFIG = {
     'com.ansjer.loocamccloud': {
-        'pem_path': 'Ansjer/file/apns_pem/lcc.pem',
+        'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
     },
     'com.ansjer.zosidcloud': {
-        'pem_path': 'Ansjer/file/apns_pem/zosidcloud.pem',
+        'pem_path': 'Ansjer/file/apns_pem/zosidcloud-dev.pem',
     },
     'com.ansjer.customizedb': {
-        'pem_path': 'Ansjer/file/apns_pem/customizedb.pem',
-    },
-    'com.ansjer.customizedd': {
-        'pem_path': 'Ansjer/file/apns_pem/customizedd.pem',
-    },
-    'com.ansjer.customizede': {
-        'pem_path': 'Ansjer/file/apns_pem/customizede.pem',
+        'pem_path': 'Ansjer/file/apns_pem/customizedb-dev.pem',
     },
     'com.ansjer.customizeda': {
-        'pem_path': 'Ansjer/file/apns_pem/customizeda.pem',
+        'pem_path': 'Ansjer/file/apns_pem/customizeda-dev.pem',
     },
     'com.ansjer.zccloud': {
-        'pem_path': 'Ansjer/file/apns_pem/zccloud.pem',
+        'pem_path': 'Ansjer/file/apns_pem/zccloud-dev.pem',
     },
     'com.ansjer.accloud': {
         'pem_path': 'Ansjer/file/apns_pem/accloud-dev.pem',
     },
-    'com.ansjer.adcloud': {
-        'pem_path': 'Ansjer/file/apns_pem/apns-dis-adcloud.pem',
+    'com.ansjer.customizede': {
+        'pem_path': 'Ansjer/file/apns_pem/ZhouShi-dev.pem',
     },
     'com.ansjer.customizedc': {
         'pem_path': 'Ansjer/file/apns_pem/customizedc.pem',
     }
 }
 APNS_MODE = 'prod'
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
 
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 60 - 2
Ansjer/config_test.py

@@ -11,6 +11,8 @@
 @file: config_test.py
 @Contact: chanjunkai@163.com
 """
+import os
+
 NGINX_RTMP_STAT = 'http://test.dvema.com/stat'
 SERVER_DOMAIN = 'http://test.dvema.com/'
 SERVER_DOMAIN_SSL = 'https://test.dvema.com/'
@@ -38,14 +40,66 @@ PAYPAL_CRD = {
 #     "client_id": "ATXTpWs8sajNYeU46jNs1yzpy4H_o3RRrGVIJ8Tscc312BjMx12cpRgCucfWX07a4G6GbK8hzElB04Pd",
 #     "client_secret": "EHcnfrpL1o1ev9WnlQ-C1uymeRKDoJ6li6Y0d6iHoRGj4u8Sx5lSEEH774XphP4LQZ0DrDUdvxbux0T2"
 # }
-DETECT_PUSH_DOMAIN = 'http://push.dvema.com/'
-DETECT_PUSH_DOMAINS = 'https://push.dvema.com/'
+DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://test.push.dvema.com/'
 DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
 DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 # 数据库dyanamo品牌日志数据库
 USER_BRAND = 'test_user_brand'
 USER_BRAND_ALL = 'test_user_brand_all'
 
+# type =2
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
 APNS_CONFIG = {
     'com.ansjer.loocamccloud': {
         'pem_path': 'Ansjer/file/apns_pem/lcc-dev.pem',
@@ -72,5 +126,9 @@ APNS_CONFIG = {
         'pem_path': 'Ansjer/file/apns_pem/customizedc.pem',
     }
 }
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 APNS_MODE = 'dev'
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+
 TUTK_PUSH_DOMAIN = 'http://push.iotcplatform.com/tpns'

+ 30 - 14
Ansjer/formal_settings.py

@@ -195,6 +195,10 @@ LOGGING = {
             # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
             'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
         },
+        'standard': {
+            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
+                      '[%(levelname)s]- %(message)s'},
+
     },
     'filters': {
     },
@@ -206,10 +210,10 @@ LOGGING = {
         },
         'default': {
             'level': 'ERROR',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/error.log',
-            'maxBytes': 1024 * 1024 * 5,  # 5 MB
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'error_format',
         },
         'console': {
@@ -217,22 +221,34 @@ LOGGING = {
             'class': 'logging.StreamHandler',
             'formatter': 'error_format'
         },
-        # 'info': {  # 向文件中输出日志
-        #     'level': 'INFO',
-        #     'class': 'logging.handlers.RotatingFileHandler',
-        #     'filename': BASE_DIR + '/static/log/print.log',  # 日志文件的位置
-        #     'maxBytes': 20 * 1024 * 1024,  # 20M大小
-        #     'backupCount': 10,
-        #     'formatter': 'verbose',
-        #     'encoding': 'utf-8'
-        # },
+        'info': {
+            'level': 'INFO',
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
+            'formatter': 'standard',
+            'encoding': 'utf-8',
+        },
     },
     'loggers': {
         'django': {
             'handlers': ['default', 'console'],
             # 'handlers': ['mail_admins','default','console'],
+            # 'level': 'ERROR',
             'level': 'ERROR',
             'propagate': False
         },
+        # log 调用时需要当作参数传入
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
+        # 'django.db.backends': {
+        #     'handlers': ['console'],
+        #     'propagate': True,
+        #     'level': 'DEBUG',
+        # },
     }
-}
+}

+ 12 - 9
Ansjer/formal_zositech_help_weekly_task.py

@@ -19,28 +19,31 @@ res = requests.post(url=login_url, data=data)
 res = res.json()
 
 if res['result_code'] == 0:
-    isbool = True
-    while isbool:
+    request_times = 0
+    while request_times < 5:
         try:
             statistics_url = base_url + 'faq/synZositechHelp'
-            zhcnDatares = requests.get(
-                url='https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=zh-cn&section=null&origin=web_widget', timeout=1).text
-
-            enusDatares = requests.get(
-                url='https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=en-us&section=null&origin=web_widget', timeout=1).text
+            # zh_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=zh-cn&section=null&origin=web_widget'
+            zh_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/zh-cn/articles.json?page%5Bsize%5D=100'
+            zhcnDatares = requests.get(url=zh_url, timeout=10).text
 
+            en_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/en-us/articles.json?page%5Bsize%5D=100'
+            # en_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=en-us&section=null&origin=web_widget'
+            enusDatares = requests.get(url=en_url, timeout=10).text
             data = {
                 'token': res['result']['access_token'],
                 'zhresults': zhcnDatares,
                 'enresults': enusDatares
             }
-            isbool = False
             res = requests.post(url=statistics_url, data=data)
 
         except Exception as e:
-            isbool=True
+            print(e)
+            request_times += 1
+            print(request_times)
             time.sleep(3)
 
+print('success')
 
 
 

+ 199 - 0
Ansjer/pushconfig.py

@@ -0,0 +1,199 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: Ansjer
+@software: PyCharm
+@DATE: 2018/7/2 14:06
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: Conf.py
+@Contact: chanjunkai@163.com
+"""
+# 主要静态变量配置文件
+import datetime, os
+
+
+DEBUG_MODE = 'DEV'
+# MODE = 'PRO'
+# 阿里云发邮箱
+ALY_SES_ACCESS_NAME = 'message@dvema.com'
+ALY_SES_ACCESS_PAW = 'SMtp123456'
+ALY_SES_ACCESS_REPLYTO = '***'
+
+# 发送邮件邮箱
+SES_COMPANY_EMAIL = 'user_server@nsst.com'
+AWS_SES_ACCESS_ID = 'AKIAJKPU23EU5QWHFPKQ'
+AWS_SES_ACCESS_SECRET = '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'
+AWS_SES_ACCESS_REGION = 'us-east-1'
+AWS_BUCKET = 'ansjertest'
+# 设定离线时间为5分钟
+OFF_LINE_TIME_DELTA = 5
+
+# token的secret
+OAUTH_ACCESS_TOKEN_SECRET = 'a+jbgnw%@1%zy^=@dn62%'
+OAUTH_REFRESH_TOKEN_SECRET = 'r+jbgnw%@1%zy^=@dn62%'
+# access_token超时
+# OAUTH_ACCESS_TOKEN_TIME = datetime.timedelta(hours=1)
+OAUTH_ACCESS_TOKEN_TIME = datetime.timedelta(days=30)
+# refresh_token超时
+OAUTH_REFRESH_TOKEN_TIME = datetime.timedelta(days=30)
+# 腾讯验证,短信发送
+TX_PHONE_APP_ID = '1400052907'
+TX_PHONE_APP_KEY = '7705976ca6e85fe7b86d6bc2d11f7783'
+
+# 验证码超时时间
+AuthCode_Expire = 600
+
+# 根路径
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+# uid token key
+UID_TOKEN_KEY = 'c+565*j@%^'
+
+# oss param
+OSS_STS_ACCESS_KEY = 'LTAIyMkGfEdogyL9'
+OSS_STS_ACCESS_SECRET = '71uIjpsqVOmF7DAITRyRuc259jHOjO'
+OSS_ROLE_ARN = 'acs:ram::1901342792446414:role/stsoss'
+
+# aws api key
+AWS_ACCESS_KEY_ID = ['AKIA2MMWBR4DSFG67DTG', 'AKIA2E67UIMD45Y3HL53']  # 0国内, 1国外
+AWS_SECRET_ACCESS_KEY = ['aI9gxcAKPmiGgPy9axrtFKzjYGbvpuytEX4xWweL', 'ckYLg4Lo9ZXJIcJEAKkzf2rWvs8Xth1FCjqiAqUw']
+AWS_ARN = ['arn:aws-cn:s3', 'arn:aws:s3']
+
+
+NGINX_RTMP_STAT = 'http://www.dvema.com/stat'
+SERVER_DOMAIN = 'http://www.dvema.com/'
+SERVER_DOMAIN_SSL = 'https://www.dvema.com/'
+DOMAIN_HOST = 'www.dvema.com'
+# SERVER_HOST = 'localhost'
+PAYPAL_CRD = {
+    "mode": "live",  # sandbox or live
+    "client_id": "AdSRd6WBn-qLl9OiQHQuNYTDFSx0ZX0RUttqa58au8bPzoGYQUrt8bc6591RmH8_pEAIPijdvVYSVXyI",
+    "client_secret": "ENT-J08N3Fw0B0uAokg4RukljAwO9hFHPf8whE6-Dwd8oBWJO8AWMgpdTKpfB1pOy89t4bsFEzMWDowm"
+}
+DETECT_PUSH_DOMAIN = 'http://push.dvema.com/'
+
+
+JPUSH_CONFIG = {
+    'com.ansjer.accloud_ab': {
+        'Key': 'f0dc047e5e53fd14199de5b0',
+        'Secret': 'aa7f7db33e9f0a7f3871aa1c'},
+    'com.ansjer.adcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_ab': {
+        'Key': 'd9924f56d3cc7c6017965130',
+        'Secret': '869d832d126a232f158b5987'},
+    'com.ansjer.loocamccloud_ab': {
+        'Key': 'd1cc44797b4642b0e05304fe',
+        'Secret': 'c3e8b4ca8c576de61401e56a'},
+    'com.ansjer.loocamdcloud_ab': {
+        'Key': '76d97b535185114985608234',
+        'Secret': 'c9a92b301043cc9c52778692'},
+    'com.ansjer.zccloud_a': {
+        'Key': '57de2a80d68bf270fd6bdf5a',
+        'Secret': '3d354eb6a0b49c2610decf42'},
+    'com.ansjer.accloud_a': {
+        'Key': 'ff95ee685f49c0dc4013347b',
+        'Secret': 'de2c20959f5516fdeeafe78e'},
+    'com.ansjer.adcloud_a': {
+        'Key': '2e47eb1aee9b164460df3668',
+        'Secret': 'b9137d8d684bc248f1809b6d'},
+    'com.ansjer.loocamccloud_a': {
+        'Key': '23c9213215c7ca0ec945629b',
+        'Secret': '81e4b1e859cc8387e2e6c431'},
+    'com.ansjer.loocamdcloud_a': {
+        'Key': '1dbdd60a16e9892d6f68a073',
+        'Secret': '80a97690e7e043109059b403'},
+    'com.ansjer.customizedb_a': {
+        'Key': '9d79630aa49adfa291fe2568',
+        'Secret': '4d8ff52f88136561875a0212'},
+    'com.ansjer.customizedd_a': {
+        'Key': '8fc4f495685bde53341ee25d',
+        'Secret': 'f1da11fa466509fa2670fb66',
+    }
+}
+# type =1
+FCM_CONFIG = {
+    'com.ansjer.zccloud_a': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+    'com.ansjer.loocamccloud_a': 'AAAAb9YP3rk:APA91bFCgd-kbVmpK4EVpfdHH_PJZQCYTkOGnTZdIuBWEz2r7aMRsJYHOH3sB-rwcbaRWgnufTyjX9nGQxb6KxQbWVk4ah_H-M3IqGh6Mb60WQQAuR33V6g_Jes5pGL6ViuIxGHqVMaR',
+    'com.ansjer.loocamdcloud_a': 'AAAAb9YP3rk:APA91bGw2I2KMD4i-5T7nZO_wB8kuAOuqgyqe5rxmY-W5qkpYEx9IL2IfmC_qf6B_xOyjIDDSjckvMo-RauN__SEoxvAkis7042GRkoKpw7cjZ_H8lC-d50PC0GclPzccrOGFusyKbFY',
+    'com.ansjer.customizedb_a': 'AAAAb9YP3rk:APA91bE7kI4vcm-9h_CJNFlOZfc-xwP4Btn6AnjOrwoKV6fgYN7fdarkO76sYxVZiAbDnxsFfOJyP7vQfwyan6mdjuyD5iHdt_XgO22VqniC0vA1V4GJiCS8Tp7LxIX8JVKZl9I_Powt',
+    'com.ansjer.customizeda_a': 'AAAAb9YP3rk:APA91bF0HzizVWDc6dKzobY9fsaKDK4veqkOZehDXshVXs8pEEvNWjR_YWbhP60wsRYCHCal8fWN5cECVOWNMMzDsfU88Ty2AUl8S5FtZsmeDTkoGntQOswBr8Ln7Fm_LAp1VqTf9CpM',
+    'com.ansjer.customizedd_a': 'AAAAb9YP3rk:APA91bHkxOozJWBrlv3eNT0PgwosYENI9aM4Zuzd418cX-iKkpa1zFNC5MkNDKApx1KH4fhmAfaJ6IMRZ0nj5GIxCpstDYCaZWwgC7-etqfSxG5JAq8LOwJx0o_1tUZqwjIic8ztsg0o',
+    'com.ansjer.adcloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.accloud_a': 'AAAAb9YP3rk:APA91bFm06w8b9OKQ0gz0iaWFuRqRIkvgAz6z7Gp3dBU_X-LNGJQd1hc1QR2W7QzBglF8SHtERA45a2lbdLRa5qv7hxfd6W_sJLBK7dA8jklsOQBvy505oUzTwMKWy4TwH-exps9KrhO',
+    'com.ansjer.zccloud_ab': 'AAAAb9YP3rk:APA91bHu8u-CTpcd0g6lKPo0WNVqCi8jZub1cPPbSAY9AucT1HxlF65ZDUko9iG8q2ch17bwu9YWHpK1xI1gHSRXCslLvZlXEmHZC0AG3JKg15XuUvlFKACIajUFV-pOeGRT8tM6-31I',
+}
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+
+APNS_CONFIG = {
+    'com.ansjer.loocamccloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/lcc-dev.pem',
+    },
+    'com.ansjer.zosidcloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/zosidcloud-dev.pem',
+    },
+    'com.ansjer.customizedb': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizedb-dev.pem',
+    },
+    'com.ansjer.customizeda': {
+        'pem_path': 'AnsjerPush/file/apns_pem/customizeda-dev.pem',
+    },
+    'com.ansjer.zccloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/zccloud-dev.pem',
+    },
+    'com.ansjer.accloud': {
+        'pem_path': 'AnsjerPush/file/apns_pem/accloud-dev.pem',
+    },
+    'com.ansjer.customizedc':{
+        'pem_path': 'AnsjerPush/file/apns_pem/customizedc.pem',
+    }
+}
+APNS_MODE = 'dev'
+REDIS_ADDRESS = '127.0.0.1'
+
+if SERVER_TYPE == 'AnsjerPush.local_settings':
+    from AnsjerPush.local_config import *
+elif SERVER_TYPE == 'AnsjerPush.test_settings':
+    from AnsjerPush.test_config import *
+elif SERVER_TYPE == 'AnsjerPush.formal_settings':
+    from AnsjerPush.formal_config import *
+
+APNS_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '请求有问题',
+    403: '证书或Token有问题',
+    405: '请求方式不正确, 只支持POST请求',
+    410: '设备的Token与证书不一致'
+}
+
+JPUSH_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '错误请求',
+    401: '没有验证信息或者验证失败',
+    403: '请求被拒绝',
+    404: '资源不存在,请求的用户的不存在,请求的格式不被支持',
+    405: '请求方法不合适',
+    410: '请求的资源已下线',
+    429: '请求超出了频率限制',
+    500: '极光内部服务错误',
+    502: '业务服务器下线了或者正在升级。请稍后重试',
+    503: '服务暂时失效',
+    504: '代理超时'
+}
+
+FCM_CODE = {
+    -1: '只库存不推送',
+    200: '推送成功',
+    400: '无效数据',
+    401: '没有验证信息或者验证失败'
+}
+
+APP_TYPE = {
+    1: 'ios',
+    2: 'android'
+}

+ 19 - 37
Ansjer/test_settings.py

@@ -88,12 +88,6 @@ SERVER_HOST2 = 'ansjerpush.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 DATABASES_USER2 = 'azrds'
 DATABASES_PASS2 = 'azrds.x.x'
 
-#序列号公共数据库
-DATABASE_DATA3 = 'AnsjerTest'
-SERVER_HOST3 = 'serial-uid.clraczw4p0yj.us-west-1.rds.amazonaws.com'
-DATABASES_USER3 = 'azrds'
-DATABASES_PASS3 = 't1ApWed1FPPQbWmclZKp'
-
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
@@ -115,22 +109,12 @@ DATABASES = {
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'AUTOCOMMIT': True
     },
-    'mysql03': {
-        'ENGINE': 'django.db.backends.mysql',
-        'NAME': DATABASE_DATA3,
-        'USER': DATABASES_USER3,
-        'PASSWORD': DATABASES_PASS3,
-        'HOST': SERVER_HOST3,
-        'PORT': '3306',
-        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
-        'AUTOCOMMIT': True
-    }
 }
+
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
     'Model': 'default',
-    'PushModel': 'mysql02',
-    'SerialModel': 'mysql03',
+    'db2': 'mysql02',
 }
 
 AUTH_PASSWORD_VALIDATORS = [
@@ -219,9 +203,7 @@ LOGGING = {
         'standard': {
             'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
                       '[%(levelname)s]- %(message)s'},
-        'simple': {  # 简单格式
-            'format': '%(levelname)s %(message)s'
-        },
+
     },
     'filters': {
     },
@@ -233,25 +215,25 @@ LOGGING = {
         },
         'default': {
             'level': 'ERROR',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/error.log',
-            'maxBytes': 1024 * 1024 * 5,  # 5 MB
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error/error.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'error_format',
         },
         'console': {
             'level': 'ERROR',
             'class': 'logging.StreamHandler',
             'formatter': 'error_format'
-        },# 输出info日志
+        },
         'info': {
             'level': 'INFO',
-            'class': 'logging.handlers.RotatingFileHandler',
-            'filename': BASE_DIR + '/static/log/info.log',
-            'maxBytes': 1024 * 1024 * 5,
-            'backupCount': 5,
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/info/info.log',
+            'backupCount': 30,
+            'when': 'D',
             'formatter': 'standard',
-            'encoding': 'utf-8',  # 设置默认编码
+            'encoding': 'utf-8',
         },
     },
     'loggers': {
@@ -263,15 +245,15 @@ LOGGING = {
             'propagate': False
         },
         # log 调用时需要当作参数传入
-        'log': {
-            'handlers': ['info', 'console', 'default'],
-            'level': 'INFO',
-            'propagate': True
-        },
+        'info': {
+            'handlers': ['info'],
+            'level':'INFO',
+            'propagate': False
+        }
         # 'django.db.backends': {
         #     'handlers': ['console'],
         #     'propagate': True,
         #     'level': 'DEBUG',
         # },
     }
-}
+}

+ 13 - 11
Ansjer/test_zositech_help_weekly_task.py

@@ -15,32 +15,34 @@ data = {
     'userName': username,
     'userPwd': password
 }
-res = requests.post(url=login_url, data=data)
+res = requests.post(url=login_url, data=data, timeout=10)
 res = res.json()
 
 if res['result_code'] == 0:
-    isbool = True
-    while isbool:
+    request_times = 0
+    while request_times < 5:
         try:
             statistics_url = base_url + 'faq/synZositechHelp'
-            zhcnDatares = requests.get(
-                url='https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=zh-cn&section=null&origin=web_widget', timeout=1).text
-
-            enusDatares = requests.get(
-                url='https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=en-us&section=null&origin=web_widget', timeout=1).text
+            # zh_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=zh-cn&section=null&origin=web_widget'
+            zh_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/zh-cn/articles.json?page%5Bsize%5D=100'
+            zhcnDatares = requests.get(url=zh_url, timeout=10).text
 
+            en_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/en-us/articles.json?page%5Bsize%5D=100'
+            # en_url = 'https://mobileapphelp.zendesk.com/api/v2/help_center/articles/embeddable_search.json?locale=en-us&section=null&origin=web_widget'
+            enusDatares = requests.get(url=en_url, timeout=10).text
             data = {
                 'token': res['result']['access_token'],
                 'zhresults': zhcnDatares,
                 'enresults': enusDatares
             }
-            isbool = False
             res = requests.post(url=statistics_url, data=data)
 
         except Exception as e:
-            isbool=True
+            print(e)
+            request_times += 1
+            print(request_times)
             time.sleep(3)
 
-
+print('success')
 
 

+ 9 - 4
Ansjer/urls.py

@@ -18,7 +18,7 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     VerifyCodeController, FileController, UIDController, LogController, SalesController, \
     OrderTaskController, HistoryUIDController, UIDManageUserController, SerialNumberController, CompanyController, \
     RegionController, VPGController, LanguageController, TestController, DeviceConfirmRegion, S3GetStsController, \
-    DetectControllerV2
+    DetectControllerV2, ShadowController, TestDetectController
 
 urlpatterns = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
@@ -111,7 +111,6 @@ urlpatterns = [
     # 统计访问日志路径
     path('access/staticPath/', AccessLog.statisticsPath),
     path('access/deleteSn/', AccessLog.deleteSn),
-    path('eq/del', EquipmentInfo.deleteExpireEquipmentInfo),
     path('eq/delById', EquipmentInfo.deleteExpireEquipmentInfoById),
     # 新需求ota接口
     url(r'^OTA/getNewVer', OTAEquipment.getNewVerInterface),
@@ -141,12 +140,18 @@ urlpatterns = [
     url(r'^v3/account/loginByFingerprint$', UserController.v3LoginByFingerprintView.as_view()),
     url(r'^v3/account/setFingerprint$', UserController.v3SetFingerprintView.as_view()),
 
-    # 新增
     url(r'^detect/detect_group_push$',DetectController.NotificationView.detect_group_push),
     url(r'^detect/add$', DetectController.PushNotificationView.as_view()),
+    # 推送项目接口
     url(r'^detect/(?P<operation>.*)$', DetectController.DetectControllerView.as_view()),
-    url(r'^detectV2/(?P<operation>.*)$', DetectControllerV2.DetectControllerViewV2.as_view()),
     url(r'^notify/push$', DetectController.NotificationView.as_view()),
+    url(r'^detectV2/(?P<operation>.*)$', DetectControllerV2.DetectControllerViewV2.as_view()),
+    url(r'^notifyV2/push$', DetectControllerV2.NotificationView.as_view()),
+    url(r'^deviceShadow/update$', ShadowController.update_device_shadow),
+    url(r'^deviceShadow/generateUTK$', ShadowController.generate_utk),
+    url(r'^test/notify/push$', TestDetectController.NotificationView.as_view()),
+    url(r'^eq/del$', EquipmentInfo.deleteExpireEquipmentInfo),
+    # 新增
     url(r'^cloudVod/(?P<operation>.*)$', CloudVod.CloudVodView.as_view()),
     url(r'^meal/(?P<operation>.*)$', MealManage.MealView.as_view()),
     url(r'^order/(?P<operation>.*)$', OrderContrller.OrderView.as_view()),

+ 77 - 25
Controller/CloudStorage.py

@@ -38,10 +38,13 @@ from pyfcm import FCMNotification
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
     SERVER_DOMAIN_SSL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN, APNS_MODE, APNS_CONFIG, BASE_DIR, \
     JPUSH_CONFIG, FCM_CONFIG, OAUTH_ACCESS_TOKEN_SECRET
+from Controller.CheckUserData import DataValid
 from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
     ExperienceContextModel, Pay_Type, CDKcontextModel, Device_User, SysMassModel, SysMsgModel, UidPushModel, \
-    Unused_Uid_Meal, UIDMainUser
+    Unused_Uid_Meal, UIDMainUser, UserModel
+from Object.AWS.S3Email import S3Email
 from Object.AliPayObject import AliPayObject
+from Object.AliSmsObject import AliSmsObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -302,7 +305,7 @@ class CloudStorageView(View):
         print(channel)
         print(uid)
         now_time = int(time.time())
-        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time). \
+        ubqs = UID_Bucket.objects.filter(uid=uid, endTime__gte=now_time, channel=channel). \
                    values("bucket__mold", "bucket__bucket", "bucket__endpoint",
                           "bucket__region", "endTime").order_by('addTime')[:1]
         if ubqs.exists():
@@ -395,7 +398,7 @@ class CloudStorageView(View):
         if dv_qs[0]['vodPrimaryUserID'] != userID:
             return response.json(10034)
         now_time = int(time.time())
-        bv_qs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time).values('bucket_id').order_by('addTime')
+        bv_qs = UID_Bucket.objects.filter(uid=uid, endTime__gte=now_time ,channel=channel).values('bucket_id').order_by('addTime')
         if not bv_qs.exists():
             return response.json(10030)
         vh_qs = VodHlsModel.objects.filter \
@@ -460,7 +463,7 @@ class CloudStorageView(View):
         print('channel:')
         print(channel)
         now_time = int(time.time())
-        ubqs = UID_Bucket.objects.filter(uid=UID, channel=channel, endTime__gte=now_time). \
+        ubqs = UID_Bucket.objects.filter(uid=UID, endTime__gte=now_time, channel=channel). \
                    values("bucket__mold", "bucket__bucket", "bucket__endpoint",
                           "bucket__region", "status", "bucket__storeDay", "bucket__id").order_by('addTime')[:1]
         if ubqs.exists():
@@ -786,7 +789,8 @@ class CloudStorageView(View):
                     #     UIDMainUser.objects.create(**uid_main_dict)
 
                     order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
-                    sys_msg_text_list = ['成功购买云存', 'Successful purchase of cloud storage']
+                    datetime = time.strftime("%Y-%m-%d", time.localtime())
+                    sys_msg_text_list = ['尊重的客户,您的'+UID+'设备在'+datetime+'已成功购买云存套餐,特此通知。', 'Dear customer, your '+UID+' device has successfully purchased the cloud storage package at '+datetime+', hereby notified.']
                     self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/success.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                     if lang != 'cn':
@@ -806,7 +810,6 @@ class CloudStorageView(View):
         PayerID = request_dict.get('PayerID', None)
         orderID = request_dict.get('orderID', None)
         lang = request_dict.get('lang', 'en')
-        file_handle=open('/web/www/AnsjerFormal/static/log/info.log',mode='w')
         try:
             order_qs = Order_Model.objects.filter(orderID=orderID, status=0)
 
@@ -823,8 +826,6 @@ class CloudStorageView(View):
             payres = payment.execute({"payer_id": PayerID})
             print(payres)
             if not payres:
-                file_handle.write('----pal----payres')
-                file_handle.write(payres)
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
                 if lang != 'cn':
                     red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
@@ -894,7 +895,10 @@ class CloudStorageView(View):
                 #     UIDMainUser.objects.create(**uid_main_dict)
 
                 order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
-                sys_msg_text_list = ['成功购买云存','Successful purchase of cloud storage']
+                datetime = time.strftime("%Y-%m-%d", time.localtime())
+                sys_msg_text_list = ['尊重的客户,您的' + UID + '设备在' + datetime + '已成功购买云存套餐,特此通知。',
+                                     'Dear customer, your ' + UID + ' device has successfully purchased the cloud storage package at ' + datetime + ', hereby notified.']
+
                 self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
 
                 # return response.json(0)
@@ -905,8 +909,6 @@ class CloudStorageView(View):
                 return HttpResponseRedirect(red_url)
         except Exception as e:
             print(repr(e))
-            file_handle.write('----pal----repr')
-            file_handle.write(repr(e))
             if order_qs:
                 order_qs.update(status=10)
             red_url = "{SERVER_DOMAIN_SSL}web/paid2/fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
@@ -996,7 +998,9 @@ class CloudStorageView(View):
                     #     UIDMainUser.objects.create(**uid_main_dict)
 
                     order_qs.update(status=1, updTime=nowTime, uid_bucket_id=uid_bucket_id)
-                    sys_msg_text_list = ['成功购买云存', 'Successful purchase of cloud storage']
+                    datetime = time.strftime("%Y-%m-%d", time.localtime())
+                    sys_msg_text_list = ['尊重的客户,您的' + UID + '设备在' + datetime + '已成功购买云存套餐,特此通知。',
+                                         'Dear customer, your ' + UID + ' device has successfully purchased the cloud storage package at ' + datetime + ', hereby notified.']
                     self.do_vod_msg_Notice(UID, channel, userid, lang, sys_msg_text_list)
                     return HttpResponse(pay.xml_to_dict({'return_code': 'SUCCESS', 'return_msg': 'OK'}))
             else:
@@ -1275,7 +1279,9 @@ class CloudStorageView(View):
                 #     }
                 #     UIDMainUser.objects.create(**uid_main_dict)
 
-                sys_msg_text_list = ['成功购买云存', 'Successful purchase of cloud storage']
+                datetime = time.strftime("%Y-%m-%d", time.localtime())
+                sys_msg_text_list = ['尊重的客户,您的' + uid + '设备在' + datetime + '已成功购买云存套餐,特此通知。',
+                                     'Dear customer, your ' + uid + ' device has successfully purchased the cloud storage package at ' + datetime + ', hereby notified.']
                 # return response.json(0)
                 returnurl = "{SERVER_DOMAIN_SSL}cloudstorage/payOK?lang={lang}".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL,lang=lang)
                 if pay_type == 10:
@@ -1285,7 +1291,9 @@ class CloudStorageView(View):
                         do_time=nowTime
                     )
                     returnurl = "{SERVER_DOMAIN_SSL}cloudstorage/payOK?paytype=10&lang={lang}".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL,lang=lang)
-                    sys_msg_text_list = ['成功体验云存', 'Successful experience of cloud storage']
+                    datetime = time.strftime("%Y-%m-%d", time.localtime())
+                    sys_msg_text_list = ['尊重的客户,您的' + uid + '设备在' + datetime + '已成功体验云存,特此通知。',
+                                         'Dear customers, your '+uid+' device has successfully experienced cloud storage at '+datetime+', hereby notified.']
 
                 if pay_type == 11:
                     update_dict = {}
@@ -1293,7 +1301,10 @@ class CloudStorageView(View):
                     update_dict['order'] = orderID
                     CDKcontextModel.objects.filter(cdk=cdk).update(**update_dict)
                     returnurl = "{SERVER_DOMAIN_SSL}cloudstorage/payOK?paytype=11&lang={lang}".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL,lang=lang)
-                    sys_msg_text_list = ['成功兑换云存', 'Successful exchange of cloud storage']
+
+                    datetime = time.strftime("%Y-%m-%d", time.localtime())
+                    sys_msg_text_list = ['尊重的客户,您的' + uid + '设备在' + datetime + '已成功兑换云存,特此通知。',
+                                         'Dear customer, your '+uid+' device has been redeemed for cloud deposit at '+datetime+', hereby notified.']
 
 
                 self.do_vod_msg_Notice(uid, channel, userID, lang, sys_msg_text_list)
@@ -1437,20 +1448,38 @@ class CloudStorageView(View):
             create_data = {'userID_id': userID, 'msg': sys_msg_text, 'addTime': nowTime,
                            'updTime': nowTime, 'uid': uid, 'eventType': 0}
             SysMsgModel.objects.create(**create_data)
-            self.pushApp(nowTime, uid, channel, sys_msg_text)
+
+            user_qs = Device_User.objects.filter(userID=userID)
+            if user_qs.exists():
+                user = user_qs[0]
+                username = user.username
+                data_valid = DataValid()
+                if data_valid.email_validate(username):
+                    S3Email.faEmail(sys_msg_text,username)
+                elif data_valid.mobile_validate(username):
+                    params = u'{"devname":"' + uid + '","submittime":"' + time.strftime("%Y-%m-%d",time.localtime()) + '"}'
+                    self.sendMessage(username, params, 'SMS_217405528')
+
+                self.pushApp(nowTime, uid, channel, sys_msg_text)
+
 
             logger.info('出去了')
         except Exception as e:
             return repr(e)
-    # 云存到期续费提醒   提前1天
+    # 云存到期续费提醒   提前3
     def do_vod_msg_end(self, request_dict):
         response = ResponseObject()
         now_time = int(time.time())
+        # 前7天提示一次
+        list = UID_Bucket.objects.filter(Q(endTime__lte=(now_time - 3600 * 168)) & Q(endTime__gt=now_time - 3600 * 72)).values('id','uid','bucket__area','channel','endTime')
+        self.do_vod_msg(now_time,list)
 
-        list = UID_Bucket.objects.filter(Q(endTime__lte=(now_time - 3600 * 24)) & Q(endTime__gt=now_time)).values('id',
-                                                                                                                  'uid',
-                                                                                                                  'bucket__area','channel')
+        # 前3天提示一次
+        list = UID_Bucket.objects.filter(Q(endTime__lte=(now_time - 3600 * 72)) & Q(endTime__gt=now_time)).values('id','uid','bucket__area','channel','endTime')
+        self.do_vod_msg(now_time,list)
+        return response.json(0)
 
+    def do_vod_msg(self, now_time, list):
         uq_list = []
         ids = []
         for ub in list:
@@ -1462,9 +1491,12 @@ class CloudStorageView(View):
             for oo in oqlist:
                 if ub['id'] == oo['uid_bucket_id']:
                     if ub['bucket__area'] == 'cn':
-                        sys_msg_text = "云存即将过期,请您注意!"
+                        sys_msg_text = "尊重的客户,您" + ub['uid'] + "设备的云存套餐将在" + time.strftime("%Y-%m-%d",
+                                                                                           ub['endTime']) + "到期,特此通知。"
                     else:
-                        sys_msg_text = "Cloud storage is about to expire, please pay attention!"
+                        sys_msg_text = "Dear customer, the cloud storage package of your " + ub[
+                            'uid'] + " device will expire in " + time.strftime("%Y-%m-%d",
+                                                                               ub['endTime']) + ", hereby notified."
                     uq_list.append(SysMsgModel(
                         userID_id=oo['userID_id'],
                         addTime=now_time,
@@ -1474,13 +1506,25 @@ class CloudStorageView(View):
                         msg=sys_msg_text,
                         status=0
                     ))
-                    self.pushApp(now_time, ub['uid'], ub['channel'], sys_msg_text)
+                    user_qs = Device_User.objects.filter(userID=oo['userID_id'])
+                    if user_qs.exists():
+                        user = user_qs[0]
+                        username = user.username
+                        data_valid = DataValid()
+
+                        if data_valid.email_validate(username):
+                            S3Email.faEmail(sys_msg_text, username)
+                        elif data_valid.mobile_validate(username):
+                            params = u'{"devname":"' + ub['uid'] + '","submittime":"' + time.strftime("%Y-%m-%d",
+                                                                                                      ub[
+                                                                                                          'endTime']) + '"}'
+                            self.sendMessage(username, params, 'SMS_217425550')
+
+                        self.pushApp(now_time, ub['uid'], ub['channel'], sys_msg_text)
 
         SysMsgModel.objects.bulk_create(uq_list)
 
 
-        return response.json(0)
-
     def pushApp(self, nowTime, uid, channel, sys_msg_text):
         n_time = nowTime
 
@@ -1598,6 +1642,14 @@ class CloudStorageView(View):
                 print(res)
                 return res.status_code
 
+    def sendMessage(self, phone , params, temp_msg):
+            # 购买成功
+            sign_ms = 'Ansjer'
+            # 发送手机验证码
+            aliSms = AliSmsObject()
+            res = aliSms.send_code_sms_cloud(phone=phone, params = params, sign_name=sign_ms,
+                                       temp_msg=temp_msg)
+
 
 
 # 删除过期云存播放列表

+ 552 - 188
Controller/DetectController.py

@@ -21,9 +21,10 @@ from django.http import JsonResponse
 from django.views.generic.base import View
 from pyfcm import FCMNotification
 from Object.RedisObject import RedisObject
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH_DOMAIN, JPUSH_CONFIG, \
-    FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE
-from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH_DOMAIN,\
+                            JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, \
+                            BASE_DIR, APNS_MODE,  SERVER_TYPE
+from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, SysMsgModel
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
@@ -331,34 +332,38 @@ class DetectControllerView(View):
             return response.json(0)
 
 
-# http://192.168.136.40:8077/notify/push?uidToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJUTjdNUEUzMjExVUU3NkFQMTExQSJ9.k501567VdnhFpn_ygzGRDat3Kqlz5CsEA9jAC2dDk_g&obj=12341234&n_time=1234561234
-# http://test.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJQMldOR0pSRDJFSEE1RVU5MTExQSJ9.xOCI5lerk8JOs5OcAzunrKCfCrtuPIZ3AnkMmnd-bPY&n_time=1526845794&channel=1&event_type=51&is_st=0
+
+'''
+http://push.dvema.com/notify/push?etk=Y2lTRXhMTjBWS01sWlpURTVJU0ZWTlJ6RXhNVUU9T3o=&n_time=1526845794&channel=1&event_type=704&is_st=0
+http://push.dvema.com/deviceShadow/generateUTK?username=debug_user&password=debug_password&uid=VVDHCVBYDKFMJRWA111A
+'''
+
+
 # 移动侦测接口
 class NotificationView(View):
 
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
-        # operation = kwargs.get('operation')
         return self.validation(request.GET)
 
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
-        # operation = kwargs.get('operation')
         return self.validation(request.POST)
 
     def validation(self, request_dict):
-        response = ResponseObject()
+
         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)
+        # print("aaa")
+        # return JsonResponse(0,safe=False)
         if not all([channel, n_time]):
             return JsonResponse(status=200, data={
                 'code': 444,
                 'msg': 'param is wrong'})
-            # return response.json(444)
         if etk:
             eto = ETkObject(etk)
             uid = eto.uid
@@ -367,20 +372,440 @@ class NotificationView(View):
         else:
             utko = UidTokenObject(uidToken)
             uid = utko.UID
-        # utko = UidTokenObject(uidToken)
-        # uid = utko.UID
-        detect_group = UidSetModel.objects.filter(uid=uid). \
-            values('detect_group')
-        event_type = detect_group
-        # 新增 移动侦测
-        if event_type == '0':
-            self.detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st)
-        # 新增 pir侦测
-        if event_type == '1':
-            self.detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st)
-        # 新增 移动侦测和pir侦测
-        if event_type == '01':
-            self.detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st)
+
+        pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, event_type=event_type, channel=channel)
+        # ykey = 'MUJ887NLR8K8GBM9111A_redis_qs'.format(uid=uid)
+        ykey = '{uid}_redis_qs'.format(uid=uid)
+        # dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
+        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.get_data(key=pkey):不为空
+        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:
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'msg': 'Push once every 10 seconds'}
+            else:
+                res_data = {'code': 0, 'msg': 'Push it once a minute'}
+
+            return JsonResponse(status=200, data=res_data)
+
+        # 数据库读取数据
+        if have_ykey:
+            redis_list = eval(redisObj.get_data(key=ykey))
+            print(have_ykey)
+        else:
+            # 从数据库查询出来
+            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid,uid_set__detect_status=1). \
+                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')
+            print(uid_push_qs)
+            # 新建一个list接收数据
+            redis_list = []
+            # 把数据库数据追加进redis_list
+            for qs in uid_push_qs:
+                redis_list.append(qs)
+            # 修改redis数据,并设置过期时间为10分钟
+            redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+            if not redis_list:
+                res_data = {'code': 404, 'msg': 'error !'}
+                return JsonResponse(status=200, data=res_data)
+
+            # 此时应该更新一下redis里面的dkey的有效时间
+            # detect_interval = redis_list[0]['uid_set__detect_interval']
+            # tmp_channel = redis_list[0]['uid_set__channel']
+            # self.do_update_detect_interval(uid, tmp_channel, redisObj, detect_interval)
+
+        if not redis_list:
+            print("没有redi_list")
+            res_data = {'code': 0, 'msg': 'no redi_list success!'}
+            return JsonResponse(status=200, data=res_data)
+
+        # is_sys_msg = self.is_sys_msg(int(event_type))
+        nickname = redis_list[0]['uid_set__nickname']
+        detect_interval = redis_list[0]['uid_set__detect_interval']
+        detect_group = redis_list[0]['uid_set__detect_group']
+        now_time = int(time.time())
+        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的话,既推送,又存库
+                # detect_group=0允许全部推送的时候
+                if detect_group == '0'or detect_group == '':
+                    redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                else:
+                    detect_group_list = detect_group.split(',')
+                    if event_type in detect_group_list:
+                        if detect_interval < 60:
+                            detect_interval = 60
+                        redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                # 改为1秒
+                # 如果不是正式
+                if SERVER_TYPE!="Ansjer.formal_settings":
+                    redisObj.set_data(key=pkey, val=1, expire=10)
+                else:
+                    redisObj.set_data(key=pkey, val=1, expire=60)
+
+            # 打印have_ykey
+        # return JsonResponse(status=200, data={'pkey': 0, 'have_ykey': have_ykey, 'have_pkey': have_pkey, 'have_ykey': have_dkey})
+
+        # 旧模式并且没有pkey,重新创建一个
+        if not detect_group and not have_pkey:
+            # 设置推送时间为60秒一次
+            # 如果不是正式
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                redisObj.set_data(key=pkey, val=1, expire=10)
+            else:
+                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,
+            # 'appBundleId': appBundleId,
+            # 'token_val': token_val,
+            # 'msg_title': msg_title,
+            # 'msg_text': msg_text
+        }
+        eq_list = []
+        sys_msg_list = []
+        userID_ids = []
+        do_apns_code = ''
+        do_fcm_code = ''
+        do_jpush_code = ''
+        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=n_time, lang=lang, tz=tz,
+                                         event_type=event_type)
+            kwag_args['appBundleId'] = appBundleId
+            kwag_args['token_val'] = token_val
+            kwag_args['msg_title'] = msg_title
+            kwag_args['msg_text'] = msg_text
+            push_server_status = 0
+            #推送
+            if detect_med_type == 2 or detect_med_type == 0:
+                if push_type == 0:  # ios apns
+                    print('do_apns')
+                    # self.do_apns(**kwag_args)
+                    do_apns_code = self.do_apns(**kwag_args)
+                    if isinstance(do_apns_code, int):
+                        push_server_status = do_apns_code
+                    else:
+                        push_server_status = 400
+                elif push_type == 1:  # android gcm
+                    print('do_fcm')
+                    do_fcm_code = self.do_fcm(**kwag_args)
+                    push_server_status = 200
+                elif push_type == 2:  # android jpush
+                    print('do_jpush')
+                    do_jpush_code = self.do_jpush(**kwag_args)
+                    push_server_status = do_jpush_code
+                    # return JsonResponse(status=200, data={'code': 0, '状态:': self.do_jpush(**kwag_args)})
+            if detect_med_type == 1:
+                do_apns_code = '只存库不推送'
+                do_fcm_code = '只存库不推送'
+                do_jpush_code = '只存库不推送'
+            # 以下是存库
+            userID_id = up["userID_id"]
+            int_is_st = int(is_st)
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=int_is_st,
+                    receiveTime=n_time,
+                    addTime=now_time,
+                    storage_location=1
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    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)
+        if is_sys_msg:
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        Equipment_Info.objects.bulk_create(eq_list)
+        if is_st == '0' or is_st == '2':
+            print("is_st=0or2")
+            for up in redis_list:
+                if up['push_type'] == 0:  # ios apns
+                    up['do_apns_code'] = do_apns_code
+                elif up['push_type'] == 1:  # android gcm
+                    up['do_fcm_code'] = do_fcm_code
+                elif up['push_type'] == 2:  # android jpush
+                    up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                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' ,'re_list':redis_list})
+
+        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 redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                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']
+                # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_push': url, 'msg': 'success', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                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 redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                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']
+
+            # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
+            return JsonResponse(status=200, data=res_data)
+
+
+    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, 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 = '电量过低'
+            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)
+                # send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+        else:
+            if etype == 704:
+                msg_type = 'Low battery'
+            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']
+        # 此处换成各自的app_key和master_secre
+        _jpush = jpush.JPush(app_key, master_secret)
+        push = _jpush.create_push()
+        # if you set the logging level to "DEBUG",it will show the debug logging.
+        # _jpush.set_logging("DEBUG")
+        # push.audience = jpush.all_
+        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()
+        print(res)
+        return res.status_code
+        # try:
+        #     res = push.send()
+        #     print(res)
+        # except Exception as e:
+        #     print("jpush fail")
+        #     print("Exception")
+        #     print(repr(e))
+        #     return
+        # else:
+        #     print("jpush success")
+        #     return
+
+    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
+                                                   })
+        print('fcm push ing')
+        print(result)
+        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": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+            alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
+            payload = apns2.Payload(alert=alert, custom=push_data)
+
+            # return uid, channel, appBundleId, str(token_val), event_type, n_time, msg_title,msg_text
+            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
+            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
+            print(res.status_code)
+
+            #     200, 推送成功。
+            #   400, 请求有问题。
+            #   403, 证书或Token有问题。
+            #   405, 请求方式不正确, 只支持POST请求
+            #   410, 设备的Token与证书不一致
+            if res.status_code == 200:
+                return res.status_code
+            else:
+                print('apns push fail')
+                print(res.reason)
+                return res.status_code
+        except (ValueError, ArithmeticError):
+            return 'The program has a numeric format exception, one of the arithmetic exceptions'
+        except Exception as e:
+            print(repr(e))
+            return repr(e)
+
+    def do_update_detect_interval(self, uid, channel, redisObject, detect_interval):
+        if channel == 0:
+            channel = 17
+        else:
+            channel += 1
+        for i in range(1, channel):
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=51, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=54, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
 
     # 新增 把代码封装以便后面分侦测类型
     def detect_group_push(self, request_dict, uid, response, channel, n_time, event_type, is_st):
@@ -442,136 +867,6 @@ class NotificationView(View):
         else:
             return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
 
-    def do_jpush(self, request_dict, uaql, response, uid, channel, nickname):
-        event_type = request_dict.get('event_type', None)
-        n_time = request_dict.get('n_time', None)
-        appBundleId = uaql['appBundleId']
-        token_val = uaql['token_val']
-        lang = uaql['lang']
-        tz = uaql['tz']
-        response = ResponseObject()
-        app_key = JPUSH_CONFIG[appBundleId]['Key']
-        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
-        # 此处换成各自的app_key和master_secre
-        _jpush = jpush.JPush(app_key, master_secret)
-        push = _jpush.create_push()
-        # if you set the logging level to "DEBUG",it will show the debug logging.
-        _jpush.set_logging("DEBUG")
-        # push.audience = jpush.all_
-        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}
-        message_title = self.get_message_title(appBundleId=appBundleId, nickname=nickname)
-        send_text = self.get_send_text(channel=channel, n_time=n_time, lang=lang, tz=tz, event_type=event_type)
-        android = jpush.android(alert=send_text, priority=1, style=1, alert_type=7,
-                                big_text=send_text, title=message_title,
-                                extras=push_data)
-
-        push.notification = jpush.notification(android=android)
-
-        push.platform = jpush.all_
-        try:
-            res = push.send()
-            print(res)
-        except Exception as e:
-            print("Exception")
-            print(repr(e))
-            return response.json(10, repr(e))
-        else:
-            return response.json(0)
-
-    def get_message_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 get_send_text(self, channel, n_time, lang, tz, event_type):
-        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
-        msg_type = ''
-        if int(event_type) == 704:
-            msg_type = 'battery is too low'
-            if lang == 'cn':
-                msg_type = '电池电量过低'
-        send_text = '{msg_type}channel:{channel} date:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
-        if lang == 'cn':
-            send_text = '{msg_type}通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
-        return send_text
-
-    def do_fcm(self, request_dict, uaql, response, uid, channel, nickname):
-        n_time = request_dict.get('n_time')
-        appBundleId = uaql['appBundleId']
-        token_val = uaql['token_val']
-        lang = uaql['lang']
-        tz = uaql['tz']
-        try:
-            serverKey = FCM_CONFIG[appBundleId]
-        except Exception as e:
-            return response.json(404)
-        event_type = request_dict.get('event_type', None)
-        push_service = FCMNotification(api_key=serverKey)
-        registration_id = token_val
-        message_title = self.get_message_title(appBundleId=appBundleId, nickname=nickname)
-        send_text = self.get_send_text(channel=channel, n_time=n_time, lang=lang, tz=tz, event_type=event_type)
-        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=registration_id, message_title=message_title,
-                                                   message_body=send_text, data_message=data,
-                                                   extra_kwargs={
-                                                       'default_vibrate_timings': True,
-                                                       'default_sound': True,
-                                                       'default_light_settings': True
-                                                   })
-        response = ResponseObject()
-        return response.json(0, result)
-
-    def do_apns(self, request_dict, uaql, response, uid, channel, nickname):
-        event_type = request_dict.get('event_type', None)
-        token_val = uaql['token_val']
-        lang = uaql['lang']
-        n_time = request_dict.get('n_time')
-        appBundleId = uaql['appBundleId']
-        tz = uaql['tz']
-        message_title = self.get_message_title(appBundleId=appBundleId, nickname=nickname)
-        send_text = self.get_send_text(channel=channel, n_time=n_time, lang=lang, tz=tz, event_type=event_type)
-        try:
-            print('---')
-
-            cli = apns2.APNSClient(mode=APNS_MODE,
-                                   client_cert=os.path.join(BASE_DIR, APNS_CONFIG[appBundleId]['pem_path']))
-            # password=APNS_CONFIG[appBundleId]['password'])
-            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}
-            # body = json.dumps(push_data)
-            alert = apns2.PayloadAlert(body=send_text, title=message_title)
-            payload = apns2.Payload(alert=alert, custom=push_data)
-            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
-            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
-            # assert res.status_code == 200, res.reason
-            # assert res.apns_id
-            print('========')
-            print(res.status_code)
-            if res.status_code == 200:
-                return response.json(0)
-            else:
-                return response.json(404, res.reason)
-        except Exception as e:
-            print(repr(e))
-            return response.json(10, repr(e))
-
     def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
         #
         qs_list = []
@@ -633,21 +928,38 @@ class PushNotificationView(View):
             redisObj = RedisObject(db=6)
             # pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
             pkey = '{uid}_ptl'.format(uid=uid)
-            # 推送时间限制
+            ykey = '{uid}_redis_qs'.format(uid=uid)
             if redisObj.get_data(key=pkey):
-                res_data = {'code': 0, 'msg': 'success,!'}
+                res_data = {'code': 0, 'msg': 'success,!33333333333'}
                 return JsonResponse(status=200, data=res_data)
             else:
                 redisObj.set_data(key=pkey, val=1, expire=60)
-            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
-                values('token_val', 'app_type', 'appBundleId', 'push_type', 'userID_id', 'userID__NickName', 'lang',
-                       'tz', 'uid_set__nickname')
-            if uid_push_qs.exists():
+            ##############
+            redis_data = redisObj.get_data(key=ykey)
+            if redis_data:
+                redis_list = eval(redis_data)
+            else:
+                # 设置推送时间为60秒一次
+                redisObj.set_data(key=pkey, val=1, expire=60)
+                print("从数据库查到数据")
+                # 从数据库查询出来
+                uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                    values('token_val', 'app_type', 'appBundleId',
+                           'push_type', 'userID_id', 'lang','m_code',
+                           'tz', 'uid_set__nickname')
+                # 新建一个list接收数据
+                redis_list = []
+                # 把数据库数据追加进redis_list
+                for qs in uid_push_qs:
+                    redis_list.append(qs)
+                # 修改redis数据,并设置过期时间为10分钟
+            if redis_list:
+                redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
                 auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
                 bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
-                self.do_bulk_create_info(uid_push_qs, n_time, channel, event_type, is_st, uid)
+                self.do_bulk_create_info(redis_list, n_time, channel, event_type, is_st, uid)
                 if is_st == '0' or is_st == '2':
-                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success'})
+                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success44444444444444444'})
                 elif is_st == '1':
                     # Endpoint以杭州为例,其它Region请按实际情况填写。
                     obj = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
@@ -672,35 +984,87 @@ class PushNotificationView(View):
             return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong etk'})
 
     def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
-        #
-        qs_list = []
-        nowTime = int(time.time())
+        now_time = int(time.time())
         # 设备昵称
         userID_ids = []
-        for dv in uaqs:
-            userID_id = dv["userID_id"]
+        sys_msg_list = []
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        is_st = int(is_st)
+        eq_list = []
+        nickname = uaqs[0]['uid_set__nickname']
+        if not nickname:
+            nickname = uid
+        for ua in uaqs:
+            lang = ua['lang']
+            tz = ua['tz']
+            userID_id = ua["userID_id"]
             if userID_id not in userID_ids:
-                if dv['uid_set__nickname']:
-                    uid_nickname = dv['uid_set__nickname']
-                else:
-                    uid_nickname = uid
-                add_data = {
-                    'userID_id': dv["userID_id"],
-                    'eventTime': n_time,
-                    'eventType': event_type,
-                    'devUid': uid,
-                    'devNickName': uid_nickname,
-                    'Channel': channel,
-                    'alarm': 'Motion \tChannel:{channel}'.format(channel=channel),
-                    'is_st': int(is_st),
-                    'receiveTime': n_time,
-                    'addTime': nowTime
-                }
-                qs_list.append(Equipment_Info(**add_data))
-                userID_ids.append(userID_id)
-        if qs_list:
-            print(1)
-            Equipment_Info.objects.bulk_create(qs_list)
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=is_st,
+                    receiveTime=n_time,
+                    addTime=now_time,
+                    storage_location=1
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+        if eq_list:
+            print('eq_list')
+            Equipment_Info.objects.bulk_create(eq_list)
+        if is_sys_msg:
+            print('sys_msg')
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        return True
+
+    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, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            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:
-            return False
+            if etype == 704:
+                msg_type = 'Low battery'
+            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

+ 834 - 38
Controller/DetectControllerV2.py

@@ -21,11 +21,11 @@ from django.http import JsonResponse
 from django.views.generic.base import View
 from pyfcm import FCMNotification
 from Object.RedisObject import RedisObject
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH_DOMAIN, \
-    JPUSH_CONFIG, \
-    FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, \
-    DETECT_PUSH_DOMAINS_JIUAN, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN
-from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, CompanyModel
+from Ansjer.config import DETECT_PUSH_DOMAIN, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, DETECT_PUSH_DOMAINS_JIUAN,\
+                            SERVER_DOMAIN, SERVER_DOMAIN_SSL, \
+                            OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, \
+                            JPUSH_CONFIG, FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE,  SERVER_TYPE
+from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, CompanyModel, SysMsgModel
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
@@ -295,11 +295,13 @@ class DetectControllerViewV2(View):
         if not qs.exists():
             return response.json(0, {'datas': [], 'count': 0})
         qs = qs.values('id', 'devUid', 'devNickName', 'Channel', 'eventType', 'status', 'alarm', 'eventTime',
-                       'receiveTime', 'is_st', 'addTime')
+                       'receiveTime', 'is_st', 'addTime', 'storage_location')
 
         count = qs.count()
         qr = qs[(page - 1) * line:page * line]
         res = []
+        auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+        oss_img_bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
         aws_s3_guonei = boto3.client(
             's3',
             aws_access_key_id=AWS_ACCESS_KEY_ID[0],
@@ -319,18 +321,23 @@ class DetectControllerViewV2(View):
             devUid = p['devUid']
             eventTime = p['eventTime']
             channel = p['Channel']
+            storage_location = p['storage_location']
             if p['is_st'] == 1:
                 thumbspng = '{uid}/{channel}/{time}.jpeg'.format(uid=devUid, channel=p['Channel'], time=eventTime)
-                if region == 2:  # 2:国内
-                    response_url = aws_s3_guonei.generate_presigned_url(
-                        'get_object',
-                        Params={'Bucket': 'push', 'Key': thumbspng}, ExpiresIn=3600)
+                if storage_location == 1:   # oss
+                    response_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
                     p['img'] = response_url
                     p['img_list'] = [response_url]
-                else:   # 1:国外
-                    response_url = aws_s3_guowai.generate_presigned_url(
-                        'get_object',
-                        Params={'Bucket': 'foreignpush', 'Key': thumbspng}, ExpiresIn=3600)
+                elif region == 2 and storage_location == 2:  # 2:国内,aws
+                    response_url = aws_s3_guonei.generate_presigned_url('get_object',
+                                                                        Params={'Bucket': 'push', 'Key': thumbspng},
+                                                                        ExpiresIn=300)
+                    p['img'] = response_url
+                    p['img_list'] = [response_url]
+                elif region == 1 and storage_location == 2:   # 1:国外,aws
+                    response_url = aws_s3_guowai.generate_presigned_url('get_object',
+                                                                        Params={'Bucket': 'foreignpush', 'Key': thumbspng},
+                                                                        ExpiresIn=300)
                     p['img'] = response_url
                     p['img_list'] = [response_url]
 
@@ -342,38 +349,44 @@ class DetectControllerViewV2(View):
                 if vodqs.exists():
                     bucket_name = vodqs[0]['bucket__bucket']
                     endpoint = vodqs[0]['bucket__endpoint']
-                    # bucket = oss2.Bucket(auth, endpoint, bucket_name)
+                    bucket = oss2.Bucket(auth, endpoint, bucket_name)
                     ts = '{uid}/vod{channel}/{etime}/ts0.ts'.format(uid=devUid, channel=p['Channel'], etime=eventTime)
-                    if region == 2:     # 2:国内
-                        thumb = aws_s3_guonei.generate_presigned_url(
-                            'get_object',
-                            Params={'Bucket': 'push', 'Key': ts}, ExpiresIn=3600)
-                    else:   # 1:国外
-                        thumb = aws_s3_guowai.generate_presigned_url(
-                            'get_object',
-                            Params={'Bucket': 'foreignpush', 'Key': ts}, ExpiresIn=3600)
-                    p['img_list'] = [thumb]
-                    # thumb0 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
-                    # thumb1 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
-                    # thumb2 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
-                    # thumb3 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_3000,w_700'})
-                    # p['img_list'] = [thumb0, thumb1, thumb2]
+                    if storage_location == 1:   # oss
+                        thumb0 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
+                        thumb1 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
+                        thumb2 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
+                        # thumb3 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_3000,w_700'})
+                        p['img_list'] = [thumb0, thumb1, thumb2]
+                    elif region == 2 and storage_location == 2:     # 2:国内,aws
+                        thumb = aws_s3_guonei.generate_presigned_url('get_object',
+                                                                     Params={'Bucket': 'push', 'Key': ts},
+                                                                     ExpiresIn=3600)
+                        p['img_list'] = [thumb]
+                    elif region == 1 and storage_location == 2:   # 1:国外,aws
+                        thumb = aws_s3_guowai.generate_presigned_url('get_object',
+                                                                     Params={'Bucket': 'foreignpush', 'Key': ts},
+                                                                     ExpiresIn=3600)
+                        p['img_list'] = [thumb]
             elif p['is_st'] == 3:
                 # 列表装载回放时间戳标记
                 p['img_list'] = []
                 for i in range(p['is_st']):
                     thumbspng = '{uid}/{channel}/{time}_{st}.jpeg'.format(uid=devUid, channel=p['Channel'], time=eventTime, st=i)
-                    if region == 2:  # 2:国内
-                        response_url = aws_s3_guonei.generate_presigned_url(
-                            'get_object',
-                            Params={'Bucket': 'push', 'Key': thumbspng}, ExpiresIn=3600)
+                    if storage_location == 1:   # oss
+                        img = oss_img_bucket.sign_url('GET', thumbspng, 300)
+                        p['img_list'].append(img)
+                    elif region == 2 and storage_location == 2:  # 2:国内,aws
+                        response_url = aws_s3_guonei.generate_presigned_url('get_object',
+                                                                            Params={'Bucket': 'push', 'Key': thumbspng},
+                                                                            ExpiresIn=300)
                         img = response_url
-                    else:   # 1:国外
-                        response_url = aws_s3_guowai.generate_presigned_url(
-                            'get_object',
-                            Params={'Bucket': 'foreignpush', 'Key': thumbspng}, ExpiresIn=3600)
+                        p['img_list'].append(img)
+                    elif region == 1 and storage_location == 2:   # 1:国外,aws
+                        response_url = aws_s3_guowai.generate_presigned_url('get_object',
+                                                                            Params={'Bucket': 'foreignpush', 'Key': thumbspng},
+                                                                            ExpiresIn=300)
                         img = response_url
-                    p['img_list'].append(img)
+                        p['img_list'].append(img)
             if devUid in uid_type_dict.keys():
                 p['uid_type'] = uid_type_dict[devUid]['type']
                 p['devNickName'] = uid_type_dict[devUid]['NickName']
@@ -397,3 +410,786 @@ class DetectControllerViewV2(View):
                 return response.json(173)
         else:
             return response.json(0)
+
+
+# 设备调用接口
+# 移动侦测接口
+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):
+
+        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)
+        company_secrete = request_dict.get('company_secrete', None)
+        region = request_dict.get('region', None)
+        if not region:
+            return JsonResponse(status=200, data={'code': 404, 'msg': 'region is not exist'})
+        region = int(region)
+        # print("aaa")
+        # return JsonResponse(0,safe=False)
+        if not all([channel, n_time]):
+            return JsonResponse(status=200, data={
+                'code': 444,
+                'msg': 'param is wrong'})
+        if etk:
+            eto = ETkObject(etk)
+            uid = eto.uid
+            if len(uid) != 20 and len(uid) != 14:
+                return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+        else:
+            utko = UidTokenObject(uidToken)
+            uid = utko.UID
+
+        pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, event_type=event_type, channel=channel)
+        # ykey = 'MUJ887NLR8K8GBM9111A_redis_qs'.format(uid=uid)
+        ykey = '{uid}_redis_qs'.format(uid=uid)
+        # dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
+        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.get_data(key=pkey):不为空
+        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:
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'msg': 'Push once every 10 seconds'}
+            else:
+                res_data = {'code': 0, 'msg': 'Push it once a minute'}
+
+            return JsonResponse(status=200, data=res_data)
+
+        # 数据库读取数据
+        if have_ykey:
+            redis_list = eval(redisObj.get_data(key=ykey))
+            print(have_ykey)
+            if not redis_list:
+                # 从数据库查询出来
+                uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                    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')
+                print(uid_push_qs)
+                # 新建一个list接收数据
+                redis_list = []
+                # 把数据库数据追加进redis_list
+                for qs in uid_push_qs:
+                    redis_list.append(qs)
+                # 修改redis数据,并设置过期时间为10分钟
+                redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+                if not redis_list:
+                    res_data = {'code': 404, 'msg': 'error !'}
+                    return JsonResponse(status=200, data=res_data)
+        else:
+            # 从数据库查询出来
+            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid,uid_set__detect_status=1). \
+                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')
+            print(uid_push_qs)
+            # 新建一个list接收数据
+            redis_list = []
+            # 把数据库数据追加进redis_list
+            for qs in uid_push_qs:
+                redis_list.append(qs)
+            # 修改redis数据,并设置过期时间为10分钟
+            redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+            if not redis_list:
+                res_data = {'code': 404, 'msg': 'error !'}
+                return JsonResponse(status=200, data=res_data)
+
+            # 此时应该更新一下redis里面的dkey的有效时间
+            # detect_interval = redis_list[0]['uid_set__detect_interval']
+            # tmp_channel = redis_list[0]['uid_set__channel']
+            # self.do_update_detect_interval(uid, tmp_channel, redisObj, detect_interval)
+
+        if not redis_list:
+            print("没有redi_list")
+            res_data = {'code': 0, 'msg': 'no redi_list success!'}
+            return JsonResponse(status=200, data=res_data)
+
+        # is_sys_msg = self.is_sys_msg(int(event_type))
+        nickname = redis_list[0]['uid_set__nickname']
+        detect_interval = redis_list[0]['uid_set__detect_interval']
+        detect_group = redis_list[0]['uid_set__detect_group']
+        now_time = int(time.time())
+        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的话,既推送,又存库
+                # detect_group=0允许全部推送的时候
+                if detect_group == '0'or detect_group == '':
+                    redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                else:
+                    detect_group_list = detect_group.split(',')
+                    if event_type in detect_group_list:
+                        if detect_interval < 60:
+                            detect_interval = 60
+                        redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                # 改为1秒
+                # 如果不是正式
+                if SERVER_TYPE!="Ansjer.formal_settings":
+                    redisObj.set_data(key=pkey, val=1, expire=10)
+                else:
+                    redisObj.set_data(key=pkey, val=1, expire=60)
+
+            # 打印have_ykey
+        # return JsonResponse(status=200, data={'pkey': 0, 'have_ykey': have_ykey, 'have_pkey': have_pkey, 'have_ykey': have_dkey})
+
+        # 旧模式并且没有pkey,重新创建一个
+        if not detect_group and not have_pkey:
+            # 设置推送时间为60秒一次
+            # 如果不是正式
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                redisObj.set_data(key=pkey, val=1, expire=10)
+            else:
+                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')
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1'
+        )
+        aws_s3_guowai = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[1],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='us-east-1'
+        )
+        kwag_args = {
+            'uid': uid,
+            'channel': channel,
+            'event_type': event_type,
+            'n_time': n_time,
+            # 'appBundleId': appBundleId,
+            # 'token_val': token_val,
+            # 'msg_title': msg_title,
+            # 'msg_text': msg_text
+        }
+        eq_list = []
+        sys_msg_list = []
+        userID_ids = []
+        do_apns_code = ''
+        do_fcm_code = ''
+        do_jpush_code = ''
+        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=n_time, lang=lang, tz=tz,
+                                         event_type=event_type)
+            kwag_args['appBundleId'] = appBundleId
+            kwag_args['token_val'] = token_val
+            kwag_args['msg_title'] = msg_title
+            kwag_args['msg_text'] = msg_text
+            push_server_status = 0
+            #推送
+            if detect_med_type == 2 or detect_med_type == 0:
+                if push_type == 0:  # ios apns
+                    print('do_apns')
+                    # self.do_apns(**kwag_args)
+                    do_apns_code = self.do_apns(**kwag_args)
+                    if isinstance(do_apns_code, int):
+                        push_server_status = do_apns_code
+                    else:
+                        push_server_status = 400
+                elif push_type == 1:  # android gcm
+                    print('do_fcm')
+                    do_fcm_code = self.do_fcm(**kwag_args)
+                    push_server_status = 200
+                elif push_type == 2:  # android jpush
+                    print('do_jpush')
+                    do_jpush_code = self.do_jpush(**kwag_args)
+                    push_server_status = do_jpush_code
+                    # return JsonResponse(status=200, data={'code': 0, '状态:': self.do_jpush(**kwag_args)})
+            if detect_med_type == 1:
+                do_apns_code = '只存库不推送'
+                do_fcm_code = '只存库不推送'
+                do_jpush_code = '只存库不推送'
+            # 以下是存库
+            userID_id = up["userID_id"]
+            int_is_st = int(is_st)
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=int_is_st,
+                    receiveTime=n_time,
+                    addTime=now_time,
+                    storage_location=2
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    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)
+        if is_sys_msg:
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        Equipment_Info.objects.bulk_create(eq_list)
+        if is_st == '0' or is_st == '2':
+            print("is_st=0or2")
+            for up in redis_list:
+                if up['push_type'] == 0:  # ios apns
+                    up['do_apns_code'] = do_apns_code
+                elif up['push_type'] == 1:  # android gcm
+                    up['do_fcm_code'] = do_fcm_code
+                elif up['push_type'] == 2:  # android jpush
+                    up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                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' ,'re_list':redis_list})
+
+        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)
+            thumbspng = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+            if region == 2:  # 2:国内
+                response_url = aws_s3_guonei.generate_presigned_url(
+                    ClientMethod='put_object',
+                    Params={
+                        'Bucket': 'push',
+                        'Key': thumbspng
+                    },
+                    ExpiresIn=3600
+                )
+            else:   # 1:国外
+                response_url = aws_s3_guowai.generate_presigned_url(
+                    ClientMethod='put_object',
+                    Params={
+                        'Bucket': 'foreignpush',
+                        'Key': thumbspng
+                    },
+                    ExpiresIn=3600
+                )
+            for up in redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                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']
+                # 不是正式服务器
+            # response_url = response_url[:4] + response_url[5:]
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                # res_data = {'code': 0, 'img_push': url, 'msg': 'success', 're_list': redis_list}
+                res_data = {'code': 0, 'img_push': response_url, 'msg': 'success', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                # res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
+                res_data = {'code': 0, 'img_push': response_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)
+
+                thumbspng = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                    format(uid=uid, channel=channel, filename=n_time, st=i)
+                if region == 2:  # 2:国内
+                    response_url = aws_s3_guonei.generate_presigned_url(
+                        ClientMethod='put_object',
+                        Params={
+                            'Bucket': 'push',
+                            'Key': thumbspng
+                        },
+                        ExpiresIn=3600
+                    )
+                else:   # 1:国外
+                    response_url = aws_s3_guowai.generate_presigned_url(
+                        ClientMethod='put_object',
+                        Params={
+                            'Bucket': 'foreignpush',
+                            'Key': thumbspng
+                        },
+                        ExpiresIn=3600
+                    )
+                # response_url = response_url[:4] + response_url[5:]
+                img_url_list.append(response_url)
+
+                # img_url_list.append(url)
+
+            for up in redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                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']
+
+            # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
+            return JsonResponse(status=200, data=res_data)
+
+
+    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, 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 = '电量过低'
+            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)
+                # send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+        else:
+            if etype == 704:
+                msg_type = 'Low battery'
+            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']
+        # 此处换成各自的app_key和master_secre
+        _jpush = jpush.JPush(app_key, master_secret)
+        push = _jpush.create_push()
+        # if you set the logging level to "DEBUG",it will show the debug logging.
+        # _jpush.set_logging("DEBUG")
+        # push.audience = jpush.all_
+        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()
+        print(res)
+        return res.status_code
+        # try:
+        #     res = push.send()
+        #     print(res)
+        # except Exception as e:
+        #     print("jpush fail")
+        #     print("Exception")
+        #     print(repr(e))
+        #     return
+        # else:
+        #     print("jpush success")
+        #     return
+
+    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
+                                                   })
+        print('fcm push ing')
+        print(result)
+        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": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+            alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
+            payload = apns2.Payload(alert=alert, custom=push_data)
+
+            # return uid, channel, appBundleId, str(token_val), event_type, n_time, msg_title,msg_text
+            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
+            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
+            print(res.status_code)
+
+            #     200, 推送成功。
+            #   400, 请求有问题。
+            #   403, 证书或Token有问题。
+            #   405, 请求方式不正确, 只支持POST请求
+            #   410, 设备的Token与证书不一致
+            if res.status_code == 200:
+                return res.status_code
+            else:
+                print('apns push fail')
+                print(res.reason)
+                return res.status_code
+        except (ValueError, ArithmeticError):
+            return 'The program has a numeric format exception, one of the arithmetic exceptions'
+        except Exception as e:
+            print(repr(e))
+            return repr(e)
+
+    def do_update_detect_interval(self, uid, channel, redisObject, detect_interval):
+        if channel == 0:
+            channel = 17
+        else:
+            channel += 1
+        for i in range(1, channel):
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=51, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=54, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+
+# 这个接口没有调用过,不敢动
+# http://test.dvema.com/detect/add?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJQMldOR0pSRDJFSEE1RVU5MTExQSJ9.xOCI5lerk8JOs5OcAzunrKCfCrtuPIZ3AnkMmnd-bPY&n_time=1526845794&channel=1&event_type=51&is_st=0
+# 移动侦测接口
+class PushNotificationView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        # operation = kwargs.get('operation')
+        return self.validation(request.GET)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        # operation = kwargs.get('operation')
+        return self.validation(request.POST)
+
+    def validation(self, request_dict):
+        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)
+        region = request_dict.get('region', '2')
+        region = int(region)
+        eto = ETkObject(etk)
+        uid = eto.uid
+        if len(uid) == 20:
+            redisObj = RedisObject(db=6)
+            # pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
+            pkey = '{uid}_ptl'.format(uid=uid)
+            ykey = '{uid}_redis_qs'.format(uid=uid)
+            if redisObj.get_data(key=pkey):
+                res_data = {'code': 0, 'msg': 'success,!33333333333'}
+                return JsonResponse(status=200, data=res_data)
+            else:
+                redisObj.set_data(key=pkey, val=1, expire=60)
+            ##############
+            redis_data = redisObj.get_data(key=ykey)
+            if redis_data:
+                redis_list = eval(redis_data)
+            else:
+                # 设置推送时间为60秒一次
+                redisObj.set_data(key=pkey, val=1, expire=60)
+                print("从数据库查到数据")
+                # 从数据库查询出来
+                uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                    values('token_val', 'app_type', 'appBundleId',
+                           'push_type', 'userID_id', 'lang','m_code',
+                           'tz', 'uid_set__nickname')
+                # 新建一个list接收数据
+                redis_list = []
+                # 把数据库数据追加进redis_list
+                for qs in uid_push_qs:
+                    redis_list.append(qs)
+                # 修改redis数据,并设置过期时间为10分钟
+            if redis_list:
+                redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+                # auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+                # bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+                aws_s3_guonei = boto3.client(
+                    's3',
+                    aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+                    config=botocore.client.Config(signature_version='s3v4'),
+                    region_name='cn-northwest-1'
+                )
+                aws_s3_guowai = boto3.client(
+                    's3',
+                    aws_access_key_id=AWS_ACCESS_KEY_ID[1],
+                    aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
+                    config=botocore.client.Config(signature_version='s3v4'),
+                    region_name='us-east-1'
+                )
+                self.do_bulk_create_info(redis_list, n_time, channel, event_type, is_st, uid)
+                if is_st == '0' or is_st == '2':
+                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success44444444444444444'})
+                elif 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)
+                    thumbspng = '{uid}/{channel}/{filename}.jpeg'.format(uid=uid, channel=channel, filename=n_time)
+                    if region == 2:  # 2:国内
+                        response_url = aws_s3_guonei.generate_presigned_url(
+                            ClientMethod='put_object',
+                            Params={
+                                'Bucket': 'push',
+                                'Key': thumbspng
+                            },
+                            ExpiresIn=3600
+                        )
+                    else:   # 1:国外
+                        response_url = aws_s3_guowai.generate_presigned_url(
+                            ClientMethod='put_object',
+                            Params={
+                                'Bucket': 'foreignpush',
+                                'Key': thumbspng
+                            },
+                            ExpiresIn=3600
+                        )
+                    # res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
+                    # response_url = response_url[:4] + response_url[5:]
+                    res_data = {'code': 0, 'img_push': response_url, 'msg': 'success'}
+                    return JsonResponse(status=200, data=res_data)
+                elif is_st == '3':
+                    # 人形检测带动图
+                    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)
+
+                        thumbspng = '{uid}/{channel}/{filename}_{st}.jpeg'. \
+                            format(uid=uid, channel=channel, filename=n_time, st=i)
+                        if region == 2:  # 2:国内
+                            response_url = aws_s3_guonei.generate_presigned_url(
+                                ClientMethod='put_object',
+                                Params={
+                                    'Bucket': 'push',
+                                    'Key': thumbspng
+                                },
+                                ExpiresIn=3600
+                            )
+                        else:   # 1:国外
+                            response_url = aws_s3_guowai.generate_presigned_url(
+                                ClientMethod='put_object',
+                                Params={
+                                    'Bucket': 'foreignpush',
+                                    'Key': thumbspng
+                                },
+                                ExpiresIn=3600
+                            )
+                        # response_url = response_url[:4] + response_url[5:]
+                        img_url_list.append(response_url)
+
+                        # img_url_list.append(url)
+                    res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success'}
+                    return JsonResponse(status=200, data=res_data)
+            else:
+                return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+        else:
+            return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong etk'})
+
+    def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
+        now_time = int(time.time())
+        # 设备昵称
+        userID_ids = []
+        sys_msg_list = []
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        is_st = int(is_st)
+        eq_list = []
+        nickname = uaqs[0]['uid_set__nickname']
+        if not nickname:
+            nickname = uid
+        for ua in uaqs:
+            lang = ua['lang']
+            tz = ua['tz']
+            userID_id = ua["userID_id"]
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=is_st,
+                    receiveTime=n_time,
+                    addTime=now_time,
+                    storage_location=2
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+        if eq_list:
+            print('eq_list')
+            Equipment_Info.objects.bulk_create(eq_list)
+        if is_sys_msg:
+            print('sys_msg')
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        return True
+
+    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, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            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 = 'Low battery'
+            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

+ 16 - 0
Controller/DeviceShare.py

@@ -56,6 +56,8 @@ class DeviceShareView(View):
                     return self.do_query_user(userID, request_dict, response)
                 elif operation == 'deleteUser':
                     return self.do_delete_user(userID, request_dict, response)
+                elif operation == 'deleteUserV2':
+                    return self.do_delete_userV2(userID, request_dict, response)
                 else:
                     return response.json(414)
             else:
@@ -244,3 +246,17 @@ class DeviceShareView(View):
                 return response.json(0)
         else:
             return response.json(444, 'id')
+
+    def do_delete_userV2(self, userID, request_dict, response):
+        ids = request_dict.get('ids', None)
+        if id:
+            try:
+                # redisObj = RedisObject(db=8)
+                # redisObj.del_data(key='uid_qs_' + userID)
+                Device_Info.objects.filter(id__in=ids, primaryUserID=userID).update(isExist=0)
+            except Exception as e:
+                return response.json(10, repr(e))
+            else:
+                return response.json(0)
+        else:
+            return response.json(444, 'id')

+ 9 - 9
Controller/EquipmentInfo.py

@@ -289,19 +289,19 @@ class EquipmentInfo(View):
 use information_schema;
 select concat(round(sum(data_length/1024/1024),2),'MB') as data from tables where table_schema='Ansjer81';
 '''
-# 按季度删除访问日志
+# 删除访问日志
 def deleteExpireEquipmentInfo(request):
     response = ResponseObject()
-    i = int(request.GET.get('i', 10))
-
     import time
     nowTime = int(time.time())
-    for i in range(i):
-        ei = Equipment_Info.objects.filter(addTime__lte=str(nowTime - 3600 * 24 * 7))[0:10000]
-        id_list = ei.values_list("id", flat=True)
-        print(id_list)
-        Equipment_Info.objects.filter(id__in=list(id_list)).delete()
-    return response.json(0)
+    try:
+        for i in range(5):
+            ei = Equipment_Info.objects.filter(addTime__lte=str(nowTime - 3600 * 24 * 7))[0:10000]
+            id_list = list(ei.values_list("id", flat=True))
+            Equipment_Info.objects.filter(id__in=id_list).delete()
+        return response.json(0)
+    except Exception as e:
+        return response.json(500, repr(e))
 
 
 # 按季度删除访问日志

+ 7 - 0
Controller/EquipmentManagerV3.py

@@ -9,6 +9,8 @@ from Controller.CheckUserData import RandomStr
 import oss2, base64
 from django.db.models import Q
 from django.views.generic.base import View
+
+from Controller.DeviceConfirmRegion import Device_Region
 from Object.RedisObject import RedisObject
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, BASE_DIR
 from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, UidChannelSetModel, \
@@ -162,6 +164,10 @@ class EquipmentManagerV3(View):
                 us_qs.update(nickname=NickName)
                 UidSet_id = us_qs.first().id
             else:
+                ip = CommonService.get_ip_address(request)
+                region_id = Device_Region().get_device_region(ip)
+                if region_id == 1:
+                    region_alexa = 'CN'
                 uid_set_create_dict = {
                     'uid': UID,
                     'addTime': nowTime,
@@ -170,6 +176,7 @@ class EquipmentManagerV3(View):
                     'channel': ChannelIndex,
                     'nickname': NickName,
                     'version': version,
+                    'region_alexa': region_alexa,
                 }
                 UidSet = UidSetModel.objects.create(**uid_set_create_dict)
                 UidSet_id = UidSet.id

+ 2 - 2
Controller/FAQController.py

@@ -360,7 +360,7 @@ class FAQView(View):
 
         ZositechHelpModel.objects.all().delete()
 
-        for data in zhresults['results']:
+        for data in zhresults['articles']:
             labname = ""
             if data['label_names']:
                 for lab in data['label_names']:
@@ -375,7 +375,7 @@ class FAQView(View):
                 'origin': 'web_widget',
                 'content': json.dumps(data).replace("\'", "\"").replace("XX??????XX", "\'")
             })
-        for data in enresults['results']:
+        for data in enresults['articles']:
             labname = ""
             if data['label_names']:
                 for lab in data['label_names']:

+ 105 - 74
Controller/IotCoreController.py

@@ -56,86 +56,105 @@ class IotCoreView(View):
 
     # CVM注册  :正使用
     def create_keys_and_certificate(self, request_dict, response, request):
-        serial_number = request_dict.get('serial_number', None)
-        serial_number_code = request_dict.get('serial_number_code', None)
+        uid = request_dict.get('uid', '')
         token = request_dict.get('token', None)
+        uid_code = request_dict.get('uid_code', None)
+        language = request_dict.get('language', None)
         time_stamp = request_dict.get('time_stamp', None)
         device_version = request_dict.get('device_version', None).replace('.', '_')  # 物品组命名不能包含'.'
-        language = request_dict.get('language', None)
 
-        if serial_number and token and time_stamp and serial_number_code and device_version and language:
-            serial_number_code = CommonService.decode_data(serial_number_code)
-            token = int(CommonService.decode_data(token))
-            time_stamp = int(time_stamp)
+        if not all([token, time_stamp, device_version, language]):
+            return response.json(444, {'param': 'token, uid_code, time_stamp, device_version, language'})
 
-            now_time = int(time.time())
-            distance = now_time - time_stamp
-            thingGroup = device_version + '_' + language
+        # token时间戳校验
+        token = int(CommonService.decode_data(token))
+        time_stamp = int(time_stamp)
+        now_time = int(time.time())
+        distance = now_time - time_stamp
+        if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+            return response.json(404)
 
-            if token != time_stamp or distance > 60000 or distance < -60000 or serial_number != serial_number_code:  # 为了全球化时间控制在一天内
+        if not uid:
+            # 使用序列号
+            serial_number = request_dict.get('serial_number', None)
+            serial_number_code = request_dict.get('serial_number_code', None)
+            if not all([serial_number, serial_number_code]):
+                return response.json(444, {'param': 'serial_number, serial_number_code'})
+
+            # 序列号编码解码校验
+            serial_number_code = CommonService.decode_data(serial_number_code)
+            if serial_number != serial_number_code:
                 return response.json(404)
 
             serial = serial_number[0:6]
+            try:
+                SerialNumberModel.objects.get(serial_number=serial)
+            except:
+                return response.json(444)
 
-            iotqs = iotdeviceInfoModel.objects.filter(serial_number=serial)
-
-            # 判断设备是否已注册证书
-            if not iotqs.exists():
-                ip = CommonService.get_ip_address(request)
-                region_id = Device_Region().get_device_region(ip)
-
-                iotClient = IOTClient(region_id)
-                res = iotClient.create_keys_and_certificate(serial_number, thingGroup, response)
-                nowTime = int(time.time())
-                token_iot_number = hashlib.md5((str(uuid.uuid1()) + str(nowTime)).encode('utf-8')).hexdigest()
-
-                # sn = SerialNumberModel.objects.get(serial_number=serial)
-                try:
-                    sn = SerialNumberModel.objects.get(serial_number=serial)
-                except:
-                    return response.json(444)
-
-                iotdeviceInfoModel.objects.create(serial_number=serial,
-                                                  endpoint=res[0]['endpoint'],
-                                                  certificate_id=res[0]['certificateId'],
-                                                  certificate_pem=res[0]['certificatePem'],
-                                                  public_key=res[0]['publicKey'],
-                                                  private_key=res[0]['privateKey'],
-                                                  thing_name=res[1]['ThingName'],
-                                                  token_iot_number=token_iot_number
-                                                  )
-                res = {
-                    'certificateId': res[0]['certificateId'],
-                    'certificatePem': res[0]['certificatePem'],
-                    'publicKey': res[0]['publicKey'],
-                    'privateKey': res[0]['privateKey'],
-                    'endpoint': res[0]['endpoint']
-                }
-                return response.json(0, {'res': res})
-            else:
+            ThingNameSuffix = serial_number  # 物品名后缀
+            iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=serial)
+        else:
+            # 使用uid
+            # uid编码解码校验
+            uid_code = CommonService.decode_data(uid_code)
+            if uid != uid_code:
+                return response.json(404)
 
-                iot = iotqs[0]
-                res = {
-                    'certificateId': iot.certificate_id,
-                    'certificatePem': iot.certificate_pem,
-                    'publicKey': iot.public_key,
-                    'privateKey': iot.private_key,
-                    'endpoint': iot.endpoint
-                }
-                # print('此设备已注册证书')
-                return response.json(0, {'res': res})
+            serial = ''     # iot_deviceInfo表写入serial_number为''
+            ThingNameSuffix = uid     # 物品名后缀
+            iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=uid)
+        # 判断设备是否已注册证书
+        if not iotdeviceInfo_qs.exists():
+            thingGroup = device_version + '_' + language
+            ip = CommonService.get_ip_address(request)
+            region_id = Device_Region().get_device_region(ip)
+
+            iotClient = IOTClient(region_id)
+            res = iotClient.create_keys_and_certificate(ThingNameSuffix, thingGroup, response)
+            token_iot_number = hashlib.md5((str(uuid.uuid1()) + str(now_time)).encode('utf-8')).hexdigest()
+
+            iotdeviceInfoModel.objects.create(uid=uid,
+                                              serial_number=serial,
+                                              endpoint=res[0]['endpoint'],
+                                              certificate_id=res[0]['certificateId'],
+                                              certificate_pem=res[0]['certificatePem'],
+                                              public_key=res[0]['publicKey'],
+                                              private_key=res[0]['privateKey'],
+                                              thing_name=res[1]['ThingName'],
+                                              thing_groups=res[1]['thingGroupName'],
+                                              token_iot_number=token_iot_number
+                                              )
+            res = {
+                'certificateId': res[0]['certificateId'],
+                'certificatePem': res[0]['certificatePem'],
+                'publicKey': res[0]['publicKey'],
+                'privateKey': res[0]['privateKey'],
+                'endpoint': res[0]['endpoint']
+            }
+            return response.json(0, {'res': res})
         else:
-            return response.json(444)
+            iot = iotdeviceInfo_qs[0]
+            res = {
+                'certificateId': iot.certificate_id,
+                'certificatePem': iot.certificate_pem,
+                'publicKey': iot.public_key,
+                'privateKey': iot.private_key,
+                'endpoint': iot.endpoint
+            }
+            # print('此设备已注册证书')
+            return response.json(0, {'res': res})
 
     def thing_regroup(self, request_dict, response, request):
         # 物品重新分组
+        uid = request_dict.get('uid', '')
         token = request_dict.get('token', None)
+        language = request_dict.get('language', None)
         time_stamp = request_dict.get('time_stamp', None)
-        serial_number = request_dict.get('serial_number', None)
         device_version = request_dict.get('device_version', None)
-        language = request_dict.get('language', None)
-        if not all([serial_number, device_version, language, token, time_stamp]):
-            return response.json(444)
+
+        if not all([token, language, time_stamp, device_version]):
+            return response.json(444, {'param: token, language, time_stamp, device_version'})
 
         # 封装token认证
         token = int(CommonService.decode_data(token))
@@ -144,15 +163,20 @@ class IotCoreView(View):
         distance = now_time - time_stamp
         if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
             return response.json(404)
+
         ip = CommonService.get_ip_address(request)
         region_id = Device_Region().get_device_region(ip)
+        iotClient = IOTClient(region_id)
 
-        thingName = 'Ansjer_Device_' + serial_number
+        ThingNameSuffix = uid
+        if not uid:
+            # 使用序列号
+            serial_number = request_dict.get('serial_number', None)
+            if not serial_number:
+                return response.json(444)
+            ThingNameSuffix = serial_number
+        thingName = 'Ansjer_Device_' + ThingNameSuffix
         new_thingGroupName = (device_version + '_' + language).replace('.', '_')  # 物品组命名不能包含'.'
-        # 调试参数
-        # thingName = 'Ansjer_Device_00EBEX'
-        # new_thingGroupName = 'C1Pro_V1_0_1_cn'
-        iotClient = IOTClient(region_id)
 
         try:
             # 获取旧物品组
@@ -177,9 +201,12 @@ class IotCoreView(View):
             iotClient.client.update_thing_groups_for_thing(thingName=thingName
                                                            , thingGroupsToAdd=[new_thingGroupName]
                                                            , thingGroupsToRemove=[old_thingGroupName])
-            # 更新设备版本信息
-            Device_Info.objects.filter(serial_number=serial_number).update(version=device_version)
 
+            # 更新设备版本信息
+            if uid:
+                Device_Info.objects.filter(UID=uid).update(version=device_version)
+            else:
+                Device_Info.objects.filter(serial_number=serial_number).update(version=device_version)
             return response.json(0)
         except Exception as e:
             print(e)
@@ -199,6 +226,7 @@ class IotCoreView(View):
             return response.json(444)
 
     def request_publish_message(self, request_dict, response, request):
+        # Alexa请求IoT Core下发MQTT消息
         UID = request_dict.get('UID', None)
         MSG = request_dict.get('MSG', None)
 
@@ -207,20 +235,23 @@ class IotCoreView(View):
 
         try:
             # 获取检查uid的序列号,如果没有序列号,不使用MQTT下发消息
-            device_info_qs = Device_Info.objects.filter(UID=UID).values('serial_number')
+            device_info_qs = Device_Info.objects.filter(UID=UID).values('UID', 'serial_number')
+            uid = device_info_qs[0]['UID']
             serial_number = device_info_qs[0]['serial_number']
-            if serial_number == '':
-                return response.json(10043)
+            # 如果device_info表的serial_number不为空,物品名为'Ansjer_Device_序列号'
+            ThingNameSuffix = serial_number if serial_number != '' else uid
 
+            thing_name = 'Ansjer_Device_' + ThingNameSuffix
             # 获取数据组织将要请求的url
-            thing_name = 'Ansjer_Device_' + serial_number
             iot = iotdeviceInfoModel.objects.filter(thing_name__contains=thing_name).values('thing_name', 'endpoint',
                                                                                             'token_iot_number')
+            if not iot.exists():
+                return response.json(10043)
             thing_name = iot[0]['thing_name']  # IoT core上的物品名: Ansjer_Device_+序列号+企业编码
             endpoint = iot[0]['endpoint']
             Token = iot[0]['token_iot_number']
             # Token = '297a601b3925e04daab5a60280650e09'
-            topic_name = thing_name + '_rtsp_topic'
+            topic_name = thing_name + '_rtsp_topic'     # MQTT主题
 
             # rtsp://rtsp.zositech.org:8554/ZFdqWldXRFpMTkVaYVZEaEJXRXhUV0RFeE1VRT1B
             # api doc: https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/http.html

+ 2 - 1
Controller/OrderContrller.py

@@ -110,7 +110,7 @@ class OrderView(View):
                                                               "updTime", "paypal", "rank__day", "payType",
                                                               "rank__price", "status",
                                                               "rank__content", "rank__title", "rank__currency",
-                                                              "rank_id")
+                                                              "rank_id","rank__expire")
         order_list = list(order_ql)
         data = []
         nowTime = int(time.time())
@@ -128,6 +128,7 @@ class OrderView(View):
                     d['did'] = did['id']
                     d['Type'] = did['Type']
                     data.append(d)
+            d['rank__expire_unit'] = '月' if lang == 'cn' else 'month'
         return response.json(0, {'data': data, 'count': count})
 
     # admins ^^^^^^^^^^^^

+ 25 - 26
Controller/SerialNumberController.py

@@ -44,12 +44,14 @@ class SerialNumberView(View):
             return self.do_attach_uid(request_dict, response, request)
         elif operation == 'detachUID':
             return self.do_detach_uid(request_dict, response)
+        elif operation == 'create':
+            return self.do_create(request_dict, response)
         else:
             if token.code != 0:
                 return response.json(token.code)
 
-            if operation == 'create':
-                return self.do_create(request_dict, response)
+            # if operation == 'create':
+            #     return self.do_create(request_dict, response)
             elif operation == 'list':
                 return self.do_list(token.userID, request_dict, response)
             elif operation == 'update':
@@ -58,36 +60,33 @@ class SerialNumberView(View):
                 return response.json(404)
 
     def do_create(self, request_dict, response):
-        quantity = int(request_dict.get('quantity', None))
-        p2p = int(request_dict.get('p2p', None))
+        quantity = int(request_dict.get('quantity', 0))
+        p2p = int(request_dict.get('p2p', 0))
 
         if not quantity:
             return response.json(444)
-        start_time = time.strftime('%Y-%m-%d %H:%M:%S')
-        print('start create ' + start_time)
-        tmp = []
-        algorithm = AlgorithmBaseOn35()
 
-        for i in range(quantity):
+        try:
             try:
                 sum = SerialNumberModel.objects.last().id
             except:
                 sum = 0
-            serial_number = algorithm.getLetter(sum)
-            tmp_len = 6 - len(serial_number)
-            # 前面补0
-            for j in range(tmp_len):
-                serial_number = '0' + serial_number
-            data = []
+            serial_number_bulk = []
             now_time = int(time.time())
-            data.append(SerialNumberModel(serial_number=serial_number, add_time=now_time, p2p=p2p))
-            SerialNumberModel.objects.bulk_create(data)
-            data.clear()
-            start_time = time.strftime('%Y-%m-%d %H:%M:%S')
-            print('start create ' + start_time)
-            redis = RedisObject()
-            redis.del_data(key='serial_number_count')
-        return response.json(0)
+            algorithm = AlgorithmBaseOn35()
+            for i in range(quantity):
+                serial_number = algorithm.getLetter(sum)
+                sum += 1    # sum每次递增1
+                # 前面补0至六位
+                serial_number = (6-len(serial_number))*'0' + serial_number
+                serial_number_bulk.append(SerialNumberModel(serial_number=serial_number, add_time=now_time, p2p=p2p))
+            # 开启事务写入
+            with transaction.atomic():
+                SerialNumberModel.objects.bulk_create(serial_number_bulk)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
 
     # 提供给pc端获取序列号
     def do_get_serial_number(self, request_dict, response):
@@ -341,7 +340,7 @@ class SerialNumberView(View):
         token = request_dict.get('token', None)
         time_stamp = request_dict.get('time_stamp', None)
 
-        if token and time_stamp and serial_number and len(serial_number) == 9:
+        if token and time_stamp and serial_number:
             token = int(CommonService.decode_data(token))
             time_stamp = int(time_stamp)
 
@@ -353,7 +352,7 @@ class SerialNumberView(View):
 
             serial = serial_number[0:6]
 
-            uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number__serial_number=serial)
+            uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number=serial)
             if uid_serial_qs.exists():
                 uid_serial = uid_serial_qs[0]
 
@@ -368,7 +367,7 @@ class SerialNumberView(View):
                     company_serial.status = 1
                     company_serial.save()
 
-                uid_qs = UIDModel.objects.filter(uid=uid_serial.uid)
+                uid_qs = UIDModel.objects.filter(uid=uid_serial.uid.uid)
                 if uid_qs.exists():
                     uid = uid_qs[0]
                     uid.status = 0

+ 157 - 0
Controller/ShadowController.py

@@ -0,0 +1,157 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerPush
+@software: PyCharm
+@DATE: 2020/2/14 13:54
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: ShadowController.py
+@Contact: chanjunkai@163.com
+"""
+# 测试环境
+# test.shadow.dvema.com
+# 生产环境
+# shadow.dvema.com
+# 设备影子更新
+from Object.LogUtil import LogUtil
+from Object.ResponseObject import ResponseObject
+from Object.ETkObject import ETkObject
+import time
+from Model.models import Device_Info, UidSetModel, UID_Preview, VoicePromptModel, UID_Bucket
+from Service.CommonService import CommonService
+from django.http import JsonResponse
+from Object.UidTokenObject import UidTokenObject
+
+def generate_utk(request):
+    request.encoding = 'utf-8'
+    response = ResponseObject()
+    if request.method == 'GET':
+        request_dict = request.GET
+    elif request.method == 'POST':
+        request_dict = request.POST
+    else:
+        return response.json(444,'wrong method')
+    username = request_dict.get('username',None)
+    password = request_dict.get('password',None)
+    uid = request_dict.get('uid',None)
+    if username and password:
+        if username == 'debug_user' and password == 'debug_password':
+            # utko = UidTokenObject()
+            # # right
+            # utko.generate(data={'uid': uid})
+            etkObj = ETkObject(etk='')
+            etk = etkObj.encrypt(uid)
+            return response.json(0, {'etk': etk})
+        else:
+            return response.json(404)
+    else:
+        return response.json(444,'username password')
+
+
+# 设备影子更新
+def update_device_shadow(request):
+    request.encoding = 'utf-8'
+    response = ResponseObject()
+    if request.method == 'POST':
+        request_dict = request.POST
+    elif request.method == 'GET':
+        request_dict = request.GET
+    else:
+        return response.json(444)
+    etk = request_dict.get('etk', None)
+    eto = ETkObject(etk)
+    uid = eto.uid
+    if uid:
+        # 重置按钮
+        is_reset = request_dict.get('is_reset', None)
+        # 传1则重置设备信息
+        if is_reset == '1':
+            UidSetModel.objects.filter(uid=uid).delete()
+            # 重置设备,判断设备为已删除
+            nowTime = int(time.time())
+            uid_bucket = UID_Bucket.objects.filter(uid=uid, endTime__gte=nowTime).values('id', 'has_unused').order_by('addTime')
+            if not uid_bucket.exists():
+                di_qs = Device_Info.objects.filter(UID=uid)
+                di_qs.update(isExist=2)
+            # 删除预览图
+            uid_pre_qs = UID_Preview.objects.filter(uid=uid)
+            if uid_pre_qs.exists():
+                uid_pre_qs.delete()
+
+            # 删除语音提示
+            voice_qs = VoicePromptModel.objects.filter(uid=uid)
+            if voice_qs.exists():
+                voice_qs.delete()
+
+        # return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+        ucode = request_dict.get('ucode', None)
+        version = request_dict.get('version', None)
+        p2p_region = request_dict.get('p2p_region', None)
+        tz = request_dict.get('tz', None)
+        video_code = request_dict.get('video_code', None)
+        ip = CommonService.get_ip_address(request)
+        channel = request_dict.get('channel', None)
+        cloud_vod = request_dict.get('cloud_vod', None)
+        push_status = request_dict.get('push_status', None)
+        pwd = request_dict.get('pwd', None)
+        resetTime = request_dict.get('resetTime', None)
+        is_alexa = request_dict.get('is_alexa', None)
+        is_human = request_dict.get('is_human', None)
+        is_custom_voice = request_dict.get('is_custom', None)
+        double_wifi = request_dict.get('double_wifi', None)
+
+        us_qs = UidSetModel.objects.filter(uid=uid)
+        # 更新
+        nowTime = int(time.time())
+
+        print('-------')
+        print(resetTime)
+        print('-------')
+        qs_dict = {
+            'updTime': nowTime,
+            'ip': ip
+        }
+        if channel:
+            qs_dict['channel'] = channel
+        if p2p_region:
+            qs_dict['p2p_region'] = p2p_region
+        if ucode:
+            qs_dict['ucode'] = ucode
+        if version:
+            qs_dict['version'] = version
+        if tz:
+            qs_dict['tz'] = tz
+        if video_code:
+            qs_dict['video_code'] = video_code
+        if cloud_vod:
+            qs_dict['cloud_vod'] = cloud_vod
+        if push_status:
+            qs_dict['detect_status'] = push_status
+        if pwd:
+            qs_dict['pwd'] = pwd
+        if is_human:
+            qs_dict['is_human'] = is_human
+        if is_custom_voice:
+            qs_dict['is_custom_voice'] = is_custom_voice
+        if double_wifi:
+            qs_dict['double_wifi'] = double_wifi
+        if us_qs.exists():
+            if is_alexa and us_qs[0].is_alexa == 0:
+                qs_dict['is_alexa'] = is_alexa
+            us_qs.update(**qs_dict)
+            # 如果推送状态开启,返回推送url
+            return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+        # 新增
+        else:
+            if is_alexa:
+                qs_dict['is_alexa'] = is_alexa
+            qs_dict['uid'] = uid
+            qs_dict['addTime'] = nowTime
+            UidSetModel.objects.create(**qs_dict)
+            # 如果推送状态开启,返回推送url
+            return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+    else:
+        return JsonResponse(status=200, data={'code': 403, 'msg': 'error etk'})

+ 708 - 0
Controller/TestDetectController.py

@@ -0,0 +1,708 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerFormal
+@software: PyCharm
+@DATE: 2019/1/14 15:57
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: DetectController.py
+@Contact: chanjunkai@163.com
+"""
+import os
+import time
+
+import apns2
+import jpush as jpush
+import oss2
+from django.http import JsonResponse, HttpResponse
+from django.views.generic.base import View
+from pyfcm import FCMNotification
+from Ansjer.config import SERVER_TYPE, JPUSH_CODE, APNS_CODE, APP_TYPE
+from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH_DOMAIN, JPUSH_CONFIG, FCM_CONFIG, \
+    APNS_CONFIG, BASE_DIR, APNS_MODE
+from Model.models import Equipment_Info, UidPushModel, SysMsgModel
+from Object.ETkObject import ETkObject
+from Object.RedisObject import RedisObject
+from Object.UidTokenObject import UidTokenObject
+from Service.CommonService import CommonService
+import json
+
+'''
+http://push.dvema.com/notify/push?etk=Y2lTRXhMTjBWS01sWlpURTVJU0ZWTlJ6RXhNVUU9T3o=&n_time=1526845794&channel=1&event_type=704&is_st=0
+http://push.dvema.com/deviceShadow/generateUTK?username=debug_user&password=debug_password&uid=VVDHCVBYDKFMJRWA111A
+'''
+
+
+# 移动侦测接口
+class NotificationView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.validation(request.GET, 0)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        return self.validation(request.POST, 1)
+
+    def validation(self, request_dict, request_type):
+        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)
+        # print("aaa")
+        # return JsonResponse(0,safe=False)
+        if not all([channel, n_time]):
+            return JsonResponse(status=200, data={
+                'code': 444,
+                'msg': 'param is wrong'})
+        if etk:
+            eto = ETkObject(etk)
+            uid = eto.uid
+            if len(uid) != 20:
+                return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+        else:
+            utko = UidTokenObject(uidToken)
+            uid = utko.UID
+        pkey = '{uid}_{channel}_{event_type}_ptl'.format(uid=uid, event_type=event_type, channel=channel)
+        # ykey = 'MUJ887NLR8K8GBM9111A_redis_qs'.format(uid=uid)
+        ykey = '{uid}_redis_qs'.format(uid=uid)
+        dkey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=event_type, channel=channel)
+        # 判断redisObj.get_data(key=pkey):不为空
+        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:
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'msg': 'Push once every 10 seconds'}
+            else:
+                res_data = {'code': 0, 'msg': 'Push it once a minute'}
+            return JsonResponse(status=200, data=res_data)
+
+        # 数据库读取数据
+        if have_ykey:
+            redis_list = eval(redisObj.get_data(key=ykey))
+        else:
+            # 从数据库查询出来
+            uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                values('token_val', 'app_type', 'appBundleId', 'm_code',
+                       'push_type', 'userID_id', 'userID__NickName', 'userID__username',
+                       'lang', 'm_code', 'tz', 'uid_set__nickname', 'uid_set__detect_interval', 'uid_set__detect_group',
+                       'uid_set__channel')
+            # 新建一个list接收数据
+            redis_list = []
+            # 把数据库数据追加进redis_list
+            for qs in uid_push_qs:
+                redis_list.append(qs)
+            # 修改redis数据,并设置过期时间为10分钟
+            redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+            if not redis_list:
+                res_data = {'code': 404, 'msg': 'error !'}
+                return JsonResponse(status=200, data=res_data)
+
+            # 此时应该更新一下redis里面的dkey的有效时间
+            detect_interval = redis_list[0]['uid_set__detect_interval']
+            channel = redis_list[0]['uid_set__channel']
+            self.do_update_detect_interval(uid, channel, redisObj, detect_interval)
+
+
+        if not redis_list:
+            print("没有redi_list")
+            res_data = {'code': 0, 'msg': 'no redi_list success!'}
+            return JsonResponse(status=200, data=res_data)
+
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        nickname = redis_list[0]['uid_set__nickname']
+        detect_interval = redis_list[0]['uid_set__detect_interval']
+        detect_group = redis_list[0]['uid_set__detect_group']
+        now_time = int(time.time())
+        if not nickname:
+            nickname = uid
+        print('detect_group')
+        print(detect_group)
+        print(detect_interval)
+        if detect_group:
+            if have_dkey:
+                detect_med_type = 1  # 1为存库不推送
+            else:
+                detect_med_type = 2  # 为2的话,既推送,又存库
+                # detect_group=0允许全部推送的时候
+                if detect_group == '0':
+                    redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                else:
+                    detect_group_list = detect_group.split(',')
+                    if event_type in detect_group_list:
+                        if detect_interval < 60:
+                            detect_interval = 60
+                        redisObj.set_data(key=dkey, val=1, expire=detect_interval)
+                # 改为1秒
+                # 如果不是正式
+                if SERVER_TYPE!="Ansjer.formal_settings":
+                    redisObj.set_data(key=pkey, val=1, expire=10)
+                else:
+                    redisObj.set_data(key=pkey, val=1, expire=60)
+
+            # 打印have_ykey
+        # return JsonResponse(status=200, data={'pkey': 0, 'have_ykey': have_ykey, 'have_pkey': have_pkey, 'have_ykey': have_dkey})
+
+        # 旧模式并且没有pkey,重新创建一个
+        if not detect_group and not have_pkey:
+            # 设置推送时间为60秒一次
+            # 如果不是正式
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                redisObj.set_data(key=pkey, val=1, expire=10)
+            else:
+                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,
+            # 'appBundleId': appBundleId,
+            # 'token_val': token_val,
+            # 'msg_title': msg_title,
+            # 'msg_text': msg_text
+        }
+        eq_list = []
+        sys_msg_list = []
+        userID_ids = []
+        do_apns_code = ''
+        do_fcm_code = ''
+        do_jpush_code = ''
+        for up in redis_list:
+            push_type = up['push_type']
+            appBundleId = up['appBundleId']
+            token_val = up['token_val']
+            lang = up['lang']
+            tz = up['tz']
+            # 发送标题
+            msg_title = self.get_msg_title(appBundleId=appBundleId, nickname=nickname)
+            # 发送内容
+            msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                         event_type=event_type)
+            kwag_args['appBundleId'] = appBundleId
+            kwag_args['token_val'] = token_val
+            kwag_args['msg_title'] = msg_title
+            kwag_args['msg_text'] = msg_text
+            #推送
+            if detect_med_type == 2 or detect_med_type == 0:
+                if push_type == 0:  # ios apns
+                    print('do_apns')
+                    # self.do_apns(**kwag_args)
+                    do_apns_code = self.do_apns(**kwag_args)
+                    up['push_code'] = do_apns_code
+                elif push_type == 1:  # android gcm
+                    print('do_fcm')
+                    do_fcm_code = self.do_fcm(**kwag_args)
+                    up['push_code'] = do_fcm_code
+                elif push_type == 2:  # android jpush
+                    print('do_jpush')
+                    do_jpush_code = self.do_jpush(**kwag_args)
+                    up['push_code'] = do_jpush_code
+                    # return JsonResponse(status=200, data={'code': 0, '状态:': self.do_jpush(**kwag_args)})
+
+            if detect_med_type == 1:
+                do_apns_code = '只存库不推送'
+                do_fcm_code = '只存库不推送'
+                do_jpush_code = '只存库不推送'
+                up['push_code'] = -1
+
+            # 以下是存库
+            userID_id = up["userID_id"]
+            int_is_st = int(is_st)
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=int_is_st,
+                    receiveTime=n_time,
+                    addTime=now_time
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    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)
+        if is_sys_msg:
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        Equipment_Info.objects.bulk_create(eq_list)
+
+        if is_st == '0' or is_st == '2':
+            print("is_st=0or2")
+            for up in redis_list:
+                # if up['push_type'] == 0:  # ios apns
+                #     up['do_apns_code'] = do_apns_code
+                # elif up['push_type'] == 1:  # android gcm
+                #     up['do_fcm_code'] = do_fcm_code
+                # elif up['push_type'] == 2:  # android jpush
+
+                try:
+
+                    code = up['push_code']
+                    print("push_code is ")
+                    print(code)
+                    if up['push_type'] == 0:
+                        up['push_res'] = '{code} {desc}'.format(code=code, desc=APNS_CODE[code])
+                        up['push_type'] = '苹果推送'
+                    elif up['push_type'] == 1:
+                        up['push_res'] = code
+                        up['push_type'] = '谷歌推送'
+                    elif up['push_type'] == 2:
+                        up['push_res'] = '{code} {desc}'.format(code=code, desc=JPUSH_CODE[code])
+                        up['push_type'] = '极光推送'
+
+
+                except KeyError as ke:
+                    print(ke)
+                else:
+                    del up['push_code']
+
+                #up['test_or_www'] = SERVER_TYPE
+                if SERVER_TYPE == 'Ansjer.formal_settings':
+                    up['server_type'] = '正式服务器'
+                else:
+                    up['server_type'] = '测试服务器'
+
+                up['app_type'] = APP_TYPE[up['app_type']]
+
+                # 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']
+
+                if request_type == 0:
+                    data = ""
+                    for up in redis_list:
+                        data += ("<p>" + repr(up) + "</p>")
+                    return HttpResponse(repr(data))
+                else:
+                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success 0 or 2', 're_list': redis_list})
+
+        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 redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                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']
+                # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_push': url, 'msg': 'success', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                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 redis_list:
+                up['do_apns_code'] = do_apns_code
+                up['do_fcm_code'] = do_fcm_code
+                up['do_jpush_code'] = do_jpush_code
+                up['test_or_www'] = SERVER_TYPE
+                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']
+
+            # 不是正式服务器
+            if SERVER_TYPE != "Ansjer.formal_settings":
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3', 're_list': redis_list}
+            else:
+                # 是正式服务器的时候
+                res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success 3'}
+            return JsonResponse(status=200, data=res_data)
+
+
+    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, 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 = '电量过低'
+            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)
+                # send_text = '{msg_type} 通道:{channel} 日期:{date}'.format(msg_type=msg_type, channel=channel, date=n_date)
+        else:
+            if etype == 704:
+                msg_type = 'Low battery'
+            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']
+        # 此处换成各自的app_key和master_secre
+        _jpush = jpush.JPush(app_key, master_secret)
+        push = _jpush.create_push()
+        # if you set the logging level to "DEBUG",it will show the debug logging.
+        # _jpush.set_logging("DEBUG")
+        # push.audience = jpush.all_
+        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()
+        print(res)
+        return res.status_code
+        # try:
+        #     res = push.send()
+        #     print(res)
+        # except Exception as e:
+        #     print("jpush fail")
+        #     print("Exception")
+        #     print(repr(e))
+        #     return
+        # else:
+        #     print("jpush success")
+        #     return
+
+    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
+                                                   })
+        print('fcm push ing')
+        print(result)
+        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": "sound.aif", "uid": uid, "zpush": "1", "channel": channel}
+            alert = apns2.PayloadAlert(body=msg_text, title=msg_title)
+            payload = apns2.Payload(alert=alert, custom=push_data)
+
+            # return uid, channel, appBundleId, str(token_val), event_type, n_time, msg_title,msg_text
+            n = apns2.Notification(payload=payload, priority=apns2.PRIORITY_LOW)
+            res = cli.push(n=n, device_token=token_val, topic=appBundleId)
+            print(res.status_code)
+
+            #     200, 推送成功。
+            #   400, 请求有问题。
+            #   403, 证书或Token有问题。
+            #   405, 请求方式不正确, 只支持POST请求
+            #   410, 设备的Token与证书不一致
+            if res.status_code == 200:
+                return res.status_code
+            else:
+                print('apns push fail')
+                print(res.reason)
+                return res.status_code
+        except (ValueError, ArithmeticError):
+            return 'The program has a numeric format exception, one of the arithmetic exceptions'
+        except Exception as e:
+            print(repr(e))
+            return repr(e)
+
+
+    def getJPushReport(self, msg_id, appBundleId):
+        app_key = JPUSH_CONFIG[appBundleId]['Key']
+        master_secret = JPUSH_CONFIG[appBundleId]['Secret']
+        _jpush = jpush.JPush(app_key, master_secret)
+        report = _jpush.create_report()
+        res = report.get_received_detail(msg_id)
+        print("getJPushReport")
+        print(res)
+
+    def do_update_detect_interval(self, uid, channel, redisObject, detect_interval):
+        if channel == 0:
+            channel = 17
+        else:
+            channel += 1
+        for i in range(1, channel):
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=51, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+            tmpDKey = '{uid}_{channel}_{event_type}_flag'.format(uid=uid, event_type=54, channel=i)
+            if tmpDKey is not False:
+                llt = redisObject.get_ttl(tmpDKey)
+                if llt > detect_interval:
+                    redisObject.set_data(key=tmpDKey, val=1, expire=detect_interval)
+
+
+
+# http://test.dvema.com/detect/add?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJQMldOR0pSRDJFSEE1RVU5MTExQSJ9.xOCI5lerk8JOs5OcAzunrKCfCrtuPIZ3AnkMmnd-bPY&n_time=1526845794&channel=1&event_type=51&is_st=0
+# 移动侦测接口
+class PushNotificationView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        # operation = kwargs.get('operation')
+        return self.validation(request.GET)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        # operation = kwargs.get('operation')
+        return self.validation(request.POST)
+
+    def validation(self, request_dict):
+        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)
+        eto = ETkObject(etk)
+        uid = eto.uid
+        if len(uid) == 20:
+            redisObj = RedisObject(db=6)
+            # pkey = '{uid}_{channel}_ptl'.format(uid=uid, channel=channel)
+            pkey = '{uid}_ptl'.format(uid=uid)
+            ykey = '{uid}_redis_qs'.format(uid=uid)
+            if redisObj.get_data(key=pkey):
+                res_data = {'code': 0, 'msg': 'success,!33333333333'}
+                return JsonResponse(status=200, data=res_data)
+            else:
+                redisObj.set_data(key=pkey, val=1, expire=60)
+            ##############
+            redis_data = redisObj.get_data(key=ykey)
+            if redis_data:
+                redis_list = eval(redis_data)
+            else:
+                # 设置推送时间为60秒一次
+                redisObj.set_data(key=pkey, val=1, expire=60)
+                print("从数据库查到数据")
+                # 从数据库查询出来
+                uid_push_qs = UidPushModel.objects.filter(uid_set__uid=uid, uid_set__detect_status=1). \
+                    values('token_val', 'app_type', 'appBundleId',
+                           'push_type', 'userID_id', 'lang','m_code',
+                           'tz', 'uid_set__nickname')
+                # 新建一个list接收数据
+                redis_list = []
+                # 把数据库数据追加进redis_list
+                for qs in uid_push_qs:
+                    redis_list.append(qs)
+                # 修改redis数据,并设置过期时间为10分钟
+            if redis_list:
+                redisObj.set_data(key=ykey, val=str(redis_list), expire=600)
+                auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+                bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+                self.do_bulk_create_info(redis_list, n_time, channel, event_type, is_st, uid)
+                if is_st == '0' or is_st == '2':
+                    return JsonResponse(status=200, data={'code': 0, 'msg': 'success44444444444444444'})
+                elif 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)
+                    res_data = {'code': 0, 'img_push': url, 'msg': 'success'}
+                    return JsonResponse(status=200, data=res_data)
+                elif is_st == '3':
+                    # 人形检测带动图
+                    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)
+                    res_data = {'code': 0, 'img_url_list': img_url_list, 'msg': 'success'}
+                    return JsonResponse(status=200, data=res_data)
+            else:
+                return JsonResponse(status=200, data={'code': 404, 'msg': 'data is not exist'})
+        else:
+            return JsonResponse(status=200, data={'code': 404, 'msg': 'wrong etk'})
+
+    def do_bulk_create_info(self, uaqs, n_time, channel, event_type, is_st, uid):
+        now_time = int(time.time())
+        # 设备昵称
+        userID_ids = []
+        sys_msg_list = []
+        is_sys_msg = self.is_sys_msg(int(event_type))
+        is_st = int(is_st)
+        eq_list = []
+        nickname = uaqs[0]['uid_set__nickname']
+        if not nickname:
+            nickname = uid
+        for ua in uaqs:
+            lang = ua['lang']
+            tz = ua['tz']
+            userID_id = ua["userID_id"]
+            if userID_id not in userID_ids:
+                eq_list.append(Equipment_Info(
+                    userID_id=userID_id,
+                    eventTime=n_time,
+                    eventType=event_type,
+                    devUid=uid,
+                    devNickName=nickname,
+                    Channel=channel,
+                    alarm='Motion \tChannel:{channel}'.format(channel=channel),
+                    is_st=is_st,
+                    receiveTime=n_time,
+                    addTime=now_time
+                ))
+                if is_sys_msg:
+                    sys_msg_text = self.get_msg_text(channel=channel, n_time=n_time, lang=lang, tz=tz,
+                                                     event_type=event_type, is_sys=1)
+                    sys_msg_list.append(SysMsgModel(
+                        userID_id=userID_id,
+                        msg=sys_msg_text,
+                        addTime=now_time,
+                        updTime=now_time,
+                        uid=uid,
+                        eventType=event_type))
+        if eq_list:
+            print('eq_list')
+            Equipment_Info.objects.bulk_create(eq_list)
+        if is_sys_msg:
+            print('sys_msg')
+            SysMsgModel.objects.bulk_create(sys_msg_list)
+        return True
+
+    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, is_sys=0):
+        n_date = CommonService.get_now_time_str(n_time=n_time, tz=tz)
+        etype = int(event_type)
+        if lang == 'cn':
+            if etype == 704:
+                msg_type = '电量过低'
+            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 = 'Low battery'
+            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

+ 13 - 3
Controller/UIDController.py

@@ -11,7 +11,7 @@ from django.views import View
 from django.views.decorators.csrf import csrf_exempt
 from django.db.models import Avg,Max,Min,Count,Sum, Q  #   引入函数
 
-from Model.models import UIDModel, UserModel, UserUIDModel, HistoryUIDModel
+from Model.models import UIDModel, UserModel, UserUIDModel, HistoryUIDModel, UIDCompanySerialModel
 from Object.RedisObject import RedisObject
 from Object.uidManageResponseObject import uidManageResponseObject
 from Object.TokenObject import TokenObject
@@ -373,8 +373,18 @@ class UIDView(View):
                 res['count'] = uid_qs.count()
                 uid_qs = uid_qs.values()[start:end]
 
-                res['data'] = list(uid_qs)
-
+                uid_list = []
+                for uobj in uid_qs:
+                    uid_list.append(uobj['id'])
+
+                serial_uid_qs = UIDCompanySerialModel.objects.filter(uid__id__in=uid_list).values('uid__id','company_serial__serial_number')
+                res['data'] = []
+                for uobj in uid_qs:
+                    list_data = uobj
+                    for data in list(serial_uid_qs):
+                            if uobj['id'] == data['uid__id']:
+                                list_data['serial_number'] = data['company_serial__serial_number']
+                    res['data'].append(list_data)
             print(res)
             return response.json(0, res)
         else:

+ 2 - 2
Controller/shareUserPermission.py

@@ -46,7 +46,7 @@ class searchUserView(View):
         else:
             User = Device_User.objects.filter(**fieldDict).order_by('-data_joined')
         if User.exists():
-            ddUser = User[0].device_info_set.all()
+            ddUser = User[0].device_info_set.filter(isShare=False)
             sqlJSON = serializers.serialize('json', User)
             sqlList = json.loads(sqlJSON)
             if ddUser:
@@ -107,7 +107,7 @@ class searchUserView(View):
                 for k, v in enumerate(sqlDict["datas"]):
                     for val in device_user_res:
                         if v['pk'] == val.userID:
-                            dvqs = val.device_info_set.all()
+                            dvqs = val.device_info_set.filter(isShare=False)
                             device_info_list = CommonService.qs_to_dict(dvqs)
                             # device_user关联到device_info
                             sqlDict["datas"][k]['device_info'] = device_info_list

+ 11 - 8
Model/models.py

@@ -296,6 +296,7 @@ class Equipment_Info(models.Model):
     receiveTime = models.CharField(blank=True, default='', max_length=16, verbose_name=u'接收到报警时间')
     userID_id = models.CharField(default='',  db_index=True, blank=True, max_length=32, verbose_name=u'用户ID')
     is_st = models.SmallIntegerField(default=0, verbose_name='是否截图')  # 0 否,1 是图,2,视频
+    storage_location = models.SmallIntegerField(default=1, db_index=True, verbose_name='数据信息存储位置。1:阿里云oss,2:aws')
     # message_id = models.CharField(blank=True, max_length=32, default='', verbose_name='第三方推送服务器返回的id')
     # push_type = models.SmallIntegerField(blank=True, default=0, verbose_name='第三方推送服务器标志。0:APNS推送,1:谷歌推送,2:极光推送')
     # push_server_status = models.IntegerField(blank=True, default=200, verbose_name='是否成功推送到第三方服务器。200:成功,other:失败')
@@ -650,7 +651,7 @@ class OssCrdModel(models.Model):
 
 class StsCrdModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
-    uid = models.CharField(max_length=20, verbose_name='设备UID')
+    uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     data = models.TextField(verbose_name='设备sts')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
@@ -670,7 +671,7 @@ class StsCrdModel(models.Model):
 
 class UID_Bucket(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
-    uid = models.CharField(max_length=20, verbose_name='设备UID')
+    uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, verbose_name='存储空间')
     status = models.SmallIntegerField(default=0, verbose_name='状态[0:开启,1:关闭]')
@@ -688,7 +689,7 @@ class UID_Bucket(models.Model):
 
 class Unused_Uid_Meal(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
-    uid = models.CharField(max_length=20, verbose_name='设备UID')
+    uid = models.CharField(max_length=20, verbose_name='设备UID', db_index=True)
     channel = models.SmallIntegerField(default=0, verbose_name='通道')
     bucket = models.ForeignKey(VodBucketModel, blank=True, to_field='id', on_delete=models.CASCADE, verbose_name='存储空间')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
@@ -734,7 +735,7 @@ class SysMsgModel(models.Model):
         verbose_name = '系统消息'
         verbose_name_plural = verbose_name
         ordering = ('-id',)
-        app_label = "PushModel"
+        app_label = "db2"
 
 
 # 设备推送重构
@@ -784,7 +785,7 @@ class UidSetModel(models.Model):
 
 
 # 设备关联用户推送
-class UidPushModel(models.Model):
+class   UidPushModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     userID = models.ForeignKey(Device_User, to_field='userID', on_delete=models.CASCADE)
     uid_set = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
@@ -1501,14 +1502,14 @@ class SerialNumberModel(models.Model):
     id = models.AutoField(primary_key=True)
     serial_number = models.CharField(max_length=9, db_index=True, unique=True, verbose_name='序列号')
     status = models.SmallIntegerField(default=1, verbose_name='可用状态。0:不可用,1:可用')
-    p2p = models.SmallIntegerField(default=0, verbose_name='p2p类型。0:无,1:宸云,2:tutk')
+    use_status = models.SmallIntegerField(default=0, db_index=True, verbose_name='使用状态, 0: 未使用, 1: 已分配')
+    p2p = models.SmallIntegerField(default=0, db_index=True, verbose_name='p2p类型。0:无,1:宸云,2:tutk')
     add_time = models.IntegerField(default=0, verbose_name='添加时间')
 
     class Meta:
         db_table = 'tb_serial_number'
         verbose_name = '序列号表'
         verbose_name_plural = verbose_name
-        app_label = 'SerialModel'
 
 
 class CompanySerialModel(models.Model):
@@ -1541,12 +1542,14 @@ class UIDCompanySerialModel(models.Model):
 
 class iotdeviceInfoModel(models.Model):
     id = models.AutoField(primary_key=True)
-    serial_number = models.CharField(max_length=11, blank=True, default='', db_index=True, verbose_name=u'关联序列号表的id')
+    serial_number = models.CharField(max_length=11, blank=True, default='', db_index=True, verbose_name=u'关联Device_Info表的序列号')
+    uid = models.CharField(blank=True, max_length=32, default='', db_index=True, verbose_name=u'设备UID')
     certificate_id = models.CharField(blank=True, max_length=256, default='', verbose_name=u'证书id')
     certificate_pem = models.TextField(blank=True, default='', verbose_name=u'证书项目')
     public_key = models.TextField(blank=True, default='', verbose_name=u'公有密钥')
     private_key = models.TextField(blank=True, default='', verbose_name=u'私有密钥')
     thing_name = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Name')
+    thing_groups = models.CharField(blank=True, max_length=256, default='', verbose_name=u'IoT Thing Groups')
     endpoint = models.CharField(blank=True, max_length=256, db_index=True, default='', verbose_name=u'iot端点')
     token_iot_number = models.CharField(blank=True,  db_index=True ,default='', max_length=50, verbose_name='连接iot令牌')
     class Meta:

+ 52 - 0
Object/AWS/S3Email.py

@@ -0,0 +1,52 @@
+import smtplib
+import email.utils
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+class S3Email:
+
+   def __init__(self, *args, **kwargs):
+       SENDER = 'rdpublic@ansjer.com'  # 邮箱名
+       SENDERNAME = 'rdpublic@ansjer.com'
+       USERNAME_SMTP = "AKIA2E67UIMD6MOSFKXW"  # 带有邮件权限的 IAM 帐号
+       PASSWORD_SMTP = "BHuQ6EQTtFK4qh46o9omO9ZzO3NXzjk/JCWLXnVFmqzM"  # 带有邮件权限的 IAM 密码
+       PORT = 587
+       HOST = "email-smtp.us-east-1.amazonaws.com"
+
+
+   def faEmail(self, content ,RECIPIENT):
+
+        SUBJECT = 'Amazon SES Error (Python smtplib)'
+        BODY_TEXT = ("Amazon SES Test\r\n"
+                     "This email was sent through the Amazon SES SMTP "
+                     "Interface using the Python smtplib package."
+                     )
+        BODY_HTML = """<html>
+        <head></head>
+        <body>
+          <h1>{}<h1>
+        </body>
+        </html>
+                    """.format(content)
+
+        msg = MIMEMultipart('alternative')
+        msg['Subject'] = SUBJECT
+        msg['From'] = email.utils.formataddr((self.SENDERNAME, self.SENDER))
+        msg['To'] = RECIPIENT
+        part1 = MIMEText(BODY_TEXT, 'plain')
+        part2 = MIMEText(BODY_HTML, 'html')
+        msg.attach(part1)
+        msg.attach(part2)
+
+        try:
+            server = smtplib.SMTP(self.HOST, self.PORT)
+            server.ehlo()
+            server.starttls()
+            server.ehlo()
+            server.login(self.USERNAME_SMTP, self.PASSWORD_SMTP)
+            server.sendmail(self.SENDER, RECIPIENT, msg.as_string())
+            server.close()
+        except Exception as e:
+            print("Error: ", e)
+        else:
+            print("Email sent!")

+ 20 - 0
Object/AliSmsObject.py

@@ -76,6 +76,26 @@ class AliSmsObject(object):
         # {"Message":"OK","RequestId":"985FA027-C887-4186-A8F5-B6B8F3D123DB","BizId":"973407842937195533^0","Code":"OK"}
         # code = isv.BUSINESS_LIMIT_CONTROL 一分钟只能发一次
         return res_json
+
+        # 发送验证码
+
+    def send_code_sms_cloud(self, phone, params, sign_name, temp_msg):
+        __business_id = uuid.uuid1()
+        # print(__business_id)
+        # params = "{\"code\":\"{"+str(code)+"}\"}"
+        params = params
+        # params = u'{"name":"wqb","code":"12345678","address":"bz","phone":"13000000000"}'
+        # 签名
+        # sign_name = 'Ansjer'
+        # 模板信息
+        # temp_msg = 'SMS_151600991'
+        res = self.do_send_sms(__business_id, phone, sign_name, temp_msg, params)
+        # print(send_sms(__business_id, "13119657713", "云通信测试", "SMS_5250008", params))
+        res_json = json.loads(res.decode('utf-8'))
+        print(res_json)
+        # {"Message":"OK","RequestId":"985FA027-C887-4186-A8F5-B6B8F3D123DB","BizId":"973407842937195533^0","Code":"OK"}
+        # code = isv.BUSINESS_LIMIT_CONTROL 一分钟只能发一次
+        return res_json
 #
 # aliSms = AliSmsObject()
 # aliSms.send_sign_in_sms(phone=13119657713,code=123456)

+ 3 - 0
Object/ETkObject.py

@@ -32,6 +32,9 @@ class ETkObject(object):
             if len(uid) == 20:
                 self.uid = uid
                 print(uid)
+            elif len(uid) == 14:
+                self.uid = uid
+                print(uid)
         except Exception as e:
             print(repr(e))
 

+ 6 - 6
Object/IOTCore/IotObject.py

@@ -69,7 +69,7 @@ class IOTClient(IOTObject):
         }
         return res
 
-    def create_keys_and_certificate(self, serial_number, thingGroup, response):
+    def create_keys_and_certificate(self, ThingNameSuffix, thingGroup, response):
         try:
             result = self.client.create_keys_and_certificate(setAsActive=True)
             res = {
@@ -147,18 +147,18 @@ class IOTClient(IOTObject):
                     },
                 }
             }
-
+            ThingName = 'Ansjer_Device_' + ThingNameSuffix
             templateBody = json.dumps(templateBody)
-            parameters = {"ThingName": "Ansjer_Device_" + serial_number,
+            parameters = {"ThingName": ThingName,
                           "thingGroupName": thingGroupName,
                           "AWS::IoT::Certificate::Id": res['certificateId']}
             self.client.register_thing(
                 templateBody=templateBody,
                 parameters=parameters
             )
-            topicsql = "SELECT * FROM 'my/things/Ansjer_Device_" + serial_number + "/shadow/update_lwt'"
+            topicsql = "SELECT * FROM 'my/things/" + ThingName + "/shadow/update_lwt'"
             self.client.create_topic_rule(
-                ruleName= 'Ansjer_Device_' + serial_number+'_LWT',
+                ruleName= ThingName + '_LWT',
                 topicRulePayload={
                     "sql": topicsql,
                     "ruleDisabled": False,
@@ -167,7 +167,7 @@ class IOTClient(IOTObject):
                         {
                             'republish': {
                                 'roleArn': self.iotrole,
-                                'topic': '$$aws/things/'+ 'Ansjer_Device_' + serial_number+'/shadow/update',
+                                'topic': '$$aws/things/' + ThingName + '/shadow/update',
                                 'qos': 1
                             }
                         }

+ 17 - 0
Object/LogUtil.py

@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+from Ansjer.config import BASE_DIR
+
+
+class LogUtil:
+
+    @staticmethod
+    def write_log(file_path=None, log=''):
+        if not file_path:
+            file_path = '/'.join((BASE_DIR, 'static/test.log'))
+
+        file = open(file_path, 'a+')
+        file.write(log)
+        file.write('\n')
+        file.flush()
+        file.close()

+ 1 - 1
Service/AlgorithmService.py

@@ -7,7 +7,7 @@ class AlgorithmBaseOn35:
 
     letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
-               'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T',
+               'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
                'U', 'V', 'W', 'X', 'Y', 'Z']
 
     len1 = len(letters)

+ 9 - 6
Service/CommonService.py

@@ -207,12 +207,15 @@ class CommonService:
 
     # 获取当前时间
     @staticmethod
-    def get_now_time_str(n_time, tz):
-        n_time = int(n_time)
-        if tz:
-            n_time = n_time + 3600 * float(tz)
-        n_date = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(int(n_time)))
-        return n_date
+    def get_now_time_str(n_time, tz, lang):
+        print(n_time)
+        print(tz)
+        print(lang)
+        n_time = int(n_time) + 3600 * float(tz)
+        if lang == 'cn':
+            return time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(int(n_time)))
+        else:
+            return time.strftime('%m-%d-%Y %H:%M:%S', time.gmtime(int(n_time)))
 
     # 生成随机数
     @staticmethod

+ 1 - 0
Service/TemplateService.py

@@ -53,6 +53,7 @@ class TemplateService:
             'deviceShare/showShareInfo',
             'deviceShare/confirm',
             'deviceShare/deleteUser',
+            'deviceShare/deleteUserV2',
             'order/querylist',
             'detect/changeStatus',
             # 'notify/push',