Files
video/util/file_util.py
2025-09-16 20:17:48 +08:00

86 lines
3.8 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.

import os
import datetime
from pathlib import Path
from typing import Dict
def save_face_to_up_images(
client_ip: str,
face_name: str,
image_bytes: bytes,
image_format: str = "jpg"
) -> Dict[str, str]:
"""
保存人脸图片到 `/up_images/用户IP/人脸名字/` 路径
确保db_path以 /api/file/up_images 开头,且统一使用正斜杠
本地不创建/api/file/文件夹仅URL访问时使用该前缀路由
参数:
client_ip: 客户端IP原始格式如192.168.1.101
face_name: 人脸名称(用户输入,可为空)
image_bytes: 人脸图片二进制数据
image_format: 图片格式默认jpg
返回:
字典success是否成功、db_path存数据库的路径带/api/file/前缀、local_abs_path本地绝对路径、msg提示
"""
try:
# 1. 基础参数校验(不变)
if not client_ip.strip():
return {"success": False, "db_path": "", "local_abs_path": "", "msg": "客户端IP不能为空"}
if not image_bytes:
return {"success": False, "db_path": "", "local_abs_path": "", "msg": "图片二进制数据为空"}
if image_format.lower() not in ["jpg", "jpeg", "png"]:
return {"success": False, "db_path": "", "local_abs_path": "", "msg": "仅支持jpg/jpeg/png格式"}
# 2. 处理特殊字符(避免路径错误)(不变)
safe_ip = client_ip.strip().replace(".", "_") # IP中的.替换为_
safe_face_name = face_name.strip() if (face_name and face_name.strip()) else "未命名"
safe_face_name = "".join([c for c in safe_face_name if c not in r'\/:*?"<>|']) # 过滤非法字符
# 3. 构建根目录(强制转为绝对路径,避免相对路径混淆)
root_dir = Path("up_images").resolve()
if not root_dir.exists():
root_dir.mkdir(parents=True, exist_ok=True)
print(f"[FileUtil] 已创建up_images根目录{root_dir}")
# 4. 构建文件层级路径确保在root_dir子目录下不变
ip_dir = root_dir / safe_ip
face_name_dir = ip_dir / safe_face_name
face_name_dir.mkdir(parents=True, exist_ok=True)
print(f"[FileUtil] 图片存储目录(本地):{face_name_dir}")
# 5. 生成唯一文件名(毫秒级时间戳)(不变)
timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")[:-3]
image_filename = f"face_{safe_ip}_{timestamp}.{image_format.lower()}"
local_abs_path = face_name_dir / image_filename
if not local_abs_path.resolve().is_relative_to(root_dir.resolve()):
raise Exception(f"图片路径不在up_images根目录下安全校验失败{local_abs_path}")
# 数据库存储路径核心修改——在原有relative_path前添加 /api/file/ 前缀
relative_path = local_abs_path.relative_to(root_dir.parent)
relative_path_str = str(relative_path).replace("\\", "/")
# 2. 再拼接/api/file/前缀
db_path = f"/api/file/{relative_path_str}"
# 7. 写入图片文件(不变)
with open(local_abs_path, "wb") as f:
f.write(image_bytes)
print(f"[FileUtil] 图片保存成功:")
print(f" 数据库路径(带/api/file/前缀):{db_path}")
print(f" 本地绝对路径(无/api/file/{local_abs_path}")
return {
"success": True,
"db_path": db_path,
"local_abs_path": str(local_abs_path),
"msg": "图片保存成功"
}
except Exception as e:
error_msg = f"图片保存失败:{str(e)}"
print(f"[FileUtil] 错误:{error_msg}")
return {"success": False, "db_path": "", "local_abs_path": "", "msg": error_msg}