"""媒体文件落盘:相对技能数据目录的路径约定。""" from __future__ import annotations import os import shutil from typing import Tuple def media_subdir(kind: str, media_id: int) -> str: """kind: images | videos""" return f"{kind}/{media_id}" def original_basename(src_path: str) -> str: ext = os.path.splitext(src_path)[1] return f"original{ext if ext else ''}" def copy_into_skill_data( skill_data_dir: str, kind: str, media_id: int, src_path: str, ) -> Tuple[str, str]: """ 将源文件复制到 {skill_data_dir}/{kind}/{id}/original.ext 返回 (relative_path, absolute_dest_path) """ sub = media_subdir(kind, media_id) dest_dir = os.path.join(skill_data_dir, sub.replace("/", os.sep)) os.makedirs(dest_dir, exist_ok=True) base = original_basename(src_path) abs_dest = os.path.join(dest_dir, base) shutil.copy2(src_path, abs_dest) rel = f"{kind}/{media_id}/{base}".replace("\\", "/") return rel, abs_dest def remove_files_for_relative_path(skill_data_dir: str, relative_file_path: str) -> None: """删除 relative_file_path 所在目录(整 id 目录)。""" rel = (relative_file_path or "").strip().replace("\\", "/") if not rel or "/" not in rel: return parts = rel.split("/") if len(parts) < 2: return id_dir = os.path.join(skill_data_dir, parts[0], parts[1]) if os.path.isdir(id_dir): shutil.rmtree(id_dir, ignore_errors=True)