save a version

This commit is contained in:
2026-03-31 11:10:40 +08:00
parent 132c7b667b
commit 40b55b3c32

View File

@@ -62,11 +62,19 @@ def extract_all_zips(
def read_word_content(doc_path: Path) -> List[str]:
"""读取 Word 文档内容,提取文本行"""
"""读取 Word 文档内容 (.docx 或 .doc),提取文本行"""
if doc_path.suffix.lower() == '.docx':
return read_docx_content(doc_path)
elif doc_path.suffix.lower() == '.doc':
return read_doc_content(doc_path)
return []
def read_docx_content(doc_path: Path) -> List[str]:
"""读取 .docx 格式 Word 文档内容"""
lines = []
try:
import zipfile as zf
with zf.ZipFile(doc_path, 'r') as z:
with zipfile.ZipFile(doc_path, 'r') as z:
content = z.read('word/document.xml').decode('utf-8')
texts = re.findall(r'<w:t[^>]*>(.*?)</w:t>', content, re.DOTALL)
for text in texts:
@@ -76,33 +84,87 @@ def read_word_content(doc_path: Path) -> List[str]:
lines.append(text)
return lines
except Exception as e:
print(f"读取 Word 失败:{e}")
print(f"读取 .docx 失败 ({doc_path.name}): {e}")
return []
def find_word_doc(base_dir: Path) -> Optional[Path]:
"""自动查找 base_dir 下的 Word 文档 (.doc 或 .docx)"""
for f in base_dir.iterdir():
if f.is_file() and f.suffix.lower() in ['.doc', '.docx']:
return f
def read_doc_content(doc_path: Path) -> List[str]:
"""读取 .doc 格式 Word 文档内容"""
lines = []
# 方法 1: 尝试使用 antiword
try:
import subprocess
result = subprocess.run(
['antiword', str(doc_path)],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
lines = [line.strip() for line in result.stdout.split('\n') if line.strip()]
return lines
except FileNotFoundError:
pass
except Exception as e:
print(f"antiword 读取失败:{e}")
# 方法 2: 尝试使用 textract
try:
import subprocess
result = subprocess.run(
['textract', str(doc_path), '--output', '/dev/stdout'],
capture_output=True,
text=True,
timeout=60
)
if result.returncode == 0:
lines = [line.strip() for line in result.stdout.split('\n') if line.strip()]
return lines
except FileNotFoundError:
pass
except Exception as e:
print(f"textract 读取失败:{e}")
# 方法 3: 尝试使用 libreoffice
try:
import subprocess
import tempfile
with tempfile.TemporaryDirectory() as tmpdir:
result = subprocess.run(
['libreoffice', '--headless', '--convert-to', 'txt', '--outdir', tmpdir, str(doc_path)],
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
txt_file = Path(tmpdir) / (doc_path.stem + '.txt')
if txt_file.exists():
with open(txt_file, 'r', encoding='utf-8', errors='ignore') as f:
lines = [line.strip() for line in f.readlines() if line.strip()]
return lines
except FileNotFoundError:
pass
except Exception as e:
print(f"libreoffice 读取失败:{e}")
print(f"⚠️ 无法读取 .doc 文件 ({doc_path.name}),请安装以下工具之一:")
print(f" - antiword: brew install antiword")
print(f" - textract: pip install textract")
print(f" - LibreOffice: brew install --cask libreoffice")
return []
def find_word_doc_recursive(base_dir: Path) -> Optional[Path]:
"""递归查找 base_dir 下任意层级的 Word 文档 (.docx 优先)"""
# 先找 .docx 文件
for item in base_dir.rglob("*.docx"):
return item
# 再找 .doc 文件
for item in base_dir.rglob("*.doc"):
return item
return None
def find_word_content(base_dir: Path) -> Optional[List[str]]:
"""自动查找 base_dir 下的 Word 文档并读取内容"""
word_doc = find_word_doc(base_dir)
if word_doc:
return read_word_content(word_doc)
return None
def get_word_content(base_dir: Optional[Path] = None) -> List[str]:
"""自动查找 Word 文档并读取内容,找到即返回"""
if base_dir is None:
base_dir = Path("data")
return find_word_content(base_dir) or []
def create_config_file(word_content: List[str], config_file: Optional[Path] = None) -> Path:
"""将 Word 内容保存为配置文件"""
if config_file is None:
@@ -277,15 +339,10 @@ def main() -> None:
parser = argparse.ArgumentParser(description='文件关联处理程序')
parser.add_argument('--unpack', action='store_true', help='解压文件')
parser.add_argument('--associate', action='store_true', help='建立文件关联')
parser.add_argument('--base-dir', type=str, help='基础目录')
parser.add_argument('--base-dir', type=str, help='基础目录(包含 Word 文档的目录)')
args = parser.parse_args()
if args.base_dir:
base_dir = Path(args.base_dir)
else:
base_dir = Path("data")
# 解压文件
if args.unpack:
extract_all_zips("data")
@@ -293,11 +350,24 @@ def main() -> None:
# 建立文件关联
if args.associate:
word_content = get_word_content(base_dir)
if not word_content:
print("⚠️ 未找到 Word 文档,请先解压文件")
base_dir = Path(args.base_dir) if args.base_dir else Path("data")
# 递归查找 Word 文档
word_doc = find_word_doc_recursive(base_dir)
if not word_doc:
print("⚠️ 未找到 Word 文档 (.doc 或 .docx),请先解压文件")
return
# 读取 Word 内容
word_content = read_word_content(word_doc)
if not word_content:
print("⚠️ 无法读取 Word 文档内容")
return
# 确定关联目录Word 文档的父目录,包含学科网和 21 世纪教育网)
base_dir = word_doc.parent
print(f"✓ 找到 Word 文档:{word_doc}")
print(f" 关联目录:{base_dir}")
twole_folder = base_dir / "21世纪教育网"
zxxk_folder = base_dir / "学科网"