瀏覽代碼

获取s3上传地址

peng 2 年之前
父節點
當前提交
81587ae75f
共有 1 個文件被更改,包括 178 次插入3 次删除
  1. 178 3
      Controller/IcloudService/IcloudService.py

+ 178 - 3
Controller/IcloudService/IcloudService.py

@@ -43,8 +43,10 @@ class IcloudServiceView(View):
             return response.json(tko.code)
         if operation == 'vodUpload':  # 云存上传云盘
             return self.vod_upload(request_dict, response, user_id)
-        elif operation == 'get-scanning-status':  # 确认app是否扫码
-            return self.get_scanning_status(request_dict, response)
+        elif operation == 'getUploadUrl':  # 获取s3上传地址
+            return self.get_upload_url(request_dict, response, user_id)
+        elif operation == 'localUpload':  # 本地上传云盘
+            return self.local_upload(request_dict, response, user_id)
         else:
             return response.json(404)
 
@@ -54,6 +56,112 @@ class IcloudServiceView(View):
         云存上传云盘
         @param request_dict: 请求参数
         @param user_id: 用户id
+        @request_dict uid: 设备uid
+        @request_dict channel: 设备通道
+        @request_dict start_time: 播放时间戳
+        @param response: 响应对象
+        @return: response
+        """
+        logger.info('开始云存转移到云盘')
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        time_stamp = request_dict.get('time_stamp', None)
+        if not all([uid, channel, time_stamp]):
+            return response.json(444, {'error param': 'uid,channel,start_time'})
+        device_qs = Device_Info.objects.filter(UID=uid, userID=user_id).values('NickName')
+        if not device_qs.exists():
+            return response.json(173)
+        # 查询是否开通云盘
+        use_details_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id', 'bucket_id', 'use_size')
+        if not use_details_qs.exists():
+            return response.json(173)
+        use_details_id = use_details_qs[0]['id']
+        target_bucket_id = use_details_qs[0]['bucket_id']
+        use_size = float(use_details_qs[0]['use_size'])
+        now_time = int(time.time())
+        nickname = device_qs[0]['NickName']
+        # 判断云盘是否还有容量
+        all_size = IcloudService.objects.filter(Q(use_details_id=use_details_id), Q(use_status=0),
+                                                Q(end_time__gt=now_time) | Q(end_time=0)).values(
+            'size').aggregate(total_size=Sum('size'))['total_size']
+        all_size = all_size * 1024 if all_size else 0
+        if use_size > all_size:
+            logger.info('{}用户套餐总容量为:{},已使用容量为:{}'.format(uid, all_size, use_size))
+            return response.json(910)
+        split_vod_hls_obj = SplitVodHlsObject()
+        vod_hls = split_vod_hls_obj.get_vod_hls_data(uid=uid, channel=channel, start_time=time_stamp).values(
+            'bucket_id', 'fg', 'sec')
+        if not vod_hls.exists():
+            logger.info('{}用户查无此云存:{}'.format(uid, time_stamp))
+            return response.json(173)
+        source_bucket_id = vod_hls[0]['bucket_id']
+        fg = int(vod_hls[0]['fg'])
+        sec = vod_hls[0]['sec']
+        target_bucket_qs = VodBucketModel.objects.filter(id=target_bucket_id).values('bucket')
+        if not target_bucket_qs.exists():
+            return response.json(173)
+        target_bucket_name = target_bucket_qs[0]['bucket']
+
+        source_bucket_qs = VodBucketModel.objects.filter(id=source_bucket_id).values('bucket', 'region', 'mold')
+        if not source_bucket_qs.exists():
+            return response.json(173)
+        bucket_region = source_bucket_qs[0]['region']
+        source_bucket_name = source_bucket_qs[0]['bucket']
+        mold = source_bucket_qs[0]["mold"]
+        ts_list = []
+        ts_size = 0
+        try:
+            s3_obj = AmazonS3Util(
+                AWS_ACCESS_KEY_ID[mold],
+                AWS_SECRET_ACCESS_KEY[mold],
+                bucket_region
+            )
+            # 获取s3对象,并计算总字节
+            for i in range(15):
+                shift = (i + 1) * 4
+                duration = (fg >> shift) & 0xf
+                if duration > 0:
+                    ts_file = '{uid}/vod{channel}/{time}/ts{i}.ts'.format(uid=uid, channel=channel, time=start_time,
+                                                                          i=i)
+                    ts_list.append(ts_file)
+                    ts_size += s3_obj.get_object_size(source_bucket_name, ts_file)  # 获取存储对象字节,单位B
+            ts_size = round(ts_size / 1024 / 1024, 2)  # 字节转换为MB单位
+            temp_size = ts_size + use_size
+            if temp_size > all_size:
+                logger.info('{}用户无空间上传,套餐容量为:{},使用容量为:{}'.format(uid, all_size, temp_size))
+                return response.json(910)
+            time_stamp = int(time_stamp) * 1000  # 转换单位为毫秒
+            icloud_record_qs = IcloudStorageRecord.objects.filter(user_id=user_id, uid=uid, channel=channel,
+                                                                  time_stamp=time_stamp,
+                                                                  size=ts_size, store_type=1)
+            if not icloud_record_qs.exists():  # 转移云盘,并记录上传记录,更新使用容量
+                for source_key in ts_list:
+                    ts_name = source_key.split('/')[-1]
+                    target_key = '{user_id}/ts_file/{uid}/vod{channel}/{time}/{ts_name}'.format(user_id=user_id,
+                                                                                                uid=uid,
+                                                                                                channel=channel,
+                                                                                                time=time_stamp,
+                                                                                                ts_name=ts_name)
+                    s3_obj.copy_single_obj(source_bucket_name, source_key, target_bucket_name, target_key)
+
+                IcloudStorageRecord.objects.create(user_id=user_id, uid=uid, channel=channel, time_stamp=time_stamp,
+                                                   nickname=nickname,
+                                                   sec=sec, bucket_id=target_bucket_id, fg=fg, size=ts_size,
+                                                   store_type=1)
+                use_details_qs.update(use_size=temp_size)
+                return response.json(0)
+            else:
+                return response.json(174)
+        except Exception as e:
+            logger.info('云存转移云盘异常:{}'.format(repr(e)))
+            return response.json(500)
+
+    @staticmethod
+    def local_upload(request_dict, response, user_id):
+        """
+        本地上传云盘
+        @param request_dict: 请求参数
+        @param user_id: 用户id
         @request_dict serial_number: 序列号
         @param response: 响应对象
         @return: response
@@ -112,6 +220,7 @@ class IcloudServiceView(View):
                 AWS_SECRET_ACCESS_KEY[mold],
                 bucket_region
             )
+            # 获取s3对象,并计算总字节
             for i in range(15):
                 shift = (i + 1) * 4
                 duration = (fg >> shift) & 0xf
@@ -129,7 +238,7 @@ class IcloudServiceView(View):
             icloud_record_qs = IcloudStorageRecord.objects.filter(user_id=user_id, uid=uid, channel=channel,
                                                                   time_stamp=start_time,
                                                                   size=ts_size, store_type=1)
-            if not icloud_record_qs.exists():
+            if not icloud_record_qs.exists():  # 转移云盘,并记录上传记录,更新使用容量
                 for source_key in ts_list:
                     ts_name = source_key.split('/')[-1]
                     target_key = '{user_id}/ts_file/{uid}/vod{channel}/{time}/{ts_name}'.format(user_id=user_id,
@@ -150,3 +259,69 @@ class IcloudServiceView(View):
         except Exception as e:
             logger.info('云存转移云盘异常:{}'.format(repr(e)))
             return response.json(500)
+
+    @staticmethod
+    def get_upload_url(request_dict, response, user_id):
+        """
+        获取s3上传地址
+        @param request_dict: 请求参数
+        @param user_id: 用户id
+        @request_dict serial_number: 序列号
+        @param response: 响应对象
+        @return: response
+        """
+        logger.info('获取s3上传地址')
+        time_stamp = request_dict.get('time_stamp', None)
+        file_type = request_dict.get('file_type', None)
+        uid = request_dict.get('uid', None)
+        channel = request_dict.get('channel', None)
+        if not all([time_stamp, uid, channel]):
+            return response.json(444, {'error param': 'time_stamp,channel,uid'})
+        device_qs = Device_Info.objects.filter(UID=uid, userID=user_id)
+        if not device_qs.exists():
+            return response.json(173)
+        # 查询是否开通云盘
+        use_details_qs = IcloudUseDetails.objects.filter(user_id=user_id).values('id', 'use_size', 'bucket_id')
+        if not use_details_qs.exists():
+            return response.json(173)
+        use_details_id = use_details_qs[0]['id']
+        use_size = use_details_qs[0]['use_size']
+        bucket_id = use_details_qs[0]['bucket_id']
+        now_time = int(time.time())
+        # 判断云盘是否还有容量
+        all_size = IcloudService.objects.filter(Q(use_details_id=use_details_id), Q(use_status=0),
+                                                Q(end_time__gt=now_time) | Q(end_time=0)).values(
+            'size').aggregate(total_size=Sum('size'))['total_size']
+        all_size = all_size * 1024 if all_size else 0
+        excess_size = all_size - use_size
+        if excess_size < 0:
+            logger.info('{}用户套餐总容量为:{},已使用容量为:{}'.format(user_id, all_size, use_size))
+            return response.json(910)
+
+        bucket_qs = VodBucketModel.objects.filter(id=bucket_id).values('bucket', 'region', 'mold')
+        if not bucket_qs.exists():
+            return response.json(173)
+        bucket_name = bucket_qs[0]['bucket']
+        bucket_region = bucket_qs[0]['region']
+        mold = bucket_qs[0]['mold']
+        try:
+            s3_obj = AmazonS3Util(
+                AWS_ACCESS_KEY_ID[mold],
+                AWS_SECRET_ACCESS_KEY[mold],
+                bucket_region
+            )
+            if file_type == '0':  # 图片
+                key_name = '{user_id}/image_file/{uid}/{channel}/{time}/{time}.jpg'.format(user_id=user_id, uid=uid,
+                                                                                           channel=channel,
+                                                                                           time=time_stamp)
+            elif file_type == '2':
+                key_name = '{user_id}/mp4_file/{uid}/{channel}/{time}/{time}.mp4'.format(user_id=user_id, uid=uid,
+                                                                                         channel=channel,
+                                                                                         time=time_stamp)
+            else:
+                return response.json(444, {'error param': 'file_type'})
+            upload_url = s3_obj.generate_put_obj_url(bucket_name, key_name)
+            return response.json(0, {'uploadUrl': upload_url, 'excessSize': excess_size})
+        except Exception as e:
+            logger.info('获取s3上传地址异常:{}'.format(repr(e)))
+            return response.json(500)