Files
Story-extractor/backend/app/services/docx_parser.py
2026-04-24 16:02:16 +08:00

94 lines
2.7 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 re
from docx import Document
def parse_transcript(file_path: str) -> list[dict]:
"""
解析直播回放文字稿 DOCX
格式:发言者(时间戳): 内容
返回:[{index, speaker, timestamp, content, raw_text}]
"""
doc = Document(file_path)
paragraphs = []
for i, para in enumerate(doc.paragraphs):
text = para.text.strip()
if not text:
continue
# 解析格式:发言者(时间戳): 内容
match = re.match(r'^(.+?)\((\d{2}:\d{2}:\d{2})\)\s*[:]\s*(.*)', text)
if match:
speaker = match.group(1).strip()
timestamp = match.group(2)
content = match.group(3).strip()
else:
# 尝试格式:发言者: 内容
match2 = re.match(r'^(.+?)\s*[:]\s*(.*)', text)
if match2:
speaker = match2.group(1).strip()
timestamp = ""
content = match2.group(2).strip()
else:
speaker = ""
timestamp = ""
content = text
paragraphs.append({
"index": i,
"speaker": speaker,
"timestamp": timestamp,
"content": content,
"raw_text": text,
})
return paragraphs
def is_teacher(speaker: str) -> bool:
"""判断是否为老师/助教发言"""
teacher_keywords = ["卢慧老师", "静静", "督导", "老师"]
return any(kw in speaker for kw in teacher_keywords)
def parse_person_info(file_path: str) -> dict:
"""
解析讲述者个人信息 DOCX
返回:{name, info_text, photos: [path]}
"""
doc = Document(file_path)
texts = []
photos = []
# 提取文本
for para in doc.paragraphs:
text = para.text.strip()
if text:
texts.append(text)
# 提取图片
import os
photo_dir = os.path.join(os.path.dirname(file_path), "photos")
os.makedirs(photo_dir, exist_ok=True)
for i, rel in enumerate(doc.part.rels.values()):
if "image" in rel.reltype:
image = rel.target_part
photo_name = f"{os.path.splitext(os.path.basename(file_path))[0]}_photo_{i}.{image.content_type.split('/')[-1]}"
photo_path = os.path.join(photo_dir, photo_name)
with open(photo_path, "wb") as f:
f.write(image.blob)
photos.append(photo_path)
# 从文件名提取姓名
filename = os.path.basename(file_path)
name = re.sub(r'[-_].*$', '', filename).strip()
# 去掉扩展名
name = os.path.splitext(name)[0].strip()
return {
"name": name,
"info_text": "\n".join(texts),
"photos": photos,
}