mirror of
https://github.com/RhenCloud/Cloud-Index.git
synced 2025-12-06 15:26:10 +08:00
- 实现 11 个 API 端点:上传、删除、重命名、复制、移动、创建文件夹等 - 构建存储抽象层,支持多后端(R2、S3、GitHub) - 添加完整的前端界面:列表/网格视图、文件操作、批量管理 - 添加深色/浅色主题支持 - 迁移至 Jinja2 模板继承架构 - 添加完整的 API 文档和项目文档 - 优化 Vercel 部署配置
211 lines
4.9 KiB
Python
211 lines
4.9 KiB
Python
from abc import ABC, abstractmethod
|
||
from datetime import datetime
|
||
from typing import Any, Dict
|
||
|
||
|
||
class BaseStorage(ABC):
|
||
"""存储后端的基类,定义统一接口"""
|
||
|
||
@abstractmethod
|
||
def list_objects(self, prefix: str = "") -> Dict[str, Any]:
|
||
"""
|
||
列出存储桶中的对象
|
||
|
||
Args:
|
||
prefix: 对象前缀(用于目录浏览)
|
||
|
||
Returns:
|
||
包含对象列表的字典
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def get_object_info(self, key: str) -> Dict[str, Any]:
|
||
"""
|
||
获取对象基本信息
|
||
|
||
Args:
|
||
key: 对象键名
|
||
|
||
Returns:
|
||
对象元数据
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def get_object(self, key: str) -> Dict[str, Any]:
|
||
"""
|
||
获取对象内容
|
||
|
||
Args:
|
||
key: 对象键名
|
||
|
||
Returns:
|
||
包含对象内容的字典
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def generate_presigned_url(self, key: str, expires: int = None) -> str:
|
||
"""
|
||
为指定对象生成预签名 URL
|
||
|
||
Args:
|
||
key: 对象键名
|
||
expires: 过期时间(秒)
|
||
|
||
Returns:
|
||
预签名 URL,失败返回 None
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def get_public_url(self, key: str) -> str:
|
||
"""
|
||
生成对象的公共访问 URL
|
||
|
||
Args:
|
||
key: 对象键名
|
||
|
||
Returns:
|
||
公共 URL,未配置返回 None
|
||
"""
|
||
pass
|
||
|
||
def format_timestamp(self, timestamp) -> str:
|
||
"""
|
||
格式化时间戳为人类可读的格式
|
||
|
||
Args:
|
||
timestamp: 时间戳对象
|
||
|
||
Returns:
|
||
格式化后的时间字符串
|
||
"""
|
||
if isinstance(timestamp, datetime):
|
||
return timestamp.strftime("%Y-%m-%d %H:%M:%S")
|
||
return str(timestamp)
|
||
|
||
@abstractmethod
|
||
def generate_thumbnail(self, file_path: str) -> bytes:
|
||
"""
|
||
生成图片缩略图
|
||
|
||
Args:
|
||
file_path: 文件路径
|
||
|
||
Returns:
|
||
缩略图字节数据
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def upload_file(self, key: str, file_data: bytes, content_type: str = None) -> bool:
|
||
"""
|
||
上传文件到存储
|
||
|
||
Args:
|
||
key: 对象键名(文件路径)
|
||
file_data: 文件二进制数据
|
||
content_type: 文件类型(MIME type)
|
||
|
||
Returns:
|
||
上传成功返回 True,失败返回 False
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def delete_file(self, key: str) -> bool:
|
||
"""
|
||
删除存储中的文件
|
||
|
||
Args:
|
||
key: 对象键名(文件路径)
|
||
|
||
Returns:
|
||
删除成功返回 True,失败返回 False
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def rename_file(self, old_key: str, new_key: str) -> bool:
|
||
"""
|
||
重命名存储中的文件
|
||
|
||
Args:
|
||
old_key: 旧的对象键名
|
||
new_key: 新的对象键名
|
||
|
||
Returns:
|
||
重命名成功返回 True,失败返回 False
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def delete_folder(self, prefix: str) -> bool:
|
||
"""
|
||
删除存储中的文件夹(前缀)
|
||
|
||
Args:
|
||
prefix: 要删除的文件夹前缀
|
||
|
||
Returns:
|
||
删除成功返回 True,失败返回 False
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def rename_folder(self, old_prefix: str, new_prefix: str) -> bool:
|
||
"""
|
||
重命名存储中的文件夹(前缀)
|
||
|
||
Args:
|
||
old_prefix: 旧的文件夹前缀
|
||
new_prefix: 新的文件夹前缀
|
||
|
||
Returns:
|
||
重命名成功返回 True,失败返回 False
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def copy_file(self, source_key: str, dest_key: str) -> bool:
|
||
"""
|
||
复制存储中的文件
|
||
|
||
Args:
|
||
source_key: 源对象键名
|
||
dest_key: 目标对象键名
|
||
|
||
Returns:
|
||
复制成功返回 True,失败返回 False
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def copy_folder(self, source_prefix: str, dest_prefix: str) -> bool:
|
||
"""
|
||
复制存储中的文件夹(前缀)
|
||
|
||
Args:
|
||
source_prefix: 源文件夹前缀
|
||
dest_prefix: 目标文件夹前缀
|
||
|
||
Returns:
|
||
复制成功返回 True,失败返回 False
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def create_folder(self, key: str) -> bool:
|
||
"""
|
||
创建文件夹
|
||
|
||
Args:
|
||
key: 文件夹路径(以 / 结尾)
|
||
|
||
Returns:
|
||
创建成功返回 True,失败返回 False
|
||
"""
|
||
pass
|