pdf-ppt / backend /utils /path_utils.py
asemxin2000's picture
Upload folder using huggingface_hub
8576e2e verified
Raw
History Blame Contribute Delete
4.28 kB
"""
Path utilities for handling MinerU file paths and prefix matching
"""
import os
import logging
from pathlib import Path
from typing import Optional
logger = logging.getLogger(__name__)
def convert_mineru_path_to_local(mineru_path: str, project_root: Optional[Path] = None) -> Optional[Path]:
"""
将 /files/mineru/{extract_id}/{rel_path} 格式的路径转换为本地文件系统路径
Args:
mineru_path: MinerU URL 路径,格式为 /files/mineru/{extract_id}/{rel_path}
project_root: 项目根目录路径(如果为 None,则自动计算)
Returns:
本地文件系统路径(Path 对象),如果转换失败则返回 None
"""
try:
if not mineru_path.startswith('/files/mineru/'):
return None
# Remove '/files/mineru/' prefix
rel_path = mineru_path.replace('/files/mineru/', '')
# Get project root if not provided
if project_root is None:
# Navigate to project root (assuming this file is in backend/utils/)
current_file = Path(__file__).resolve()
backend_dir = current_file.parent.parent
project_root = backend_dir.parent
# Construct full path: {project_root}/uploads/mineru_files/{rel_path}
local_path = project_root / 'uploads' / 'mineru_files' / rel_path
return local_path
except Exception as e:
logger.warning(f"Failed to convert MinerU path to local: {mineru_path}, error: {str(e)}")
return None
def find_mineru_file_with_prefix(mineru_path: str, project_root: Optional[Path] = None) -> Optional[Path]:
"""
查找 MinerU 文件,支持前缀匹配
首先尝试直接路径匹配,如果失败则尝试前缀匹配。
前缀匹配逻辑:如果文件名看起来像是一个前缀+扩展名(前缀长度 >= 5),
则在目录中查找以该前缀开头的文件。
Args:
mineru_path: MinerU URL 路径,格式为 /files/mineru/{extract_id}/{rel_path}
project_root: 项目根目录路径(如果为 None,则自动计算)
Returns:
找到的文件路径(Path 对象),如果未找到则返回 None
"""
# First try direct path conversion
local_path = convert_mineru_path_to_local(mineru_path, project_root)
if local_path is None:
return None
# Direct file matching
if local_path.exists() and local_path.is_file():
return local_path
# Try prefix match using the generic function
return find_file_with_prefix(local_path)
def find_file_with_prefix(file_path: Path) -> Optional[Path]:
"""
查找文件,支持前缀匹配
首先检查文件是否存在,如果不存在则尝试前缀匹配。
前缀匹配逻辑:如果文件名看起来像是一个前缀+扩展名(前缀长度 >= 5),
则在目录中查找以该前缀开头的文件。
Args:
file_path: 要查找的文件路径(Path 对象)
Returns:
找到的文件路径(Path 对象),如果未找到则返回 None
"""
# Direct file matching
if file_path.exists() and file_path.is_file():
return file_path
# Try prefix match if not found and filename looks like a prefix with extension
filename = file_path.name
dirpath = file_path.parent
if '.' in filename and dirpath.exists() and dirpath.is_dir():
prefix, ext = os.path.splitext(filename)
if len(prefix) >= 5:
try:
for fname in os.listdir(dirpath):
fp, fe = os.path.splitext(fname)
if fp.lower().startswith(prefix.lower()) and fe.lower() == ext.lower():
matched_path = dirpath / fname
if matched_path.is_file():
logger.debug(f"Prefix match found: {file_path} -> {matched_path}")
return matched_path
except OSError as e:
logger.warning(f"Failed to list directory {dirpath}: {str(e)}")
return None