Files
nanocode/new-media-platform/website-new/backend/app/utils/file_utils.py
T
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

102 lines
3.1 KiB
Python

"""
文件工具函数
提供统一的文件删除功能,自动处理缩略图同步删除
"""
import os
from pathlib import Path
from app.config import get_settings
settings = get_settings()
# 文件系统路径(从配置读取)
UPLOAD_DIR = Path(settings.UPLOAD_DIR)
THUMBNAIL_DIR = UPLOAD_DIR / "thumbnails"
# URL 路径
STORAGE_URL = "/storage/admin/images"
THUMBNAIL_URL = f"{STORAGE_URL}/thumbnails"
def cleanup_file(file_path: str | Path) -> bool:
"""
删除文件并同步删除对应的缩略图
Args:
file_path: 文件路径(相对 /uploads 的路径、/storage/admin/images/ 格式或绝对路径)
Returns:
bool: 是否成功删除原文件
"""
if not file_path:
return False
# 统一处理为 Path 对象
if isinstance(file_path, str):
# 处理新的存储路径格式 /storage/admin/images/...
if file_path.startswith("/storage/admin/images/"):
# 提取相对路径部分
relative_path = file_path[len("/storage/admin/images/"):]
full_path = UPLOAD_DIR / relative_path
else:
# 移除开头的 / 并构建完整路径(兼容旧格式)
relative_path = file_path.lstrip("/")
full_path = UPLOAD_DIR / relative_path
else:
full_path = file_path
# 删除原文件
deleted = False
try:
if full_path.exists():
full_path.unlink()
deleted = True
print(f"[cleanup] 已删除文件: {full_path}")
except Exception as e:
print(f"[cleanup] 删除文件失败 {full_path}: {e}")
# 同步删除缩略图
# 缩略图与原图同名,但扩展名统一为 .jpg,存放在 /uploads/thumbnails/
try:
thumbnail_name = f"{full_path.stem}.jpg"
thumb_path = THUMBNAIL_DIR / thumbnail_name
if thumb_path.exists():
thumb_path.unlink()
print(f"[cleanup] 已删除缩略图: {thumb_path}")
except Exception as e:
print(f"[cleanup] 删除缩略图失败: {e}")
return deleted
def cleanup_file_by_path(relative_path: str) -> bool:
"""
根据相对路径删除文件及其缩略图
Args:
relative_path: 相对于 /uploads 的路径,如 "20250420_xxx.jpg"
或者完整的存储路径如 "/storage/admin/images/xxx.jpg"
Returns:
bool: 是否成功删除原文件
"""
if not relative_path:
return False
# 排除外部 URL
if relative_path.startswith(("http://", "https://")):
print(f"[cleanup] 跳过外部 URL: {relative_path}")
return False
# 处理新的存储路径格式 /storage/admin/images/...
if relative_path.startswith("/storage/admin/images/"):
# 提取相对路径部分
rel_path = relative_path[len("/storage/admin/images/"):]
full_path = UPLOAD_DIR / rel_path
else:
# 处理可能包含开头 / 的路径(兼容旧格式)
rel_path = relative_path.lstrip("/")
full_path = UPLOAD_DIR / rel_path
return cleanup_file(full_path)