Эх сурвалжийг харах

升级python版本更新代码

peng 2 жил өмнө
parent
commit
820bfc9d63
61 өөрчлөгдсөн 2505 нэмэгдсэн , 973 устгасан
  1. 24 2
      AdminController/ServeManagementController.py
  2. 21 2
      AdminController/UnicomManageController.py
  3. 36 1
      AdminController/UserManageController.py
  4. 1 2
      AdminController/dataSystemManagement/BusinessDataController.py
  5. 1 1
      AdminController/dataSystemManagement/UserDataController.py
  6. 1 0
      Ansjer/cn_config/config_formal.py
  7. 11 6
      Ansjer/cn_config/config_test.py
  8. 5 5
      Ansjer/cn_config/formal_settings.py
  9. 8 20
      Ansjer/cn_config/test_settings.py
  10. 1 0
      Ansjer/eur_config/config_formal.py
  11. 4 4
      Ansjer/eur_config/formal_settings.py
  12. 1 0
      Ansjer/local_config/config_local.py
  13. 5 41
      Ansjer/local_config/local_settings.py
  14. 4 0
      Ansjer/server_urls/algorithm_shop_url.py
  15. 13 0
      Ansjer/server_urls/kvs_url.py
  16. 0 85
      Ansjer/test/coposs_sts.py
  17. 0 65
      Ansjer/test/oss_sts.py
  18. 0 44
      Ansjer/test/osssigput.py
  19. 10 1
      Ansjer/urls.py
  20. 1 0
      Ansjer/us_config/config_formal.py
  21. 2 0
      Ansjer/us_config/formal_settings.py
  22. 472 0
      Controller/AWS/KVSController.py
  23. 2 3
      Controller/AdminManage.py
  24. 173 0
      Controller/AppAccountManagement.py
  25. 7 7
      Controller/AppInfo.py
  26. 12 63
      Controller/CDKController.py
  27. 183 0
      Controller/CloudPhoto/CloudPhotoController.py
  28. 232 0
      Controller/Cron/CronCloudPhotoController.py
  29. 32 6
      Controller/DeviceShare.py
  30. 3 0
      Controller/EquipmentManager.py
  31. 1 1
      Controller/EquipmentManagerV3.py
  32. 25 2
      Controller/PcInfo.py
  33. 154 0
      Controller/ShadowController.py
  34. 7 22
      Controller/StsOssController.py
  35. 1 0
      Controller/SysMsg.py
  36. 76 314
      Controller/TestApi.py
  37. 2 2
      Controller/UserBrandController.py
  38. 23 24
      Controller/UserController.py
  39. 195 0
      Controller/UserDevice/UserDeviceShareController.py
  40. 2 1
      Controller/UserExController.py
  41. 1 1
      Controller/shareUserPermission.py
  42. 227 10
      Model/models.py
  43. 34 0
      Object/AWS/AmazonKVSUtil.py
  44. 187 0
      Object/AWS/AmazonKinesisVideoUtil.py
  45. 15 2
      Object/AWS/AmazonS3Util.py
  46. 8 0
      Object/RedisObject.py
  47. 15 38
      Object/TokenObject.py
  48. 6 27
      Object/UidTokenObject.py
  49. 1 1
      Object/UrlTokenObject.py
  50. 0 58
      README.md
  51. 0 0
      SerialModel/__init__.py
  52. 0 3
      SerialModel/admin.py
  53. 0 5
      SerialModel/apps.py
  54. 0 0
      SerialModel/migrations/__init__.py
  55. 0 3
      SerialModel/models.py
  56. 0 3
      SerialModel/tests.py
  57. 0 3
      SerialModel/views.py
  58. 37 90
      Service/CommonService.py
  59. 86 5
      Service/UserDeviceService.py
  60. 137 0
      Service/VodHlsService.py
  61. BIN
      requirements.txt

+ 24 - 2
AdminController/ServeManagementController.py

@@ -679,6 +679,7 @@ class serveManagement(View):
         status = request_dict.get('status', None)
         status = request_dict.get('status', None)
         timeRange = request_dict.getlist('timeRange[]', None)
         timeRange = request_dict.getlist('timeRange[]', None)
         orderType = request_dict.get('orderType', None)
         orderType = request_dict.get('orderType', None)
+        serialNumber = request_dict.get('serialNumber', None)
 
 
         if not all([pageNo, pageSize]):
         if not all([pageNo, pageSize]):
             return response.json(444)
             return response.json(444)
@@ -704,6 +705,10 @@ class serveManagement(View):
                 omqs = omqs.filter(status=status)
                 omqs = omqs.filter(status=status)
             if orderType:
             if orderType:
                 omqs = omqs.filter(order_type=int(orderType))
                 omqs = omqs.filter(order_type=int(orderType))
+            if serialNumber:
+                device_info_qs = Device_Info.objects.filter(serial_number=serialNumber).values('UID')
+                uid = device_info_qs[0]['UID'] if device_info_qs.exists() else 'N/A'
+                omqs = omqs.filter(UID=uid)
             if timeRange:
             if timeRange:
                 startTime, endTime = int(
                 startTime, endTime = int(
                     timeRange[0][:-3]), int(timeRange[1][:-3])
                     timeRange[0][:-3]), int(timeRange[1][:-3])
@@ -763,6 +768,12 @@ class serveManagement(View):
                         data['user_status'] = 1
                         data['user_status'] = 1
                     else:
                     else:
                         data['user_status'] = 2
                         data['user_status'] = 2
+                #  添加序列号
+                data['serial_number'] = 'N/A'
+                device_info_qs = Device_Info.objects.filter(UID=order['UID']).values('serial_number')
+                if device_info_qs.exists():
+                    data['serial_number'] = device_info_qs[0]['serial_number'] if device_info_qs[0][
+                        'serial_number'] else 'N/A'
                 #  添加PayPal交易号字段
                 #  添加PayPal交易号字段
                 data['trade_no'] = 'N/A'
                 data['trade_no'] = 'N/A'
                 if data['payType'] == 1:
                 if data['payType'] == 1:
@@ -995,6 +1006,9 @@ class serveManagement(View):
         # 日志表查询
         # 日志表查询
         logTimeRange = request_dict.getlist('logTimeRange[]', None)
         logTimeRange = request_dict.getlist('logTimeRange[]', None)
 
 
+        # 序列号查询
+        serialNumber = request_dict.get('serialNumber', None)
+
         pageNo = request_dict.get('pageNo', None)
         pageNo = request_dict.get('pageNo', None)
         pageSize = request_dict.get('pageSize', None)
         pageSize = request_dict.get('pageSize', None)
         if not all([pageNo, pageSize]):
         if not all([pageNo, pageSize]):
@@ -1012,6 +1026,10 @@ class serveManagement(View):
                 uid_bucket_qs = uid_bucket_qs.filter(use_status=use_status)
                 uid_bucket_qs = uid_bucket_qs.filter(use_status=use_status)
             if has_unused:
             if has_unused:
                 uid_bucket_qs = uid_bucket_qs.filter(has_unused=has_unused)
                 uid_bucket_qs = uid_bucket_qs.filter(has_unused=has_unused)
+            if serialNumber:
+                device_info_qs = Device_Info.objects.filter(serial_number=serialNumber).values('UID')
+                uid = device_info_qs[0]['UID'] if device_info_qs.exists() else 'N/A'
+                uid_bucket_qs = uid_bucket_qs.filter(uid__icontains=uid)
             if addTimeRange:
             if addTimeRange:
                 addStartTime, addEndTime = int(
                 addStartTime, addEndTime = int(
                     addTimeRange[0][:-3]), int(addTimeRange[1][:-3])
                     addTimeRange[0][:-3]), int(addTimeRange[1][:-3])
@@ -1114,9 +1132,13 @@ class serveManagement(View):
                         'phone': order['userID__phone'],
                         'phone': order['userID__phone'],
                         'userEmail': order['userID__userEmail'],
                         'userEmail': order['userID__userEmail'],
                         'data_joined': order['userID__data_joined'].strftime("%Y-%m-%d %H:%M:%S"),
                         'data_joined': order['userID__data_joined'].strftime("%Y-%m-%d %H:%M:%S"),
-                        'playcount': cg_qs.filter(operation='cloudstorage/queryvodlist', uid=order['UID']).count()
+                        'playcount': cg_qs.filter(operation='cloudstorage/queryvodlist', uid=order['UID']).count(),
+                        'serial_number': 'N/A'
                     }
                     }
-
+                    device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number')
+                    if device_info_qs.exists():
+                        data['serial_number'] = device_info_qs[0]['serial_number'] if device_info_qs[0][
+                            'serial_number'] else 'N/A'
                     if uid in uid_set_dict:
                     if uid in uid_set_dict:
                         data['ucode'] = uid_set_dict[uid]['ucode']
                         data['ucode'] = uid_set_dict[uid]['ucode']
                         data['version'] = uid_set_dict[uid]['version']
                         data['version'] = uid_set_dict[uid]['version']

+ 21 - 2
AdminController/UnicomManageController.py

@@ -10,8 +10,7 @@ from django.db import transaction, connection
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
 from Controller.UnicomCombo.UnicomComboController import UnicomComboView
 from Controller.UnicomCombo.UnicomComboController import UnicomComboView
-from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, UnicomComboOrderInfo, Device_User, Device_Info, \
-    Order_Model
+from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, UnicomComboOrderInfo, Device_User, Order_Model
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.UnicomObject import UnicomObjeect
 from Object.UnicomObject import UnicomObjeect
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
@@ -56,6 +55,8 @@ class UnicomManageControllerView(View):
         #  获取 / 筛选4G流量卡订单信息
         #  获取 / 筛选4G流量卡订单信息
         elif operation == 'query-order':
         elif operation == 'query-order':
             return self.query_4G_user_order(request_dict, response)
             return self.query_4G_user_order(request_dict, response)
+        elif operation == 'sim-info':
+            return self.get_iccid_info(request_dict, response)
         else:
         else:
             return response.json(0)
             return response.json(0)
 
 
@@ -496,3 +497,21 @@ class UnicomManageControllerView(View):
         except Exception as e:
         except Exception as e:
             print(e)
             print(e)
             return response.json(500, repr(e))
             return response.json(500, repr(e))
+
+    @classmethod
+    def get_iccid_info(cls, request_dict, response):
+        """
+        获取联通iccid最新状态
+        """
+        try:
+            iccid = request_dict.get('iccid', None)
+            if not iccid:
+                return response.json(444)
+            re_data = {'iccid': iccid}
+            result = UnicomObjeect().query_device_status(**re_data)
+            res_dict = UnicomObjeect().get_text_dict(result)
+            # 状态不等于1(激活)时进行激活 1:激活;2:停用
+            return response.json(0, res_dict['data']['status'])
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 36 - 1
AdminController/UserManageController.py

@@ -310,6 +310,16 @@ class UserManagement(View):
                 return response.json(404)
                 return response.json(404)
 
 
     def getUserInfo(self, userID, request_dict, response):
     def getUserInfo(self, userID, request_dict, response):
+        """
+        @param userID:用户ID
+        @param request_dict:请求参数
+        @param response:响应对象
+        @param username:用户名
+        @param NickName:用户昵称
+        @param phone:电话号
+        @param userEmail:用户邮箱
+        @return:
+        """
         print('request_dict: ', request_dict)
         print('request_dict: ', request_dict)
         username = request_dict.get('username', '').strip()  # 移除字符串头尾的空格
         username = request_dict.get('username', '').strip()  # 移除字符串头尾的空格
         NickName = request_dict.get('NickName', '').strip()
         NickName = request_dict.get('NickName', '').strip()
@@ -369,7 +379,15 @@ class UserManagement(View):
             return response.json(500, repr(e))
             return response.json(500, repr(e))
 
 
     def AddOrEditAccount(self, userID, request_dict, response):
     def AddOrEditAccount(self, userID, request_dict, response):
-        # 添加/编辑用户
+        """
+        添加/编辑用户
+        @param userID:用户ID
+        @param request_dict:请求参数
+        @param response:响应对象
+        @param roleName:用户角色
+        @param isEdit:添加用户需要输入密码
+        @return:
+        """
         print('request_dict: ', request_dict)
         print('request_dict: ', request_dict)
         username = request_dict.get('username', '').strip()  # 移除字符串头尾的空格
         username = request_dict.get('username', '').strip()  # 移除字符串头尾的空格
         userEmail = request_dict.get('userEmail', '').strip()
         userEmail = request_dict.get('userEmail', '').strip()
@@ -454,6 +472,14 @@ class UserManagement(View):
             return response.json(500, repr(e))
             return response.json(500, repr(e))
 
 
     def getFeedbackList(self, request_dict, response):
     def getFeedbackList(self, request_dict, response):
+        """
+        用户反馈查询
+        @param request_dict:请求参数
+        @param response:响应对象
+        @param status:回复状态
+        @param collectStatus:收藏状态1
+        @return:
+        """
         status = request_dict.get('status', 0)
         status = request_dict.get('status', 0)
         username = request_dict.get('username', None)
         username = request_dict.get('username', None)
         collectStatus = request_dict.get('collectStatus', None)
         collectStatus = request_dict.get('collectStatus', None)
@@ -542,6 +568,14 @@ class UserManagement(View):
             return response.json(500, repr(e))
             return response.json(500, repr(e))
 
 
     def sendSysMsgToUser(self, request_dict, response):
     def sendSysMsgToUser(self, request_dict, response):
+        """
+        发送系统消息至用户
+        @param request_dict:请求参数
+        @param response:响应对象
+        @param userID:用户ID
+        @param msg:发送内容
+        @return:
+        """
         userID = request_dict.get('userID', None)
         userID = request_dict.get('userID', None)
         msg = request_dict.get('msg', None)
         msg = request_dict.get('msg', None)
 
 
@@ -571,6 +605,7 @@ class UserManagement(View):
             return response.json(500, repr(e))
             return response.json(500, repr(e))
 
 
     def getSysMessageList(self, request_dict, response):
     def getSysMessageList(self, request_dict, response):
+        # 功能群发查询
         print('request_dict: ', request_dict)
         print('request_dict: ', request_dict)
         pageNo = request_dict.get('pageNo', None)
         pageNo = request_dict.get('pageNo', None)
         pageSize = request_dict.get('pageSize', None)
         pageSize = request_dict.get('pageSize', None)

+ 1 - 2
AdminController/dataSystemManagement/BusinessDataController.py

@@ -8,10 +8,9 @@
 """
 """
 
 
 import requests
 import requests
-from django.db.models import Count, Sum
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
-from Model.models import VodHlsModel, VodHlsSummary
+from Model.models import VodHlsSummary
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
 
 
 
 

+ 1 - 1
AdminController/dataSystemManagement/UserDataController.py

@@ -12,7 +12,7 @@ from django.views.generic.base import View
 import datetime
 import datetime
 import requests
 import requests
 
 
-from Model.models import Device_User, CountryModel, DeviceUserSummary
+from Model.models import DeviceUserSummary
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
 
 
 
 

+ 1 - 0
Ansjer/cn_config/config_formal.py

@@ -20,6 +20,7 @@ PUSH_BUCKET = 'push'                                # 推送存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 AVATAR_BUCKET = 'avatar-cn'                         # 头像存储桶
 AVATAR_BUCKET = 'avatar-cn'                         # 头像存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
+PUSH_CLOUD_PHOTO = 'push-cloud-photo'               # 推送云相册存储桶
 
 
 # redis节点
 # redis节点
 SERVER_HOST = 'backendserver.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
 SERVER_HOST = 'backendserver.3xavzq.0001.cnw1.cache.amazonaws.com.cn'

+ 11 - 6
Ansjer/cn_config/config_test.py

@@ -10,16 +10,21 @@ AWS相关
 """
 """
 # ======================================================================================================================
 # ======================================================================================================================
 # aws api key
 # aws api key
-AWS_ARN_S3 = 'arn:aws-cn:s3'
-REGION_NAME = 'cn-northwest-1'
-ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
-SECRET_ACCESS_KEY = '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'
+# AWS_ARN_S3 = 'arn:aws-cn:s3'
+# REGION_NAME = 'cn-northwest-1'
+# ACCESS_KEY_ID = 'AKIA2MMWBR4DSFG67DTG'
+# SECRET_ACCESS_KEY = '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'
+AWS_ARN_S3 = 'arn:aws:s3'
+REGION_NAME = 'us-east-1'
+ACCESS_KEY_ID = 'AKIA2E67UIMD45Y3HL53'
+SECRET_ACCESS_KEY = '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'
 
 
 # 存储桶
 # 存储桶
-PUSH_BUCKET = 'push'                                # 推送存储桶
+PUSH_BUCKET = 'foreignpush'                                # 推送存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
-AVATAR_BUCKET = 'avatar-cn'                         # 头像存储桶
+AVATAR_BUCKET = 'avatar-us'                         # 头像存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
+PUSH_CLOUD_PHOTO = 'push-cloud-photo'               # 推送云相册存储桶
 
 
 # redis节点
 # redis节点
 SERVER_HOST = 'backendserver.3xavzq.0001.cnw1.cache.amazonaws.com.cn'
 SERVER_HOST = 'backendserver.3xavzq.0001.cnw1.cache.amazonaws.com.cn'

+ 5 - 5
Ansjer/cn_config/formal_settings.py

@@ -6,6 +6,8 @@ SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
 DEBUG = False
 DEBUG = False
 ALLOWED_HOSTS = ['*']
 ALLOWED_HOSTS = ['*']
 
 
+DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
+
 INSTALLED_APPS = [
 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.auth',
@@ -44,7 +46,7 @@ ADDR_URL = []
 ANONYMOUS_USER_ID = -1  # 支持匿名用户.
 ANONYMOUS_USER_ID = -1  # 支持匿名用户.
 
 
 STATIC_URL = '/static/'
 STATIC_URL = '/static/'
-STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)
+STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
 
 
 # 上传路径根目录
 # 上传路径根目录
 MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
 MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
@@ -114,8 +116,6 @@ DATABASE_APPS_MAPPING = {
     'PushModel': 'mysql02',
     'PushModel': 'mysql02',
 }
 }
 
 
-
-
 AUTH_PASSWORD_VALIDATORS = [
 AUTH_PASSWORD_VALIDATORS = [
     {
     {
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@@ -254,7 +254,7 @@ LOGGING = {
         # log 调用时需要当作参数传入
         # log 调用时需要当作参数传入
         'info': {
         'info': {
             'handlers': ['info'],
             'handlers': ['info'],
-            'level':'INFO',
+            'level': 'INFO',
             'propagate': False
             'propagate': False
         },
         },
         'pay': {
         'pay': {
@@ -268,4 +268,4 @@ LOGGING = {
         #     'level': 'DEBUG',
         #     'level': 'DEBUG',
         # },
         # },
     }
     }
-}
+}

+ 8 - 20
Ansjer/cn_config/test_settings.py

@@ -1,12 +1,13 @@
 import os
 import os
 from Ansjer.config import BASE_DIR
 from Ansjer.config import BASE_DIR
 
 
-
 SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
 SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
 DEBUG = True
 DEBUG = True
 # DEBUG = False
 # DEBUG = False
 ALLOWED_HOSTS = ['*']
 ALLOWED_HOSTS = ['*']
 
 
+DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
+
 INSTALLED_APPS = [
 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.auth',
@@ -18,7 +19,6 @@ INSTALLED_APPS = [
     'imagekit',
     'imagekit',
     'Model',
     'Model',
     'PushModel',
     'PushModel',
-    'SerialModel',
 ]
 ]
 
 
 MIDDLEWARE = [
 MIDDLEWARE = [
@@ -27,25 +27,23 @@ MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.common.CommonMiddleware',
-    'MiddleWare.requestRecord.RequestRecordMiddleware',     # 记录请求信息
+    'MiddleWare.requestRecord.RequestRecordMiddleware',  # 记录请求信息
     # 'django.middleware.csrf.CsrfViewMiddleware',
     # 'django.middleware.csrf.CsrfViewMiddleware',
     'corsheaders.middleware.CorsPostCsrfMiddleware',
     'corsheaders.middleware.CorsPostCsrfMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.security.SecurityMiddleware',
     'django.middleware.security.SecurityMiddleware',
-    'django_global_request.middleware.GlobalRequestMiddleware',
 ]
 ]
 
 
 AUTHENTICATION_BACKENDS = (
 AUTHENTICATION_BACKENDS = (
     'django.contrib.auth.backends.ModelBackend',  # django default backend
     'django.contrib.auth.backends.ModelBackend',  # django default backend
-    'guardian.backends.ObjectPermissionBackend',
 )
 )
 
 
 ADDR_URL = []
 ADDR_URL = []
 ANONYMOUS_USER_ID = -1  # 支持匿名用户
 ANONYMOUS_USER_ID = -1  # 支持匿名用户
 
 
-STATIC_URL = '/static/'
+STATIC_URL = './static/'
 
 
 # 上传路径根目录
 # 上传路径根目录
 MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
 MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
@@ -59,7 +57,6 @@ APPEND_SLASH = False
 TEMPLATES = [
 TEMPLATES = [
     {
     {
         'BACKEND': 'django.template.backends.django.DjangoTemplates',
         'BACKEND': 'django.template.backends.django.DjangoTemplates',
-        # 'DIRS': [BASE_DIR + '/static/templates', ],
         'DIRS': [BASE_DIR + '/templates', ],
         'DIRS': [BASE_DIR + '/templates', ],
         'APP_DIRS': True,
         'APP_DIRS': True,
         'OPTIONS': {
         'OPTIONS': {
@@ -196,7 +193,6 @@ LOGGING = {
     'disable_existing_loggers': True,
     'disable_existing_loggers': True,
     'formatters': {
     'formatters': {
         'error_format': {
         'error_format': {
-            # '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'
             'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
         },
         },
         'standard': {
         'standard': {
@@ -256,21 +252,18 @@ LOGGING = {
     'loggers': {
     'loggers': {
         'django': {
         'django': {
             'handlers': ['default', 'console'],
             'handlers': ['default', 'console'],
-            # 'handlers': ['mail_admins','default','console'],
-            # 'level': 'ERROR',
             'level': 'ERROR',
             'level': 'ERROR',
             'propagate': False
             'propagate': False
         },
         },
         # log 调用时需要当作参数传入
         # log 调用时需要当作参数传入
         'info': {
         'info': {
             'handlers': ['info'],
             'handlers': ['info'],
-            'level':'INFO',
+            'level': 'INFO',
             'propagate': False
             'propagate': False
         },
         },
-
-        'device_info':{
+        'device_info': {
             'handlers': ['device_info'],
             'handlers': ['device_info'],
-            'level':'INFO',
+            'level': 'INFO',
             'propagate': False
             'propagate': False
         },
         },
         'pay': {
         'pay': {
@@ -278,10 +271,5 @@ LOGGING = {
             'level': 'INFO',
             'level': 'INFO',
             'propagate': False
             'propagate': False
         },
         },
-        # 'django.db.backends': {
-        #     'handlers': ['console'],
-        #     'propagate': True,
-        #     'level': 'DEBUG',
-        # },
     }
     }
-}
+}

+ 1 - 0
Ansjer/eur_config/config_formal.py

@@ -20,6 +20,7 @@ PUSH_BUCKET = 'foreignpush'                         # 推送存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 AVATAR_BUCKET = 'avatar-us'                         # 头像存储桶
 AVATAR_BUCKET = 'avatar-us'                         # 头像存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
+PUSH_CLOUD_PHOTO = 'push-cloud-photo'               # 推送云相册存储桶
 
 
 # redis节点
 # redis节点
 SERVER_HOST = 'server-redis-001.av1kep.0001.euw1.cache.amazonaws.com'
 SERVER_HOST = 'server-redis-001.av1kep.0001.euw1.cache.amazonaws.com'

+ 4 - 4
Ansjer/eur_config/formal_settings.py

@@ -6,6 +6,8 @@ SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
 DEBUG = False
 DEBUG = False
 ALLOWED_HOSTS = ['*']
 ALLOWED_HOSTS = ['*']
 
 
+DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
+
 INSTALLED_APPS = [
 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.auth',
@@ -72,7 +74,6 @@ TEMPLATES = [
 
 
 WSGI_APPLICATION = 'Ansjer.eur_config.formal_wsgi.application'
 WSGI_APPLICATION = 'Ansjer.eur_config.formal_wsgi.application'
 
 
-
 # 服务器类型
 # 服务器类型
 DATABASE_DATA = 'Ansjer81'
 DATABASE_DATA = 'Ansjer81'
 SERVER_HOST = 'server-eur.chi0brrjyz8l.eu-west-1.rds.amazonaws.com'
 SERVER_HOST = 'server-eur.chi0brrjyz8l.eu-west-1.rds.amazonaws.com'
@@ -112,7 +113,6 @@ DATABASE_APPS_MAPPING = {
     'PushModel': 'mysql02',
     'PushModel': 'mysql02',
 }
 }
 
 
-
 AUTH_PASSWORD_VALIDATORS = [
 AUTH_PASSWORD_VALIDATORS = [
     {
     {
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@@ -252,7 +252,7 @@ LOGGING = {
         # log 调用时需要当作参数传入
         # log 调用时需要当作参数传入
         'info': {
         'info': {
             'handlers': ['info'],
             'handlers': ['info'],
-            'level':'INFO',
+            'level': 'INFO',
             'propagate': False
             'propagate': False
         },
         },
         'pay': {
         'pay': {
@@ -266,4 +266,4 @@ LOGGING = {
         #     'level': 'DEBUG',
         #     'level': 'DEBUG',
         # },
         # },
     }
     }
-}
+}

+ 1 - 0
Ansjer/local_config/config_local.py

@@ -20,6 +20,7 @@ PUSH_BUCKET = 'push'                                # 推送存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 AVATAR_BUCKET = 'avatar-cn'                         # 头像存储桶
 AVATAR_BUCKET = 'avatar-cn'                         # 头像存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
+PUSH_CLOUD_PHOTO = 'push-cloud-photo'               # 推送云相册存储桶
 
 
 # redis节点
 # redis节点
 SERVER_HOST = '127.0.0.1'
 SERVER_HOST = '127.0.0.1'

+ 5 - 41
Ansjer/local_config/local_settings.py

@@ -1,21 +1,18 @@
 import os
 import os
 from Ansjer.config import BASE_DIR
 from Ansjer.config import BASE_DIR
 
 
-
 SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
 SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
 DEBUG = True
 DEBUG = True
 # DEBUG = False
 # DEBUG = False
 ALLOWED_HOSTS = ['*']
 ALLOWED_HOSTS = ['*']
 
 
-
-
-
+DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
 
 
 ADDR_URL = []
 ADDR_URL = []
 ANONYMOUS_USER_ID = -1  # 支持匿名用户
 ANONYMOUS_USER_ID = -1  # 支持匿名用户
 
 
-STATIC_URL = '/static/'
-STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)
+STATIC_URL = './static/'
+STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
 
 
 # 上传路径根目录
 # 上传路径根目录
 MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
 MEDIA_ROOT = os.path.join(BASE_DIR, 'static/Upgrate')
@@ -43,15 +40,6 @@ TEMPLATES = [
     },
     },
 ]
 ]
 
 
-'''
-增加错误信息推送到管理员邮箱
-'''
-# 管理员邮箱
-ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
-)
-
 INSTALLED_APPS = [
 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.auth',
@@ -72,30 +60,21 @@ MIDDLEWARE = [
     'django.middleware.security.SecurityMiddleware',
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.common.CommonMiddleware',
-    'MiddleWare.requestRecord.RequestRecordMiddleware',     # 记录请求信息
+    'MiddleWare.requestRecord.RequestRecordMiddleware',  # 记录请求信息
     # 'django.middleware.csrf.CsrfViewMiddleware',
     # 'django.middleware.csrf.CsrfViewMiddleware',
     'corsheaders.middleware.CorsPostCsrfMiddleware',
     'corsheaders.middleware.CorsPostCsrfMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'django.middleware.security.SecurityMiddleware',
     'django.middleware.security.SecurityMiddleware',
-    # 'django_global_request.middleware.GlobalRequestMiddleware',
 ]
 ]
 
 
 AUTHENTICATION_BACKENDS = (
 AUTHENTICATION_BACKENDS = (
     'django.contrib.auth.backends.ModelBackend',  # django default backend
     'django.contrib.auth.backends.ModelBackend',  # django default backend
-    'guardian.backends.ObjectPermissionBackend',
 )
 )
 
 
 WSGI_APPLICATION = 'Ansjer.local_config.local_wsgi.application'
 WSGI_APPLICATION = 'Ansjer.local_config.local_wsgi.application'
 
 
-# 服务器类型
-# 国内测试数据库
-# DATABASE_DATA = 'AnsjerTest'
-# SERVER_HOST = 'business-server.cvp7gfpnmziz.rds.cn-northwest-1.amazonaws.com.cn'
-# DATABASES_USER = 'azrds'
-# DATABASES_PASS = 'UKv78ezQhiGMmSef5U5s'
-
 # 本地数据库
 # 本地数据库
 DATABASE_DATA = 'ansjer'
 DATABASE_DATA = 'ansjer'
 SERVER_HOST = '127.0.0.1'
 SERVER_HOST = '127.0.0.1'
@@ -108,11 +87,6 @@ SERVER_HOST2 = '127.0.0.1'
 DATABASES_USER2 = 'root'
 DATABASES_USER2 = 'root'
 DATABASES_PASS2 = '123456'
 DATABASES_PASS2 = '123456'
 
 
-# 序列号公共数据库
-# DATABASE_DATA3 = 'ansjer_test'
-# SERVER_HOST3 = '127.0.0.1'
-# DATABASES_USER3 = 'root'
-# DATABASES_PASS3 = '123456'
 DATABASES = {
 DATABASES = {
     'default': {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
         'ENGINE': 'django.db.backends.mysql',
@@ -134,16 +108,6 @@ DATABASES = {
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'AUTOCOMMIT': True
         '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_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
 DATABASE_APPS_MAPPING = {
@@ -282,7 +246,7 @@ LOGGING = {
         # log 调用时需要当作参数传入
         # log 调用时需要当作参数传入
         'info': {
         'info': {
             'handlers': ['info'],
             'handlers': ['info'],
-            'level':'INFO',
+            'level': 'INFO',
             'propagate': False
             'propagate': False
         }
         }
     }
     }

+ 4 - 0
Ansjer/server_urls/algorithm_shop_url.py

@@ -9,7 +9,11 @@
 from django.urls import re_path
 from django.urls import re_path
 
 
 from Controller.AlgorithmShop import AlgorithmShopController
 from Controller.AlgorithmShop import AlgorithmShopController
+from Controller.CloudPhoto import CloudPhotoController
+from Controller.Cron import CronCloudPhotoController
 
 
 urlpatterns = [
 urlpatterns = [
     re_path(r'^api/(?P<operation>.*)$', AlgorithmShopController.AlgorithmShopView.as_view()),
     re_path(r'^api/(?P<operation>.*)$', AlgorithmShopController.AlgorithmShopView.as_view()),
+    re_path(r'^cron/(?P<operation>.*)$', CronCloudPhotoController.CronCloudPhotoView.as_view()),
+    re_path(r'^photo/(?P<operation>.*)$', CloudPhotoController.CronCloudPhotoView.as_view()),
 ]
 ]

+ 13 - 0
Ansjer/server_urls/kvs_url.py

@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+"""
+@Author : Rocky
+@Time : 2022/10/18 10:23
+@File :kvs_url.py
+"""
+from django.urls import re_path
+from Controller.AWS import KVSController
+
+urlpatterns = [
+    re_path(r'^user-related/(?P<operation>.*)$', KVSController.UserRelatedView.as_view()),
+    re_path(r'^(?P<operation>.*)$', KVSController.KVSView.as_view()),
+]

+ 0 - 85
Ansjer/test/coposs_sts.py

@@ -1,85 +0,0 @@
-# -*- coding: utf-8 -*-
-'''
-生成sts上传授权
-'''
-'''
-
-
-
-
-tar -cvpzf ubuntu_backup@`date +%Y-%m+%d`.tar.gz --exclude=/proc --exclude=/tmp --exclude=/boot --exclude=/home --exclude=/lost+found --exclude=/media --exclude=/mnt --exclude=/run --exclude=/home/sda1 / --warning=no-file-change
-
-'''
-from aliyunsdkcore import client
-from aliyunsdksts.request.v20150401 import AssumeRoleRequest
-import json
-import oss2
-
-# Endpoint以杭州为例,其它Region请按实际情况填写。
-endpoint = 'oss-cn-shenzhen.aliyuncs.com'
-# 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
-access_key_id = 'LTAIyMkGfEdogyL9'
-access_key_secret = '71uIjpsqVOmF7DAITRyRuc259jHOjO'
-bucket_name = 'cloudvod1'
-# role_arn是角色的资源名称。
-role_arn = 'acs:ram::1901342792446414:role/stsoss'
-
-clt = client.AcsClient(access_key_id, access_key_secret, 'cn-shenzhen')
-req = AssumeRoleRequest.AssumeRoleRequest()
-
-# 设置返回值格式为JSON。
-req.set_accept_format('json')
-req.set_RoleArn(role_arn)
-req.set_RoleSessionName('test')
-req.set_DurationSeconds(3600)
-policys = {
-    "Version": "1",
-    "Statement": [
-        {
-            "Action": [
-                "oss:PutObject",
-                "oss:DeleteObject",
-            ],
-            "Resource": ["acs:oss:*:*:cloudvod1/*"],
-            "Effect": "Allow",
-            "Condition": {
-                "IpAddress": {
-                    "acs:SourceIp": "120.237.157.184"
-                }
-            }
-        }
-    ]
-}
-req.set_Policy(Policy=json.dumps(policys))
-body = clt.do_action(req)
-# body = clt.do_action_with_exception(req)
-# 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
-token = json.loads(body)
-print(token)
-# exit()
-# tokens = {
-#     "Credentials":{
-#     'AccessKeySecret': 'eDwALgKkfZp6eXD2jz8ckktfduneNCjEz8NgHxcZsVe',
-#     'AccessKeyId': 'STS.NJNUa1UjHgo5idVKqY9wBLB3e',
-#     'Expiration': '2018-11-15T09:06:30Z',
-#     'SecurityToken': 'CAISwgJ1q6Ft5B2yfSjIr4n7HtuFuLVp0K3ea0Lnr3EMNfhuo4eYhzz2IHxLf3RuAe8dvvw+nGBV7vsdlqN4S5ZDR1HCbsJxtkXiZd84J9ivgde8yJBZom/MewHKeeKSvqL7Z+H+U6mSGJOEYEzFkSle2KbzcS7YMXWuLZyOj+wADLEQRRLqVSdaI91UKwB+0pN4U0HcLvGwKBXnr3PNBU5zwGpGhHh49L60z7/siGTXh0aozfQO9cajYMq4YtJwJot6S5D3pqgUF4vZ+SJc8RVR790ShadfqwzAo8uWDnhJkWzkVLOOqps1d1A/P/VlXfcU8NqEzKUi5raIyN+tkE0WZboOCh6yHt7wnJH2f8qyLcs8eLrBPHDA78uCLJGdsXl/PS1AaV0SJIFxci4oWUF0F27ASqqu6FnGZwalW1srcmfDSBocGoABBPrYt/W5rkesL4dOVkQTaYz14WpwbEQfMBi+8/T5xLEqUP4tuwsiiBbsQhfAm3QLKzGODGJB9bCcfxpQPSnZuAyCI4uSUZiuCFUzdKX/eaiurRDLMnACYx3aEzfmDCvQ6dYbbHxIdk+0UNMWk51eWKXfWnoH+udI6rkks2AWjTM='
-#   }
-# }
-# 使用临时token中的认证信息初始化StsAuth实例。
-auth = oss2.StsAuth(token['Credentials']['AccessKeyId'],
-                    token['Credentials']['AccessKeySecret'],
-                    token['Credentials']['SecurityToken'])
-print(auth)
-# 使用StsAuth实例初始化存储空间。
-bucket = oss2.Bucket(auth, endpoint, bucket_name)
-# 上传一个字符串。
-# res = bucket.put_object('oss_media_hls.ts', b'hello world')
-res = bucket.put_object('object-name.txt', b'hello world')
-print(res)
-
-
-'''
-# master 172.17.0.4
-
-slave 172.17.0.8
-'''

+ 0 - 65
Ansjer/test/oss_sts.py

@@ -1,65 +0,0 @@
-from aliyunsdkcore import client
-from aliyunsdksts.request.v20150401 import AssumeRoleRequest
-import json
-import oss2
-
-
-# Endpoint以杭州为例,其它egion请按实际情况填写。
-endpoint = 'oss-cn-shenzhen.aliyuncs.com'
-access_key_id = 'LTAIyMkGfEdogyL9'
-access_key_secret = '71uIjpsqVOmF7DAITRyRuc259jHOjO'
-bucket_name = 'cnvod1'
-# role_arn是角色的资源名称。
-role_arn = 'acs:ram::1901342792446414:role/stsoss'
-
-clt = client.AcsClient(access_key_id, access_key_secret, 'cn-shenzhen')
-req = AssumeRoleRequest.AssumeRoleRequest()
-
-# 设置返回值格式为JSON。
-req.set_accept_format('json')
-req.set_RoleArn(role_arn)
-req.set_RoleSessionName('uid13241234123')
-req.set_DurationSeconds(3600)
-policys = {
-    "Version": "1",
-    "Statement": [
-        {
-            "Action": [
-                "oss:PutObject",
-                "oss:DeleteObject",
-            ],
-            # "Resource": ["acs:oss:*:*:cloudvod1/*"],
-            "Resource": ["acs:oss:*:*:cloudvod1/test/*"],
-            "Effect": "Allow",
-            "Condition": {
-                "IpAddress": {
-                    "acs:SourceIp": "120.237.157.184"
-                }
-            }
-        }
-    ]
-}
-req.set_Policy(Policy=json.dumps(policys))
-body = clt.do_action(req)
-# body = clt.do_action_with_exception(req)
-# 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
-token = json.loads(body)
-print(token)
-exit()
-
-# 使用临时token中的认证信息初始化StsAuth实例。
-auth = oss2.StsAuth(token['Credentials']['AccessKeyId'],
-                    token['Credentials']['AccessKeySecret'],
-                    token['Credentials']['SecurityToken'])
-print(auth)
-# 使用StsAuth实例初始化存储空间。
-bucket = oss2.Bucket(auth, endpoint, bucket_name)
-# 上传一个字符串。
-# res = bucket.put_object('oss_media_hls.ts', b'hello world')
-# res = bucket.put_object('test/test-name.txt', b'hello world')
-# print(res)
-# oss append obj
-result = bucket.append_object('mio', 0, 'content of first append')
-print(result)
-# 如果不是首次上传,可以通过bucket.head_object方法或上次追加返回值的next_position属性,得到追加位置。
-# bucket.append_object('<yourObjectName>', result.next_position, 'content of second append')

+ 0 - 44
Ansjer/test/osssigput.py

@@ -1,44 +0,0 @@
-#!/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: 2018/11/8 9:23
-@Version: python3.6
-@MODIFY DECORD:ansjer dev
-@file: oss_sts.py
-@Contact: chanjunkai@163.com
-"""
-# -*- coding: utf-8 -*-
-'''
-生成sts上传授权
-'''
-from aliyunsdkcore import client
-from aliyunsdksts.request.v20150401 import AssumeRoleRequest
-import json
-import oss2
-import base64
-
-'''
-http://test.dvema.com/cloudVod/getSts?uidToken=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjaGFubmVsIjoiNCIsInVpZCI6IkZUU0xMOEhNNDM3WjM4V1UxMTFBIn0.wkrwYvIYf5qEukOSTxALSAgSqop-gNBdEvSwScOgYB8
-'''
-endpoint = 'oss-cn-shenzhen.aliyuncs.com'
-bucket_name = 'cnvod1'
-
-tokenss ={
-    'AccessKeySecret': '7kWzxVezTBs5Qd3AArRAcuXiYaQoLYVUnLb14iuv5LWW',
-    'AccessKeyId': 'STS.NU3npZw8fkd7sSeFFrehxRmud',
-    'Expiration': '2019-12-16T04:40:40Z',
-    'SecurityToken': 'CAIS3AJ1q6Ft5B2yfSjIr5aGJcrumudH3KbccXXUokYnaedUvajehjz2IHFIf3NhAe0bv/kzm2lX7/YYlqduSpMcHhaYNJErss0NqltYtGpBI4nng4YfgbiJREJJYnyShb0WCoeUZdfZfejXOjKgvyRvwLz8WCy/Vli+S/OggoJmadJlF2vdaiFdVu9LOixoqsIRKRmpMu22YDLnhmfMAW1iuAd3lRkti8KFz9ab9wDVgXDj1+YRvP6RGJW/aNR2N5oNJbXB1edtJK3ay3wSuVoY/6NxkaBa/jue+c2QGEUWoW/CUYv16vRjIBV0fbNAf6dPt6rHkuBiseHyj/aOqXEUZ7kTCX+AAtn9n42dSL+LTo9oLe+gZy6Sg4rTasep6l8eDChFZF8QSb0IMWRtDBEgcDbeJ5K89UrCCgXZEPnZi/tniccongi0ooPVfgjVWduCzT0fIYQsyci1stvWBQcagAFYkAuSbf8lQF1U2ifn3hKAD3S5+CVRyluQoYJBnel5o1MsL6gzccGXwBC0Jpuux/tzOZBETh0DqA+BrfYsPEUdHyZ9O5wVAHym8gx9TYiZNYNkd9FXev1k5i9pOMoy+DzaF90gZBiiZv9AYhlw8k8WGo+0InLNdI8F4CcjA1oYBQ=='
-  }
-# 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
-
-# 使用临时token中的认证信息初始化StsAuth实例。
-auth = oss2.StsAuth(tokenss['AccessKeyId'],
-                    tokenss['AccessKeySecret'],
-                    tokenss['SecurityToken'])
-bucket = oss2.Bucket(auth, endpoint, bucket_name)
-result = bucket.append_object('mio', 0, 'content of first append')
-print(result)

+ 10 - 1
Ansjer/urls.py

@@ -22,13 +22,15 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     OrderTaskController, HistoryUIDController, UIDManageUserController, SerialNumberController, CompanyController, \
     OrderTaskController, HistoryUIDController, UIDManageUserController, SerialNumberController, CompanyController, \
     RegionController, VPGController, LanguageController, TestController, DeviceConfirmRegion, S3GetStsController, \
     RegionController, VPGController, LanguageController, TestController, DeviceConfirmRegion, S3GetStsController, \
     DetectControllerV2, PcInfo, PctestController, DeviceDebug, PaymentCycle, \
     DetectControllerV2, PcInfo, PctestController, DeviceDebug, PaymentCycle, \
-    DeviceLogController, CouponController, AiController
+    DeviceLogController, CouponController, AiController, ShadowController, AppAccountManagement
 from Controller.Cron import CronTaskController
 from Controller.Cron import CronTaskController
 from Controller.MessagePush import EquipmentMessagePush
 from Controller.MessagePush import EquipmentMessagePush
 from Controller.Surveys import CloudStorageController
 from Controller.Surveys import CloudStorageController
 from Controller.SensorGateway import SensorGatewayController, EquipmentFamilyController
 from Controller.SensorGateway import SensorGatewayController, EquipmentFamilyController
 from django.urls import include
 from django.urls import include
 
 
+from Controller.UserDevice import UserDeviceShareController
+
 urlpatterns = [
 urlpatterns = [
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
     url(r'^testApi/(?P<operation>.*)$', TestApi.testView.as_view()),
     url(r'^account/authcode$', UserController.authCodeView.as_view()),
     url(r'^account/authcode$', UserController.authCodeView.as_view()),
@@ -309,6 +311,7 @@ urlpatterns = [
     path('sales', SalesController.SalesView.as_view()),
     path('sales', SalesController.SalesView.as_view()),
     path('device/online', SalesController.DeviceOnlineView.as_view()),
     path('device/online', SalesController.DeviceOnlineView.as_view()),
     re_path('serialNumber/(?P<operation>.*)', SerialNumberController.SerialNumberView.as_view()),
     re_path('serialNumber/(?P<operation>.*)', SerialNumberController.SerialNumberView.as_view()),
+    path('deviceShadow/update', ShadowController.update_device_shadow),
     re_path('company/(?P<operation>.*)', CompanyController.CompanyView.as_view()),
     re_path('company/(?P<operation>.*)', CompanyController.CompanyView.as_view()),
     re_path('region/(?P<operation>.*)', RegionController.RegionView.as_view()),
     re_path('region/(?P<operation>.*)', RegionController.RegionView.as_view()),
     re_path('vpg/(?P<operation>.*)', VPGController.VPGView.as_view()),
     re_path('vpg/(?P<operation>.*)', VPGController.VPGView.as_view()),
@@ -342,6 +345,8 @@ urlpatterns = [
 
 
     # 问卷调查
     # 问卷调查
     url(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
     url(r'^api/surveys/(?P<operation>.*)$', CloudStorageController.CloudStorageView.as_view()),
+    # 设备分享
+    url(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
 
 
     # 网关家庭模块
     # 网关家庭模块
     url(r'^app/sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
     url(r'^app/sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
@@ -350,6 +355,10 @@ urlpatterns = [
     url(r'^unicom/', include("Ansjer.server_urls.unicom_url")),
     url(r'^unicom/', include("Ansjer.server_urls.unicom_url")),
     # 算法小店
     # 算法小店
     url(r'^algorithm-shop/', include("Ansjer.server_urls.algorithm_shop_url")),
     url(r'^algorithm-shop/', include("Ansjer.server_urls.algorithm_shop_url")),
+    # KVS模块
+    url(r'^kvs/', include("Ansjer.server_urls.kvs_url")),
+    # 超级密码模块
+    re_path('appAccout/(?P<operation>.*)', AppAccountManagement.AppAccoutView.as_view()),
 
 
     # 传感器网关
     # 传感器网关
     re_path('sensorGateway/(?P<operation>.*)', SensorGatewayController.SensorGateway.as_view()),
     re_path('sensorGateway/(?P<operation>.*)', SensorGatewayController.SensorGateway.as_view()),

+ 1 - 0
Ansjer/us_config/config_formal.py

@@ -20,6 +20,7 @@ PUSH_BUCKET = 'foreignpush'                         # 推送存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 PUSH_INACCURATE_BUCKET = 'push-inaccurate'          # 推送不准确存储桶
 AVATAR_BUCKET = 'avatar-us'                         # 头像存储桶
 AVATAR_BUCKET = 'avatar-us'                         # 头像存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
 LOG_BUCKET = 'ansjer-statres'                       # 日志存储桶
+PUSH_CLOUD_PHOTO = 'push-cloud-photo'               # 推送云相册存储桶
 
 
 # redis节点
 # redis节点
 SERVER_HOST = 'backendserver.5tgle2.0001.usw1.cache.amazonaws.com'
 SERVER_HOST = 'backendserver.5tgle2.0001.usw1.cache.amazonaws.com'

+ 2 - 0
Ansjer/us_config/formal_settings.py

@@ -6,6 +6,8 @@ SECRET_KEY = 'c7ki2_gkg4#sjfm-u1%$s#&n#szf01f*v69rwv2qsf#-zmm@tl'
 DEBUG = False
 DEBUG = False
 ALLOWED_HOSTS = ['*']
 ALLOWED_HOSTS = ['*']
 
 
+DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
+
 INSTALLED_APPS = [
 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.auth',

+ 472 - 0
Controller/AWS/KVSController.py

@@ -0,0 +1,472 @@
+# -*- coding: utf-8 -*-
+"""
+@Author : Rocky
+@Time : 2022/10/18 9:48
+@File :KVSController.py
+"""
+import hashlib
+import time
+import uuid
+import datetime
+
+from django.http import HttpResponse
+from django.views import View
+
+from Model.models import KVS, Device_User, Device_Info
+from Object.AWS.AmazonKinesisVideoUtil import AmazonKinesisVideoObject, AmazonKVAMObject
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Ansjer.config import ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, SERVER_DOMAIN
+from Object.TokenObject import TokenObject
+
+
+class UserRelatedView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, operation, request)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, operation, request)
+
+    def validation(self, request_dict, operation, request):
+        response = ResponseObject()
+        if operation == 'generate-qr-code':  # 网页生成二维码
+            return self.generate_qr_code(response)
+        elif operation == 'get-scanning-status':  # 确认app是否扫码
+            return self.get_scanning_status(request_dict, response)
+        elif operation == 'web-login':  # 网页登录
+            return self.web_login(request_dict, response)
+        elif operation == 'pc-login':  # pc端登录
+            return self.pc_login(request_dict, response)
+        elif operation == 'confirm-login':  # app确认登录
+            return self.confirm_login(request_dict, response)
+        else:
+            tko = TokenObject(
+                request.META.get('HTTP_AUTHORIZATION'),
+                returntpye='pc')
+            if tko.code != 0:
+                return response.json(tko.code)
+            response.lang = tko.lang
+            user_id = tko.userID
+            if operation == 'get-device':  # 获取设备列表
+                return self.get_device(response, user_id)
+            else:
+                return response.json(404)
+
+    @staticmethod
+    def get_user_info(user_id):
+        """
+        获取用户信息
+        @param user_id: 用户id
+        @return: response
+        """
+        device_user_qs = Device_User.objects.filter(userID=user_id).values('NickName', 'userIconPath',
+                                                                           'userIconUrl')
+        if not device_user_qs.exists():
+            user_icon_url = ''
+            nick_name = ''
+        else:
+            users = device_user_qs.first()
+            nick_name = users['NickName']
+            user_icon_path = str(users['userIconPath'])
+            if user_icon_path:
+                user_icon_path = user_icon_path.replace('static/', '').replace('\\', '/')
+                user_icon_url = SERVER_DOMAIN + 'account/getAvatar/' + user_icon_path
+            else:
+                user_icon_url = ''
+        return user_icon_url, nick_name
+
+    @staticmethod
+    def generate_qr_code(response):
+        """
+        网页生成二维码
+        @param response: 响应对象
+        @return: response
+        """
+        nwo_time = time.time()
+        redis_obj = RedisObject()
+        try:
+            uuid_number = hashlib.md5((str(uuid.uuid1()) + str(nwo_time)).encode('utf-8')).hexdigest()
+            flag = redis_obj.set_ex_data(uuid_number, 0, 300)  # redis记录uuid,状态为生成二维码
+            res = {'type': 'autologin', 'id': uuid_number}
+            if flag:
+                return response.json(0, res)
+            else:
+                return response.json(119)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def get_scanning_status(request_dict, response):
+        """
+        获取app扫码状态
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @param response: 响应对象
+        @return: response
+        """
+        uuid_number = request_dict.get('uuid', None)
+        if not uuid_number:
+            return response.json(444, {'error param': 'uuid'})
+        try:
+            redis_obj = RedisObject()
+            status = redis_obj.get_data(uuid_number)
+            if status is False:
+                return response.json(119)
+            elif status == '1' or status == '2':
+                res = {'status': 1}  # 已扫码
+            else:
+                res = {'status': 0}  # 未扫码
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def pc_login(request_dict, response):
+        """
+        pc端登录
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @param response: 响应对象
+        @return: response
+        """
+        uuid_number = request_dict.get('uuid', None)
+        if not uuid_number:
+            return response.json(444, {'error param': 'uuid'})
+        try:
+            redis_obj = RedisObject()
+            status = redis_obj.get_data(uuid_number)
+            token = redis_obj.get_data(uuid_number + 'token')
+            if status is False or token is False:
+                return response.json(119)
+            elif status == '2':  # 已登录
+                token_obj = TokenObject(token)
+                response.lang = token_obj.lang
+                if token_obj.code != 0:
+                    return response.json(token_obj.code)
+                user_id = token_obj.userID
+                user_icon_url, nick_name = UserRelatedView.get_user_info(user_id)
+                res = {'status': 1, 'userIconUrl': user_icon_url, 'nickName': nick_name, 'token': token}
+                redis_obj.del_data(uuid_number)
+                redis_obj.del_data(uuid_number + 'token')
+            else:  # 未登录
+                res = {'status': 0}
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def web_login(request_dict, response):
+        """
+        网页登录
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @param response: 响应对象
+        @return: response
+        """
+        uuid_number = request_dict.get('uuid', None)
+        confirm = request_dict.get('confirm', None)
+        if not all([uuid_number, confirm]):
+            return response.json(444, {'error param': 'uuid or confirm'})
+        try:
+            redis_obj = RedisObject()
+            if confirm == '1':  # 取消登录
+                redis_obj.del_data(uuid_number)
+                redis_obj.del_data(uuid_number + 'token')
+                return response.json(0)
+            token = redis_obj.get_data(uuid_number + 'token')
+            ttl = redis_obj.get_ttl(uuid_number)
+            if token is False or ttl <= 0:
+                return response.json(119)
+            result = redis_obj.set_ex_data(uuid_number, 2, ttl)  # 修改uuid状态为已登录
+            if result is False:
+                return response.json(119)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def confirm_login(request_dict, response):
+        """
+        app确认登录
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @param response: 响应对象
+        @return: response
+        """
+        uuid_number = request_dict.get('uuid', None)
+        token = request_dict.get('token', None)
+        if not all([uuid_number, token]):
+            return response.json(444, {'error param': 'uuid or token'})
+        redis_obj = RedisObject()
+        try:
+            status = redis_obj.get_data(uuid_number)
+            ttl = redis_obj.get_ttl(uuid_number)
+            if status is False or ttl <= 0:
+                return response.json(119)
+            result1 = redis_obj.set_ex_data(uuid_number, 1, ttl)  # 修改uuid状态为已扫码
+            result2 = redis_obj.set_ex_data(uuid_number + 'token', token, ttl)
+            if result1 is False or result2 is False:
+                return response.json(119)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def get_device(response, user_id):
+        """
+        获取设备列表
+        @param response: 响应对象
+        @param user_id: 用户id
+        @return: response
+        """
+        try:
+            device_qs = Device_Info.objects.filter(userID=user_id).values('serial_number', 'NickName')
+            return response.json(0, list(device_qs))
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+
+class KVSView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        if operation == 'create-media':  # 创建视频流
+            return self.create_media(request_dict, response)
+        elif operation == 'update-data-retention':  # 修改视频流数据保留时间
+            return self.update_data_retention(request_dict, response)
+        else:
+            # tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
+            # if tko.code != 0:
+            #     return response.json(tko.code)
+            # response.lang = tko.lang
+            # user_id = tko.userID
+            if operation == 'get-device-midea-list':  # 获取设备列表
+                return self.get_device_midea_list(request_dict, response)
+            elif operation == 'get-hls-midea':  # 获取视频播放地址
+                return self.get_hls_midea_url(request_dict, response)
+            elif operation == 'download-clip':  # 获取视频播放地址
+                return self.download_clip(request_dict, response)
+            else:
+                return response.json(404)
+
+    @staticmethod
+    def create_media(request_dict, response):
+        """
+        创建视频流
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @param response: 响应对象
+        @return: response
+        """
+        serial_number = request_dict.get('serial_number', None)
+
+        try:
+            kvs_qs = KVS.objects.filter(stream_name=serial_number)
+            if kvs_qs.exists():
+                return response.json(174)
+            kinesis_video_obj = AmazonKinesisVideoObject(
+                aws_access_key_id=ACCESS_KEY_ID,
+                secret_access_key=SECRET_ACCESS_KEY,
+                region_name=REGION_NAME
+            )
+            stream_arn = kinesis_video_obj.create_stream(stream_name=serial_number)
+            if stream_arn:
+                now_time = int(time.time())
+                KVS.objects.create(stream_name=serial_number, stream_arn=stream_arn, created_time=now_time,
+                                   updated_time=now_time)
+                return response.json(0)
+            else:
+                return response.json(178)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def update_data_retention(request_dict, response):
+        """
+        修改视频流数据保留时间
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @request_dict operation: 操作,增加/减少
+        @request_dict data_retention_change_in_hours: 修改的时间
+        @param response: 响应对象
+        @return: response
+        """
+        serial_number = request_dict.get('serial_number', None)
+        operation = request_dict.get('operation', None)
+        data_retention_change_in_hours = request_dict.get('data_retention_change_in_hours', None)
+
+        try:
+            kvs_qs = KVS.objects.filter(stream_name=serial_number)
+            if not kvs_qs.exists():
+                return response.json(174)
+            kinesis_video_obj = AmazonKinesisVideoObject(
+                aws_access_key_id=ACCESS_KEY_ID,
+                secret_access_key=SECRET_ACCESS_KEY,
+                region_name=REGION_NAME
+            )
+            now_time = int(time.time())
+            data_retention_change_in_hours = int(data_retention_change_in_hours)
+            kinesis_video_obj.update_data_retention(stream_name=serial_number, operation=operation,
+                                                    data_retention_change_in_hours=data_retention_change_in_hours)
+            kvs_qs.update(data_retention_in_hours=data_retention_change_in_hours, updated_time=now_time)
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def get_hls_midea_url(request_dict, response):
+        """
+        获取视频播放地址
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @request_dict startTime: 开始时间
+        @request_dict endTime: 结束时间
+        @request_dict playMode: 播放模式
+        @param response: 响应对象
+        @return: response
+        """
+        serial_number = request_dict.get('serial_number', None)
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        play_mode = request_dict.get('playMode', None)
+        if not all([serial_number, start_time, end_time, play_mode]):
+            return response.json(444)
+        start_time = datetime.datetime.fromtimestamp(int(start_time)) - datetime.timedelta(hours=8)
+        end_time = datetime.datetime.fromtimestamp(int(end_time)) - datetime.timedelta(hours=8)
+        play_mode = int(play_mode)
+        play_mode = 'ON_DEMAND' if play_mode == 0 else 'LIVE_REPLAY'
+        try:
+            # kvs_qs = KVS.objects.filter(stream_name=serial_number)
+            # if not kvs_qs.exists():
+            #     return response.json(174)
+            kinesis_video_obj = AmazonKVAMObject(
+                aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                secret_access_key='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',
+                region_name='us-east-1',
+                stream_name=serial_number,
+                api_name='GET_HLS_STREAMING_SESSION_URL'
+            )
+            hls_streaming_session_url = kinesis_video_obj.get_hls_streaming_session_url(serial_number, start_time,
+                                                                                        end_time, play_mode)
+            return response.json(0, {"HlsStreamingSessionUrl": hls_streaming_session_url})
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def get_device_midea_list(request_dict, response):
+        """
+        获取视频播放列表
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @request_dict startTime: 开始时间
+        @request_dict endTime: 结束时间
+        @param response: 响应对象
+        @return: response
+        """
+        serial_number = request_dict.get('serial_number', None)
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        page = request_dict.get('page', None)
+        size = request_dict.get('size', None)
+        if not all([serial_number, start_time, end_time, page, size]):
+            return response.json(444)
+        page = int(page)
+        size = int(size)
+        start_time = datetime.datetime.fromtimestamp(int(start_time)) - datetime.timedelta(hours=8)
+        end_time = datetime.datetime.fromtimestamp(int(end_time)) - datetime.timedelta(hours=8)
+        try:
+            # kvs_qs = KVS.objects.filter(stream_name=serial_number)
+            # if not kvs_qs.exists():
+            #     return response.json(174)
+            kinesis_fragments_obj = AmazonKVAMObject(
+                aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                secret_access_key='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',
+                region_name='us-east-1',
+                stream_name=serial_number,
+                api_name='LIST_FRAGMENTS'
+            )
+            kinesis_images_obj = AmazonKVAMObject(
+                aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                secret_access_key='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',
+                region_name='us-east-1',
+                stream_name=serial_number,
+                api_name='GET_IMAGES'
+            )
+            stream_list = kinesis_fragments_obj.get_list_fragments(serial_number, start_time, end_time)
+            total_page = len(stream_list)
+            stream_list = stream_list[(page - 1) * size:page * size]
+            for item in stream_list:
+                temp_start_time = (item['startTime'] - datetime.timedelta(hours=8)).replace(tzinfo=datetime.timezone.utc)
+                temp_end_time = temp_start_time + datetime.timedelta(seconds=300)
+                item['image'] = kinesis_images_obj.get_images(serial_number, temp_start_time, temp_end_time)
+                item['startTime'] = int(item['startTime'].timestamp())
+                item['endTime'] = int(item['endTime'].timestamp())
+            res = {
+                'totalPage': total_page,
+                'fragments': stream_list
+            }
+            return response.json(0, res)
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def download_clip(request_dict, response):
+        """
+        获取视频播放地址
+        @param request_dict: 请求参数
+        @request_dict serial_number: 序列号
+        @request_dict startTime: 开始时间
+        @request_dict endTime: 结束时间
+        @param response: 响应对象
+        @return: response
+        """
+        serial_number = request_dict.get('serial_number', None)
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        if not all([serial_number, start_time, end_time]):
+            return response.json(444)
+        start_time = datetime.datetime.fromtimestamp(int(start_time)) - datetime.timedelta(hours=8)
+        end_time = datetime.datetime.fromtimestamp(int(end_time)) - datetime.timedelta(hours=8)
+        try:
+            # kvs_qs = KVS.objects.filter(stream_name=serial_number)
+            # if not kvs_qs.exists():
+            #     return response.json(174)
+            kinesis_video_obj = AmazonKVAMObject(
+                aws_access_key_id='AKIA2E67UIMD45Y3HL53',
+                secret_access_key='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',
+                region_name='us-east-1',
+                stream_name=serial_number,
+                api_name='GET_CLIP'
+            )
+            clip_obj, clip_size = kinesis_video_obj.get_clip(serial_number, start_time, end_time)
+            res = HttpResponse(clip_obj.read())
+            res["content_type"] = "video/mp4"
+            res["Content-Disposition"] = "attachment;filename=video.mp4"
+            res['Content-Length'] = str(clip_size)
+            return res
+        except Exception as e:
+            print(e)
+            return response.json(500, repr(e))

+ 2 - 3
Controller/AdminManage.py

@@ -1,16 +1,15 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 import time
 import time
-from datetime import date, timedelta, timezone as asj_timezone
+from datetime import timedelta, timezone as asj_timezone
 
 
 import boto3
 import boto3
 import xlwt
 import xlwt
-from django.db.models import Count,Q
+from django.db.models import Count, Q
 from django.http import HttpResponse
 from django.http import HttpResponse
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 from django.views.generic import TemplateView
 from django.utils.decorators import method_decorator
 from django.utils.decorators import method_decorator
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
-from openpyxl import workbook
 
 
 from Model.models import Device_Info, Role, UserExModel, User_Brand, UidSetModel, AppFrequencyYearStatisticsModel, \
 from Model.models import Device_Info, Role, UserExModel, User_Brand, UidSetModel, AppFrequencyYearStatisticsModel, \
     AppFrequencyStatisticsModel, EquipmentInfoExStatisticsModel, Equipment_Info
     AppFrequencyStatisticsModel, EquipmentInfoExStatisticsModel, Equipment_Info

+ 173 - 0
Controller/AppAccountManagement.py

@@ -0,0 +1,173 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : UserDeviceShareController.py
+@Time    : 2023/2/3 13:25
+@Author  : guanhailong
+@Email   : guanhailong@asj6.wecom.work
+@Software: PyCharm
+"""
+import datetime
+import random
+import time
+
+from Controller.CheckUserData import RandomStr
+from Model.models import Device_User, Device_Info, DeviceSuperPassword
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from django.views import View
+
+from Service.CommonService import CommonService
+
+
+class AppAccoutView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.GET
+        return self.validation(request_dict, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        request_dict = request.GET
+        return self.validation(request_dict, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
+        lang = request_dict.get('lang', token.lang)
+        response = ResponseObject(lang)
+        userID = token.userID
+        if token.code != 0:
+            return response.json(token.code)
+        if operation == 'getAuthorizationCode':  # 获取用户请求/生成授权码
+            return self.getAuthorizationCode(request_dict, response, userID)
+        if operation == 'verifyTheVerificationCode':  # 效验验证码
+            return self.verifyTheVerificationCode(request_dict, response)
+        if operation == 'customerServiceManagement':  # 客服管理
+            return self.customerServiceManagement(request_dict, response)
+        if operation == 'getDeviceSuperPassword':  # 查询超级密码请求表
+            return self.getDeviceSuperPassword(request_dict, response)
+        else:
+            return response.json(404)
+
+    def getAuthorizationCode(self, request_dict, response, userID):
+        """
+        @param uid:设备id
+        @param request_dict:请求参数
+        @param response:响应对象
+        @param describe:需求描述
+        @param Purchase_channel:购买渠道描述
+        @param orderID:订单id
+        @param buyTime:购买时间
+        @return:
+        """
+        uid = request_dict.get('uid', None)
+        describe = request_dict.get('describe', None)
+        if not all([uid, describe]):
+            return response.json(444)
+        purchase_channel = request_dict.get('purchase_channel', None)
+        orderID = request_dict.get('orderID', None)
+        buyTime = request_dict.get('buyTime', None)
+        try:
+            now = int(time.time())
+            addTime = now
+            device_info_qs = Device_Info.objects.filter(UID=uid, userID_id=userID)
+            if not device_info_qs.exists():
+                return response.json(173)
+            if buyTime:
+                buyTime = datetime.datetime.strptime(buyTime, '%Y-%m-%d')
+                buyTime = CommonService.str_to_timestamp(str_time=str(buyTime))
+            DeviceSuperPassword.objects.create(uid=uid, orderID=orderID, describe=describe,
+                                               purchase_channel=purchase_channel, addTime=addTime, userID=userID,
+                                               buyTime=buyTime, status=0)
+            # 验证码生成
+            super_code = RandomStr(6, True)
+            super_password_id = "super_password_%s" % super_code
+            redisObj = RedisObject(db=6)
+            redisObj.set_data(key=super_password_id, val=super_code, expire=86400)
+            authcode = CommonService.encode_data(super_code)
+
+            return response.json(0, {'authcode': authcode})
+        except Exception as e:
+            print('获取验证码异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, repr(e))
+
+    def verifyTheVerificationCode(self, request_dict, response):
+        verificationCode = request_dict.get('verificationCode', None)
+        authcode = request_dict.get('authcode', None)
+
+        if verificationCode and authcode:
+
+            authcode = CommonService.decode_data(authcode)
+            super_password_id = 'super_password_' + verificationCode
+            redisObj = RedisObject(db=6)
+            # redis里面的验证码
+            redis_image_code = redisObj.get_data(key=super_password_id)
+            # 验证用户输入的验证码和redis中的验证码
+            if redis_image_code is False or authcode.lower() != redis_image_code.lower():
+                return response.json(121)
+            else:
+                return response.json(0)
+        else:
+            return response.json(444)
+
+    def customerServiceManagement(self, request_dict, response):
+        userID = request_dict.get('userID')
+        uid = request_dict.get('uid', None)
+        status = request_dict.get('status', None)
+        hint = request_dict.get('hint', None)
+        if not all({uid, userID}):
+            return response.json(444)
+        try:
+            device_super_password_qs = DeviceSuperPassword.objects.filter(uid=uid, userID=userID)
+            if not device_super_password_qs.exists():
+                return response.json(173)
+            status = int(status)
+            if status == 1:
+                device_super_password_qs.update(status=status)
+                return response.json(0)
+            else:
+                device_super_password_qs.update(status=status, hint=hint)
+                return response.json(0)
+        except Exception as e:
+            print('修改状态异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, repr(e))
+
+    def getDeviceSuperPassword(self, request_dict, response):
+        pageNo = request_dict.get('pageNo', None)
+        pageSize = request_dict.get('pageSize', None)
+        status = request_dict.get('status', None)
+        userID = request_dict.get('userID', None)
+        uid = request_dict.get('uid', None)
+        if not all([pageNo, pageSize]):
+            return response.json(444)
+        page = int(pageNo)
+        line = int(pageSize)
+        try:
+            device_super_password_qs = DeviceSuperPassword.objects.all()
+            if status:
+                device_super_password_qs = device_super_password_qs.filter(status=status)
+            if userID:
+                device_super_password_qs = device_super_password_qs.filter(userID=userID)
+            if uid:
+                device_super_password_qs = device_super_password_qs.filter(uid=uid)
+            if not device_super_password_qs.exists():
+                return response.json(0, [])
+            count = device_super_password_qs.count()
+            device_super_password_qs = device_super_password_qs.values('id',
+                                                                       'uid',
+                                                                       'userID',
+                                                                       'orderID',
+                                                                       'describe',
+                                                                       'purchase_channel',
+                                                                       'addTime',
+                                                                       'status',
+                                                                       'buyTime',
+                                                                       'hint')
+            device_super_password_qs = device_super_password_qs.order_by('-addTime')[
+                                       (page - 1) * line:page * line]
+            return response.json(0, {'list': list(device_super_password_qs), 'count': count})
+        except Exception as e:
+            print('查询异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, repr(e))

+ 7 - 7
Controller/AppInfo.py

@@ -1,7 +1,7 @@
 import time
 import time
 import traceback
 import traceback
 import os
 import os
-from django.shortcuts import render_to_response
+from django.shortcuts import render
 from django.utils.decorators import method_decorator
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.base import View
 from django.views.generic.base import View
@@ -263,21 +263,21 @@ class AppVersionView(View):
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
-        return self.validation(request_dict=request.GET)
+        return self.validation(request, request_dict=request.GET)
 
 
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
-        return self.validation(request_dict=request.POST)
+        return self.validation(request, request_dict=request.POST)
 
 
-    def validation(self, request_dict, *args, **kwargs):
+    def validation(self, request, request_dict, *args, **kwargs):
         appBundleId = request_dict.get('appBundleId', None)
         appBundleId = request_dict.get('appBundleId', None)
         app_type = request_dict.get('app_type', None)
         app_type = request_dict.get('app_type', None)
         lang = request_dict.get('lang', None)
         lang = request_dict.get('lang', None)
         # print (appBundleId)
         # print (appBundleId)
         # if lang == 'cn':
         # if lang == 'cn':
-        #     return render_to_response('appVersionLists_cn.html')
+        #     return render('appVersionLists_cn.html')
         # else:
         # else:
-        #     return render_to_response('appVersionLists_en.html')
+        #     return render('appVersionLists_en.html')
         queryset = App_Colophon.objects.filter(lang=lang, app_id__appBundleId=appBundleId,
         queryset = App_Colophon.objects.filter(lang=lang, app_id__appBundleId=appBundleId,
                                                app_id__app_type=app_type).order_by('-version_time', '-newApp_version')
                                                app_id__app_type=app_type).order_by('-version_time', '-newApp_version')
         queryset_dict = CommonService.qs_to_dict(queryset).get('datas')
         queryset_dict = CommonService.qs_to_dict(queryset).get('datas')
@@ -291,7 +291,7 @@ class AppVersionView(View):
             version_time = v['fields']['version_time']
             version_time = v['fields']['version_time']
             version_time = time.strftime("%Y-%m-%d", time.localtime(version_time))
             version_time = time.strftime("%Y-%m-%d", time.localtime(version_time))
             v['fields']['version_time'] = version_time
             v['fields']['version_time'] = version_time
-        return render_to_response('appVerList.html', locals())
+        return render(request, 'appVerList.html', locals())
 
 
 
 
 class AppIdDataView(View):
 class AppIdDataView(View):

+ 12 - 63
Controller/CDKController.py

@@ -1,51 +1,17 @@
-#!/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: 2018/12/5 9:30
-@Version: python3.6
-@MODIFY DECORD:ansjer dev
-@file: cloudstorage.py
-@Contact: chanjunkai@163.com
-"""
-import json
+import hashlib
 import logging
 import logging
 import time
 import time
-import urllib
 import uuid
 import uuid
-import hashlib
 
 
-import boto3
-import oss2
-import paypalrestsdk
-import threading
-from aliyunsdkcore import client
-from aliyunsdksts.request.v20150401 import AssumeRoleRequest
-from boto3.session import Session
-from django.http import JsonResponse, HttpResponseRedirect, HttpResponse
+from django.db.models import F
+from django.http import StreamingHttpResponse
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
-from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
-    SERVER_DOMAIN_SSL
-from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, StsCrdModel, \
-    ExperienceContextModel, CDKcontextModel
-from Object.AliPayObject import AliPayObject
+from Model.models import CDKcontextModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
-from Object.UidTokenObject import UidTokenObject
-from Service.CommonService import CommonService
-from Object.m3u8generate import PlaylistGenerator
-from Object.WechatPayObject import WechatPayObject
-from django.db.models import Q, F
-from django.http import StreamingHttpResponse
 
 
-SERVER_DOMAIN = 'http://test.dvema.com/'
 
 
-
-# 设备信息添加
 class CDKView(View):
 class CDKView(View):
 
 
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
@@ -65,7 +31,6 @@ class CDKView(View):
             return response.json(444, 'error path')
             return response.json(444, 'error path')
         else:
         else:
             token = request_dict.get('token', None)
             token = request_dict.get('token', None)
-            # 设备主键uid
             tko = TokenObject(token)
             tko = TokenObject(token)
             response.lang = tko.lang
             response.lang = tko.lang
             if tko.code != 0:
             if tko.code != 0:
@@ -77,8 +42,6 @@ class CDKView(View):
                 return self.deleteCDK(request_dict, response)
                 return self.deleteCDK(request_dict, response)
             elif operation == 'queryCDK':
             elif operation == 'queryCDK':
                 return self.queryCDK(request_dict, response)
                 return self.queryCDK(request_dict, response)
-            elif operation == 'saveOrEditCDKform':
-                return self.saveOrEditCDKform(request_dict, response)
             elif operation == 'saveOrEditCDK':
             elif operation == 'saveOrEditCDK':
                 return self.saveOrEditCDK(request_dict, response)
                 return self.saveOrEditCDK(request_dict, response)
             elif operation == 'downloadCDK':
             elif operation == 'downloadCDK':
@@ -128,7 +91,7 @@ class CDKView(View):
         logger = logging.getLogger('info')
         logger = logging.getLogger('info')
         logger.info('CDK测试打印1: {}'.format(time.localtime(time.time())))
         logger.info('CDK测试打印1: {}'.format(time.localtime(time.time())))
         if page and line:
         if page and line:
-            cdk_qs = CDKcontextModel.objects.filter().all()  # values('cdk','create_time','valid_time','is_activate','rank__id','order__id')
+            cdk_qs = CDKcontextModel.objects.filter().all()
             if searchVal:
             if searchVal:
                 if cdk:
                 if cdk:
                     cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
                     cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
@@ -137,21 +100,14 @@ class CDKView(View):
                 elif is_activate:
                 elif is_activate:
                     cdk_qs = cdk_qs.filter(is_activate=searchVal)
                     cdk_qs = cdk_qs.filter(is_activate=searchVal)
 
 
-
             cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
             cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
             cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
             cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
             cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id', 'rank__title',
             cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id', 'rank__title',
-                                    'rank__bucket__mold', 'order', 'create_time')
+                                   'rank__bucket__mold', 'order', 'create_time')
             cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
             cdk_qs = cdk_qs.order_by('-create_time')  # 根据CDK创建时间降序排序
             count = cdk_qs.count()
             count = cdk_qs.count()
             cdk_qs = cdk_qs[(page - 1) * line:page * line]
             cdk_qs = cdk_qs[(page - 1) * line:page * line]
 
 
-            # cdk_dict = {}
-            # for cdk in cdk_qs:
-            #     cdk_dict[cdk['id']] = {'id': cdk['id'], 'cdk': cdk['cdk'], 'create_time': cdk['create_time'],
-            #                            'valid_time': cdk['valid_time'], 'is_activate': cdk['is_activate'],
-            #                            'rank': cdk['rank__id'], 'order': cdk['order']}
-
             res = {
             res = {
                 'datas': list(cdk_qs),
                 'datas': list(cdk_qs),
                 'count': count
                 'count': count
@@ -185,7 +141,7 @@ class CDKView(View):
                 searchVal = is_activate.strip()
                 searchVal = is_activate.strip()
 
 
             if page and line:
             if page and line:
-                cdk_qs = CDKcontextModel.objects.filter().all()  # values('cdk','create_time','valid_time','is_activate','rank__id','order__id')
+                cdk_qs = CDKcontextModel.objects.filter().all()
                 if searchVal:
                 if searchVal:
                     if cdk:
                     if cdk:
                         cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
                         cdk_qs = cdk_qs.filter(cdk__contains=searchVal)
@@ -194,7 +150,6 @@ class CDKView(View):
                     elif is_activate:
                     elif is_activate:
                         cdk_qs = cdk_qs.filter(is_activate=searchVal)
                         cdk_qs = cdk_qs.filter(is_activate=searchVal)
 
 
-
                 cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
                 cdk_qs = cdk_qs.filter(rank__lang__lang=lang)
                 cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
                 cdk_qs = cdk_qs.annotate(rank__title=F('rank__lang__title'))
                 cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id',
                 cdk_qs = cdk_qs.values('id', 'cdk', 'create_time', 'valid_time', 'is_activate', 'rank__id',
@@ -209,8 +164,6 @@ class CDKView(View):
                 }
                 }
                 return response.json(0, res)
                 return response.json(0, res)
 
 
-
-
     def saveOrEditCDK(self, request_dict, response):
     def saveOrEditCDK(self, request_dict, response):
         cdk_id = request_dict.get("id", None)
         cdk_id = request_dict.get("id", None)
         cdk = request_dict.get('cdk', None)
         cdk = request_dict.get('cdk', None)
@@ -236,28 +189,24 @@ class CDKView(View):
         else:
         else:
             return response.json(0)
             return response.json(0)
 
 
-    def downloadCDK(self,request_dict, response):
+    def downloadCDK(self, request_dict, response):
         region = request_dict.get('region', None)
         region = request_dict.get('region', None)
         content = ''
         content = ''
         if region == 'cn':
         if region == 'cn':
             # 下载国内未使用激活码
             # 下载国内未使用激活码
             content += '激活码(国内)\n'
             content += '激活码(国内)\n'
-            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=0, rank__is_show=0).values('cdk')
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=0,
+                                                               rank__is_show=0).values('cdk')
         else:
         else:
             # 下载国外未使用激活码
             # 下载国外未使用激活码
             content += '激活码(国外)\n'
             content += '激活码(国外)\n'
-            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=1, rank__is_show=0).values('cdk')
+            cdk_inactivate_qs = CDKcontextModel.objects.filter(is_down=0, is_activate=0, rank__bucket__mold=1,
+                                                               rank__is_show=0).values('cdk')
         for cdk_inactivate in cdk_inactivate_qs:
         for cdk_inactivate in cdk_inactivate_qs:
             content += cdk_inactivate['cdk'] + '\n'
             content += cdk_inactivate['cdk'] + '\n'
-        # print(content)
 
 
         cdk_inactivate_qs.update(is_down=1)
         cdk_inactivate_qs.update(is_down=1)
         response = StreamingHttpResponse(content)
         response = StreamingHttpResponse(content)
         response['Content-Type'] = 'application/octet-stream'
         response['Content-Type'] = 'application/octet-stream'
         response['Content-Disposition'] = 'attachment;filename="CDK.txt"'
         response['Content-Disposition'] = 'attachment;filename="CDK.txt"'
         return response
         return response
-
-
-
-
-

+ 183 - 0
Controller/CloudPhoto/CloudPhotoController.py

@@ -0,0 +1,183 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : CronCloudPhotoController.py
+@Time    : 2022/11/3 10:16
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+import logging
+import time
+
+from django.db import transaction
+from django.views import View
+
+from Ansjer.cn_config.config_test import PUSH_CLOUD_PHOTO
+from Ansjer.config import ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME
+from Model.models import DeviceCloudPhotoInfo, Device_Info, CloudPhotoBGM, DevicePicturePushInfo
+from Object.AWS.AmazonS3Util import AmazonS3Util
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Object.utils import LocalDateTimeUtil
+
+LOGGER = logging.getLogger('info')
+
+
+class CronCloudPhotoView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
+        lang = request_dict.get('lang', token.lang)
+        response = ResponseObject(lang)
+        if token.code != 0:
+            return response.json(token.code)
+        user_id = token.userID
+        if operation == 'save-photo':
+            return self.save_cloud_photo(user_id, request_dict, response)
+        elif operation == 'bgm-list':
+            return self.get_bgm_list(response)
+        elif operation == 'video-list':
+            return self.query_cloud_photo_page(user_id, request_dict, response)
+        elif operation == 'video-del':
+            return self.del_cloud_photo(request_dict, response)
+        else:
+            return response.json(404)
+
+    @classmethod
+    def save_cloud_photo(cls, user_id, request_dict, response):
+        """
+        保存云相册
+        """
+        try:
+            with transaction.atomic():
+                status = request_dict.get('status', None)
+                uid = request_dict.get('uid', None)
+                if not all([status, user_id]):
+                    return response(444)
+                status = int(status)
+                device_info_qs = Device_Info.objects.filter(userID_id=user_id)
+                if uid:
+                    device_info_qs = device_info_qs.filter(UID=uid)
+                device_info_qs = device_info_qs.values('vodPrimaryUserID', 'UID')
+                if not device_info_qs.exists():
+                    return response.json(14)
+                for item in device_info_qs:
+                    master_user_id = item['vodPrimaryUserID']
+                    uid = item['UID']
+                    if master_user_id == '' or master_user_id != user_id:
+                        continue
+                    now_time = int(time.time())
+                    cloud_photo_qs = DeviceCloudPhotoInfo.objects.filter(uid=uid)
+                    if not cloud_photo_qs.exists():
+                        data = {'status': status, 'user_id': user_id, 'uid': uid, 'created_time': now_time,
+                                'updated_time': now_time}
+                        DeviceCloudPhotoInfo.objects.create(**data)
+                        continue
+                    cloud_photo_qs.update(status=status, updated_time=now_time)
+                return response.json(0)
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500)
+
+    @classmethod
+    def get_bgm_list(cls, response):
+        """
+        获取背景音乐列表
+        """
+        photo_bgm = CloudPhotoBGM.objects.filter(is_show=1).values('name', 'link').order_by('sort')
+        if not photo_bgm.exists():
+            return response.json(0, [])
+        return response.json(0, list(photo_bgm))
+
+    @classmethod
+    def query_cloud_photo_page(cls, user_id, request_dict, response):
+        """
+        分页查询云相册视频
+        @param user_id: 用户id
+        @param request_dict: 请求参数
+        @param response: 响应对象
+        @return: []
+        """
+        try:
+            device_name = request_dict.get('deviceName', None)
+            start_time = request_dict.get('startTime', None)
+            end_time = request_dict.get('endTime', None)
+            page = request_dict.get('page', None)
+            size = request_dict.get('size', None)
+            if not all([page, size]):
+                return response.json(444)
+            page = int(page)
+            size = int(size)
+            video_qs = DevicePicturePushInfo.objects.filter(user_id=user_id, type=1)
+            if device_name:
+                name_list = device_name.split(',')
+                video_qs = video_qs.filter(device_nick_name__in=name_list)
+            if start_time:
+                start_time = LocalDateTimeUtil.time_stamp_to_time(int(start_time), '%Y%m')
+                video_qs = video_qs.filter(event_time__gte=int(start_time))
+            if end_time:
+                end_time = LocalDateTimeUtil.time_stamp_to_time(int(end_time), '%Y%m')
+                video_qs = video_qs.filter(event_time__lte=int(end_time))
+            video_qs = video_qs.values('id', 'uid', 'device_nick_name', 'event_time', 'created_time').order_by(
+                '-event_time')[(page - 1) * size:page * size]
+            if not video_qs.exists():
+                return response.json(0, [])
+            s3 = AmazonS3Util(ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME)
+            res_data = []
+            now_month = LocalDateTimeUtil.get_cur_month_start()
+            start_time = "{} 00:00:00".format(str(now_month))
+            time_array = time.strptime(start_time, "%Y-%m-%d %H:%M:%S")
+            for item in video_qs:
+                picture_qs = DevicePicturePushInfo.objects \
+                    .filter(uid=item['uid'], event_time__gt=int(time.mktime(time_array)), type=0).order_by('event_time')
+                event_time = picture_qs.first().event_time
+                channel = picture_qs.first().channel
+                data = {'id': item['id'], 'deviceNickname': item['device_nick_name'],
+                        'createdTime': item['created_time']}
+                picture_key = '{}/{}/{}.jpeg'.format(item['uid'], channel, event_time)
+                picture_url = s3.generate_file_obj_url(PUSH_CLOUD_PHOTO, picture_key)
+                data['picture'] = picture_url
+                key = '{}/video/{}.mp4'.format(item['uid'], str(item['event_time']))
+                obj_url = s3.generate_file_obj_url(PUSH_CLOUD_PHOTO, key)
+                data['videoLink'] = obj_url
+
+                res_data.append(data)
+            return response.json(0, res_data)
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500)
+
+    @classmethod
+    def del_cloud_photo(cls, request_dict, response):
+        """
+        根据id删除视频列表
+        @param request_dict:
+        @param response:
+        @return:
+        """
+        try:
+            ids = request_dict.get('ids', None)
+            if not ids:
+                return response.json(444)
+            cloud_photo_qs = DevicePicturePushInfo.objects.filter(id__in=ids.split(','))
+            if not cloud_photo_qs.exists():
+                return response.json(173)
+            s3 = AmazonS3Util(ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME)
+            for item in cloud_photo_qs:
+                key = '{}/video/{}.mp4'.format(item.uid, str(item.event_time))
+                s3.delete_obj(PUSH_CLOUD_PHOTO, key)
+            cloud_photo_qs.delete()
+            return response.json(0)
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500)

+ 232 - 0
Controller/Cron/CronCloudPhotoController.py

@@ -0,0 +1,232 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : CronCloudPhotoController.py
+@Time    : 2022/10/24 15:48
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+import datetime
+import logging
+import os
+import time
+import traceback
+
+import cv2
+from django.db import transaction
+from django.views import View
+
+from Ansjer.config import PUSH_CLOUD_PHOTO, ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME, PUSH_BUCKET
+from Model.models import UidSetModel, DeviceCloudPhotoInfo, DevicePicturePushInfo
+from Object.AWS.AmazonS3Util import AmazonS3Util
+from Object.RedisObject import RedisObject
+from Object.ResponseObject import ResponseObject
+from Object.utils import LocalDateTimeUtil
+from Service.EquipmentInfoService import EquipmentInfoService
+
+LOGGER = logging.getLogger('info')
+UID_KEY = 'ANSJER:UID:SET:INFO'
+
+
+class CronCloudPhotoView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        response = ResponseObject()
+        if operation == 'get-photo':
+            return self.get_photo(response)
+        elif operation == 'cache-uid-set':
+            return self.cache_photo_uid_set(response)
+        elif operation == 'generate-video':
+            return self.generate_video(response)
+        else:
+            return response.json(404)
+
+    @classmethod
+    def get_photo(cls, response):
+        """
+        定时获取设备消息推送图
+        """
+        try:
+            now_time = int(time.time())
+            LOGGER.info('进入缓存uid进行获取消息推送图片进行对象copy:{}'.format(now_time))
+            redis = RedisObject().CONN
+            uid_set_cache = redis.lrange(UID_KEY, 0, -1)
+            if not uid_set_cache:
+                return response.json(0)
+            uid_set_cache = list(uid_set_cache)
+            today = datetime.date.today()
+            time_stamp = cls.get_month_stamp()
+            s3 = AmazonS3Util(ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME)
+            for item in uid_set_cache:
+                try:
+                    eq_qs = EquipmentInfoService.get_equipment_info_model(str(today))
+                    item = str(item, encoding="utf-8")
+                    last_date = LocalDateTimeUtil.get_cur_month_end()
+                    start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(last_date, '%Y-%m-%d')
+                    eq_qs = eq_qs.filter(event_time__gt=time_stamp, event_time__lt=end_time, is_st=1, device_uid=item) \
+                        .values('device_uid', 'channel', 'event_time', 'device_nick_name')
+                    count = eq_qs.count()
+                    page = int(count / 2) if count > 1 else count
+                    redis.lrem(UID_KEY, 0, item)
+                    if page == 0:
+                        continue
+                    eq_qs = eq_qs[(page - 1) * 1:page * 1]
+                    eq_vo = eq_qs[0]
+                    file_path = '{uid}/{channel}/{event_time}.jpeg'.format(uid=eq_vo['device_uid'],
+                                                                           channel=eq_vo['channel'],
+                                                                           event_time=eq_vo['event_time'])
+                    s3.copy_obj(PUSH_BUCKET, PUSH_CLOUD_PHOTO, file_path)
+                    push_data = {'type': 0, 'uid': eq_vo['device_uid'], 'channel': eq_vo['channel'],
+                                 'event_time': eq_vo['event_time'], 'updated_time': now_time, 'created_time': now_time,
+                                 'device_nick_name': eq_vo['device_nick_name']}
+                    DevicePicturePushInfo.objects.create(**push_data)
+                except Exception as e:
+                    LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+                    redis.lrem(UID_KEY, 0, item)
+                    continue
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            LOGGER.info('--->抽取推送图片异常:{}'.format(traceback.format_exc()))
+            return response.json(177, repr(e))
+
+    @classmethod
+    def cache_photo_uid_set(cls, response):
+        """
+        缓存uid_set信息
+        """
+        try:
+            now_time = int(time.time())
+            LOGGER.info('进入读取开启云相册用户并把UID存在redis:{}'.format(now_time))
+            photo_qs = DeviceCloudPhotoInfo.objects.filter(status=1).values('uid')
+            if not photo_qs.exists():
+                return response.json(0)
+            redis = RedisObject()
+            for item in photo_qs:
+                uid_set_qs = UidSetModel.objects.filter(uid=item['uid'], detect_status=1)
+                if not uid_set_qs:
+                    continue
+                redis.CONN.rpush(UID_KEY, item['uid'])
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            LOGGER.info('--->获取uid_set信息异常:{}'.format(traceback.format_exc()))
+            return response.json(177, repr(e))
+
+    @classmethod
+    def generate_video(cls, response):
+        """
+        生成视频并存库
+        """
+        try:
+            now_time = int(time.time())
+            LOGGER.info('进入云相册开启用户,进行消息推送图进行合成视频:{}'.format(now_time))
+            photo_qs = DeviceCloudPhotoInfo.objects.filter(status=1).values('uid', 'user_id')
+            if not photo_qs.exists():
+                return response.json(0)
+            # 获取当前项目路径
+            poj_path = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
+            time_stamp = cls.get_month_stamp()
+            s3 = AmazonS3Util(ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION_NAME)
+            for item in photo_qs:
+                try:
+                    with transaction.atomic():
+                        last_date = LocalDateTimeUtil.get_cur_month_end()
+                        start_time, end_time = LocalDateTimeUtil.get_start_and_end_time(last_date, '%Y-%m-%d')
+                        picture_qs = DevicePicturePushInfo.objects.filter(uid=item['uid'],
+                                                                          event_time__gt=time_stamp,
+                                                                          event_time__lt=end_time,
+                                                                          type=0) \
+                            .values('uid', 'channel', 'event_time', 'device_nick_name')
+                        if not picture_qs.exists():
+                            continue
+                        device_nickname = picture_qs[0]['device_nick_name']
+                        pic_list = cls.download_push_picture(s3, item['uid'], poj_path, picture_qs)
+                        video_path = poj_path + r'\Ansjer\file\video.mp4'  # 输出视频的保存路径
+                        cls.picture_synthesis_video(video_path, poj_path, pic_list)  # 图片合成视频
+                        video_name = datetime.datetime.now().strftime('%Y%m')
+                        data = open(video_path, 'rb')
+                        key = '{}/video/{}.mp4'.format(item['uid'], video_name)
+                        s3.upload_file_obj(PUSH_CLOUD_PHOTO, key, data)  # 将视频资源上传至S3保存
+                        os.remove(video_path)  # 上传完成删除本地资源
+                        push_data = {'type': 1, 'uid': item['uid'], 'channel': 1,
+                                     'event_time': int(video_name), 'updated_time': now_time, 'created_time': now_time,
+                                     'device_nick_name': device_nickname, 'user_id': item['user_id']}
+                        DevicePicturePushInfo.objects.create(**push_data)
+                except Exception as e:
+                    LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+                    continue
+            return response.json(0)
+        except Exception as e:
+            print(e)
+            LOGGER.info('--->图片合成视频异常:{}'.format(traceback.format_exc()))
+            return response.json(177)
+
+    @staticmethod
+    def download_push_picture(s3, uid, dir_url, picture_qs):
+        """
+        下载推送图片,讲下载资源保存到项目本地
+        @param s3: s3对象
+        @param uid: 设备uid
+        @param dir_url: 项目文件路径
+        @param picture_qs: 消息推送图片对象
+        @return: pic_list 图片文件名集合
+        """
+        pic_list = []
+        for pic in picture_qs:
+            path = dir_url + r'\Ansjer\file\{}.jpeg'.format(pic['event_time'])
+            s3_key = '{}/{}/{}.jpeg'.format(uid, pic['channel'], pic['event_time'])
+            s3.download_object(PUSH_CLOUD_PHOTO, s3_key, path)
+            pic_list.append('{}.jpeg'.format(pic['event_time']))
+        return pic_list
+
+    @staticmethod
+    def picture_synthesis_video(video_path, poj_path, pic_list):
+        """
+        图片合成视频
+        @param video_path: 输出视频的保存路径
+        @param poj_path: 项目路径
+        @param pic_list: 图片文件名集合
+        @return:
+        """
+        if not pic_list:
+            raise Exception('this pic_list is null.')
+        fps = 1  # 帧率
+        img_path = poj_path + r'\Ansjer\file\{}'.format(pic_list[0])
+        image = cv2.imread(img_path)
+        size = image.shape
+        w = size[1]  # 宽度
+        h = size[0]  # 高度
+        img_size = (w, h)  # 图片尺寸
+        fourcc = cv2.VideoWriter_fourcc(*"mp4v")
+        video_writer = cv2.VideoWriter(video_path, fourcc, fps, img_size)
+        for item in pic_list:
+            img_path = poj_path + r'\Ansjer\file\{}'.format(item)
+            frame = cv2.imread(img_path)
+            if frame is None:
+                continue
+            frame = cv2.resize(frame, img_size)  # 生成视频   图片尺寸和设定尺寸相同
+            video_writer.write(frame)  # 将图片写进视频里
+            os.remove(img_path)
+        video_writer.release()  # 释放资源
+
+    @staticmethod
+    def get_month_stamp():
+        """
+        获取当月开始时间戳
+        """
+        now_month = LocalDateTimeUtil.get_cur_month_start()
+        start_time = "{} 00:00:00".format(str(now_month))
+        time_array = time.strptime(start_time, "%Y-%m-%d %H:%M:%S")
+        # 转换为时间戳
+        return int(time.mktime(time_array))

+ 32 - 6
Controller/DeviceShare.py

@@ -16,15 +16,16 @@ import json
 import time
 import time
 
 
 from django.views.generic.base import View
 from django.views.generic.base import View
-from Object.RedisObject import RedisObject
+
 from Ansjer.config import SERVER_DOMAIN
 from Ansjer.config import SERVER_DOMAIN
-from Model.models import Device_Info, Device_User
+from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
+from Controller.UserDevice.UserDeviceShareController import UserDeviceShareView
+from Model.models import Device_Info, Device_User, DeviceChannelUserSet, DeviceChannelUserPermission
 from Model.models import UID_Bucket
 from Model.models import UID_Bucket
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
-from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
 
 
 
 
 class DeviceShareView(View):
 class DeviceShareView(View):
@@ -183,7 +184,7 @@ class DeviceShareView(View):
                     sharerDvqs.primaryMaster = primaryMaster
                     sharerDvqs.primaryMaster = primaryMaster
                     sharerDvqs.data_joined = None
                     sharerDvqs.data_joined = None
                     sharerDvqs.save()
                     sharerDvqs.save()
-
+                    UserDeviceShareView.qrcode_share_channel_permission_save(userID, UID)
                     # redisObj = RedisObject(db=8)
                     # redisObj = RedisObject(db=8)
                     # redisObj.del_data(key='uid_qs_' + userID)
                     # redisObj.del_data(key='uid_qs_' + userID)
                 except Exception as e:
                 except Exception as e:
@@ -218,12 +219,12 @@ class DeviceShareView(View):
         if UID is not None:
         if UID is not None:
             # 查询分享获得的用户
             # 查询分享获得的用户
             qs = Device_Info.objects.filter(UID=UID, isShare=True, primaryUserID=userID, isExist=1). \
             qs = Device_Info.objects.filter(UID=UID, isShare=True, primaryUserID=userID, isExist=1). \
-                values('userID__NickName', 'userID__username', 'userID__userEmail', 'userID__phone', 'id',
+                values('userID__NickName', 'userID__username', 'userID__userEmail', 'userID__phone', 'id', 'userID',
                        'userID__userIconPath')
                        'userID__userIconPath')
             data = []
             data = []
             # print(qs)
             # print(qs)
             for q in qs:
             for q in qs:
-                d = {'id': q['id']}
+                d = {'id': q['id'], 'userID': q['userID']}
                 if q['userID__NickName']:
                 if q['userID__NickName']:
                     d['user'] = q['userID__NickName']
                     d['user'] = q['userID__NickName']
                 elif q['userID__username']:
                 elif q['userID__username']:
@@ -262,7 +263,32 @@ class DeviceShareView(View):
             return response.json(444, 'id')
             return response.json(444, 'id')
         try:
         try:
             Device_Info.objects.filter(id__in=ids.split(','), primaryUserID=userID).delete()
             Device_Info.objects.filter(id__in=ids.split(','), primaryUserID=userID).delete()
+
         except Exception as e:
         except Exception as e:
             return response.json(10, repr(e))
             return response.json(10, repr(e))
         else:
         else:
             return response.json(0)
             return response.json(0)
+
+    @staticmethod
+    def del_device_channel_permission(user_id, uid):
+        """
+        删除设备通道权限
+        @param user_id: 用户ID
+        @param uid: 设备UID
+        @return: True | False
+        """
+        if user_id and uid:
+            user_channel_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
+            if user_channel_qs.exists():
+                DeviceChannelUserPermission.objects.filter(channel_user_id=user_channel_qs.first().id).delete()
+                user_channel_qs.delete()
+            return True
+        elif uid:
+            user_channel_qs = DeviceChannelUserSet.objects.filter(uid=uid)
+            if user_channel_qs.exists():
+                channels_user_list = [val.id for val in user_channel_qs]
+                DeviceChannelUserPermission.objects.filter(channel_user_id__in=channels_user_list).delete()
+                user_channel_qs.delete()
+            return True
+        else:
+            return False

+ 3 - 0
Controller/EquipmentManager.py

@@ -14,6 +14,7 @@ from django.utils import timezone
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, BASE_DIR
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, BASE_DIR
 from Ansjer.config import PUSH_REDIS_ADDRESS
 from Ansjer.config import PUSH_REDIS_ADDRESS
 from Controller.DetectController import DetectControllerView
 from Controller.DetectController import DetectControllerView
+from Controller.DeviceShare import DeviceShareView
 from Model.models import Device_User, Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, \
 from Model.models import Device_User, Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, \
     UIDCompanySerialModel, iotdeviceInfoModel, UidChannelSetModel, LogModel, UnicomDeviceInfo, SysMsgModel, CountryModel
     UIDCompanySerialModel, iotdeviceInfoModel, UidChannelSetModel, LogModel, UnicomDeviceInfo, SysMsgModel, CountryModel
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
@@ -824,6 +825,7 @@ def deleteInterface(request):
 
 
             if dv_qs[0].isShare:
             if dv_qs[0].isShare:
                 dv_qs.delete()
                 dv_qs.delete()
+                DeviceShareView.del_device_channel_permission(userID, uid)
             else:
             else:
                 # a.主用户删除设备
                 # a.主用户删除设备
                 dv_qs.delete()
                 dv_qs.delete()
@@ -840,6 +842,7 @@ def deleteInterface(request):
                     up_qs.delete()
                     up_qs.delete()
                 # b.删除次用户设备
                 # b.删除次用户设备
                 Device_Info.objects.filter(UID=uid, isShare=True, primaryUserID=userID).delete()
                 Device_Info.objects.filter(UID=uid, isShare=True, primaryUserID=userID).delete()
+                DeviceShareView.del_device_channel_permission('', uid)
 
 
             if not serial_number:
             if not serial_number:
                 serial_number = CommonService.query_serial_with_uid(uid)
                 serial_number = CommonService.query_serial_with_uid(uid)

+ 1 - 1
Controller/EquipmentManagerV3.py

@@ -677,7 +677,7 @@ class EquipmentManagerV3(View):
 
 
             if p_uid in uv_dict:
             if p_uid in uv_dict:
                 # 获取设备信息DTO
                 # 获取设备信息DTO
-                UserDeviceService.get_device_info_dto(p, p_uid, uv_dict)
+                UserDeviceService.get_device_info_dto(p, p_uid, uv_dict, userID)
             else:
             else:
                 # 设备版本号
                 # 设备版本号
                 p['uid_version'] = ''
                 p['uid_version'] = ''

+ 25 - 2
Controller/PcInfo.py

@@ -12,7 +12,7 @@ from django.http import HttpResponse
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
 from Controller.PctestController import TokenObject1
 from Controller.PctestController import TokenObject1
-from Model.models import Pc_Info, PctestlogModel
+from Model.models import Pc_Info, PctestlogModel, AVSSVersion
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
@@ -71,6 +71,8 @@ class PcInfo(View):
                 return self.download(request_dict, response)
                 return self.download(request_dict, response)
             elif operation == 'delete':
             elif operation == 'delete':
                 return self.delete(request_dict, response)
                 return self.delete(request_dict, response)
+            elif operation == 'AVSS/check-version':
+                return self.check_version(request_dict, response)
             else:
             else:
                 return response.json(414)
                 return response.json(414)
 
 
@@ -643,6 +645,28 @@ class PcInfo(View):
         else:
         else:
             return response.json(0)
             return response.json(0)
 
 
+    @staticmethod
+    def check_version(request_dict, response):
+        """
+        AVSS检查版本
+        @param request_dict: 请求数据
+        @request_dict version: 当前版本
+        @param response: 响应
+        @return: response
+        """
+        version = request_dict.get('version', None)
+        if version is None:
+            return response.json(444)
+        avss_version_qs = AVSSVersion.objects.filter().values('online_version')
+        if not avss_version_qs.exists():
+            return response.json(173)
+        # 比较当前版本和线上版本
+        online_version = avss_version_qs[0]['online_version']
+        if version < online_version:
+            return response.json(0, {'online_version': online_version})
+        else:
+            return response.json(0)
+
 def compareVersion(s1: str, s2: str) -> Union[str, int]:
 def compareVersion(s1: str, s2: str) -> Union[str, int]:
     i, j = 0, 0
     i, j = 0, 0
     while i < len(s1) or j < len(s2):
     while i < len(s1) or j < len(s2):
@@ -693,4 +717,3 @@ def getMD5orSHA265(fileName, encryptionType='MD5'):
 
 
         f.close()
         f.close()
         return encryption.hexdigest()
         return encryption.hexdigest()
-

+ 154 - 0
Controller/ShadowController.py

@@ -0,0 +1,154 @@
+import logging
+import time
+
+from django.http import JsonResponse
+
+from Ansjer.config import SERVER_TYPE
+from Model.models import Device_Info, UidSetModel, UID_Preview, VoicePromptModel, UID_Bucket, UidChannelSetModel, \
+    AiService, CountryModel
+from Object.ETkObject import ETkObject
+from Service.CommonService import CommonService
+
+
+# 更新设备影子
+def update_device_shadow(request):
+    request.encoding = 'utf-8'
+    if request.method == 'POST':
+        request_dict = request.POST
+    elif request.method == 'GET':
+        request_dict = request.GET
+    else:
+        return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+
+    logger = logging.getLogger('info')
+    logger.info('---更新设备影子---, 使用配置:{}, 参数:{}'.format(SERVER_TYPE, request_dict.dict()))
+
+    try:
+        etk = request_dict.get('etk', None)
+        eto = ETkObject(etk)
+        uid = eto.uid
+        if not uid:
+            return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+
+        nowTime = int(time.time())
+
+        # 重置按钮
+        is_reset = request_dict.get('is_reset', None)
+        # 传1则重置设备信息
+        if is_reset == '1':
+            logger.info('设备重置: {}'.format(uid))
+
+            # 重置语音提示
+            uid_channel_qs = UidChannelSetModel.objects.filter(uid__uid=uid)
+            if uid_channel_qs.exists():
+                uid_channel_qs.update(voice_prompt_intelligent_mute=0, voice_prompt_status=0, voice_prompt_enter=0,
+                                      voice_prompt_leave=0, voice_repeat_day=127, voice_start_time=0, voice_end_time=0,
+                                      voice_start_x=0, voice_start_y=18, voice_end_x=44, voice_end_y=18,
+                                      voice_direction=0)
+
+            # 购买云存套餐的设备isExist置为2
+            uid_bucket = UID_Bucket.objects.filter(uid=uid, endTime__gte=nowTime).values('id', 'has_unused').order_by(
+                'addTime')
+            if not uid_bucket.exists():
+                Device_Info.objects.filter(UID=uid).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()
+
+            # 关闭移动侦测的消息提醒
+            Device_Info.objects.filter(UID=uid).update(NotificationMode=0)
+
+            # 关闭AI
+            AiService.objects.filter(uid=uid, use_status=1).update(detect_status=0, detect_group='')
+            logger.info('{}重置成功'.format(uid))
+
+        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)
+        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)
+        mobile_4g = request_dict.get('mobile4G', None)
+        is_ptz = request_dict.get('is_ptz', None)
+        is_ai = request_dict.get('is_ai', None)
+        ai_type = request_dict.get('AiType', None)
+        isSupportFourPoint = request_dict.get('isSupportFourPoint', None)
+
+        # 更新
+        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'] = 0 if is_reset == '1' else 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 mobile_4g:
+            qs_dict['mobile_4g'] = int(mobile_4g)
+        if is_ptz:
+            qs_dict['is_ptz'] = is_ptz
+        if is_ai:
+            qs_dict['is_ai'] = is_ai
+        if isSupportFourPoint:
+            qs_dict['isSupportFourPoint'] = isSupportFourPoint
+        if ai_type:
+            qs_dict['ai_type'] = ai_type
+        ipInfo = CommonService.getIpIpInfo(ip, 'CN')
+        country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id')
+        if country_qs.exists():
+            country = country_qs[0]['id']
+            qs_dict['tb_country'] = country
+        logger.info('{} qs_dict: {}'.format(uid, qs_dict))
+
+        us_qs = UidSetModel.objects.filter(uid=uid)
+        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)
+        # 新增
+        else:
+            if is_alexa:
+                qs_dict['is_alexa'] = is_alexa
+            qs_dict['uid'] = uid
+            qs_dict['addTime'] = nowTime
+            UidSetModel.objects.create(**qs_dict)
+        logger.info('***设备影子保存成功{}'.format(uid))
+        return JsonResponse(status=200, data={'code': 0, 'msg': 'success', 'data': {}})
+    except Exception as e:
+        logger.info('更新设备影子异常: {}'.format(repr(e)))
+        return JsonResponse(status=200, data={'code': 0, 'update_shadow_error': repr(e)})

+ 7 - 22
Controller/StsOssController.py

@@ -1,26 +1,12 @@
-#!/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/5/10 8:43
-@Version: python3.6
-@MODIFY DECORD:ansjer dev
-@file: StsOssController.py
-@Contact: chanjunkai@163.com
-"""
+import json
 
 
+from aliyunsdkcore import client
+from aliyunsdksts.request.v20150401 import AssumeRoleRequest
 from django.views.generic import View
 from django.views.generic import View
 
 
+from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, OSS_ROLE_ARN
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
-from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, OSS_ROLE_ARN
-from aliyunsdkcore import client
-from aliyunsdksts.request.v20150401 import AssumeRoleRequest
-import json
-from var_dump import var_dump
 
 
 
 
 class StsOssView(View):
 class StsOssView(View):
@@ -39,7 +25,6 @@ class StsOssView(View):
 
 
     def validation(self, request_dict, operation):
     def validation(self, request_dict, operation):
         response = ResponseObject()
         response = ResponseObject()
-        from var_dump import var_dump
         # var_dump(request_dict)
         # var_dump(request_dict)
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
         if operation == 'uidPreview':
         if operation == 'uidPreview':
@@ -63,13 +48,13 @@ class StsOssView(View):
         req.set_RoleArn(OSS_ROLE_ARN)
         req.set_RoleArn(OSS_ROLE_ARN)
         req.set_RoleSessionName(userID)
         req.set_RoleSessionName(userID)
         req.set_DurationSeconds(3600)
         req.set_DurationSeconds(3600)
-        Resource_access = "acs:oss:*:*:{bucket_name}/{userID}*".\
-            format(bucket_name=bucket_name,userID=userID)
+        Resource_access = "acs:oss:*:*:{bucket_name}/{userID}*". \
+            format(bucket_name=bucket_name, userID=userID)
         policys = {
         policys = {
             "Version": "1",
             "Version": "1",
             "Statement": [
             "Statement": [
                 {
                 {
-                    "Action": ["oss:PutObject", "oss:DeleteObject", "oss:GetObject",],
+                    "Action": ["oss:PutObject", "oss:DeleteObject", "oss:GetObject", ],
                     # "Action": ["*"],
                     # "Action": ["*"],
                     # "Action": ["*"],
                     # "Action": ["*"],
                     "Resource": [Resource_access],
                     "Resource": [Resource_access],

+ 1 - 0
Controller/SysMsg.py

@@ -187,6 +187,7 @@ class SysMsgView(View):
             uid_list = []
             uid_list = []
 
 
             for sm_q in sm_qs:
             for sm_q in sm_qs:
+                sm_q['jumpLink'] = ''
                 if sm_q['eventType'] > 0:
                 if sm_q['eventType'] > 0:
                     uid_list.append(sm_q['uid'])
                     uid_list.append(sm_q['uid'])
                 data_res.append(sm_q)
                 data_res.append(sm_q)

+ 76 - 314
Controller/TestApi.py

@@ -11,11 +11,17 @@
 @file: Test.py
 @file: Test.py
 @Contact: chanjunkai@163.com
 @Contact: chanjunkai@163.com
 """
 """
+import os
+import traceback
+
 import botocore
 import botocore
+import cv2
 from botocore import client
 from botocore import client
+
 from Controller.DeviceConfirmRegion import Device_Region
 from Controller.DeviceConfirmRegion import Device_Region
 from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.AWS.AmazonS3Util import AmazonS3Util
 from Object.RedisObject import RedisObject
 from Object.RedisObject import RedisObject
+from Service.VodHlsService import SplitVodHlsObject
 
 
 '''
 '''
 http://192.168.136.40:8077/Test
 http://192.168.136.40:8077/Test
@@ -30,7 +36,6 @@ import oss2
 import paypalrestsdk
 import paypalrestsdk
 import logging
 import logging
 from aliyunsdkcore import client
 from aliyunsdkcore import client
-from aliyunsdksts.request.v20150401 import AssumeRoleRequest
 from django.http import JsonResponse, HttpResponse
 from django.http import JsonResponse, HttpResponse
 from django.utils.decorators import method_decorator
 from django.utils.decorators import method_decorator
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.csrf import csrf_exempt
@@ -38,7 +43,7 @@ from django.views.generic.base import View
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
 from django.contrib.auth.hashers import make_password  # 对密码加密模块
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, AWS_ACCESS_KEY_ID, \
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, AWS_ACCESS_KEY_ID, \
     AWS_SECRET_ACCESS_KEY, SERVER_TYPE, AWS_SES_ACCESS_REGION
     AWS_SECRET_ACCESS_KEY, SERVER_TYPE, AWS_SES_ACCESS_REGION
-from Model.models import Order_Model, Store_Meal, VodHlsModel, OssCrdModel, StsCrdModel, DeviceLogModel
+from Model.models import Order_Model, Store_Meal, OssCrdModel, StsCrdModel, DeviceLogModel, VodBucketModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
@@ -49,6 +54,7 @@ from Ansjer.config import SERVER_DOMAIN_SSL
 SERVER_DOMAIN = 'http://test.dvema.com/'
 SERVER_DOMAIN = 'http://test.dvema.com/'
 ACCESS_KEY = "AKIA2E67UIMD3CYTIWPA"
 ACCESS_KEY = "AKIA2E67UIMD3CYTIWPA"
 SECRET_KEY = "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"
 SECRET_KEY = "mHl79oiKxEf+89friTtwIcF8FUFIdVksUwySixwQ"
+LOGGER = logging.getLogger('info')
 
 
 
 
 # 测试接口sdk
 # 测试接口sdk
@@ -148,9 +154,47 @@ class testView(View):
             return self.read_redis_list(response)
             return self.read_redis_list(response)
         elif operation == 'playM3u8':
         elif operation == 'playM3u8':
             return self.play_m3u8(request_dict, response)
             return self.play_m3u8(request_dict, response)
+        elif operation == 'generate_video':
+            return self.generate_video(request_dict, response)
         else:
         else:
             return 123
             return 123
 
 
+    @classmethod
+    def generate_video(cls, request_dict, response):
+        # 设计抽取图片规则通过消息随机还是时间随机,调试copy S3对象查询是否携带失效时间
+        try:
+            DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
+            arr_list = ['1666756086.jpeg', '1666831275.jpeg', '1666841492.jpeg']
+            s3 = AmazonS3Util(AWS_ACCESS_KEY_ID[0], AWS_SECRET_ACCESS_KEY[0], 'cn-northwest-1')
+            bucket = 'push-cloud-photo'
+            for item in arr_list:
+                path = DIR + r'\Ansjer\file\{}'.format(item)
+                s3_key = 'HA154GVEDH41RY8Y111A/1/{}'.format(item)
+                s3.download_object(bucket, s3_key, path)
+            video_dir = DIR + r'\Ansjer\file\result.mp4'  # 输出视频的保存路径
+            fps = 0.5  # 帧率
+            img_size = (1920, 1080)  # 图片尺寸
+            fourcc = cv2.VideoWriter_fourcc(*"mp4v")
+            videoWriter = cv2.VideoWriter(video_dir, fourcc, fps, img_size)
+            for i in arr_list:
+                img_path = DIR + r'\Ansjer\file\{}'.format(i)
+                frame = cv2.imread(img_path)
+                frame = cv2.resize(frame, img_size)  # 生成视频   图片尺寸和设定尺寸相同
+                videoWriter.write(frame)  # 将图片写进视频里
+                os.remove(img_path)
+            videoWriter.release()  # 释放资源
+            data = open(video_dir, 'rb')
+            key = 'HA154GVEDH41RY8Y111A/1/20221027.mp4'
+            s3.upload_file_obj(bucket, key, data)
+            response_url = s3.generate_file_obj_url(bucket, key)
+            os.remove(video_dir)
+        except Exception as e:
+            print(e)
+            ex = traceback.format_exc()
+            LOGGER.info('--->抽取推送图片异常:{}'.format(ex))
+            return response.json(177, ex)
+        return response.json(0, response_url)
+
     @classmethod
     @classmethod
     def head_bucket(cls, request_dict, response):
     def head_bucket(cls, request_dict, response):
         bucket_name = request_dict.get('bucket', None)
         bucket_name = request_dict.get('bucket', None)
@@ -489,294 +533,6 @@ class testView(View):
         # return response
         # return response
         # return HttpResponse(status=200, content=playlist)
         # return HttpResponse(status=200, content=playlist)
 
 
-    def do_test_get_sign_sts(self, request_dict, ip, response):
-        # uid = 'GZL2PEFJPLY7W6BG111A'
-        # channel = 2
-        uid = 'VVDHCVBYDKFMJRWA111A'
-        channel = 1
-        now_time = int(time.time())
-        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time). \
-            values("bucket__mold", "bucket__bucket", "bucket__endpoint", "bucket__region", "endTime")
-        if ubqs.exists():
-            if ubqs[0]["bucket__mold"] == 0:
-                # 阿里云 oss sts
-                oc_qs = OssCrdModel.objects.filter(uid=uid, channel=channel). \
-                    values("addTime", "data")
-                if oc_qs.exists():
-                    endTime = int(oc_qs[0]["addTime"]) + 3500
-                    if endTime > now_time:
-                        print(endTime)
-                        print(now_time)
-                        res = json.loads(oc_qs[0]["data"])
-                        return JsonResponse(status=200, data=res)
-                # 套餐id
-                storage = '{uid}/vod{channel}/'.format(uid=uid, channel=channel)
-                bucket_name = ubqs[0]['bucket__bucket']
-                endpoint = ubqs[0]['bucket__endpoint']
-                access_key_id = OSS_STS_ACCESS_KEY
-                access_key_secret = OSS_STS_ACCESS_SECRET
-                region_id = ubqs[0]['bucket__region']
-                role_arn = OSS_ROLE_ARN
-                clt = client.AcsClient(access_key_id, access_key_secret, region_id)
-                req = AssumeRoleRequest.AssumeRoleRequest()
-                # 设置返回值格式为JSON。
-                req.set_accept_format('json')
-                req.set_RoleArn(role_arn)
-                req.set_RoleSessionName(uid + '_' + channel)
-                req.set_DurationSeconds(3600)
-                Resource_access = "acs:oss:*:*:{bucket_name}/{uid_channel}*". \
-                    format(bucket_name=bucket_name, uid_channel=storage)
-                print(Resource_access)
-                policys = {
-                    "Version": "1",
-                    "Statement": [
-                        {
-                            "Action": ["oss:PutObject", "oss:DeleteObject", ],
-                            "Resource": [Resource_access],
-                            "Effect": "Allow",
-                            "Condition": {
-                                "IpAddress": {"acs:SourceIp": ip}
-                                # "IpAddress": {"acs:SourceIp": "120.237.157.184"}
-                                # "IpAddress": {"acs:SourceIp": "*"}
-                            }
-                        }
-                    ]
-                }
-                req.set_Policy(Policy=json.dumps(policys))
-                body = clt.do_action(req)
-                # 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
-                token = json.loads(body.decode('utf-8'))
-                print(token)
-                res = {
-                    'AccessKeyId': token['Credentials']['AccessKeyId'],
-                    'AccessKeySecret': token['Credentials']['AccessKeySecret'],
-                    'SecurityToken': token['Credentials']['SecurityToken'],
-                    'Expiration': token['Credentials']['Expiration'],
-                    'expire': '3600',
-                    'endpoint': endpoint,
-                    'bucket_name': bucket_name,
-                    'arn': token['AssumedRoleUser']['Arn'],
-                    'code': 0,
-                    'storage': storage,
-                    'endTime': ubqs[0]['endTime'],
-                    'ip': ip}
-                if oc_qs.exists():
-                    oc_qs.update(data=json.dumps(res), addTime=now_time)
-                else:
-                    OssCrdModel.objects.create \
-                        (uid=uid, channel=channel, data=json.dumps(res), addTime=now_time)
-                return JsonResponse(status=200, data=res)
-            elif ubqs[0]["bucket__mold"] == 1:
-                # 亚马逊 s3 sts
-                sts_qs = StsCrdModel.objects.filter(uid=uid, channel=channel). \
-                    values("addTime", "data")
-                if sts_qs.exists():
-                    endTime = int(sts_qs[0]["addTime"]) + 3500
-                    if endTime > now_time:
-                        print(endTime)
-                        print(now_time)
-                        res = json.loads(sts_qs[0]["data"])
-                        return JsonResponse(status=200, data=res)
-                    # 套餐id
-                storage = '{uid}/vod{channel}/'.format(uid=uid, channel=channel)
-                bucket_name = ubqs[0]['bucket__bucket']
-                endpoint = ubqs[0]['bucket__endpoint']
-                region_id = ubqs[0]['bucket__region']
-
-                ###############
-                REGION_NAME = region_id
-                boto3_sts = boto3.client(
-                    'sts',
-                    aws_access_key_id='AKIA2E67UIMD45Y3HL53',
-                    aws_secret_access_key='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',
-                    region_name=REGION_NAME
-                )
-                Policy = {
-                    "Version": "2012-10-17",
-                    "Statement": [
-                        {
-                            "Effect": "Allow",
-                            "Action": "s3:*",
-                            "Resource": ["arn:aws:s3:::azvod1/{uid_channel}/*".
-                                             format(uid_channel=storage)]
-                        }
-                    ]
-                }
-                response = boto3_sts.get_federation_token(
-                    Name='{role_name}'.format(role_name=uid + '_' + channel),
-                    Policy=json.dumps(Policy),
-                    DurationSeconds=7200
-                )
-                ###############
-                res = {
-                    'AccessKeyId': response['Credentials']['AccessKeyId'],
-                    'AccessKeySecret': response['Credentials']['SecretAccessKey'],
-                    'SessionToken': response['Credentials']['SessionToken'],
-                    'Expiration': response['Credentials']['Expiration'],
-                    'expire': '3600',
-                    'endpoint': endpoint,
-                    'bucket_name': bucket_name,
-                    'arn': response['FederatedUser']['Arn'],
-                    'code': 0,
-                    'storage': storage,
-                    'endTime': ubqs[0]['endTime'],
-                    'ip': ip,
-                }
-                if sts_qs.exists():
-                    sts_qs.update(data=json.dumps(res, default=str), addTime=now_time)
-                else:
-                    StsCrdModel.objects.create(uid=uid, channel=channel, data=json.dumps(res, default=str),
-                                               addTime=now_time, type=1)
-                return JsonResponse(status=200, data=res)
-            else:
-                res = {'code': 404, 'msg': 'data not exists!'}
-                return HttpResponse(json.dumps(res, ensure_ascii=False),
-                                    content_type="application/json,charset=utf-8")
-
-    def do_get_sign_sts(self, request_dict, ip, response):
-        # uid = 'GZL2PEFJPLY7W6BG111A'
-        # channel = 2
-        uid = '86YC8Z192VB1VMKU111A'
-        channel = 1
-        now_time = int(time.time())
-        ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel, endTime__gte=now_time). \
-            values("bucket__mold", "bucket__bucket", "bucket__endpoint", "bucket__region", "endTime")
-        if ubqs.exists():
-            if ubqs[0]["bucket__mold"] == 0:
-                # 阿里云 oss sts
-                oc_qs = OssCrdModel.objects.filter(uid=uid, channel=channel). \
-                    values("addTime", "data")
-                if oc_qs.exists():
-                    endTime = int(oc_qs[0]["addTime"]) + 3500
-                    if endTime > now_time:
-                        print(endTime)
-                        print(now_time)
-                        res = json.loads(oc_qs[0]["data"])
-                        return JsonResponse(status=200, data=res)
-                # 套餐id
-                storage = '{uid}/vod{channel}/'.format(uid=uid, channel=channel)
-                bucket_name = ubqs[0]['bucket__bucket']
-                endpoint = ubqs[0]['bucket__endpoint']
-                access_key_id = OSS_STS_ACCESS_KEY
-                access_key_secret = OSS_STS_ACCESS_SECRET
-                region_id = ubqs[0]['bucket__region']
-                role_arn = OSS_ROLE_ARN
-                clt = client.AcsClient(access_key_id, access_key_secret, region_id)
-                req = AssumeRoleRequest.AssumeRoleRequest()
-                # 设置返回值格式为JSON。
-                req.set_accept_format('json')
-                req.set_RoleArn(role_arn)
-                req.set_RoleSessionName(uid + '_' + channel)
-                req.set_DurationSeconds(3600)
-                Resource_access = "acs:oss:*:*:{bucket_name}/{uid_channel}*". \
-                    format(bucket_name=bucket_name, uid_channel=storage)
-                print(Resource_access)
-                policys = {
-                    "Version": "1",
-                    "Statement": [
-                        {
-                            "Action": ["oss:PutObject", "oss:DeleteObject", ],
-                            "Resource": [Resource_access],
-                            "Effect": "Allow",
-                            "Condition": {
-                                "IpAddress": {"acs:SourceIp": ip}
-                                # "IpAddress": {"acs:SourceIp": "120.237.157.184"}
-                                # "IpAddress": {"acs:SourceIp": "*"}
-                            }
-                        }
-                    ]
-                }
-                req.set_Policy(Policy=json.dumps(policys))
-                body = clt.do_action(req)
-                # 使用RAM账号的AccessKeyId和AccessKeySecret向STS申请临时token。
-                token = json.loads(body.decode('utf-8'))
-                print(token)
-                res = {
-                    'AccessKeyId': token['Credentials']['AccessKeyId'],
-                    'AccessKeySecret': token['Credentials']['AccessKeySecret'],
-                    'SecurityToken': token['Credentials']['SecurityToken'],
-                    'Expiration': token['Credentials']['Expiration'],
-                    'expire': '3600',
-                    'endpoint': endpoint,
-                    'bucket_name': bucket_name,
-                    'arn': token['AssumedRoleUser']['Arn'],
-                    'code': 0,
-                    'storage': storage,
-                    'endTime': ubqs[0]['endTime'],
-                    'ip': ip}
-                if oc_qs.exists():
-                    oc_qs.update(data=json.dumps(res), addTime=now_time)
-                else:
-                    OssCrdModel.objects.create \
-                        (uid=uid, channel=channel, data=json.dumps(res), addTime=now_time)
-                return JsonResponse(status=200, data=res)
-            elif ubqs[0]["bucket__mold"] == 1:
-                # 亚马逊 s3 sts
-                sts_qs = StsCrdModel.objects.filter(uid=uid, channel=channel). \
-                    values("addTime", "data")
-                if sts_qs.exists():
-                    endTime = int(sts_qs[0]["addTime"]) + 3500
-                    if endTime > now_time:
-                        print(endTime)
-                        print(now_time)
-                        res = json.loads(sts_qs[0]["data"])
-                        return JsonResponse(status=200, data=res)
-                    # 套餐id
-                storage = '{uid}/vod{channel}/'.format(uid=uid, channel=channel)
-                bucket_name = ubqs[0]['bucket__bucket']
-                endpoint = ubqs[0]['bucket__endpoint']
-                region_id = ubqs[0]['bucket__region']
-
-                ###############
-                REGION_NAME = region_id
-                boto3_sts = boto3.client(
-                    'sts',
-                    aws_access_key_id='AKIA2E67UIMD45Y3HL53',
-                    aws_secret_access_key='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',
-                    region_name=REGION_NAME
-                )
-                Policy = {
-                    "Version": "2012-10-17",
-                    "Statement": [
-                        {
-                            "Effect": "Allow",
-                            "Action": "s3:*",
-                            "Resource": ["arn:aws:s3:::azvod1/{uid_channel}/*".
-                                             format(uid_channel=storage)]
-                        }
-                    ]
-                }
-                response = boto3_sts.get_federation_token(
-                    Name='{role_name}'.format(role_name=uid + '_' + channel),
-                    Policy=json.dumps(Policy),
-                    DurationSeconds=7200
-                )
-                ###############
-                res = {
-                    'AccessKeyId': response['Credentials']['AccessKeyId'],
-                    'AccessKeySecret': response['Credentials']['SecretAccessKey'],
-                    'SessionToken': response['Credentials']['SessionToken'],
-                    'Expiration': response['Credentials']['Expiration'],
-                    'expire': '3600',
-                    'endpoint': endpoint,
-                    'bucket_name': bucket_name,
-                    'arn': response['FederatedUser']['Arn'],
-                    'code': 0,
-                    'storage': storage,
-                    'endTime': ubqs[0]['endTime'],
-                    'ip': ip,
-                }
-                if sts_qs.exists():
-                    sts_qs.update(data=json.dumps(res, default=str), addTime=now_time)
-                else:
-                    StsCrdModel.objects.create(uid=uid, channel=channel, data=json.dumps(res, default=str),
-                                               addTime=now_time, type=1)
-                return JsonResponse(status=200, data=res)
-            else:
-                res = {'code': 404, 'msg': 'data not exists!'}
-                return HttpResponse(json.dumps(res, ensure_ascii=False),
-                                    content_type="application/json,charset=utf-8")
-
     def do_pay_by_ali(self, request_dict, userID, response):
     def do_pay_by_ali(self, request_dict, userID, response):
         uid = request_dict.get('uid', None)
         uid = request_dict.get('uid', None)
         rank = request_dict.get('rank', None)
         rank = request_dict.get('rank', None)
@@ -855,23 +611,24 @@ class testView(View):
         ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel).values('status')
         ubqs = UID_Bucket.objects.filter(uid=uid, channel=channel).values('status')
         if not ubqs.exists():
         if not ubqs.exists():
             return response.json(10, '设备未购买')
             return response.json(10, '设备未购买')
-        nowTime = int(time.time())
-        # vodqs = VodHlsModel.objects.filter(uid=uid, channel=channel, time__range=(startTime, endTime),
-        #                                    endTime__gte=nowTime) \
-        #     .values("time", "sec", "bucket__bucket", "bucket__endpoint", "bucket__region")
-        vodqs = VodHlsModel.objects.filter(uid=uid, channel=channel) \
-            .values("time", "sec", "bucket__bucket", "bucket__endpoint", "bucket__region")
+        split_vod_hls_obj = SplitVodHlsObject()
+        vodqs = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel).values("start_time", "sec", "bucket_id")
+        if not vodqs.exists():
+            return response.json(173)
         vod_play_list = []
         vod_play_list = []
-        print(vodqs)
         auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
         auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+        bucket_id = vodqs[0]['bucket_id']
+        vod_bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'endpoint')
+        if not vod_bucket_qs.exists():
+            return response.json(173)
+        bucket_name = vod_bucket_qs[0]["bucket"]
+        endpoint = vod_bucket_qs[0]["endpoint"]
         for vod in vodqs:
         for vod in vodqs:
-            bucket_name = vod["bucket__bucket"]
-            endpoint = vod["bucket__endpoint"]
             bucket = oss2.Bucket(auth, endpoint, bucket_name)
             bucket = oss2.Bucket(auth, endpoint, bucket_name)
             m3u8 = '{uid}/vod{channel}/{time}/{time}.m3u8'. \
             m3u8 = '{uid}/vod{channel}/{time}/{time}.m3u8'. \
-                format(uid=uid, channel=channel, time=vod['time'])
+                format(uid=uid, channel=channel, time=vod['start_time'])
             ts = '{uid}/vod{channel}/{time}/ts0.ts'. \
             ts = '{uid}/vod{channel}/{time}/ts0.ts'. \
-                format(uid=uid, channel=channel, time=vod['time'])
+                format(uid=uid, channel=channel, time=vod['start_time'])
             url = bucket.sign_url('GET', m3u8, 3600, params={'x-oss-process': 'hls/sign'})
             url = bucket.sign_url('GET', m3u8, 3600, params={'x-oss-process': 'hls/sign'})
             urllst = url.split('?')
             urllst = url.split('?')
             url_start = urllib.parse.unquote(urllst[0])
             url_start = urllib.parse.unquote(urllst[0])
@@ -880,7 +637,8 @@ class testView(View):
                 format(url_start=url_start, url_end=url_end)
                 format(url_start=url_start, url_end=url_end)
             thumb = bucket.sign_url('GET', ts, 3600,
             thumb = bucket.sign_url('GET', ts, 3600,
                                     params={'x-oss-process': 'video/snapshot,t_10000,m_fast,w_300'})
                                     params={'x-oss-process': 'video/snapshot,t_10000,m_fast,w_300'})
-            vod_play_list.append({'name': vod['time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec']})
+            vod_play_list.append(
+                {'name': vod['start_time'], 'sign_url': vod_play_url, 'thumb': thumb, 'sec': vod['sec']})
         return response.json(0, vod_play_list)
         return response.json(0, vod_play_list)
 
 
     def generate_token(self, request_dict, userID):
     def generate_token(self, request_dict, userID):
@@ -977,7 +735,8 @@ class testView(View):
         month = int(month)
         month = int(month)
         startTime = CommonService.str_to_timestamp('{year}-{month}'.format(year=year, month=month), '%Y-%m')
         startTime = CommonService.str_to_timestamp('{year}-{month}'.format(year=year, month=month), '%Y-%m')
         endTime = CommonService.str_to_timestamp('{year}-{month}'.format(year=year, month=month + 1), '%Y-%m') - 1
         endTime = CommonService.str_to_timestamp('{year}-{month}'.format(year=year, month=month + 1), '%Y-%m') - 1
-        qsTs = VodHlsModel.objects.filter(time__gte=startTime, time__lte=endTime).values('fg')
+        split_vod_hls_obj = SplitVodHlsObject()
+        qsTs = split_vod_hls_obj.get_vod_hls_data(time__gte=startTime, time__lte=endTime).values('fg')
         if not qsTs.exists():
         if not qsTs.exists():
             return HttpResponse('查无数据')
             return HttpResponse('查无数据')
         sumTs = 0  # 总ts个数
         sumTs = 0  # 总ts个数
@@ -1020,22 +779,25 @@ class testView(View):
         storeTime = request_dict.get('time', None)
         storeTime = request_dict.get('time', None)
         now_time = int(time.time())
         now_time = int(time.time())
         try:
         try:
-            vh_qs = VodHlsModel.objects.filter(uid=uid, channel=channel, time=storeTime, endTime__gte=now_time). \
-                values("sec", "fg", "bucket__bucket", "bucket__endpoint", "bucket__region", "bucket__mold")
+            split_vod_hls_obj = SplitVodHlsObject()
+            vh_qs = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel, start_time=storeTime,
+                                                       end_time__gte=now_time).values("sec", "fg", "bucket_id")
             if not vh_qs.exists():
             if not vh_qs.exists():
                 return response.json(173)
                 return response.json(173)
-            fg = vh_qs[0]['fg']
-            bucket__region = vh_qs[0]['bucket__region']
-            bucket_name = vh_qs[0]['bucket__bucket']
-
+            vod_bucket_qs = VodBucketModel.objects.filter(id=vh_qs[0]['bucket_id']).values('bucket', 'region', 'mold')
+            if not vod_bucket_qs.exists():
+                return response.json(173)
+            fg = int(vh_qs[0]['fg'])
+            bucket_region = vod_bucket_qs[0]['region']
+            bucket_name = vod_bucket_qs[0]['bucket']
+            mold = vod_bucket_qs[0]['mold']
             session = Session(
             session = Session(
-                aws_access_key_id=AWS_ACCESS_KEY_ID[vh_qs[0]["bucket__mold"]],
-                aws_secret_access_key=AWS_SECRET_ACCESS_KEY[vh_qs[0]["bucket__mold"]],
-                region_name=bucket__region
+                aws_access_key_id=AWS_ACCESS_KEY_ID[mold],
+                aws_secret_access_key=AWS_SECRET_ACCESS_KEY[mold],
+                region_name=bucket_region
             )
             )
             conn = session.client('s3')
             conn = session.client('s3')
             playlist_entries = []
             playlist_entries = []
-            fg = int(fg)
             # ts_count = fg & 0xf
             # ts_count = fg & 0xf
             # fg 64位整型,低四位代表ts文件总数,然后进行位运算,一次移四位,每四位转为十进制即为当前ts文件的秒数
             # fg 64位整型,低四位代表ts文件总数,然后进行位运算,一次移四位,每四位转为十进制即为当前ts文件的秒数
             for i in range(15):
             for i in range(15):
@@ -1050,7 +812,7 @@ class testView(View):
                             'Bucket': bucket_name,
                             'Bucket': bucket_name,
                             'Key': tsFile
                             'Key': tsFile
                         },
                         },
-                        ExpiresIn=24*60*60
+                        ExpiresIn=24 * 60 * 60
                     )
                     )
                     playlist_entries.append({
                     playlist_entries.append({
                         'name': response_url,
                         'name': response_url,

+ 2 - 2
Controller/UserBrandController.py

@@ -618,7 +618,7 @@ class UserBrandInfo(View):
             check_perm = ModelService.check_perm(userID=userID, permID=30)
             check_perm = ModelService.check_perm(userID=userID, permID=30)
             page_value = []
             page_value = []
             if check_perm is True:
             if check_perm is True:
-                if username is None or username is '':
+                if username is None or username == '':
                     # table_Limit_value = my.get_page_line(page,line,user_brand,None,page_value)
                     # table_Limit_value = my.get_page_line(page,line,user_brand,None,page_value)
                     # # 页面减1
                     # # 页面减1
                     # page = page-1
                     # page = page-1
@@ -689,7 +689,7 @@ class UserBrandInfo(View):
             check_perm = ModelService.check_perm(userID=userID, permID=30)
             check_perm = ModelService.check_perm(userID=userID, permID=30)
             page_value = []
             page_value = []
             if check_perm is True:
             if check_perm is True:
-                if username is None or username is '':
+                if username is None or username == '':
                     return response.json(0, {'datas': {}, 'count': 0})
                     return response.json(0, {'datas': {}, 'count': 0})
                 else:
                 else:
                     # 查询
                     # 查询

+ 23 - 24
Controller/UserController.py

@@ -35,10 +35,10 @@ from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView
 from django.views.generic import TemplateView
 from django.views.generic import View
 from django.views.generic import View
 from jwt.algorithms import RSAAlgorithm
 from jwt.algorithms import RSAAlgorithm
-from ratelimit.decorators import ratelimit
+from ratelimit import limits
 
 
 from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG, TUTK_PUSH_DOMAIN
 from Ansjer.config import AuthCode_Expire, SERVER_DOMAIN, APNS_CONFIG, JPUSH_CONFIG, FCM_CONFIG, TUTK_PUSH_DOMAIN
-from Ansjer.config import BASE_DIR, CONFIG_US, CONFIG_EUR, CONFIG_INFO, SERVER_DOMAIN_EUR, CONFIG_CN
+from Ansjer.config import BASE_DIR, CONFIG_EUR, CONFIG_INFO, SERVER_DOMAIN_EUR
 from Controller.CheckUserData import DataValid, date_handler, RandomStr
 from Controller.CheckUserData import DataValid, date_handler, RandomStr
 from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
 from Model.models import Device_User, Role, UidPushModel, UserOauth2Model, UserExModel, Device_Info, UidSetModel, \
     UserAppFrequencyModel, CountryIPModel, CountryModel, UidChannelSetModel, Order_Model, UID_Bucket, Unused_Uid_Meal, \
     UserAppFrequencyModel, CountryIPModel, CountryModel, UidChannelSetModel, Order_Model, UID_Bucket, Unused_Uid_Meal, \
@@ -62,7 +62,7 @@ class authCodeView(TemplateView):
         # testtest11111111111111
         # testtest11111111111111
         return super(authCodeView, self).dispatch(*args, **kwargs)
         return super(authCodeView, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='2/m')
+    @limits(calls=2, period=60)
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         lang = request.POST.get('language', None)
         lang = request.POST.get('language', None)
@@ -74,7 +74,7 @@ class authCodeView(TemplateView):
         useremail = request.POST.get('userEmail', None)
         useremail = request.POST.get('userEmail', None)
         return self.ValidationError(username, useremail, response)
         return self.ValidationError(username, useremail, response)
 
 
-    # @ratelimit(key='ip', rate='2/m')
+    # @limits(calls=2, period=60)
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
         # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
@@ -320,6 +320,7 @@ class LogoutView(TemplateView):
         Device_User.objects.filter(userID=tko.userID).update(online=False)
         Device_User.objects.filter(userID=tko.userID).update(online=False)
         redisObj = RedisObject(db=3)
         redisObj = RedisObject(db=3)
         redisObj.del_data(key=tko.userID)
         redisObj.del_data(key=tko.userID)
+        Device_Info.objects.filter(userID=tko.userID).update(NotificationMode=0)
         m_code = request_dict.get('m_code', None)
         m_code = request_dict.get('m_code', None)
         if m_code:
         if m_code:
             userID = tko.userID
             userID = tko.userID
@@ -499,7 +500,7 @@ class ForgetPwdView(TemplateView):
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(ForgetPwdView, self).dispatch(*args, **kwargs)
         return super(ForgetPwdView, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='1/m')
+    @limits(calls=2, period=60)
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         response = ResponseObject()
         response = ResponseObject()
@@ -509,7 +510,7 @@ class ForgetPwdView(TemplateView):
         userName = request.GET.get('userName', None)
         userName = request.GET.get('userName', None)
         return self.ValidationError(userName, response)
         return self.ValidationError(userName, response)
 
 
-    @ratelimit(key='ip', rate='1/m')
+    @limits(calls=2, period=60)
     def post(self, request):
     def post(self, request):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         userName = request.POST.get('userName', None)
         userName = request.POST.get('userName', None)
@@ -695,7 +696,7 @@ class refreshTokenViewV3(TemplateView):
             url_list.remove(SERVER_DOMAIN_EUR)
             url_list.remove(SERVER_DOMAIN_EUR)
         if CONFIG_INFO != CONFIG_EUR:
         if CONFIG_INFO != CONFIG_EUR:
             for url in url_list:
             for url in url_list:
-                requests.post(url=url+'v3/account/deleteUser', data=data, timeout=3)
+                requests.post(url=url + 'v3/account/deleteUser', data=data, timeout=3)
 
 
     def validation(self, request_dict):
     def validation(self, request_dict):
         token = request_dict.get('token', None)
         token = request_dict.get('token', None)
@@ -756,7 +757,7 @@ class v2authCodeView(TemplateView):
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(v2authCodeView, self).dispatch(*args, **kwargs)
         return super(v2authCodeView, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='2/m')
+    @limits(calls=2, period=60)
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         lang = request.POST.get('lang', None)
         lang = request.POST.get('lang', None)
@@ -771,7 +772,7 @@ class v2authCodeView(TemplateView):
                 return response.json(5)
                 return response.json(5)
         return self.ValidationError(request_dict, response)
         return self.ValidationError(request_dict, response)
 
 
-    @ratelimit(key='ip', rate='2/m')
+    @limits(calls=2, period=60)
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
         # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
@@ -1330,7 +1331,7 @@ class v2forgetPwdCodeView(TemplateView):
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(v2forgetPwdCodeView, self).dispatch(*args, **kwargs)
         return super(v2forgetPwdCodeView, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='1/m')
+    @limits(calls=2, period=60)
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         request_dict = request.GET
         request_dict = request.GET
@@ -1341,7 +1342,7 @@ class v2forgetPwdCodeView(TemplateView):
             return response.json(5)
             return response.json(5)
         return self.ValidationError(request_dict, response)
         return self.ValidationError(request_dict, response)
 
 
-    @ratelimit(key='ip', rate='1/m')
+    @limits(calls=2, period=60)
     def post(self, request):
     def post(self, request):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         request_dict = request.POST
         request_dict = request.POST
@@ -1525,7 +1526,7 @@ class v2forgetPwdCodeView(TemplateView):
         language_qs = LanguageModel.objects.filter(lang=lang).values('id')
         language_qs = LanguageModel.objects.filter(lang=lang).values('id')
         if not language_qs.exists():
         if not language_qs.exists():
             language_qs = LanguageModel.objects.filter(lang='en').values('id')
             language_qs = LanguageModel.objects.filter(lang='en').values('id')
-        region_qs = CountryLanguageModel.objects.filter(country_id=region_country, language_id=language_qs[0]['id']).\
+        region_qs = CountryLanguageModel.objects.filter(country_id=region_country, language_id=language_qs[0]['id']). \
             values('country_name')
             values('country_name')
         res['region'] = region_qs[0]['country_name'] if region_qs.exists() else ''
         res['region'] = region_qs[0]['country_name'] if region_qs.exists() else ''
 
 
@@ -1840,7 +1841,7 @@ class v2LoginView(TemplateView):
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(v2LoginView, self).dispatch(*args, **kwargs)
         return super(v2LoginView, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='5/m')
+    @limits(calls=2, period=60)
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         request_dict = request.POST
         request_dict = request.POST
@@ -1851,7 +1852,6 @@ class v2LoginView(TemplateView):
             return response.json(5)
             return response.json(5)
         return self.validates(request_dict, response)
         return self.validates(request_dict, response)
 
 
-    # @ratelimit(key='ip', rate='5/m')
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         print("进来了")
         print("进来了")
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
@@ -1940,7 +1940,7 @@ class noPasslogin(TemplateView):
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(noPasslogin, self).dispatch(*args, **kwargs)
         return super(noPasslogin, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='5/m')
+    @limits(calls=2, period=60)
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         request_dict = request.POST
         request_dict = request.POST
@@ -1951,7 +1951,6 @@ class noPasslogin(TemplateView):
             return response.json(5)
             return response.json(5)
         return self.validates(request_dict, response)
         return self.validates(request_dict, response)
 
 
-    # @ratelimit(key='ip', rate='5/m')
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         print("进来了")
         print("进来了")
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
@@ -2031,7 +2030,7 @@ class v3LoginView(TemplateView):
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(v3LoginView, self).dispatch(*args, **kwargs)
         return super(v3LoginView, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='5/m')
+    @limits(calls=2, period=60)
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         request_dict = request.POST
         request_dict = request.POST
@@ -2162,13 +2161,13 @@ class v3LoginView(TemplateView):
         else:
         else:
             # 判断所选地区和用户注册地区是否一致
             # 判断所选地区和用户注册地区是否一致
             number = int(number)
             number = int(number)
-            if number != region_country and region_country != 0:    # 不一致
+            if number != region_country and region_country != 0:  # 不一致
                 res['status'] = 1
                 res['status'] = 1
                 user_qs.update(last_login=now_time, language=response.lang)
                 user_qs.update(last_login=now_time, language=response.lang)
-            else:   # 一致
+            else:  # 一致
                 res['status'] = 0
                 res['status'] = 0
                 user_qs.update(last_login=now_time, language=response.lang, region_country=number)
                 user_qs.update(last_login=now_time, language=response.lang, region_country=number)
-        region_qs = CountryLanguageModel.objects.filter(country_id=region_country, language_id=language_qs[0]['id']).\
+        region_qs = CountryLanguageModel.objects.filter(country_id=region_country, language_id=language_qs[0]['id']). \
             values('country_name')
             values('country_name')
 
 
         res['rid'] = users['role__rid']
         res['rid'] = users['role__rid']
@@ -2760,7 +2759,7 @@ class OauthAuthCodeView(TemplateView):
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(OauthAuthCodeView, self).dispatch(*args, **kwargs)
         return super(OauthAuthCodeView, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='2/m')
+    @limits(calls=2, period=60)
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         lang = request.POST.get('lang', None)
         lang = request.POST.get('lang', None)
@@ -2775,7 +2774,7 @@ class OauthAuthCodeView(TemplateView):
                 return response.json(5)
                 return response.json(5)
         return self.ValidationError(request_dict, response)
         return self.ValidationError(request_dict, response)
 
 
-    @ratelimit(key='ip', rate='2/m')
+    @limits(calls=2, period=60)
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
         # Device_User.objects.filter(userEmail='chanjunkai@163.com').delete()
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
@@ -3647,7 +3646,7 @@ class loginCodeView(View):
     def dispatch(self, *args, **kwargs):
     def dispatch(self, *args, **kwargs):
         return super(loginCodeView, self).dispatch(*args, **kwargs)
         return super(loginCodeView, self).dispatch(*args, **kwargs)
 
 
-    @ratelimit(key='ip', rate='2/m')
+    @limits(calls=2, period=60)
     def post(self, request, *args, **kwargs):
     def post(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         lang = request.POST.get('lang', None)
         lang = request.POST.get('lang', None)
@@ -3662,7 +3661,7 @@ class loginCodeView(View):
                 return response.json(5)
                 return response.json(5)
         return self.validate(request_dict, response)
         return self.validate(request_dict, response)
 
 
-    @ratelimit(key='ip', rate='2/m')
+    @limits(calls=2, period=60)
     def get(self, request, *args, **kwargs):
     def get(self, request, *args, **kwargs):
         request.encoding = 'utf-8'
         request.encoding = 'utf-8'
         lang = request.GET.get('lang', None)
         lang = request.GET.get('lang', None)

+ 195 - 0
Controller/UserDevice/UserDeviceShareController.py

@@ -0,0 +1,195 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : UserDeviceShareController.py
+@Time    : 2023/1/7 15:05
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+import logging
+import time
+
+from django.db import transaction
+from django.db.models import Q
+from django.views import View
+
+from Model.models import DeviceSharePermission, DeviceChannelUserSet, DeviceChannelUserPermission, UidChannelSetModel, \
+    Device_Info
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+from Service.UserDeviceService import UserDeviceService
+
+LOGGER = logging.getLogger('info')
+
+
+class UserDeviceShareView(View):
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
+        lang = request_dict.get('lang', token.lang)
+        response = ResponseObject(lang)
+        if token.code != 0:
+            return response.json(token.code)
+        if operation == 'user-permissions':
+            return self.get_user_share_permission(request_dict, response)
+        elif operation == 'permissions-save':
+            return self.user_channel_permission_save(request_dict, response)
+        elif operation == 'permissions-test':
+            return self.synch_share_device_permission(response)
+        else:
+            return response.json(404)
+
+    @classmethod
+    def get_user_share_permission(cls, request_dict, response):
+        """
+        获取用户分享权限
+        @param request_dict: 设备uid
+        @param response: 响应对象
+        @return: permission List
+        """
+        try:
+            uid = request_dict.get('uid', None)
+            user_id = request_dict.get('userId', None)
+            channel_count = request_dict.get('channelCount', None)
+            if not all([user_id, uid, channel_count]):
+                return response(444, 'uid, userId and channelCount is required')
+            user_permission_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid) \
+                .values('id', 'channels')
+            if not user_permission_qs.exists():
+                return response.json(0, {})
+            up_id = user_permission_qs[0]['id']
+            channel_permission_qs = DeviceChannelUserPermission.objects.filter(channel_user_id=up_id) \
+                .values('permission_id', 'channel_user_id')
+            if not channel_permission_qs.exists():
+                return response.json(0, {})
+            channel_list = list(range(1, int(channel_count) + 1))
+            share_channel_list = user_permission_qs[0]['channels'].split(',')
+            c_list = []
+            for channel in channel_list:
+                is_select = 1 if str(channel) in share_channel_list else 0
+                c_list.append({'channelIndex': channel, 'isSelect': is_select})
+            p_list = []
+            permission_qs = DeviceSharePermission.objects.all()
+            share_permission_list = [item['permission_id'] for item in channel_permission_qs]
+            for item in permission_qs:
+                is_select = 1 if item.id in share_permission_list else 0
+                p_list.append({'permissionId': item.id, 'code': item.code, 'isSelect': is_select})
+            data = {'channels': c_list, 'permissions': p_list}
+            return response.json(0, data)
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, repr(e))
+
+    @classmethod
+    def user_channel_permission_save(cls, request_dict, response):
+        """
+        主用户分享设备时设置通道权限保存
+        """
+        try:
+            uid = request_dict.get('uid', None)
+            channels = request_dict.get('channels', None)  # 通道集合,多个','隔开
+            user_id = request_dict.get('userId', None)
+            permission_ids = request_dict.get('permissionIds', None)  # 权限集合,多个','隔开
+            if not all([user_id, uid, channels, permission_ids]):
+                return response.json(444)
+            p_ids = []
+            device_user_set = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
+            now_time = int(time.time())
+            with transaction.atomic():
+                is_delete = False
+                if not device_user_set.exists():
+                    device_set = {'uid': uid, 'user_id': user_id, 'channels': channels,
+                                  'created_time': now_time, 'updated_time': now_time}
+                    device_user_set = DeviceChannelUserSet.objects.create(**device_set)
+                    channel_user_id = device_user_set.id
+                else:
+                    DeviceChannelUserSet.objects.update(channels=channels, updated_time=now_time)
+                    channel_user_id = device_user_set.first().id
+                    is_delete = True
+                if ',' in permission_ids:
+                    p_ids = [int(val) for val in permission_ids.split(',')]
+                if is_delete:
+                    DeviceChannelUserPermission.objects.filter(
+                        channel_user_id=channel_user_id).delete()
+                if not p_ids:
+                    channel_permission = {'permission_id': int(permission_ids),
+                                          'channel_user_id': channel_user_id,
+                                          'created_time': now_time}
+                    DeviceChannelUserPermission.objects.create(**channel_permission)
+                else:
+                    channel_permission_list = []
+                    for item in p_ids:
+                        channel_permission_list.append(DeviceChannelUserPermission(
+                            permission_id=int(item),
+                            channel_user_id=channel_user_id,
+                            created_time=now_time))
+                    DeviceChannelUserPermission.objects.bulk_create(channel_permission_list)
+                return response.json(0)
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def qrcode_share_channel_permission_save(user_id, uid):
+        """
+        二维码分享保存通道权限
+        @param user_id: 用户id
+        @param uid: 用户设备ID
+        @return: True | False
+        """
+        try:
+            if not all([user_id, uid]):
+                return False
+            with transaction.atomic():
+                ds_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid)
+                if ds_qs.exists():
+                    return True
+                UserDeviceService.update_device_channel(uid)
+                channel_qs = UidChannelSetModel.objects.filter(uid__uid=uid).values('channel')
+                if not channel_qs.exists():
+                    return False
+                channel_list = [str(val['channel']) for val in channel_qs]
+                channel_str = ','.join(channel_list)
+                now_time = int(time.time())
+                device_set = {'uid': uid, 'user_id': user_id, 'channels': channel_str,
+                              'created_time': now_time, 'updated_time': now_time}
+                device_user_set = DeviceChannelUserSet.objects.create(**device_set)
+                channel_permission_qs = DeviceSharePermission.objects \
+                    .all().values('id', 'code').order_by('sort')
+                user_set_id = device_user_set.id
+                channel_permission_list = []
+                for item in channel_permission_qs:
+                    channel_permission_list.append(DeviceChannelUserPermission(
+                        permission_id=item['id'],
+                        channel_user_id=user_set_id,
+                        created_time=now_time))
+                DeviceChannelUserPermission.objects.bulk_create(channel_permission_list)
+            return True
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False
+
+    @staticmethod
+    def synch_share_device_permission(response):
+        """
+        同步分析设备权限
+        @param response: 响应结果
+        """
+        device_info_qs = Device_Info.objects \
+            .filter(~Q(Type__in=[1, 2, 3, 4, 10001]), ~Q(primaryUserID=''), isShare=1) \
+            .values('userID_id', 'UID').order_by('-data_joined')
+        if not device_info_qs.exists():
+            return response.json(0)
+        for item in device_info_qs:
+            UserDeviceShareView.qrcode_share_channel_permission_save(item['userID_id'], item['UID'])
+        return response.json(0)

+ 2 - 1
Controller/UserExController.py

@@ -21,8 +21,9 @@ from django.views.generic.base import View
 import datetime, simplejson as json
 import datetime, simplejson as json
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
 from Model.models import Device_Info, Role, UserExModel, Device_User
 from Model.models import Device_Info, Role, UserExModel, Device_User
+from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
-from Object.TokenObject import TokenObject, RedisObject
+from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
 from Service.ModelService import ModelService
 class UserExView(View):
 class UserExView(View):

+ 1 - 1
Controller/shareUserPermission.py

@@ -80,7 +80,7 @@ class searchUserView(View):
             sqlDict = dict(zip(["datas"], [sqlList]))
             sqlDict = dict(zip(["datas"], [sqlList]))
             return response.json(0, sqlDict)
             return response.json(0, sqlDict)
         else:
         else:
-            return response.json(102)
+            return response.json(104)
 
 
     def searchUserPCSQL(self, fieldDict, response):
     def searchUserPCSQL(self, fieldDict, response):
         try:
         try:

+ 227 - 10
Model/models.py

@@ -2,7 +2,6 @@ from itertools import chain
 
 
 from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
 from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
 from django.db import models
 from django.db import models
-from django.utils import six
 from django.utils import timezone
 from django.utils import timezone
 from imagekit.models import ProcessedImageField
 from imagekit.models import ProcessedImageField
 from imagekit.processors import ResizeToFill
 from imagekit.processors import ResizeToFill
@@ -63,10 +62,6 @@ class Permissions(models.Model):
     description = models.CharField(blank=True, null=True, max_length=128, verbose_name=u'描述信息', default='')
     description = models.CharField(blank=True, null=True, max_length=128, verbose_name=u'描述信息', default='')
     objects = PermissionsManager()
     objects = PermissionsManager()
 
 
-    def __str__(self):
-        return "%s" % (
-            six.text_type(self.description))
-
     class Meta:
     class Meta:
         ordering = ['permName']
         ordering = ['permName']
         db_table = 'permissions'
         db_table = 'permissions'
@@ -207,8 +202,6 @@ class Device_User(AbstractBaseUser):
 
 
     def get_all_permission(self):
     def get_all_permission(self):
         roles = self.role.all()
         roles = self.role.all()
-        perms = self.permission.all()
-
         permslist = []
         permslist = []
         for role in roles:
         for role in roles:
             if role.rid == 100:
             if role.rid == 100:
@@ -217,9 +210,6 @@ class Device_User(AbstractBaseUser):
                     permslist.append(perm.permName)
                     permslist.append(perm.permName)
                 return permslist
                 return permslist
 
 
-        for perm in perms:
-            permslist.append(perm.permName)
-
         permSet = set(permslist)
         permSet = set(permslist)
         for role in roles:
         for role in roles:
             permlist_tmp = []
             permlist_tmp = []
@@ -847,6 +837,15 @@ class Equipment_Version(models.Model):
         db_table = 'equipment_version'
         db_table = 'equipment_version'
 
 
 
 
+class AVSSVersion(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    online_version = models.CharField(default='', max_length=32, verbose_name='线上版本')
+
+    class Meta:
+        verbose_name = 'AVSS版本'
+        db_table = 'avss_version'
+
+
 class App_Info(models.Model):
 class App_Info(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记ID')
     appBundleId = models.CharField(blank=True, max_length=32, verbose_name=u'appID')
     appBundleId = models.CharField(blank=True, max_length=32, verbose_name=u'appID')
@@ -1073,6 +1072,139 @@ class VodHlsModel(models.Model):
         ordering = ('-id',)
         ordering = ('-id',)
 
 
 
 
+class VodHlsMon(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    uid = models.CharField(max_length=20, db_index=True, verbose_name='uid')
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    start_time = models.IntegerField(default=0, db_index=True, verbose_name='开始时间')
+    end_time = models.IntegerField(default=0, db_index=True, verbose_name='结束时间')
+    sec = models.IntegerField(default=0, verbose_name='秒数')
+    bucket_id = models.SmallIntegerField(default=1, blank=True, verbose_name='关联vod_bucket表id')
+    fg = models.CharField(max_length=20, verbose_name='ts文件信息数据')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'vod_hls_mon'
+        verbose_name = '星期一云存回放信息表'
+        ordering = ('-id',)
+
+
+class VodHlsTues(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    uid = models.CharField(max_length=20, db_index=True, verbose_name='uid')
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    start_time = models.IntegerField(default=0, db_index=True, verbose_name='开始时间')
+    end_time = models.IntegerField(default=0, db_index=True, verbose_name='结束时间')
+    sec = models.IntegerField(default=0, verbose_name='秒数')
+    bucket_id = models.SmallIntegerField(default=1, blank=True, verbose_name='关联vod_bucket表id')
+    fg = models.CharField(max_length=20, verbose_name='ts文件信息数据')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'vod_hls_tues'
+        verbose_name = '星期二云存回放信息表'
+        ordering = ('-id',)
+
+
+class VodHlsWed(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    uid = models.CharField(max_length=20, db_index=True, verbose_name='uid')
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    start_time = models.IntegerField(default=0, db_index=True, verbose_name='开始时间')
+    end_time = models.IntegerField(default=0, db_index=True, verbose_name='结束时间')
+    sec = models.IntegerField(default=0, verbose_name='秒数')
+    bucket_id = models.SmallIntegerField(default=1, blank=True, verbose_name='关联vod_bucket表id')
+    fg = models.CharField(max_length=20, verbose_name='ts文件信息数据')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'vod_hls_wed'
+        verbose_name = '星期三云存回放信息表'
+        ordering = ('-id',)
+
+
+class VodHlsThur(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    uid = models.CharField(max_length=20, db_index=True, verbose_name='uid')
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    start_time = models.IntegerField(default=0, db_index=True, verbose_name='开始时间')
+    end_time = models.IntegerField(default=0, db_index=True, verbose_name='结束时间')
+    sec = models.IntegerField(default=0, verbose_name='秒数')
+    bucket_id = models.SmallIntegerField(default=1, blank=True, verbose_name='关联vod_bucket表id')
+    fg = models.CharField(max_length=20, verbose_name='ts文件信息数据')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'vod_hls_thur'
+        verbose_name = '星期四云存回放信息表'
+        ordering = ('-id',)
+
+
+class VodHlsFri(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    uid = models.CharField(max_length=20, db_index=True, verbose_name='uid')
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    start_time = models.IntegerField(default=0, db_index=True, verbose_name='开始时间')
+    end_time = models.IntegerField(default=0, db_index=True, verbose_name='结束时间')
+    sec = models.IntegerField(default=0, verbose_name='秒数')
+    bucket_id = models.SmallIntegerField(default=1, blank=True, verbose_name='关联vod_bucket表id')
+    fg = models.CharField(max_length=20, verbose_name='ts文件信息数据')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'vod_hls_fri'
+        verbose_name = '星期五云存回放信息表'
+        ordering = ('-id',)
+
+
+class VodHlsSat(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    uid = models.CharField(max_length=20, db_index=True, verbose_name='uid')
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    start_time = models.IntegerField(default=0, db_index=True, verbose_name='开始时间')
+    end_time = models.IntegerField(default=0, db_index=True, verbose_name='结束时间')
+    sec = models.IntegerField(default=0, verbose_name='秒数')
+    bucket_id = models.SmallIntegerField(default=1, blank=True, verbose_name='关联vod_bucket表id')
+    fg = models.CharField(max_length=20, verbose_name='ts文件信息数据')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'vod_hls_sat'
+        verbose_name = '星期六云存回放信息表'
+        ordering = ('-id',)
+
+
+class VodHlsSun(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='主键')
+    uid = models.CharField(max_length=20, db_index=True, verbose_name='uid')
+    channel = models.SmallIntegerField(default=0, verbose_name='通道')
+    start_time = models.IntegerField(default=0, db_index=True, verbose_name='开始时间')
+    end_time = models.IntegerField(default=0, db_index=True, verbose_name='结束时间')
+    sec = models.IntegerField(default=0, verbose_name='秒数')
+    bucket_id = models.SmallIntegerField(default=1, blank=True, verbose_name='关联vod_bucket表id')
+    fg = models.CharField(max_length=20, verbose_name='ts文件信息数据')
+
+    def __str__(self):
+        return self.id
+
+    class Meta:
+        db_table = 'vod_hls_sun'
+        verbose_name = '星期天云存回放信息表'
+        ordering = ('-id',)
+
+
 class OssCrdModel(models.Model):
 class OssCrdModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='主键')
     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')
@@ -3116,3 +3248,88 @@ class UidCloudStorageCount(models.Model):
         db_table = 'uid_cloud_storage_count'
         db_table = 'uid_cloud_storage_count'
         verbose_name = '云存储uid日上传次数统计'
         verbose_name = '云存储uid日上传次数统计'
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name
+
+
+class DeviceChannelUserSet(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    uid = models.CharField(blank=True, db_index=True, max_length=32, verbose_name=u'设备UID')
+    channels = models.CharField(default='', blank=True, max_length=128, verbose_name=u'用户通道多个逗号隔开')
+    user_id = models.CharField(default='', db_index=True, max_length=32, verbose_name=u'用户id')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'device_channel_user_set'
+        verbose_name = '设备通道用户设置'
+        verbose_name_plural = verbose_name
+
+
+class DeviceSharePermission(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    code = models.CharField(blank=True, db_index=True, max_length=32, verbose_name=u'权限编码')
+    sort = models.IntegerField(default=99, blank=True, verbose_name=u'排序,越小越靠前')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'device_share_permission'
+        verbose_name = '设备分享权限'
+        verbose_name_plural = verbose_name
+
+
+class DevicePermissionLang(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    permission_id = models.IntegerField(default=0, verbose_name=u'关联设备权限ID')
+    name = models.CharField(default='', max_length=50, verbose_name=u'权限名称')
+    desc = models.CharField(blank=True, max_length=64, default='', verbose_name=u'描述')
+    lang = models.CharField(default='', max_length=20, db_index=True, verbose_name='例如:cn')
+    sort = models.IntegerField(default=99, blank=True, verbose_name=u'排序,越小越靠前')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 'device_permission_lang'
+        verbose_name = '设备分享权限语言描述'
+        verbose_name_plural = verbose_name
+
+
+class DeviceChannelUserPermission(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    permission_id = models.IntegerField(default=0, verbose_name=u'关联设备权限ID')
+    channel_user_id = models.IntegerField(default=0, verbose_name=u'通道用户id')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 'device_channel_user_permission'
+        verbose_name = '设备分享权限关联通道用户'
+        verbose_name_plural = verbose_name
+
+
+class DeviceTypeSharePermission(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    permission_id = models.IntegerField(default=0, verbose_name=u'关联设备权限ID')
+    type = models.SmallIntegerField(default=0, verbose_name='设备类型')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 'device_type_share_permission'
+        verbose_name = '设备类型关联分享权限'
+        verbose_name_plural = verbose_name
+
+
+class DeviceSuperPassword(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    uid = models.CharField(blank=True, db_index=True, max_length=32, verbose_name=u'设备UID')
+    userID = models.ForeignKey(Device_User, blank=True, to_field='userID', on_delete=models.CASCADE)
+    orderID = models.CharField(max_length=30, db_index=True, verbose_name='订单ID', blank=True, default='')
+    describe = models.CharField(max_length=128, blank=True, verbose_name='需求描述', default=0)
+    purchase_channel = models.CharField(max_length=128, blank=True, verbose_name='购买渠道描述', default='')
+    addTime = models.IntegerField(default=0, verbose_name='添加时间')
+    status = models.SmallIntegerField(default=0, verbose_name='0:未通过,1:通过')
+    buyTime = models.IntegerField(default=0, verbose_name='购买时间')
+    hint = models.CharField(max_length=128, blank=True, verbose_name='温馨提示', default='')
+
+    class Meta:
+        db_table = 'device_super_password'
+        verbose_name = '超级密码请求表'
+        verbose_name_plural = verbose_name

+ 34 - 0
Object/AWS/AmazonKVSUtil.py

@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+"""
+@Author : Rocky
+@Time : 2022/10/17 16:57
+@File :AmazonKVSUtil.py
+"""
+import boto3
+
+
+class AmazonKVSObject:
+    def __init__(self, aws_access_key_id, secret_access_key, region_name):
+        self.access_id = aws_access_key_id
+        self.access_secret = secret_access_key
+        self.region_name = region_name
+        self.client_conn = boto3.client(
+            'kinesis-video-media',
+            aws_access_key_id=aws_access_key_id,
+            aws_secret_access_key=secret_access_key,
+            region_name=region_name
+        )
+
+    def get_media(self, stream_name):
+        """
+        获取视频流数据保留时间
+        @param stream_name: 视频流名称
+        @param shard_count: 碎片数量
+        @return : boolean
+        """
+        try:
+            self.client_conn.get_media(StreamName=stream_name)
+            return True
+        except Exception as e:
+            print(e)
+            return False

+ 187 - 0
Object/AWS/AmazonKinesisVideoUtil.py

@@ -0,0 +1,187 @@
+# -*- coding: utf-8 -*-
+"""
+@Author : Rocky
+@Time : 2022/10/18 17:13
+@File :AmazonKinesisVideoUtil.py
+"""
+import datetime
+
+import boto3
+
+
+class AmazonKinesisVideoObject:
+    """
+    Amazon Kinesis Video Streams对象
+    api文档链接: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kinesisvideo.html
+    """
+
+    def __init__(self, aws_access_key_id, secret_access_key, region_name):
+        self.access_id = aws_access_key_id
+        self.access_secret = secret_access_key
+        self.region_name = region_name
+        self.client_conn = boto3.client(
+            'kinesisvideo',
+            aws_access_key_id=aws_access_key_id,
+            aws_secret_access_key=secret_access_key,
+            region_name=region_name
+        )
+
+    def create_stream(self, stream_name):
+        """
+        创建视频流
+        @param stream_name: 视频流名称
+        @return : stream_arn or False
+        """
+        tags = {'project_kvs': 'kvs'}
+        try:
+            stream_arn = self.client_conn.create_stream(StreamName=stream_name, Tags=tags)['StreamARN']
+            return stream_arn
+        except Exception as e:
+            print(e)
+            return False
+
+    def update_data_retention(self, stream_name, operation, data_retention_change_in_hours):
+        """
+        修改视频流数据保留时间
+        @param stream_name: 视频流名称
+        @param operation: 增加/减少, 'INCREASE_DATA_RETENTION'|'DECREASE_DATA_RETENTION'
+        @param data_retention_change_in_hours: 修改的时间
+        @return : True or False
+        """
+        try:
+            version = self.describe_stream(stream_name)['Version']
+            self.client_conn.update_data_retention(StreamName=stream_name, Operation=operation, CurrentVersion=version,
+                                                   DataRetentionChangeInHours=data_retention_change_in_hours)
+            return True
+        except Exception as e:
+            print(e)
+            return False
+
+    def describe_stream(self, stream_name):
+        """
+        获取视频流信息数据
+        @param stream_name: 视频流名称
+        @return stream_info: 视频流信息数据
+        """
+        return self.client_conn.describe_stream(StreamName=stream_name)['StreamInfo']
+
+    def get_data_endpoint(self, stream_name, api_name):
+        """
+        获取指定流的终端节点以读取或写入
+        @param api_name: API名称
+        @param stream_name: 视频流名称
+        @return stream_info: 视频流信息数据
+        """
+        return self.client_conn.get_data_endpoint(StreamName=stream_name, APIName=api_name)['DataEndpoint']
+
+
+class AmazonKVAMObject:
+    def __init__(self, aws_access_key_id, secret_access_key, region_name, stream_name, api_name):
+        self.access_id = aws_access_key_id
+        self.access_secret = secret_access_key
+        self.region_name = region_name
+        self.kv_client_conn = AmazonKinesisVideoObject(aws_access_key_id, secret_access_key, region_name)
+        self.endpoint = self.kv_client_conn.get_data_endpoint(stream_name, api_name)
+        self.kvam_client_coon = boto3.client(
+            'kinesis-video-archived-media',
+            endpoint_url=self.endpoint,
+            aws_access_key_id=aws_access_key_id,
+            aws_secret_access_key=secret_access_key,
+            region_name=region_name
+        )
+
+    def get_hls_streaming_session_url(self, stream_name, start_time, end_time, play_mode):
+        """
+        获取视频流数据保留时间
+        @param stream_name: 视频流名称
+        @param start_time: 开始时间
+        @param end_time: 结束时间
+        @param play_mode: 播放模式
+        @return HLSStreamingSessionURL: 媒体播放器可用于检索HLS主播放列表的URL
+        """
+        return self.kvam_client_coon.get_hls_streaming_session_url(StreamName=stream_name,
+                                                                   PlaybackMode=play_mode,
+                                                                   HLSFragmentSelector={
+                                                                       'FragmentSelectorType': 'PRODUCER_TIMESTAMP',
+                                                                       'TimestampRange': {
+                                                                           'StartTimestamp': start_time,
+                                                                           'EndTimestamp': end_time
+                                                                       }
+                                                                   },
+                                                                   ContainerFormat='FRAGMENTED_MP4',
+                                                                   DiscontinuityMode='ON_DISCONTINUITY',
+                                                                   DisplayFragmentTimestamp='ALWAYS',
+                                                                   Expires=43200,
+                                                                   MaxMediaPlaylistFragmentResults=5000)[
+            'HLSStreamingSessionURL']
+
+    def get_list_fragments(self, stream_name, start_time, end_time):
+        """
+        获取视频流片段
+        @param stream_name: 视频流名称
+        @param start_time: 开始时间
+        @param end_time: 结束时间
+        @return HLSStreamingSessionURL: 视频流片段列表信息
+        """
+        stream_list = []
+        result = self.kvam_client_coon.list_fragments(StreamName=stream_name, FragmentSelector={
+            'FragmentSelectorType': 'PRODUCER_TIMESTAMP',
+            'TimestampRange': {
+                'StartTimestamp': start_time,
+                'EndTimestamp': end_time
+            }}, MaxResults=1000)
+        fragments_list = result['Fragments']
+        while 'NextToken' in result:
+            result = self.kvam_client_coon.list_fragments(StreamName=stream_name, NextToken=result['NextToken'])
+            fragments_list.extend(result['Fragments'])
+        fragments_list = sorted(fragments_list, key=lambda item: item['FragmentNumber'])
+        for item in fragments_list:
+            stream_list.append({'startTime': item['ProducerTimestamp'],
+                                'endTime': item['ProducerTimestamp'] + datetime.timedelta(
+                                    milliseconds=item['FragmentLengthInMilliseconds']),
+                                'duration': item['FragmentLengthInMilliseconds']})
+        return stream_list
+
+    def get_images(self, stream_name, start_time, end_time):
+        """
+        获取视频流片段封面图片
+        @param stream_name: 视频流名称
+        @param start_time: 开始时间
+        @param end_time: 结束时间
+        @return HLSStreamingSessionURL: 视频流片段列表信息
+        """
+        try:
+            images_list = self.kvam_client_coon.get_images(StreamName=stream_name,
+                                                           ImageSelectorType='PRODUCER_TIMESTAMP',
+                                                           StartTimestamp=start_time,
+                                                           EndTimestamp=end_time,
+                                                           SamplingInterval=3000,
+                                                           MaxResults=100,
+                                                           Format='JPEG')['Images']
+            for image in images_list:
+                if 'ImageContent' in image:
+                    return image['ImageContent']
+        except Exception as e:
+            return ''
+
+    def get_clip(self, stream_name, start_time, end_time):
+        """
+        获取视频流片段封面图片
+        @param stream_name: 视频流名称
+        @param start_time: 开始时间
+        @param end_time: 结束时间
+        @return HLSStreamingSessionURL: 视频流片段列表信息
+        """
+        try:
+            clip = self.kvam_client_coon.get_clip(StreamName=stream_name,
+                                                  ClipFragmentSelector={
+                                                      'FragmentSelectorType': 'PRODUCER_TIMESTAMP',
+                                                      'TimestampRange': {
+                                                          'StartTimestamp': start_time,
+                                                          'EndTimestamp': end_time
+                                                      }
+                                                  })
+
+            return clip['Payload'], clip['ResponseMetadata']['HTTPHeaders']['content-length']
+        except Exception as e:
+            return ''

+ 15 - 2
Object/AWS/AmazonS3Util.py

@@ -72,8 +72,7 @@ class AmazonS3Util:
             Params={
             Params={
                 'Bucket': bucket,
                 'Bucket': bucket,
                 'Key': file_key
                 'Key': file_key
-            },
-            ExpiresIn=3600
+            }
         )
         )
         return response_url
         return response_url
 
 
@@ -124,6 +123,20 @@ class AmazonS3Util:
         except self.client_conn.exceptions.NoSuchKey:
         except self.client_conn.exceptions.NoSuchKey:
             return False
             return False
 
 
+    def download_object(self, bucket, key, file_name):
+        """
+        下载对象至本地
+        @param file_name: 保存位置以及名称
+        @param bucket: 存储桶
+        @param key: 文件
+        @return : boolean
+        """
+        try:
+            self.client_conn.download_file(bucket, key, file_name)
+            return True
+        except Exception as e:
+            return e.args
+
     def copy_obj(self, source_bucket, to_bucket, file_key):
     def copy_obj(self, source_bucket, to_bucket, file_key):
         """
         """
         复制对象
         复制对象

+ 8 - 0
Object/RedisObject.py

@@ -98,3 +98,11 @@ class RedisObject:
             return keys
             return keys
         else:
         else:
             return False
             return False
+
+    def set_ex_data(self, key, val, expire=0):
+        try:
+            self.CONN.setex(name=key, time=expire, value=val)
+        except Exception as e:
+            return False
+        else:
+            return True

+ 15 - 38
Object/TokenObject.py

@@ -1,20 +1,7 @@
-#!/usr/bin/env python3  
-# -*- coding: utf-8 -*-  
-"""
-@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
-@AUTHOR: ASJRD018
-@NAME: AnsjerOA
-@software: PyCharm
-@DATE: 2018/8/13 15:36
-@Version: python3.6
-@MODIFY DECORD:ansjer dev
-@file: TokenObject.py
-@Contact: chanjunkai@163.com
-"""
+import jwt
+import time
 from Ansjer.config import OAUTH_ACCESS_TOKEN_SECRET, OAUTH_REFRESH_TOKEN_SECRET, OAUTH_ACCESS_TOKEN_TIME, \
 from Ansjer.config import OAUTH_ACCESS_TOKEN_SECRET, OAUTH_REFRESH_TOKEN_SECRET, OAUTH_ACCESS_TOKEN_TIME, \
     OAUTH_REFRESH_TOKEN_TIME
     OAUTH_REFRESH_TOKEN_TIME
-import jwt, time
-from Object.RedisObject import RedisObject
 
 
 
 
 class TokenObject:
 class TokenObject:
@@ -29,7 +16,6 @@ class TokenObject:
         self.userID = None
         self.userID = None
         self.user = ''
         self.user = ''
         self.code = 0
         self.code = 0
-        # 令牌校验
         self.valid()
         self.valid()
         self.returntpye = returntpye
         self.returntpye = returntpye
 
 
@@ -38,10 +24,9 @@ class TokenObject:
             self.code = 309
             self.code = 309
             return
             return
         try:
         try:
-            self.token= self.token.replace("Bearer ", "")
+            self.token = self.token.replace("Bearer ", "")
 
 
             res = jwt.decode(self.token, OAUTH_ACCESS_TOKEN_SECRET, algorithms='HS256')
             res = jwt.decode(self.token, OAUTH_ACCESS_TOKEN_SECRET, algorithms='HS256')
-            # print(res)
             self.userID = res.get('userID', None)
             self.userID = res.get('userID', None)
             self.lang = res.get('lang', None)
             self.lang = res.get('lang', None)
             self.user = res.get('user', '')
             self.user = res.get('user', '')
@@ -52,8 +37,6 @@ class TokenObject:
             #     redisObj.set_data(key=self.userID, val=self.user, expire=300)
             #     redisObj.set_data(key=self.userID, val=self.user, expire=300)
 
 
         except jwt.ExpiredSignatureError as e:
         except jwt.ExpiredSignatureError as e:
-            print('过期')
-            print(repr(e))
             self.code = 309
             self.code = 309
             return
             return
         except Exception as e:
         except Exception as e:
@@ -70,8 +53,10 @@ class TokenObject:
                 else:
                 else:
                     self.code = 309
                     self.code = 309
                     return
                     return
-    # token加密
-    def generate(self, data={}):
+
+    def generate(self, data=None):
+        if data is None:
+            data = {}
         try:
         try:
             access_expire = int(OAUTH_ACCESS_TOKEN_TIME.total_seconds())
             access_expire = int(OAUTH_ACCESS_TOKEN_TIME.total_seconds())
             refresh_expire = int(OAUTH_REFRESH_TOKEN_TIME.total_seconds())
             refresh_expire = int(OAUTH_REFRESH_TOKEN_TIME.total_seconds())
@@ -89,18 +74,18 @@ class TokenObject:
                 algorithm='HS256')
                 algorithm='HS256')
 
 
             res = {
             res = {
-                'access_token': access_token.decode('utf-8'),
+                'access_token': access_token,
                 'access_expire': access_expire,
                 'access_expire': access_expire,
                 'refresh_expire': refresh_expire,
                 'refresh_expire': refresh_expire,
-                'refresh_token': refresh_token.decode('utf-8'),
+                'refresh_token': refresh_token,
             }
             }
 
 
             if self.returntpye=='pc':
             if self.returntpye=='pc':
                 res = {
                 res = {
-                    'token': access_token.decode('utf-8'),
+                    'token': access_token,
                     'access_expire': access_expire,
                     'access_expire': access_expire,
                     'refresh_expire': refresh_expire,
                     'refresh_expire': refresh_expire,
-                    'refresh_token': refresh_token.decode('utf-8'),
+                    'refresh_token': refresh_token,
                 }
                 }
 
 
         except Exception as e:
         except Exception as e:
@@ -110,7 +95,9 @@ class TokenObject:
             self.code = 0
             self.code = 0
             return res
             return res
 
 
-    def encryption(self, data={}):
+    def encryption(self, data=None):
+        if data is None:
+            data = {}
         try:
         try:
             access_expire = int(OAUTH_ACCESS_TOKEN_TIME.total_seconds())
             access_expire = int(OAUTH_ACCESS_TOKEN_TIME.total_seconds())
             refresh_expire = int(OAUTH_REFRESH_TOKEN_TIME.total_seconds())
             refresh_expire = int(OAUTH_REFRESH_TOKEN_TIME.total_seconds())
@@ -122,13 +109,10 @@ class TokenObject:
             access_token = jwt.encode(access_data,
             access_token = jwt.encode(access_data,
                                       OAUTH_ACCESS_TOKEN_SECRET,
                                       OAUTH_ACCESS_TOKEN_SECRET,
                                       algorithm='HS256')
                                       algorithm='HS256')
-            return access_token.decode('utf-8')
+            return access_token
         except Exception as e:
         except Exception as e:
             self.code = 309
             self.code = 309
             print(repr(e))
             print(repr(e))
-        else:
-            self.code = 0
-            return res
 
 
     def refresh(self):
     def refresh(self):
         if not self.token:
         if not self.token:
@@ -152,10 +136,3 @@ class TokenObject:
             self.user = user
             self.user = user
             refreshRes = self.generate(data={'userID': userID, 'lang': lang, 'user': user})
             refreshRes = self.generate(data={'userID': userID, 'lang': lang, 'user': user})
             return refreshRes
             return refreshRes
-
-# import jwt
-#
-#
-# token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySUQiOiIxNTMzODg0NDE4NTE5MTM4MDAxMzgwMDAiLCJleHAiOjE1NTU1NTEwNjUsInVzZXIiOiIxMTFAcXEuY29tIiwibGFuZyI6ImVuIn0.waPlfIBucSA7rFfnsxOKIVJ_cL6xiP33cAiz1IDoteY'
-# res = jwt.decode(token, 'a+jbgnw%@1%zy^=@dn62%', algorithms='HS256')
-# print(res)

+ 6 - 27
Object/UidTokenObject.py

@@ -1,19 +1,5 @@
-#!/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: 2018/12/5 11:52
-@Version: python3.6
-@MODIFY DECORD:ansjer dev
-@file: UidTokenObject.py
-@Contact: chanjunkai@163.com
-"""
-from Ansjer.config import UID_TOKEN_KEY
 import jwt
 import jwt
-# UID_TOKEN_KEY = 'c+565*j@%^'
+from Ansjer.config import UID_TOKEN_KEY
 
 
 
 
 class UidTokenObject:
 class UidTokenObject:
@@ -43,16 +29,9 @@ class UidTokenObject:
         except Exception as e:
         except Exception as e:
             print(repr(e))
             print(repr(e))
 
 
-    def generate(self, data={}):
-        token = jwt.encode(data, UID_TOKEN_KEY, algorithm='HS256').decode('utf-8')
-        self.token= token
+    def generate(self, data=None):
+        if data is None:
+            data = {}
+        token = jwt.encode(data, UID_TOKEN_KEY, algorithm='HS256')
+        self.token = token
         return token
         return token
-# uidToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJNVUo4ODdOTFI4SzhHQk05MTExQSJ9.NHYNwmcRLCRBv2FUMA-FlM1Gtx4ir8rrwfoz7QQ67bM'
-# utko = UidTokenObject(uidToken)
-#
-# utko = UidTokenObject()
-# rr = utko.generate(data={'uid':'JW3684H8BSHG9TTM111A','channel':1})
-# print(rr)
-
-# print(utko)
-

+ 1 - 1
Object/UrlTokenObject.py

@@ -52,6 +52,6 @@ class UrlTokenObject:
         # print (now_stamp)
         # print (now_stamp)
         # 过期时间为两天
         # 过期时间为两天
         data['exp'] = 172800 + now_stamp
         data['exp'] = 172800 + now_stamp
-        token = jwt.encode(data, '12345', algorithm='HS256').decode('utf-8')
+        token = jwt.encode(data, '12345', algorithm='HS256')
         self.token = token
         self.token = token
         return token
         return token

+ 0 - 58
README.md

@@ -1,58 +0,0 @@
-### 软件版本:V2.0.0.2020-2-10
-    1,自主推送方案 移动侦测,图片推送
-    2,alexa oauth2 rtsp
-### 软件版本:V1.5.0.2019-2-12
-    1,云存功能第二版测试完成,功能完善,bug修正,使用公司提供账号
-    2,新版本ota功能(主要未dvr)
-### 软件版本:V1.4.0.2018-12-12
-	1,云存基础架构(完成)
-	2,付款(完成)
-	3,签名(完成)
-	4,云存视频流存储设计并实现(完成)
-    5,多语言OTA功能
-
-### 软件版本:V1.1.1.2018-9-12
-	1,令牌加密方案使用jwt
-	2,重写response类,redis类
-	3,无用预定义变量,加快交互速度
-
-### 软件版本:V1.0.3.2018-7-23
-    1.增加报警推送信息
-    2.增加设备操作日志
-    3.设备昵称支持emoji
-    4.支持多设备多终端进行登录
-    5.更改邮件发送为亚马逊aws
-    6.修改邮件模板,发件人
-    7.设备第一次添加为绑定人(其他人只能通过解绑,或者分享,或者通过密码添加获得,暂时未更新到正式)
-    8.增加操作文档
-    9.增加p2p定时发送邮件脚本
-### 软件版本:V1.0.1.2018-5-15  
-    1.用户管理下的反馈问题界面(分页,显示,编辑,删除),排序功能(反馈时间排序,状态排序,更新时间排序)     
-	2.版本管理下的APP界面(分页,显示,编辑,删除,添加,重置) 
-	3.帮助管理下的访问日志界面(分页,显示),搜索功能(用户名搜索,ip地址搜索,访问状态搜索,访问路径搜索,访问参数搜索)排序功能(时间排序) 
-	4.用户管理下的用户信息(显示,分页),要求用安卓APP与IOS测试注册的功能。注意:(尽量进行极限测试,比如国外手机是否有非11位的,邮箱长度是否有50位以上的) 
-	管理员账号: 
-	1.用户管理下的反馈问题界面(分页,显示),排序功能(反馈时间排序,状态排序,更新时间排序) 
-	2.版本管理下的APP界面(分页,显示)  
-	3.帮助管理下的访问日志界面(分页,显示),搜索功能(用户名搜索,ip地址搜索,访问状态搜索,访问路径搜索,访问参数搜索)  排序功能(时间排序) 
-	版本上传管理员: 
-	1.没有该功能 
-### 软件版本:V1.0.0.2018-4-23
-	1.登录功能,权限,角色添加,权限控制功能          
-	2.用户列表添加,删除,编辑(是否激活),显示功能,分页功能 
-	3.设备列表搜索(设备名称搜索),显示,传感器功能(修改,删除,显示的操作)         
-	4.版本列表上传版本,添加版本的信息,显示功能 
-	5.帮助管理的更新日志显示,数据统计显示,分页功能        
-	6.导航栏的全屏,修改密码,退出登录功能,显示账户资料,编辑用户的邮箱,昵称,是否在线      
-	管理员账号:         
-	1.登录功能          
-	2.用户列表显示功能        
-	3.设备列表搜索(设备名称搜索),显示功能,分页功能          
-	4.版本列表上传版本显示功能  
-	5.帮助管理的更新日志显示,数据统计显示,分页功能         
-	6.导航栏的全屏,显示账户资料,编辑用户的邮箱,昵称,是否在线,修改密码,退出登录功能 
-	版本上传管理员: 
-	1.登录功能   
-	2.版本列表上传版本,添加版本信息功能  
-	3.帮助管理的更新日志显示,数据统计显示,分页功能 
-	4.导航栏的全屏,修改密码,退出登录功能,显示账户资料,编辑用户的邮箱,昵称,是否在线

+ 0 - 0
SerialModel/__init__.py


+ 0 - 3
SerialModel/admin.py

@@ -1,3 +0,0 @@
-from django.contrib import admin
-
-# Register your models here.

+ 0 - 5
SerialModel/apps.py

@@ -1,5 +0,0 @@
-from django.apps import AppConfig
-
-
-class SerialmodelConfig(AppConfig):
-    name = 'SerialModel'

+ 0 - 0
SerialModel/migrations/__init__.py


+ 0 - 3
SerialModel/models.py

@@ -1,3 +0,0 @@
-from django.db import models
-
-# Create your models here.

+ 0 - 3
SerialModel/tests.py

@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.

+ 0 - 3
SerialModel/views.py

@@ -1,3 +0,0 @@
-from django.shortcuts import render
-
-# Create your views here.

+ 37 - 90
Service/CommonService.py

@@ -1,17 +1,15 @@
-# -*- coding: utf-8 -*-
-# 高复用性函数封装到CommonService类
 import base64
 import base64
 import datetime
 import datetime
+import ipdb
 import time
 import time
 from base64 import encodebytes
 from base64 import encodebytes
 from pathlib import Path
 from pathlib import Path
 from random import Random
 from random import Random
-from dateutil.relativedelta import relativedelta
 
 
 import OpenSSL.crypto as ct
 import OpenSSL.crypto as ct
-import ipdb
 import requests
 import requests
 import simplejson as json
 import simplejson as json
+from dateutil.relativedelta import relativedelta
 from django.core import serializers
 from django.core import serializers
 from django.utils import timezone
 from django.utils import timezone
 from pyipip import IPIPDatabase
 from pyipip import IPIPDatabase
@@ -19,15 +17,17 @@ from pyipip import IPIPDatabase
 from Ansjer.config import BASE_DIR, SERVER_DOMAIN_SSL, CONFIG_INFO, CONFIG_TEST, CONFIG_CN, SERVER_DOMAIN_TEST, \
 from Ansjer.config import BASE_DIR, SERVER_DOMAIN_SSL, CONFIG_INFO, CONFIG_TEST, CONFIG_CN, SERVER_DOMAIN_TEST, \
     SERVER_DOMAIN_CN, SERVER_DOMAIN_US, CONFIG_US, CONFIG_EUR, SERVER_DOMAIN_LIST, SERVER_DOMAIN_EUR
     SERVER_DOMAIN_CN, SERVER_DOMAIN_US, CONFIG_US, CONFIG_EUR, SERVER_DOMAIN_LIST, SERVER_DOMAIN_EUR
 from Controller.CheckUserData import RandomStr
 from Controller.CheckUserData import RandomStr
-from Model.models import iotdeviceInfoModel, Device_Info, CountryModel, RegionModel, UIDModel
+from Model.models import iotdeviceInfoModel, Device_Info, UIDModel
 from Object.ResponseObject import ResponseObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.TokenObject import TokenObject
 
 
 
 
 class CommonService:
 class CommonService:
-    # 添加模糊搜索
+    # 高复用性函数类
+
     @staticmethod
     @staticmethod
     def get_kwargs(data=None):
     def get_kwargs(data=None):
+        # 添加模糊搜索
         if data is None:
         if data is None:
             data = {}
             data = {}
         kwargs = {}
         kwargs = {}
@@ -36,10 +36,9 @@ class CommonService:
                 kwargs[k + '__icontains'] = v
                 kwargs[k + '__icontains'] = v
         return kwargs
         return kwargs
 
 
-    # 定义静态方法
-    # 格式化query_set转dict
     @staticmethod
     @staticmethod
     def qs_to_dict(query_set):
     def qs_to_dict(query_set):
+        # 格式化query_set转dict
         sqlJSON = serializers.serialize('json', query_set)
         sqlJSON = serializers.serialize('json', query_set)
         sqlList = json.loads(sqlJSON)
         sqlList = json.loads(sqlJSON)
         sqlDict = dict(zip(["datas"], [sqlList]))
         sqlDict = dict(zip(["datas"], [sqlList]))
@@ -265,43 +264,37 @@ class CommonService:
         return str
         return str
 
 
     @staticmethod
     @staticmethod
-    def decode_data(content, start=1, end=4):
+    def encode_data(content, start=1, end=4):
+        """
+        数据加密
+        @param content: 数据内容
+        @param start: 起始长度
+        @param end: 结束长度
+        @return content: 加密的数据
+        """
         if not content:
         if not content:
             return ''
             return ''
-        try:
-            for i in range(start, end):
-                if i == 1:
-                    content = base64.b64decode(content)
-                    content = content.decode('utf-8')
-                    content = content[1:-1]
-                if i == 2:
-                    content = base64.b64decode(content)
-                    content = content.decode('utf-8')
-                    content = content[2:-2]
-                if i == 3:
-                    content = base64.b64decode(content)
-                    content = content.decode('utf-8')
-                    content = content[3:-3]
-
-            return content
-        except Exception as e:
-            print(e)
-            return None
+        for i in range(start, end):
+            length = end - i
+            content = RandomStr(length, False) + content + RandomStr(length, False)
+            content = base64.b64encode(str(content).encode('utf-8')).decode('utf8')
+        return content
 
 
     @staticmethod
     @staticmethod
-    def encode_data(content, start=1, end=4):
+    def decode_data(content, start=1, end=4):
+        """
+        数据解密
+        @param content: 数据内容
+        @param start: 起始长度
+        @param end: 结束长度
+        @return content: 解密的数据
+        """
         if not content:
         if not content:
             return ''
             return ''
         for i in range(start, end):
         for i in range(start, end):
-            if i == 1:
-                content = RandomStr(3, False) + content + RandomStr(3, False)
-                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
-            if i == 2:
-                content = RandomStr(2, False) + str(content) + RandomStr(2, False)
-                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
-            if i == 3:
-                content = RandomStr(1, False) + str(content) + RandomStr(1, False)
-                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
+            content = base64.b64decode(content)
+            content = content.decode('utf-8')
+            content = content[i:-i]
         return content
         return content
 
 
     # 把格式化时间转换成时间戳
     # 把格式化时间转换成时间戳
@@ -347,6 +340,7 @@ class CommonService:
             else:
             else:
                 now_month += 1
                 now_month += 1
 
 
+        timestamps = 0
         for is_format in range(4):
         for is_format in range(4):
             try:
             try:
                 date_format = '{now_year}-{now_month}-{now_day} {now_hour}:{now_min}:{now_second}' \
                 date_format = '{now_year}-{now_month}-{now_day} {now_hour}:{now_min}:{now_second}' \
@@ -369,11 +363,6 @@ class CommonService:
         second = int(macArray[4], 16)
         second = int(macArray[4], 16)
         three = int(macArray[3], 16)
         three = int(macArray[3], 16)
 
 
-        # print(macArray)
-        # print(first)
-        # print(second)
-        # print(three)
-
         if first == 255 and second == 255 and three == 255:
         if first == 255 and second == 255 and three == 255:
             return None
             return None
 
 
@@ -390,53 +379,10 @@ class CommonService:
         macArray[3] = three
         macArray[3] = three
         macArray[4] = second
         macArray[4] = second
         macArray[5] = first
         macArray[5] = first
-        # print(macArray)
 
 
         tmp = ':'.join(map(lambda x: "%02x" % x, macArray))
         tmp = ':'.join(map(lambda x: "%02x" % x, macArray))
-        # print(tmp)
         return tmp.upper()
         return tmp.upper()
 
 
-    @staticmethod
-    def decode_data(content, start=1, end=4):
-        if not content:
-            return ''
-        try:
-            for i in range(start, end):
-                if i == 1:
-                    content = base64.b64decode(content)
-                    content = content.decode('utf-8')
-                    content = content[1:-1]
-                if i == 2:
-                    content = base64.b64decode(content)
-                    content = content.decode('utf-8')
-                    content = content[2:-2]
-                if i == 3:
-                    content = base64.b64decode(content)
-                    content = content.decode('utf-8')
-                    content = content[3:-3]
-                    print(content)
-
-            return content
-        except Exception as e:
-            print(e)
-            return None
-
-    @staticmethod
-    def encode_data(content, start=1, end=4):
-        if not content:
-            return ''
-        for i in range(start, end):
-            if i == 1:
-                content = CommonService.RandomStr(3, False) + content + CommonService.RandomStr(3, False)
-                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
-            if i == 2:
-                content = CommonService.RandomStr(2, False) + str(content) + CommonService.RandomStr(2, False)
-                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
-            if i == 3:
-                content = CommonService.RandomStr(1, False) + str(content) + CommonService.RandomStr(1, False)
-                content = base64.b64encode(str(content).encode("utf-8")).decode('utf8')
-        return content
-
     @staticmethod
     @staticmethod
     def encode_data_without_salt(content):
     def encode_data_without_salt(content):
         return base64.b64encode(str(content).encode("utf-8")).decode('utf8')
         return base64.b64encode(str(content).encode("utf-8")).decode('utf8')
@@ -631,13 +577,13 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
         @return: region_id
         @return: region_id
         """
         """
         region_id = 3
         region_id = 3
-        if CONFIG_INFO == CONFIG_US:        # 美洲
+        if CONFIG_INFO == CONFIG_US:  # 美洲
             region_id = 3
             region_id = 3
-        elif CONFIG_INFO == CONFIG_EUR:     # 欧洲
+        elif CONFIG_INFO == CONFIG_EUR:  # 欧洲
             region_id = 4
             region_id = 4
-        elif CONFIG_INFO == CONFIG_CN:      # 中国
+        elif CONFIG_INFO == CONFIG_CN:  # 中国
             region_id = 1
             region_id = 1
-        elif CONFIG_INFO == CONFIG_TEST:    # 测试
+        elif CONFIG_INFO == CONFIG_TEST:  # 测试
             region_id = 5
             region_id = 5
         return region_id
         return region_id
 
 
@@ -656,6 +602,7 @@ GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
             return token_obj.code, token_obj.userID, response
             return token_obj.code, token_obj.userID, response
         except Exception as e:
         except Exception as e:
             print(e)
             print(e)
+            return 309, None, None
 
 
     @staticmethod
     @staticmethod
     def cutting_time(start_time, end_time, time_unit):
     def cutting_time(start_time, end_time, time_unit):

+ 86 - 5
Service/UserDeviceService.py

@@ -6,12 +6,16 @@
 @Email   : zhangdongming@asj6.wecom.work
 @Email   : zhangdongming@asj6.wecom.work
 @Software: PyCharm
 @Software: PyCharm
 """
 """
+import logging
+
 from django.db.models import Q
 from django.db.models import Q
 
 
 from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, UnicomDeviceInfo, \
 from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, UnicomDeviceInfo, \
-    UIDModel
+    UIDModel, DeviceChannelUserSet, DeviceChannelUserPermission, DeviceSharePermission
 from Service.CommonService import CommonService
 from Service.CommonService import CommonService
 
 
+LOGGER = logging.getLogger('info')
+
 
 
 class UserDeviceService:
 class UserDeviceService:
 
 
@@ -195,12 +199,13 @@ class UserDeviceService:
             p_vo['initStringApp'] = uid_qs[0]['init_string_app']
             p_vo['initStringApp'] = uid_qs[0]['init_string_app']
 
 
     @classmethod
     @classmethod
-    def get_device_info_dto(cls, p_vo, p_uid, uv_dict):
+    def get_device_info_dto(cls, p_vo, p_uid, uv_dict, user_id=None):
         """
         """
         获取设备信息DTO
         获取设备信息DTO
-        @param p_vo: 设备对象
+        @param user_id: 用户ID
+        @param p_vo: 设备信息
         @param p_uid: 设备uid
         @param p_uid: 设备uid
-        @param uv_dict: 设备通道字典
+        @param uv_dict: 设备通道信息
         """
         """
         uidversion = uv_dict[p_uid]['version']
         uidversion = uv_dict[p_uid]['version']
         if len(uidversion) > 6:
         if len(uidversion) > 6:
@@ -226,7 +231,8 @@ class UserDeviceService:
         p_vo['is_human'] = uv_dict[p_uid]['is_human']
         p_vo['is_human'] = uv_dict[p_uid]['is_human']
         p_vo['is_custom_voice'] = uv_dict[p_uid]['is_custom_voice']
         p_vo['is_custom_voice'] = uv_dict[p_uid]['is_custom_voice']
         p_vo['is_ptz'] = uv_dict[p_uid]['is_ptz']
         p_vo['is_ptz'] = uv_dict[p_uid]['is_ptz']
-        p_vo['channels'] = uv_dict[p_uid]['channels']
+        p_vo['channels'] = cls.get_channel_permission_by_user(user_id, p_vo['isShare'], p_uid,
+                                                              uv_dict[p_uid]['channels'])
         p_vo['double_wifi'] = uv_dict[p_uid]['double_wifi']
         p_vo['double_wifi'] = uv_dict[p_uid]['double_wifi']
         p_vo['mobile4G'] = uv_dict[p_uid]['mobile4G']
         p_vo['mobile4G'] = uv_dict[p_uid]['mobile4G']
         p_vo['isCameraOpenCloud'] = 0 if uv_dict[p_uid]['mobile4G'] == 1 else p_vo['isCameraOpenCloud']
         p_vo['isCameraOpenCloud'] = 0 if uv_dict[p_uid]['mobile4G'] == 1 else p_vo['isCameraOpenCloud']
@@ -236,3 +242,78 @@ class UserDeviceService:
         # 设备昵称 调用影子信息昵称,先阶段不可
         # 设备昵称 调用影子信息昵称,先阶段不可
         if uv_dict[p_uid]['nickname']:
         if uv_dict[p_uid]['nickname']:
             p_vo['NickName'] = uv_dict[p_uid]['nickname']
             p_vo['NickName'] = uv_dict[p_uid]['nickname']
+
+    @staticmethod
+    def get_channel_permission_by_user(user_id, is_share, uid, channels):
+        """
+        根据用户获取设备通道权限
+        @param user_id: 用户ID
+        @param is_share: 是否分享设备
+        @param uid: 设备UID
+        @param channels: 通道信息
+        @return: channels
+        """
+        try:
+            if not is_share:
+                return channels
+            # 获取设备权限
+            channel_set_qs = DeviceChannelUserSet.objects.filter(user_id=user_id, uid=uid).values('id', 'channels')
+            if not channel_set_qs.exists() or not channels:
+                return channels
+            channel_list = [int(val) for val in channel_set_qs[0]['channels'].split(',')]
+            channel_permission_qs = DeviceChannelUserPermission.objects \
+                .filter(channel_user_id=channel_set_qs[0]['id']).values('permission_id')
+            ids = [val['permission_id'] for val in channel_permission_qs]
+            channel_permission_qs = DeviceSharePermission.objects \
+                .all().values('id', 'code').order_by('sort')
+            channel_permission_list = []
+            default_permissions = []
+            if not channel_permission_qs.exists():
+                return channels
+
+            for item in channel_permission_qs:
+                default_permissions.append({'permissionId': item['id'], 'code': item['code'], 'isSelect': 0})
+                p_data = {'permissionId': item['id'], 'code': item['code'], 'isSelect': 1 if item['id'] in ids else 0}
+                channel_permission_list.append(p_data)
+
+            for item in channels:
+                channel = item['channel']
+                if channel in channel_list:
+                    item['channelPermissions'] = channel_permission_list
+                else:
+                    item['channelPermissions'] = default_permissions
+            return channels
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return channels
+
+    @staticmethod
+    def update_device_channel(uid):
+        """
+        UID通道同步更新
+        @param uid: 设备UID
+        @return: True | False
+        """
+        try:
+            uid_set_qs = UidSetModel.objects.filter(uid=uid).values('id', 'channel')
+            if not uid_set_qs.exists():
+                return False
+            uid_set_id = uid_set_qs[0]['id']
+            channel_index = uid_set_qs[0]['channel']
+            uid_channel_qs = UidChannelSetModel.objects.filter(uid_id=uid_set_id).values('channel')
+            if uid_channel_qs.exists() and uid_channel_qs.count() != channel_index:
+                uid_channel_list = []
+                channels = [val['channel'] for val in uid_channel_qs]
+                for i in range(1, channel_index + 1):
+                    if i in channels:
+                        continue
+                    channel_name = 'channel' + str(i)  # channel1,channel2...
+                    UidChannelSet = UidChannelSetModel(uid_id=uid_set_id, channel=i, channel_name=channel_name)
+                    uid_channel_list.append(UidChannelSet)
+                if not uid_channel_list:
+                    return True
+                UidChannelSetModel.objects.bulk_create(uid_channel_list)
+            return True
+        except Exception as e:
+            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False

+ 137 - 0
Service/VodHlsService.py

@@ -0,0 +1,137 @@
+# @Author    : Rocky
+# @File      : VodHlsService.py
+# @Time      : 2023/2/1 15:57
+import datetime
+from Model.models import VodHlsMon, VodHlsTues, VodHlsWed, VodHlsThur, VodHlsFri, VodHlsSat, VodHlsSun
+from Service.CommonService import CommonService
+from django.db.models import Count
+
+class SplitVodHlsObject:
+    # VodHls分表功能类
+
+    def creat_vod_hls_data(self, **kwargs):
+        """
+        分表保存云存信息数据
+        """
+        start_time = kwargs.get('start_time')
+        week = datetime.datetime.fromtimestamp(int(start_time)).isoweekday()
+        if week == 1:
+            VodHlsMon.objects.create(**kwargs)
+        elif week == 2:
+            VodHlsTues.objects.create(**kwargs)
+        elif week == 3:
+            VodHlsWed.objects.create(**kwargs)
+        elif week == 4:
+            VodHlsThur.objects.create(**kwargs)
+        elif week == 5:
+            VodHlsFri.objects.create(**kwargs)
+        elif week == 6:
+            VodHlsSat.objects.create(**kwargs)
+        elif week == 7:
+            VodHlsSun.objects.create(**kwargs)
+
+    def del_vod_hls_data(self, **kwargs):
+        """
+        分表删除云存信息数据
+        """
+        VodHlsMon.objects.filter(**kwargs).delete()
+        VodHlsTues.objects.filter(**kwargs).delete()
+        VodHlsWed.objects.filter(**kwargs).delete()
+        VodHlsThur.objects.filter(**kwargs).delete()
+        VodHlsFri.objects.filter(**kwargs).delete()
+        VodHlsSat.objects.filter(**kwargs).delete()
+        VodHlsSun.objects.filter(**kwargs).delete()
+
+    def get_vod_hls_data(self, **kwargs):
+        """
+        分表获取云存信息数据
+        @return: vod_hls
+        """
+        vod_hls = VodHlsMon.objects.filter(pk=-1)
+        if 'start_time' in kwargs:
+            start_time = kwargs.get('start_time')
+            week = datetime.datetime.fromtimestamp(int(start_time)).isoweekday()
+            if week == 1:
+                vod_hls = VodHlsMon.objects.filter(**kwargs)
+            elif week == 2:
+                vod_hls = VodHlsTues.objects.filter(**kwargs)
+            elif week == 3:
+                vod_hls = VodHlsWed.objects.filter(**kwargs)
+            elif week == 4:
+                vod_hls = VodHlsThur.objects.filter(**kwargs)
+            elif week == 5:
+                vod_hls = VodHlsFri.objects.filter(**kwargs)
+            elif week == 6:
+                vod_hls = VodHlsSat.objects.filter(**kwargs)
+            elif week == 7:
+                vod_hls = VodHlsSun.objects.filter(**kwargs)
+            return vod_hls
+        if 'start_time__range' in kwargs:
+            start_time, end_time = kwargs.get('start_time__range')
+            vod_hls_mon = VodHlsMon.objects.filter(pk=-1)
+            vod_hls_tus = VodHlsTues.objects.filter(pk=-1)
+            vod_hls_wed = VodHlsWed.objects.filter(pk=-1)
+            vod_hls_thur = VodHlsThur.objects.filter(pk=-1)
+            vod_hls_fri = VodHlsFri.objects.filter(pk=-1)
+            vod_hls_sat = VodHlsSat.objects.filter(pk=-1)
+            vod_hls_sun = VodHlsSun.objects.filter(pk=-1)
+            start_time = datetime.datetime.fromtimestamp(int(start_time))
+            end_time = datetime.datetime.fromtimestamp(int(end_time))
+            time_list = CommonService.cutting_time(start_time, end_time, 'day')
+            day_list = []
+            for time_item in time_list:
+                week = datetime.datetime.fromtimestamp(int(time_item[0])).isoweekday()
+                if week not in day_list:
+                    day_list.append(week)
+            for week in day_list:
+                if week == 1:
+                    vod_hls_mon = VodHlsMon.objects.filter(**kwargs)
+                elif week == 2:
+                    vod_hls_tus = VodHlsTues.objects.filter(**kwargs)
+                elif week == 3:
+                    vod_hls_wed = VodHlsWed.objects.filter(**kwargs)
+                elif week == 4:
+                    vod_hls_thur = VodHlsThur.objects.filter(**kwargs)
+                elif week == 5:
+                    vod_hls_fri = VodHlsFri.objects.filter(**kwargs)
+                elif week == 6:
+                    vod_hls_sat = VodHlsSat.objects.filter(**kwargs)
+                elif week == 7:
+                    vod_hls_sun = VodHlsSun.objects.filter(**kwargs)
+            vod_hls = vod_hls.union(vod_hls_mon, vod_hls_tus, vod_hls_wed, vod_hls_thur, vod_hls_fri, vod_hls_sat,
+                                    vod_hls_sun)
+            return vod_hls
+        vod_hls_mon = VodHlsMon.objects.filter(**kwargs)
+        vod_hls_tus = VodHlsTues.objects.filter(**kwargs)
+        vod_hls_wed = VodHlsWed.objects.filter(**kwargs)
+        vod_hls_thur = VodHlsThur.objects.filter(**kwargs)
+        vod_hls_fri = VodHlsFri.objects.filter(**kwargs)
+        vod_hls_sat = VodHlsSat.objects.filter(**kwargs)
+        vod_hls_sun = VodHlsSun.objects.filter(**kwargs)
+
+        vod_hls = vod_hls.union(vod_hls_mon, vod_hls_tus, vod_hls_wed, vod_hls_thur, vod_hls_fri, vod_hls_sat, vod_hls_sun)
+        return vod_hls
+
+    def get_vod_hls_date(self, **kwargs):
+        """
+        分表获取云存日期信息数据
+        @return: vod_hls
+        """
+
+        vod_hls_mon = VodHlsMon.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
+             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+        vod_hls_tus = VodHlsTues.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
+             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+        vod_hls_wed = VodHlsWed.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
+             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+        vod_hls_thur = VodHlsThur.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
+             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+        vod_hls_fri = VodHlsFri.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
+             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+        vod_hls_sat = VodHlsSat.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
+             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+        vod_hls_sun = VodHlsSun.objects.extra(select={'date': "FROM_UNIXTIME(start_time,'%%Y-%%m-%%d')"}).values(
+             'date').filter(**kwargs).annotate(count=Count('start_time')).order_by('-date')
+
+        vod_hls = vod_hls_mon.union(vod_hls_tus, vod_hls_wed, vod_hls_thur, vod_hls_fri, vod_hls_sat, vod_hls_sun)
+        return vod_hls

BIN
requirements.txt