mirror of
https://github.com/huge-dream/django-vue3-admin.git
synced 2026-10-01 00:05:15 +00:00
- Rename minio_storage.py to rustfs_storage.py - Update all MINIO_* settings to RUSTFS_* in env.py - Update file_list.py to import rustfs_upload_file - Update test files and factory to use rustfs engine
119 lines
3.2 KiB
Python
119 lines
3.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
RustFS (S3-compatible) 文件存储工具
|
|
"""
|
|
import uuid
|
|
from typing import Optional
|
|
|
|
import boto3
|
|
from botocore.config import Config
|
|
from botocore.exceptions import ClientError
|
|
from django.conf import settings
|
|
|
|
|
|
def get_rustfs_client():
|
|
"""
|
|
创建 RustFS S3 客户端
|
|
"""
|
|
client = boto3.client(
|
|
's3',
|
|
endpoint_url=f"{'https' if settings.RUSTFS_SECURE else 'http'}://{settings.RUSTFS_ENDPOINT}",
|
|
aws_access_key_id=settings.RUSTFS_ACCESS_KEY,
|
|
aws_secret_access_key=settings.RUSTFS_SECRET_KEY,
|
|
region_name=settings.RUSTFS_REGION or 'us-east-1',
|
|
config=Config(signature_version='s3v4'),
|
|
)
|
|
return client
|
|
|
|
|
|
def rustfs_upload_file(file_obj, file_name: str) -> Optional[str]:
|
|
"""
|
|
上传文件到 RustFS
|
|
|
|
Args:
|
|
file_obj: 文件对象 (InMemoryUploadedFile 或 UploadedFile)
|
|
file_name: 原始文件名
|
|
|
|
Returns:
|
|
文件访问URL,失败返回 None
|
|
"""
|
|
try:
|
|
# 生成唯一文件名 (uuid前缀避免冲突)
|
|
ext = file_name.split('.')[-1] if '.' in file_name else ''
|
|
unique_name = f"{uuid.uuid4().hex}.{ext}" if ext else uuid.uuid4().hex
|
|
|
|
# 路径前缀处理
|
|
path_prefix = getattr(settings, 'RUSTFS_PATH_PREFIX', '')
|
|
if path_prefix:
|
|
path_prefix = path_prefix.strip('/') + '/'
|
|
object_name = f"{path_prefix}{unique_name}"
|
|
|
|
# 获取文件内容
|
|
file_obj.seek(0)
|
|
file_content = file_obj.read()
|
|
|
|
# 上传
|
|
client = get_rustfs_client()
|
|
client.put_object(
|
|
Bucket=settings.RUSTFS_BUCKET,
|
|
Key=object_name,
|
|
Body=file_content,
|
|
ContentType=getattr(file_obj, 'content_type', 'application/octet-stream'),
|
|
)
|
|
|
|
# 生成访问URL
|
|
file_url = rustfs_get_file_url(object_name)
|
|
return file_url
|
|
|
|
except ClientError as e:
|
|
print(f"RustFS upload error: {e}")
|
|
return None
|
|
except Exception as e:
|
|
print(f"RustFS upload unexpected error: {e}")
|
|
return None
|
|
|
|
|
|
def rustfs_delete_file(file_url: str) -> bool:
|
|
"""
|
|
从 RustFS 删除文件
|
|
|
|
Args:
|
|
file_url: 文件完整URL或 object_key
|
|
|
|
Returns:
|
|
删除成功返回 True,否则 False
|
|
"""
|
|
try:
|
|
# 从URL中提取 object_key
|
|
object_key = file_url
|
|
if settings.RUSTFS_ENDPOINT in file_url:
|
|
# 提取 /bucket/key 部分
|
|
parts = file_url.split(settings.RUSTFS_BUCKET + '/')
|
|
if len(parts) > 1:
|
|
object_key = parts[-1]
|
|
else:
|
|
return True # URL格式不对,当作已删除
|
|
|
|
client = get_rustfs_client()
|
|
client.delete_object(Bucket=settings.RUSTFS_BUCKET, Key=object_key)
|
|
return True
|
|
except ClientError as e:
|
|
print(f"RustFS delete error: {e}")
|
|
return False
|
|
|
|
|
|
def rustfs_get_file_url(object_key: str) -> str:
|
|
"""
|
|
获取文件访问URL
|
|
|
|
Args:
|
|
object_key: 对象存储的key
|
|
|
|
Returns:
|
|
完整的文件访问URL
|
|
"""
|
|
scheme = 'https' if settings.RUSTFS_SECURE else 'http'
|
|
endpoint = settings.RUSTFS_ENDPOINT
|
|
bucket = settings.RUSTFS_BUCKET
|
|
return f"{scheme}://{endpoint}/{bucket}/{object_key}"
|