135 lines
5.1 KiB
Python
135 lines
5.1 KiB
Python
from obs import ObsClient
|
||
import traceback
|
||
import atexit
|
||
import os
|
||
|
||
|
||
class HW_OBS:
|
||
def __init__(self, ak='', sk='', server="https://obs.cn-south-1.myhuaweicloud.com"):
|
||
"""初始化OBS客户端"""
|
||
self.obsClient = ObsClient(access_key_id=ak, secret_access_key=sk, server=server)
|
||
atexit.register(self.close) # 注册 close 方法到 atexit
|
||
|
||
def get_packages(self, bucket_name, prefix, max_keys=100):
|
||
"""
|
||
列举OBS存储桶内的对象。
|
||
:param bucket_name: 存储桶名称
|
||
:param prefix: 对象的前缀
|
||
:param max_keys: 单次列举对象的最大数量
|
||
:return: 对象列表
|
||
"""
|
||
try:
|
||
# 列举对象
|
||
resp = self.obsClient.listObjects(bucket_name, prefix, max_keys=max_keys, encoding_type='url')
|
||
|
||
if resp.status < 300:
|
||
print('List Objects Succeeded')
|
||
# print('requestId:', resp.requestId)
|
||
# print('bucket_name:', resp.body.name)
|
||
# print('prefix:', resp.body.prefix)
|
||
# print('max_keys:', resp.body.max_keys)
|
||
# print('is_truncated:', resp.body.is_truncated)
|
||
|
||
object_list = []
|
||
for content in resp.body.contents:
|
||
obj_info = {
|
||
'key': content.key,
|
||
'lastModified': content.lastModified,
|
||
'etag': content.etag,
|
||
'size': content.size,
|
||
'storageClass': content.storageClass,
|
||
'owner_id': content.owner.owner_id,
|
||
'owner_name': content.owner.owner_name,
|
||
}
|
||
object_list.append(obj_info)
|
||
# print(obj_info)
|
||
return object_list
|
||
else:
|
||
print('List Objects Failed')
|
||
# print('requestId:', resp.requestId)
|
||
print('errorCode:', resp.errorCode)
|
||
print('errorMessage:', resp.errorMessage)
|
||
return None
|
||
except Exception:
|
||
print('List Objects Failed')
|
||
print(traceback.format_exc())
|
||
return None
|
||
|
||
def download(self, bucket_name, object_key, download_dir, part_size=10 * 1024 * 1024, task_num=5, enable_checkpoint=True, callback = None):
|
||
"""
|
||
下载OBS存储桶内的对象。
|
||
:param bucket_name: 存储桶名称
|
||
:param object_key: 对象的Key
|
||
:param download_dir: 下载到本地的文件夹路径
|
||
:param part_size: 分段大小(默认10MB)
|
||
:param task_num: 分段下载的并发数
|
||
:param enable_checkpoint: 是否启用断点续传
|
||
"""
|
||
if callback is None:
|
||
def callback(transferredAmount, totalAmount, totalSeconds):
|
||
"""下载进度回调"""
|
||
try:
|
||
avg_speed_kb = transferredAmount / totalSeconds / 1024
|
||
progress_percent = transferredAmount * 100.0 / totalAmount
|
||
# print(f"Downloaded: {transferredAmount / (1024 * 1024):.2f} MB / {totalAmount / (1024 * 1024):.2f} MB")
|
||
print(f"Progress: {progress_percent:.2f}% | Speed: {avg_speed_kb:.2f} KB/s")
|
||
except ZeroDivisionError:
|
||
print("Calculating speed... insufficient data (totalSeconds is 0).")
|
||
|
||
try:
|
||
# 检查目标文件夹是否存在,不存在则创建
|
||
if not os.path.exists(download_dir):
|
||
os.makedirs(download_dir)
|
||
print(f"Directory created: {download_dir}")
|
||
|
||
# 提取文件名并拼接完整路径
|
||
file_name = object_key.split("/")[-1]
|
||
download_file = os.path.join(download_dir, file_name)
|
||
|
||
resp = self.obsClient.downloadFile(
|
||
bucket_name, object_key, download_file, part_size, task_num, enable_checkpoint, progressCallback=callback
|
||
)
|
||
|
||
if resp.status < 300:
|
||
print('Download File Succeeded:', download_file)
|
||
else:
|
||
print('Download File Failed')
|
||
print('errorCode:', resp.errorCode)
|
||
print('errorMessage:', resp.errorMessage)
|
||
except Exception:
|
||
print('Download File Failed')
|
||
print(traceback.format_exc())
|
||
|
||
def close(self):
|
||
"""关闭OBS客户端"""
|
||
try:
|
||
if self.obsClient:
|
||
self.obsClient.close()
|
||
print("OBS Client closed successfully.")
|
||
except Exception as e:
|
||
print("Failed to close OBS Client:", e)
|
||
|
||
|
||
# 使用示例
|
||
if __name__ == '__main__':
|
||
# 替换为实际的ak、sk和服务器地址
|
||
ak = ''
|
||
sk = ''
|
||
server = "https://obs.cn-south-1.myhuaweicloud.com"
|
||
|
||
obs = HW_OBS(ak, sk, server)
|
||
|
||
# 列举对象
|
||
bucket_name = "robotstorm-files"
|
||
prefix = "MassageRobot_aubo/MassageRobot_aubo-"
|
||
packages = obs.get_packages(bucket_name, prefix)
|
||
print(packages)
|
||
|
||
# 下载对象
|
||
object_key = packages[0]['key']
|
||
download_dir = '/home/jsfb/jsfb_ws/downloads/'
|
||
obs.download(bucket_name, object_key, download_dir)
|
||
|
||
# 关闭客户端
|
||
# obs.close()
|