|
|
from __future__ import annotations
|
|
|
|
|
|
import os
|
|
|
from typing import Dict, Optional, Union
|
|
|
|
|
|
from flask import current_app
|
|
|
|
|
|
from .interface import StorageInterface
|
|
|
from .local import LocalStorage
|
|
|
from ..enums import StorageTypeEnum
|
|
|
|
|
|
|
|
|
class StorageManager:
|
|
|
"""存储管理器,负责根据类型创建存储实例"""
|
|
|
|
|
|
_instances: Dict[str, StorageInterface] = {}
|
|
|
|
|
|
@classmethod
|
|
|
def get_storage(cls, storage_type: Optional[Union[str, StorageTypeEnum]] = None) -> StorageInterface:
|
|
|
"""
|
|
|
获取存储实例(单例模式)
|
|
|
|
|
|
Args:
|
|
|
storage_type: 存储类型(支持字符串或 StorageTypeEnum),为None时使用默认类型
|
|
|
|
|
|
Returns:
|
|
|
存储实例
|
|
|
"""
|
|
|
# 标准化存储类型为字符串
|
|
|
storage_type_str = cls._normalize_storage_type(storage_type)
|
|
|
|
|
|
if storage_type_str not in cls._instances:
|
|
|
config = current_app.config.get("FILE_STORAGE", {})
|
|
|
cls._instances[storage_type_str] = cls._create_storage(storage_type_str, config)
|
|
|
return cls._instances[storage_type_str]
|
|
|
|
|
|
@staticmethod
|
|
|
def _normalize_storage_type(storage_type: Optional[Union[str, StorageTypeEnum]]) -> str:
|
|
|
"""
|
|
|
标准化存储类型为字符串
|
|
|
|
|
|
Args:
|
|
|
storage_type: 存储类型(字符串或 StorageTypeEnum)
|
|
|
|
|
|
Returns:
|
|
|
存储类型字符串
|
|
|
"""
|
|
|
# 如果未指定,使用默认类型
|
|
|
if storage_type is None:
|
|
|
config = current_app.config.get("FILE_STORAGE", {})
|
|
|
return config.get("DEFAULT_STORAGE_TYPE", StorageTypeEnum.LOCAL.value)
|
|
|
|
|
|
# 如果是 enum,转换为字符串
|
|
|
if isinstance(storage_type, StorageTypeEnum):
|
|
|
return storage_type.value
|
|
|
|
|
|
# 已经是字符串,直接返回
|
|
|
return storage_type
|
|
|
|
|
|
@staticmethod
|
|
|
def _create_storage(storage_type: str, config: dict) -> StorageInterface:
|
|
|
"""
|
|
|
创建存储实例
|
|
|
|
|
|
Args:
|
|
|
storage_type: 存储类型
|
|
|
config: 配置字典
|
|
|
|
|
|
Returns:
|
|
|
存储实例
|
|
|
"""
|
|
|
if storage_type == StorageTypeEnum.LOCAL.value:
|
|
|
local_config = config.get("LOCAL", {})
|
|
|
if not local_config.get("base_path"):
|
|
|
local_config["base_path"] = os.path.join(
|
|
|
current_app.config.get("BASE_DIR", current_app.root_path), "runtime", "uploads"
|
|
|
)
|
|
|
return LocalStorage(local_config)
|
|
|
|
|
|
elif storage_type == StorageTypeEnum.ALIYUN_OSS.value:
|
|
|
from .aliyun_oss import AliyunOSSStorage
|
|
|
oss_config = config.get("ALIYUN_OSS", {})
|
|
|
return AliyunOSSStorage(oss_config)
|
|
|
|
|
|
elif storage_type == StorageTypeEnum.TENCENT_COS.value:
|
|
|
from .tencent_cos import TencentCOSStorage
|
|
|
cos_config = config.get("TENCENT_COS", {})
|
|
|
return TencentCOSStorage(cos_config)
|
|
|
|
|
|
elif storage_type == StorageTypeEnum.QINIU_KODO.value:
|
|
|
from .qiniu_kodo import QiniuKodoStorage
|
|
|
kodo_config = config.get("QINIU_KODO", {})
|
|
|
return QiniuKodoStorage(kodo_config)
|
|
|
|
|
|
elif storage_type == StorageTypeEnum.AWS_S3.value:
|
|
|
# AWS S3 可以后续添加
|
|
|
raise NotImplementedError("AWS S3 适配器尚未实现")
|
|
|
|
|
|
elif storage_type == StorageTypeEnum.HUAWEI_OBS.value:
|
|
|
from .huawei_obs import HuaweiOBSStorage
|
|
|
obs_config = config.get("HUAWEI_OBS", {})
|
|
|
return HuaweiOBSStorage(obs_config)
|
|
|
|
|
|
elif storage_type == StorageTypeEnum.MINIO.value:
|
|
|
from .minio_storage import MinIOStorage
|
|
|
minio_config = config.get("MINIO", {})
|
|
|
return MinIOStorage(minio_config)
|
|
|
|
|
|
raise ValueError(f"未支持的存储类型: {storage_type}")
|
|
|
|