CodeReview/backend/app/services/zip_storage.py

146 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
ZIP文件存储服务
用于管理项目的ZIP文件持久化存储
"""
import os
import shutil
from pathlib import Path
from typing import Optional
from datetime import datetime
from app.core.config import settings
def get_zip_storage_path() -> Path:
"""获取ZIP文件存储目录"""
path = Path(settings.ZIP_STORAGE_PATH)
path.mkdir(parents=True, exist_ok=True)
return path
def get_project_zip_path(project_id: str) -> Path:
"""获取项目ZIP文件路径"""
return get_zip_storage_path() / f"{project_id}.zip"
def get_project_zip_meta_path(project_id: str) -> Path:
"""获取项目ZIP文件元数据路径"""
return get_zip_storage_path() / f"{project_id}.meta"
async def save_project_zip(project_id: str, file_path: str, original_filename: str) -> dict:
"""
保存项目ZIP文件
Args:
project_id: 项目ID
file_path: 临时文件路径
original_filename: 原始文件名
Returns:
文件元数据
"""
target_path = get_project_zip_path(project_id)
meta_path = get_project_zip_meta_path(project_id)
# 复制文件到存储目录
shutil.copy2(file_path, target_path)
# 获取文件大小
file_size = os.path.getsize(target_path)
# 保存元数据
meta = {
"original_filename": original_filename,
"file_size": file_size,
"uploaded_at": datetime.utcnow().isoformat(),
"project_id": project_id
}
import json
with open(meta_path, 'w') as f:
json.dump(meta, f)
print(f"✓ ZIP文件已保存: {project_id} ({file_size / 1024 / 1024:.2f} MB)")
return meta
async def load_project_zip(project_id: str) -> Optional[str]:
"""
加载项目ZIP文件路径
Args:
project_id: 项目ID
Returns:
ZIP文件路径如果不存在返回None
"""
zip_path = get_project_zip_path(project_id)
if zip_path.exists():
return str(zip_path)
return None
async def get_project_zip_meta(project_id: str) -> Optional[dict]:
"""
获取项目ZIP文件元数据
Args:
project_id: 项目ID
Returns:
元数据字典如果不存在返回None
"""
meta_path = get_project_zip_meta_path(project_id)
if not meta_path.exists():
return None
import json
with open(meta_path, 'r') as f:
return json.load(f)
async def delete_project_zip(project_id: str) -> bool:
"""
删除项目ZIP文件
Args:
project_id: 项目ID
Returns:
是否成功删除
"""
zip_path = get_project_zip_path(project_id)
meta_path = get_project_zip_meta_path(project_id)
deleted = False
if zip_path.exists():
os.remove(zip_path)
deleted = True
print(f"✓ 已删除ZIP文件: {project_id}")
if meta_path.exists():
os.remove(meta_path)
return deleted
async def has_project_zip(project_id: str) -> bool:
"""
检查项目是否有ZIP文件
Args:
project_id: 项目ID
Returns:
是否存在ZIP文件
"""
zip_path = get_project_zip_path(project_id)
return zip_path.exists()