save a version
This commit is contained in:
@@ -62,11 +62,19 @@ def extract_all_zips(
|
|||||||
|
|
||||||
|
|
||||||
def read_word_content(doc_path: Path) -> List[str]:
|
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 = []
|
lines = []
|
||||||
try:
|
try:
|
||||||
import zipfile as zf
|
with zipfile.ZipFile(doc_path, 'r') as z:
|
||||||
with zf.ZipFile(doc_path, 'r') as z:
|
|
||||||
content = z.read('word/document.xml').decode('utf-8')
|
content = z.read('word/document.xml').decode('utf-8')
|
||||||
texts = re.findall(r'<w:t[^>]*>(.*?)</w:t>', content, re.DOTALL)
|
texts = re.findall(r'<w:t[^>]*>(.*?)</w:t>', content, re.DOTALL)
|
||||||
for text in texts:
|
for text in texts:
|
||||||
@@ -76,33 +84,87 @@ def read_word_content(doc_path: Path) -> List[str]:
|
|||||||
lines.append(text)
|
lines.append(text)
|
||||||
return lines
|
return lines
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"读取 Word 失败:{e}")
|
print(f"读取 .docx 失败 ({doc_path.name}): {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def find_word_doc(base_dir: Path) -> Optional[Path]:
|
def read_doc_content(doc_path: Path) -> List[str]:
|
||||||
"""自动查找 base_dir 下的 Word 文档 (.doc 或 .docx)"""
|
"""读取 .doc 格式 Word 文档内容"""
|
||||||
for f in base_dir.iterdir():
|
lines = []
|
||||||
if f.is_file() and f.suffix.lower() in ['.doc', '.docx']:
|
|
||||||
return f
|
# 方法 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
|
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:
|
def create_config_file(word_content: List[str], config_file: Optional[Path] = None) -> Path:
|
||||||
"""将 Word 内容保存为配置文件"""
|
"""将 Word 内容保存为配置文件"""
|
||||||
if config_file is None:
|
if config_file is None:
|
||||||
@@ -277,15 +339,10 @@ def main() -> None:
|
|||||||
parser = argparse.ArgumentParser(description='文件关联处理程序')
|
parser = argparse.ArgumentParser(description='文件关联处理程序')
|
||||||
parser.add_argument('--unpack', action='store_true', help='解压文件')
|
parser.add_argument('--unpack', action='store_true', help='解压文件')
|
||||||
parser.add_argument('--associate', 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()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.base_dir:
|
|
||||||
base_dir = Path(args.base_dir)
|
|
||||||
else:
|
|
||||||
base_dir = Path("data")
|
|
||||||
|
|
||||||
# 解压文件
|
# 解压文件
|
||||||
if args.unpack:
|
if args.unpack:
|
||||||
extract_all_zips("data")
|
extract_all_zips("data")
|
||||||
@@ -293,11 +350,24 @@ def main() -> None:
|
|||||||
|
|
||||||
# 建立文件关联
|
# 建立文件关联
|
||||||
if args.associate:
|
if args.associate:
|
||||||
word_content = get_word_content(base_dir)
|
base_dir = Path(args.base_dir) if args.base_dir else Path("data")
|
||||||
if not word_content:
|
# 递归查找 Word 文档
|
||||||
print("⚠️ 未找到 Word 文档,请先解压文件")
|
word_doc = find_word_doc_recursive(base_dir)
|
||||||
|
if not word_doc:
|
||||||
|
print("⚠️ 未找到 Word 文档 (.doc 或 .docx),请先解压文件")
|
||||||
return
|
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世纪教育网"
|
twole_folder = base_dir / "21世纪教育网"
|
||||||
zxxk_folder = base_dir / "学科网"
|
zxxk_folder = base_dir / "学科网"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user