2024-09-25 13:46:23 +08:00
|
|
|
import os
|
2025-05-09 23:47:16 +08:00
|
|
|
import asyncio
|
2024-09-25 13:46:23 +08:00
|
|
|
from pathlib import Path
|
2024-09-26 22:45:02 +08:00
|
|
|
from llama_index.core import Document
|
2024-09-25 13:46:23 +08:00
|
|
|
from llama_index.core.node_parser import SimpleFileNodeParser
|
2024-09-26 22:45:02 +08:00
|
|
|
from llama_index.core.node_parser import SentenceSplitter
|
|
|
|
|
from llama_index.readers.file import FlatReader, DocxReader
|
2024-09-25 13:46:23 +08:00
|
|
|
|
2025-03-20 19:51:46 +08:00
|
|
|
from src.utils import hashstr, logger
|
|
|
|
|
|
2024-09-25 13:46:23 +08:00
|
|
|
|
2024-09-26 22:45:02 +08:00
|
|
|
def chunk(text_or_path, params=None):
|
2025-03-12 21:15:04 +08:00
|
|
|
"""
|
|
|
|
|
将文本或文件切分成固定大小的块
|
2025-03-20 19:51:46 +08:00
|
|
|
|
2025-03-12 21:15:04 +08:00
|
|
|
Args:
|
|
|
|
|
text_or_path: 文本或文件路径
|
|
|
|
|
params: 参数
|
|
|
|
|
chunk_size: 块大小
|
|
|
|
|
chunk_overlap: 块重叠大小
|
|
|
|
|
use_parser: 是否使用文件解析器
|
|
|
|
|
Returns:
|
|
|
|
|
nodes: 节点列表
|
|
|
|
|
"""
|
2024-09-25 13:46:23 +08:00
|
|
|
params = params or {}
|
|
|
|
|
chunk_size = int(params.get("chunk_size", 500))
|
2025-03-12 21:15:04 +08:00
|
|
|
chunk_overlap = int(params.get("chunk_overlap", 100))
|
2024-09-25 13:46:23 +08:00
|
|
|
splitter = SentenceSplitter(
|
|
|
|
|
chunk_size=chunk_size,
|
|
|
|
|
chunk_overlap=chunk_overlap,
|
|
|
|
|
)
|
|
|
|
|
|
2025-03-23 23:10:32 +08:00
|
|
|
# 如果文件存在,并且是当前目录下的文件,则使用文件解析器
|
|
|
|
|
if os.path.isfile(text_or_path) and os.path.exists(text_or_path) and os.path.abspath(text_or_path).startswith(os.getcwd()):
|
2024-09-26 22:45:02 +08:00
|
|
|
parser = SimpleFileNodeParser()
|
2024-09-29 16:13:06 +08:00
|
|
|
file_type = Path(text_or_path).suffix.lower()
|
2024-09-26 22:45:02 +08:00
|
|
|
if file_type in [".txt", ".json", ".md"]:
|
|
|
|
|
docs = FlatReader().load_data(Path(text_or_path))
|
|
|
|
|
elif file_type in [".docx"]:
|
|
|
|
|
docs = DocxReader().load_data(Path(text_or_path))
|
|
|
|
|
else:
|
|
|
|
|
raise ValueError(f"Unsupported file type `{file_type}`")
|
|
|
|
|
|
|
|
|
|
if params.get("use_parser"):
|
|
|
|
|
nodes = parser.get_nodes_from_documents(docs)
|
|
|
|
|
else:
|
|
|
|
|
nodes = splitter.get_nodes_from_documents(docs)
|
|
|
|
|
|
2024-09-25 13:46:23 +08:00
|
|
|
else:
|
2024-09-26 22:45:02 +08:00
|
|
|
docs = [Document(id_=hashstr(text_or_path), text=text_or_path)]
|
|
|
|
|
nodes = splitter.get_nodes_from_documents(docs)
|
2024-09-25 13:46:23 +08:00
|
|
|
|
2024-09-26 22:45:02 +08:00
|
|
|
return nodes
|
2025-03-20 19:51:46 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pdfreader(file_path):
|
|
|
|
|
"""读取PDF文件并返回text文本"""
|
|
|
|
|
assert os.path.exists(file_path), "File not found"
|
|
|
|
|
assert file_path.endswith(".pdf"), "File format not supported"
|
|
|
|
|
|
|
|
|
|
from llama_index.readers.file import PDFReader
|
|
|
|
|
doc = PDFReader().load_data(file=Path(file_path))
|
|
|
|
|
|
|
|
|
|
# 简单的拼接起来之后返回纯文本
|
|
|
|
|
text = "\n\n".join([d.get_content() for d in doc])
|
|
|
|
|
return text
|
|
|
|
|
|
|
|
|
|
def plainreader(file_path):
|
|
|
|
|
"""读取普通文本文件并返回text文本"""
|
|
|
|
|
assert os.path.exists(file_path), "File not found"
|
|
|
|
|
|
|
|
|
|
with open(file_path, "r") as f:
|
|
|
|
|
text = f.read()
|
|
|
|
|
return text
|
|
|
|
|
|
|
|
|
|
def read_text(file, params=None):
|
|
|
|
|
support_format = [".pdf", ".txt", ".md"]
|
|
|
|
|
assert os.path.exists(file), "File not found"
|
|
|
|
|
logger.info(f"Try to read file {file}")
|
|
|
|
|
|
|
|
|
|
if not os.path.isfile(file):
|
|
|
|
|
logger.error(f"Directory not supported now!")
|
|
|
|
|
raise NotImplementedError("Directory not supported now!")
|
|
|
|
|
|
|
|
|
|
if file.endswith(".pdf"):
|
|
|
|
|
from src.plugins import ocr
|
|
|
|
|
return ocr.process_pdf(file)
|
|
|
|
|
|
|
|
|
|
elif file.endswith(".txt") or file.endswith(".md"):
|
|
|
|
|
return plainreader(file)
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
logger.error(f"File format not supported, only support {support_format}")
|
|
|
|
|
raise Exception(f"File format not supported, only support {support_format}")
|
|
|
|
|
|
|
|
|
|
|
2025-05-09 23:47:16 +08:00
|
|
|
async def read_text_async(file):
|
|
|
|
|
return await asyncio.to_thread(read_text, file)
|