Browse Source

新增OCI对象存储

zhangdongming 1 year ago
parent
commit
46f04746d7

+ 18 - 0
Ansjer/cn_config/config_formal.py

@@ -140,3 +140,21 @@ APNS_CONFIG = {
         'pem_path': 'Ansjer/file/apns_pem/commissionf.pem',
     }
 }
+
+OCI_CONFIG = {
+    'us': {
+        'user': 'ocid1.user.oc1..aaaaaaaa63vtn64izdujrghlfby6xrlrrdce4yldtnjm7tmqzoc5i2b36s5q',
+        'fingerprint': '09:ff:f4:fa:64:bd:7b:72:64:67:5e:9a:ba:01:68:7b',
+        'tenancy': 'ocid1.tenancy.oc1..aaaaaaaaemreyqoegf4wbegfzetg63bwvzxa7ahfptbziexslzfmc7gnuwmq',
+        'region': 'us-phoenix-1',
+        'key_file': 'Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem'
+    },
+    'eur': {
+        'user': 'ocid1.user.oc1..aaaaaaaa63vtn64izdujrghlfby6xrlrrdce4yldtnjm7tmqzoc5i2b36s5q',
+        'fingerprint': '09:ff:f4:fa:64:bd:7b:72:64:67:5e:9a:ba:01:68:7b',
+        'tenancy': 'ocid1.tenancy.oc1..aaaaaaaaemreyqoegf4wbegfzetg63bwvzxa7ahfptbziexslzfmc7gnuwmq',
+        'region': 'uk-london-1',
+        'key_file': 'Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem'
+    }
+}
+OCI_NAMESPACE_NAME = 'cnmlmfa4fooi'

+ 18 - 0
Ansjer/cn_config/config_test.py

@@ -149,3 +149,21 @@ APNS_CONFIG = {
         'pem_path': 'Ansjer/file/apns_pem/commissionf-dev.pem',
     }
 }
+
+OCI_CONFIG = {
+    'us': {
+        'user': 'ocid1.user.oc1..aaaaaaaa63vtn64izdujrghlfby6xrlrrdce4yldtnjm7tmqzoc5i2b36s5q',
+        'fingerprint': '09:ff:f4:fa:64:bd:7b:72:64:67:5e:9a:ba:01:68:7b',
+        'tenancy': 'ocid1.tenancy.oc1..aaaaaaaaemreyqoegf4wbegfzetg63bwvzxa7ahfptbziexslzfmc7gnuwmq',
+        'region': 'us-phoenix-1',
+        'key_file': 'Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem'
+    },
+    'eur': {
+        'user': 'ocid1.user.oc1..aaaaaaaa63vtn64izdujrghlfby6xrlrrdce4yldtnjm7tmqzoc5i2b36s5q',
+        'fingerprint': '09:ff:f4:fa:64:bd:7b:72:64:67:5e:9a:ba:01:68:7b',
+        'tenancy': 'ocid1.tenancy.oc1..aaaaaaaaemreyqoegf4wbegfzetg63bwvzxa7ahfptbziexslzfmc7gnuwmq',
+        'region': 'uk-london-1',
+        'key_file': 'Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem'
+    }
+}
+OCI_NAMESPACE_NAME = 'cnmlmfa4fooi'

+ 18 - 0
Ansjer/eur_config/config_formal.py

@@ -140,3 +140,21 @@ APNS_CONFIG = {
         'pem_path': 'Ansjer/file/apns_pem/commissionf.pem',
     }
 }
+
+OCI_CONFIG = {
+    'us': {
+        'user': 'ocid1.user.oc1..aaaaaaaa63vtn64izdujrghlfby6xrlrrdce4yldtnjm7tmqzoc5i2b36s5q',
+        'fingerprint': '09:ff:f4:fa:64:bd:7b:72:64:67:5e:9a:ba:01:68:7b',
+        'tenancy': 'ocid1.tenancy.oc1..aaaaaaaaemreyqoegf4wbegfzetg63bwvzxa7ahfptbziexslzfmc7gnuwmq',
+        'region': 'us-phoenix-1',
+        'key_file': 'Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem'
+    },
+    'eur': {
+        'user': 'ocid1.user.oc1..aaaaaaaa63vtn64izdujrghlfby6xrlrrdce4yldtnjm7tmqzoc5i2b36s5q',
+        'fingerprint': '09:ff:f4:fa:64:bd:7b:72:64:67:5e:9a:ba:01:68:7b',
+        'tenancy': 'ocid1.tenancy.oc1..aaaaaaaaemreyqoegf4wbegfzetg63bwvzxa7ahfptbziexslzfmc7gnuwmq',
+        'region': 'uk-london-1',
+        'key_file': 'Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem'
+    }
+}
+OCI_NAMESPACE_NAME = 'cnmlmfa4fooi'

+ 28 - 0
Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCRP0y7XdQ04WV7
+pMGtdCMx5Kdq+NIBzCNSbn4sEzjsAGnmqNuJYLYDtKZaWZp2xwq3+0EoRiHkN+P9
+Jrzb5MplbAzGEDWMevdYdqCxPL0H+KIEd2Zy7e3npYUipQ56astPq/9HytwvfbsL
+5ED8/csRqyPy8/JfuRlQ/i7XhhAG7HNx+hEVaiJLhfi0Y7IYX5+Zx4040fmDybfE
+J+IGB0qYNm/OfPIK8x8lr3RcOla86nFPrkgbxQOW1c0hbZ5NYILBJuzhCDsiU62A
+3o557ur8Tr2xAeS3ZVtW1yzbqwZwMyRtN0Anl3inVrSyDgXcEjWlckCi24OVnu2F
+QAd1d4ujAgMBAAECggEAClQyjDZ5c0M+GMNYJJIYOKGWiERmhssyDdger9q0FxBW
+d5k1d3kBqJTNqaoqklzINdovwYHvQg/5bhS1pHuKKxk6dVFMxY8vDMLu3XvAw5La
+TrABAJZL70e1hoevVmRGzgUgs8XIz7XEue1C89rGeJyvg0T2zPjYRIq24Qu/Ewbd
+JvVmjz4nAe28VjgEwzOnrPFkykT9YojUF1Bl26dJBj+oVk+O6Jf74TMhoT9O/B35
+VGDypqm2qyQQ9ra8myNKmTOCpi1RiK433k6RRCywyf6o+Lehot31eFFO6caIayVG
+j2aWe5N2gaWBPGeioFInKXqkw4tjLafWb3oEDJpAdQKBgQDD9CY8M9K3GQekE0Fb
+dh6a6Aza47WXdoOP/wnO+w3DsaqL42ZCp5/L3D3LtNBJiHXQZhXTuciV5qEtjszt
+XquXYJqyz29A7SNLOXLilvjPq71qWzJF6ViWcHBjX1R/7XqJkK0FuaJWaQFJ5uvS
+kEw55IrKnJ8DQ4m1ZJECn4nWLwKBgQC9wWpkmNNOTLyNJ5Ukf5IE2onL3aaa7iUG
+nLCXCUOXBUUGt9FE9As0PdNjXeTqqH80mWIEgyTBkvFNG5yGwNiVVIMd4Sa9Sm7W
+GND1NFeU3TDJ00rV9FSnVSbrJywi8NEst7qZqy4CS7xjr1+qP6xqIKhHS9n4+K8S
+idlsWB94zQKBgFUv7+teMC3vULYQtOoZGMcJOIV0Vv6IxDs2icIUvHAl7dmwu0Ug
+8ERE9Ax6B87f5y/5IWYRL1WTlOBkY0ySSpCdq8MukNQuA5jxWbOOJI7Lv6XcDaf9
+AMkuCn349JhE2m+xmLaTdDKSpb/GByFcH/dPFtNscWiO1PApzyzPxLF7AoGAMZ8M
+pXXZfBZREFCTjdHWa3KCqk8yLD2ubQY4n6aKiEmWfWVAUlnHPEgWqVt6a2rYqPab
+TTbGO+CjPVjFG+/+Mz7AcuXX7ZQzW8Vtj1G6vXECOyUH4t9b6842uTOrNQ/og1sg
+buL2yx7nCuJnj+vKuI4Fs29Adv0BO0XVF6ILyNkCgYAvP+bOLbPCS3u9Sw23e63t
+9EqeyNfR88KmQzVQGcP5yL3yUytQp5RrDqDdndP3uQa1TY6WQLKPqMh7sMWH9yWB
+6B/CudtduRWbWxLjXVN8Lhb9w7ORLRcY23xDQwdueOER3PHnp3UwaebHJ4+JXcdA
+KtygcG+9e3hWuUzyV/QdLQ==
+-----END PRIVATE KEY-----

+ 18 - 0
Ansjer/us_config/config_formal.py

@@ -140,3 +140,21 @@ APNS_CONFIG = {
         'pem_path': 'Ansjer/file/apns_pem/commissionf.pem',
     }
 }
+
+OCI_CONFIG = {
+    'us': {
+        'user': 'ocid1.user.oc1..aaaaaaaa63vtn64izdujrghlfby6xrlrrdce4yldtnjm7tmqzoc5i2b36s5q',
+        'fingerprint': '09:ff:f4:fa:64:bd:7b:72:64:67:5e:9a:ba:01:68:7b',
+        'tenancy': 'ocid1.tenancy.oc1..aaaaaaaaemreyqoegf4wbegfzetg63bwvzxa7ahfptbziexslzfmc7gnuwmq',
+        'region': 'us-phoenix-1',
+        'key_file': 'Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem'
+    },
+    'eur': {
+        'user': 'ocid1.user.oc1..aaaaaaaa63vtn64izdujrghlfby6xrlrrdce4yldtnjm7tmqzoc5i2b36s5q',
+        'fingerprint': '09:ff:f4:fa:64:bd:7b:72:64:67:5e:9a:ba:01:68:7b',
+        'tenancy': 'ocid1.tenancy.oc1..aaaaaaaaemreyqoegf4wbegfzetg63bwvzxa7ahfptbziexslzfmc7gnuwmq',
+        'region': 'uk-london-1',
+        'key_file': 'Ansjer/file/oci_pem/servers@ansjer.com_2023-12-20T07_21_33.069Z.pem'
+    }
+}
+OCI_NAMESPACE_NAME = 'cnmlmfa4fooi'

+ 212 - 12
Controller/DetectControllerV2.py

@@ -1,3 +1,4 @@
+import datetime
 import json
 import time
 
@@ -10,9 +11,11 @@ from django.views.generic.base import View
 
 from Ansjer.config import DETECT_PUSH_DOMAIN, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, DETECT_PUSH_DOMAINS_JIUAN, \
     OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, LOGGER, ALGORITHM_COMBO_TYPES
+from Ansjer.config import PUSH_BUCKET
 from Model.models import Device_Info, Equipment_Info, UidSetModel, UidPushModel, CompanyModel, SysMsgModel, \
     AiService, VodBucketModel
 from Object.ETkObject import ETkObject
+from Object.OCIObjectStorage import OCIObjectStorage
 from Object.RedisObject import RedisObject
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
@@ -55,6 +58,9 @@ class DetectControllerViewV2(View):
             # 查询推送信息
             elif operation == 'queryInfo':
                 return self.do_query(request_dict, response, userID)
+            # 点击推送信息跳转到列表信息
+            elif operation == 'transferInfo':
+                return self.do_transfer(request_dict, response, userID)
             # 更新推送延迟
             elif operation == 'updateInterval':
                 return self.do_update_interval(userID, request_dict, response)
@@ -329,7 +335,7 @@ class DetectControllerViewV2(View):
                 end_time = int(time.time())
                 start_time = LocalDateTimeUtil.get_before_days_timestamp(end_time, 7)
 
-            equipment_info_qs, count = EquipmentInfoService.\
+            equipment_info_qs, count = EquipmentInfoService. \
                 union_equipment_info(userID, uid_list, event_type, start_time, end_time, page, line)
 
             # 查询设备类型,昵称
@@ -365,7 +371,193 @@ class DetectControllerViewV2(View):
                 config=botocore.client.Config(signature_version='s3v4'),
                 region_name='cn-northwest-1'
             )
+            oci_eur = OCIObjectStorage('eur')
+            oci_us = OCIObjectStorage('us')
+            redis_obj = RedisObject(3)
+            # ai消息标识所有组合标签
+            ai_all_event_type = EquipmentInfoService.get_all_comb_event_type()
+            for equipment_info in equipment_info_qs:
+                uid = equipment_info['devUid']
+                event_time = equipment_info['eventTime']
+                channel = equipment_info['Channel']
+                storage_location = equipment_info['storage_location']
+                border_coords = equipment_info['borderCoords']
+                event_type = equipment_info['eventType']
+                event_tag = equipment_info['eventTag']
+
+                if equipment_info['is_st'] == 1:
+                    thumbspng = '{}/{}/{}.jpeg'.format(uid, channel, event_time)
+                    if storage_location == 1:  # 阿里云oss
+                        img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
+                    elif storage_location in [3, 4]:
+                        oci = oci_eur if storage_location == 4 else oci_us
+                        img_url = DetectControllerViewV2.oci_object_url(oci, thumbspng)
+                    else:
+                        params = {'Key': thumbspng}
+                        if region == 1:  # AWS国外
+                            params['Bucket'] = 'foreignpush'
+                            img_url = aws_s3.generate_presigned_url(
+                                'get_object', Params=params, ExpiresIn=300)
+                        else:  # AWS国内
+                            params['Bucket'] = 'push'
+                            img_url = aws_s3_cn.generate_presigned_url(
+                                'get_object', Params=params, ExpiresIn=300)
+
+                    equipment_info['img'] = img_url
+                    equipment_info['img_list'] = [img_url]
+
+                elif equipment_info['is_st'] == 2:
+                    # 列表装载回放时间戳标记
+                    split_vod_hls_obj = SplitVodHlsObject()
+                    vodqs = split_vod_hls_obj.get_vod_hls_data(
+                        uid=uid, channel=channel, start_time=int(event_time)).values('bucket_id')
+                    if not vodqs.exists():
+                        return response.json(173)
+                    vod_bucket_qs = VodBucketModel.objects.filter(id=vodqs[0]['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']
+                    bucket = oss2.Bucket(auth, endpoint, bucket_name)
+                    ts = '{}/vod{}/{}/ts0.ts'.format(uid, channel, event_time)
+                    if storage_location == 1:  # 阿里云oss
+                        thumb0 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
+                        thumb1 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
+                        thumb2 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
+                        equipment_info['img_list'] = [thumb0, thumb1, thumb2]
+                    else:
+                        params = {'Key': ts}
+                        if region == 1:  # AWS国外
+                            params['Bucket'] = 'foreignpush'
+                            img_url = aws_s3.generate_presigned_url(
+                                'get_object', Params=params, ExpiresIn=300)
+                        else:  # AWS国内
+                            params['Bucket'] = 'push'
+                            img_url = aws_s3_cn.generate_presigned_url(
+                                'get_object', Params=params, ExpiresIn=300)
+                        equipment_info['img_list'] = [img_url]
+
+                elif equipment_info['is_st'] == 3 or equipment_info['is_st'] == 4:
+                    # 列表装载回放时间戳标记
+                    equipment_info['img_list'] = []
+
+                    msg_key = f'{uid}:{channel}:{event_time}'
+                    # OCI三张图 获取缓存临时URL
+                    img_data = DetectControllerViewV2.get_msg_redis_url(redis_obj, msg_key,
+                                                                        equipment_info['is_st'], storage_location)
+                    if img_data:
+                        equipment_info['img_list'] = img_data
+                    else:
+                        for i in range(equipment_info['is_st']):
+                            thumbspng = '{}/{}/{}_{}.jpeg'.format(uid, channel, event_time, i)
+                            if storage_location == 1:  # 阿里云oss
+                                img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
+                            elif storage_location in [3, 4]:  # 国外OCI云
+                                oci = oci_eur if storage_location == 4 else oci_us
+                                img_url = DetectControllerViewV2.oci_object_url(oci, thumbspng)
+                            else:
+                                params = {'Key': thumbspng}
+                                if region == 1:  # 国外AWS
+                                    params['Bucket'] = 'foreignpush'
+                                    img_url = aws_s3.generate_presigned_url(
+                                        'get_object', Params=params, ExpiresIn=300)
+                                else:  # 国内AWS
+                                    params['Bucket'] = 'push'
+                                    img_url = aws_s3_cn.generate_presigned_url(
+                                        'get_object', Params=params, ExpiresIn=300)
+                            equipment_info['img_list'].append(img_url)
+                        if not img_data and equipment_info['is_st'] == 3 and storage_location in [3, 4]:
+                            DetectControllerViewV2.set_msg_redis_url(redis_obj, msg_key, equipment_info['img_list'])
+
+                if uid in uid_type_dict.keys():
+                    equipment_info['uid_type'] = uid_type_dict[uid]['type']
+                    equipment_info['devNickName'] = uid_type_dict[uid]['NickName']
+                else:
+                    equipment_info['uid_type'] = ''
+
+                equipment_info['borderCoords'] = '' if border_coords == '' else eval(border_coords)  # ai消息坐标信息
+                equipment_info['ai_event_type_list'] = []
+                # 如果是ai消息类型,则分解eventType, 如:123 -> [1,2,3]
+                if border_coords and event_type in ai_all_event_type:
+                    equipment_info['ai_event_type_list'] = list(map(int, str(event_type)))
+                if EquipmentInfoService.is_combo_tag(event_type, event_tag):
+                    equipment_info['ai_event_type_list'] += EquipmentInfoService.get_combo_types(event_type, event_tag)
+
+                res.append(equipment_info)
+            return response.json(0, {'datas': res, 'count': count})
+        except Exception as e:
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
+    @staticmethod
+    def get_msg_redis_url(redis_client, msg_key, is_st, storage_location):
+        if is_st == 3 and storage_location in [3, 4]:
+            img_data = redis_client.get_data(msg_key)
+            if img_data:
+                return json.loads(img_data)
+        return None
+
+    @staticmethod
+    def set_msg_redis_url(redis_client, msg_key, img_list):
+        redis_client.set_data(msg_key, json.dumps(img_list), 580)
+
+    @staticmethod
+    def oci_object_url(oci, obj_name):
+        """
+        获取OCI对象存储URL 有效期5分钟
+        @param oci:
+        @param obj_name: 对象名称
+        @return: url
+        """
+        time_expires = datetime.datetime.utcnow() + datetime.timedelta(minutes=10)
+        result = oci.get_preauthenticated_request_url(PUSH_BUCKET, 'ociPush', obj_name, time_expires)
+        return result.full_path if result else ''
+
+    def do_transfer(self, request_dict, response, userID):
+        event_time = request_dict.get('eventTime', None)
+        event_type = request_dict.get('eventType', None)
+        region = int(request_dict.get('region', None))
+        uid = request_dict.get('uid', None)
 
+        if not all([event_time, region, uid]):
+            return response.json(444)
+
+        try:
+            kwargs = {'device_user_id': userID, 'device_uid': uid, 'event_time': event_time, 'event_type': event_type}
+            equipment_info_qs, count = EquipmentInfoService.get_equipment_info(**kwargs)
+
+            # 查询设备类型,昵称
+            dvqs = Device_Info.objects.filter(UID=uid, userID_id=userID).values('UID', 'Type', 'NickName')
+            uid_type_dict = {}
+            for dv in dvqs:
+                uid_type_dict[dv['UID']] = {'type': dv['Type'], 'NickName': dv['NickName']}
+
+            # 没有推送数据返回空列表
+            if count == 0:
+                return response.json(0, {'datas': [], 'count': 0})
+
+            res = []
+            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
+            oss_img_bucket = oss2.Bucket(auth, 'oss-cn-shenzhen.aliyuncs.com', 'apg')
+            aws_s3 = boto3.client(
+                's3',
+                aws_access_key_id=AWS_ACCESS_KEY_ID[1],
+                aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
+                config=botocore.client.Config(signature_version='s3v4'),
+                region_name='us-east-1'
+            )
+            aws_s3_cn = boto3.client(
+                's3',
+                aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+                aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+                config=botocore.client.Config(signature_version='s3v4'),
+                region_name='cn-northwest-1'
+            )
+
+            oci_eur = OCIObjectStorage('eur')
+            oci_us = OCIObjectStorage('us')
             # ai消息标识所有组合标签
             ai_all_event_type = EquipmentInfoService.get_all_comb_event_type()
             for equipment_info in equipment_info_qs:
@@ -381,13 +573,16 @@ class DetectControllerViewV2(View):
                     thumbspng = '{}/{}/{}.jpeg'.format(uid, channel, event_time)
                     if storage_location == 1:  # 阿里云oss
                         img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
+                    elif storage_location in [3, 4]:
+                        oci = oci_eur if storage_location == 4 else oci_us
+                        img_url = DetectControllerViewV2.oci_object_url(oci, thumbspng)
                     else:
                         params = {'Key': thumbspng}
-                        if region == 1:     # AWS国外
+                        if region == 1:  # AWS国外
                             params['Bucket'] = 'foreignpush'
                             img_url = aws_s3.generate_presigned_url(
                                 'get_object', Params=params, ExpiresIn=300)
-                        else:               # AWS国内
+                        else:  # AWS国内
                             params['Bucket'] = 'push'
                             img_url = aws_s3_cn.generate_presigned_url(
                                 'get_object', Params=params, ExpiresIn=300)
@@ -410,17 +605,20 @@ class DetectControllerViewV2(View):
                     bucket = oss2.Bucket(auth, endpoint, bucket_name)
                     ts = '{}/vod{}/{}/ts0.ts'.format(uid, channel, event_time)
                     if storage_location == 1:  # 阿里云oss
-                        thumb0 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
-                        thumb1 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
-                        thumb2 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
+                        thumb0 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
+                        thumb1 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
+                        thumb2 = bucket.sign_url('GET', ts, 3600,
+                                                 params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
                         equipment_info['img_list'] = [thumb0, thumb1, thumb2]
                     else:
                         params = {'Key': ts}
-                        if region == 1:     # AWS国外
+                        if region == 1:  # AWS国外
                             params['Bucket'] = 'foreignpush'
                             img_url = aws_s3.generate_presigned_url(
                                 'get_object', Params=params, ExpiresIn=300)
-                        else:               # AWS国内
+                        else:  # AWS国内
                             params['Bucket'] = 'push'
                             img_url = aws_s3_cn.generate_presigned_url(
                                 'get_object', Params=params, ExpiresIn=300)
@@ -433,13 +631,16 @@ class DetectControllerViewV2(View):
                         thumbspng = '{}/{}/{}_{}.jpeg'.format(uid, channel, event_time, i)
                         if storage_location == 1:  # 阿里云oss
                             img_url = oss_img_bucket.sign_url('GET', thumbspng, 300)
+                        elif storage_location in [3, 4]:
+                            oci = oci_eur if storage_location == 4 else oci_us
+                            img_url = DetectControllerViewV2.oci_object_url(oci, thumbspng)
                         else:
                             params = {'Key': thumbspng}
-                            if region == 1:        # 国外AWS
+                            if region == 1:  # 国外AWS
                                 params['Bucket'] = 'foreignpush'
                                 img_url = aws_s3.generate_presigned_url(
                                     'get_object', Params=params, ExpiresIn=300)
-                            else:                  # 国内AWS
+                            else:  # 国内AWS
                                 params['Bucket'] = 'push'
                                 img_url = aws_s3_cn.generate_presigned_url(
                                     'get_object', Params=params, ExpiresIn=300)
@@ -462,8 +663,7 @@ class DetectControllerViewV2(View):
                 res.append(equipment_info)
             return response.json(0, {'datas': res, 'count': count})
         except Exception as e:
-            print('error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
-            return response.json(474)
+            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
 
     def do_update_interval(self, userID, request_dict, response):
         uid = request_dict.get('uid', None)

+ 133 - 0
Object/OCIObjectStorage.py

@@ -0,0 +1,133 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : OCIObjectStorage.py
+@Time    : 2024/4/10 15:06
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+
+import oci
+
+from Ansjer.config import OCI_CONFIG, OCI_NAMESPACE_NAME
+
+
+class OCIObjectStorage:
+
+    # Create a default oci_config using DEFAULT profile in default location
+    # Refer to
+    # https://docs.cloud.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm#SDK_and_CLI_Configuration_File
+    # for more info
+
+    def __init__(self, region):
+        # Initialize service client with default oci_config file
+        self.object_storage_client = oci.object_storage.ObjectStorageClient(OCI_CONFIG[region])
+
+    def create_ereauthenticated_request(self, bucket_name, name, object_name, time_expires):
+        """
+        创建特定于桶的预认证请求。
+        api:https://docs.oracle.com/en-us/iaas/api/#/en/objectstorage/20160918/PreauthenticatedRequest/CreatePreauthenticatedRequest
+        @param bucket_name: 存储桶名称
+        @param name: 请求名称 是创建的预授权链接的名称,是方便管理用的,不会影响功能。比如对每个桶分别创建链接,如果要删除或者查看,可以根据name看出来是对哪个桶的链接。
+        @param object_name: 对象名
+        @param time_expires: 失效时间 需要datetime类型格式 例如:datetime.utcnow() + timedelta(minutes=30)
+        @return: 预认证请求URL
+        """
+        try:
+            object_storage_client = self.object_storage_client
+
+            # Send the request to service, some parameters are not required, see API
+            # doc for more info
+            response = object_storage_client.create_preauthenticated_request(
+                namespace_name=OCI_NAMESPACE_NAME,
+                bucket_name=bucket_name,
+                create_preauthenticated_request_details=oci.object_storage.models.CreatePreauthenticatedRequestDetails(
+                    name=name,
+                    access_type="AnyObjectWrite",
+                    time_expires=time_expires,
+                    bucket_listing_action="Deny",
+                    object_name=object_name))
+
+            assert response.status == 200
+            return response.data
+
+        except Exception as e:
+            print(repr(e))
+            return None
+
+    def get_preauthenticated_request_url(self, bucket_name, name, object_name, time_expires):
+        """
+        获取指定对象预认证请求URL。
+        @param bucket_name: 存储桶名称
+        @param name: 请求名称 是创建的预授权链接的名称,是方便管理用的,不会影响功能。比如对每个桶分别创建链接,如果要删除或者查看,可以根据name看出来是对哪个桶的链接。
+        @param object_name: 对象名
+        @param time_expires: 失效时间 需要datetime类型格式 例如:datetime.utcnow() + timedelta(minutes=30)
+        @return: 预认证请求URL
+        """
+        try:
+            object_storage_client = self.object_storage_client
+            # 创建预认证请求
+            response = object_storage_client.create_preauthenticated_request(
+                namespace_name=OCI_NAMESPACE_NAME,
+                bucket_name=bucket_name,
+                create_preauthenticated_request_details=oci.object_storage.models.CreatePreauthenticatedRequestDetails(
+                    name=name,
+                    object_name=object_name,
+                    access_type="ObjectRead",
+                    time_expires=time_expires
+                )
+            )
+
+            assert response.status == 200
+            return response.data
+
+        except Exception as e:
+            print(repr(e))
+            return None
+
+    def put_object(self, bucket_name, object_name, obj, content_type=None):
+        """
+        上传对象
+        @param bucket_name: 存储桶名称
+        @param object_name: 对象名
+        @param obj: 数据内容
+        @param content_type: 文件类型
+        @return: 可访问对象URL
+        """
+        try:
+            object_storage_client = self.object_storage_client
+
+            # 发送上传请求
+            put_object_response = object_storage_client.put_object(
+                namespace_name=OCI_NAMESPACE_NAME,
+                bucket_name=bucket_name,
+                object_name=object_name,
+                put_object_body=obj,
+                content_type=content_type
+            )
+
+            # 打印响应头信息
+            assert put_object_response.status == 200
+        except Exception as e:
+            print(repr(e))
+            return None
+
+    def delete_object(self, bucket_name, object_name, content_type=None):
+        """
+        删除对象
+        @param bucket_name: 存储桶名称
+        @param object_name: 对象名
+        @param content_type: 文件类型
+        @return: 可访问对象URL
+        """
+        try:
+            object_storage_client = self.object_storage_client
+            # 发送删除请求
+            object_storage_client.delete_object(
+                namespace_name=OCI_NAMESPACE_NAME,
+                bucket_name=bucket_name,
+                object_name=object_name)
+        except Exception as e:
+            print(repr(e))
+            return None
+