import time
from docx import Document
from pprint import pprint
from qwen_agent.agents import Assistant
import re
import json_repair
import math
from docx.opc.pkgreader import _SerializedRelationships, _SerializedRelationship
from docx.opc.oxml import parse_xml
# from myLogger import outLog
def load_from_xml_v2(baseURI, rels_item_xml):
"""
Return |_SerializedRelationships| instance loaded with the
relationships contained in *rels_item_xml*. Returns an empty
collection if *rels_item_xml* is |None|.
"""
srels = _SerializedRelationships()
if rels_item_xml is not None:
rels_elm = parse_xml(rels_item_xml)
for rel_elm in rels_elm.Relationship_lst:
if rel_elm.target_ref in ('../NULL', 'NULL'):
continue
srels._srels.append(_SerializedRelationship(baseURI, rel_elm))
return srels
_SerializedRelationships.load_from_xml = load_from_xml_v2
import logging
# outLog.logger = logging.getLogger("checkTitleName")
userLog = None
llm_cfg = {
# 'model': 'qwen1.5-72b-chat',
'model': "qwen2-72b-instruct",
'model_server': 'DashScope', # base_url, also known as api_base
'api_key': 'sk-ea89cf04431645b185990b8af8c9bb13',
}
bot = Assistant(llm=llm_cfg,
name='Assistant',
)
# 记录程序开始的时间戳
def getOutlineLevel(inputXml):
"""
功能 从xml字段中提取出中的数字number
参数 inputXml
返回 number
"""
start_index = inputXml.find('', start_index)
number = inputXml[start_index:end_index + 1]
number = re.search("\d+", number).group()
return number
def isTitle(paragraph):
"""
功能 判断该段落是否设置了大纲等级
参数 paragraph:段落
返回 None:普通正文,没有大纲级别 0:一级标题 1:二级标题 2:三级标题
"""
# 如果是空行,直接返回None
if paragraph.text.strip() == '':
return None
# 如果该段落是直接在段落里设置大纲级别的,根据xml判断大纲级别
paragraphXml = paragraph._p.xml
if paragraphXml.find('= 0:
return getOutlineLevel(paragraphXml)
# 如果该段落是通过样式设置大纲级别的,逐级检索样式及其父样式,判断大纲级别
targetStyle = paragraph.style
while targetStyle is not None:
# 如果在该级style中找到了大纲级别,返回
if targetStyle.element.xml.find('= 0:
return getOutlineLevel(targetStyle.element.xml)
else:
targetStyle = targetStyle.base_style
# 如果在段落、样式里都没有找到大纲级别,返回None
return None
# 获取文档中 详细设计方案 章节的所有内容
def getDocxToTitleName(docxPath):
loopCount = 0
while True:
loopCount += 1
if (loopCount >= 60):
raise Exception("文档读取超时,或文档存在问题无法读取")
break
try:
document = Document(docxPath)
break
except Exception as e:
time.sleep(1)
pass
# 逐段读取docx文档的内容
levelList = []
words = []
addStart = False
levelText = ""
count = 0
total = len(document.paragraphs)
yield f"文档结构检查----文档内容解析中{str(count)}/{str(total)}"
for paragraph in document.paragraphs:
count += 1
yield f"文档结构检查----文档内容解析中{str(count)}/{str(total)}"
# 判断该段落的标题级别
# 这里用isTitle()临时代表,具体见下文介绍的方法
text = paragraph.text
if text.strip(): # 非空判断
level = isTitle(paragraph)
if level == "0":
words.append(text)
yield words
def checkTitleName(filename, user_id, outLog):
global userLog
userLog = outLog.get_queue(user_id, "checkTitleName")
yield '文档结构检查----启动中'
userLog.info("文档结构检查---任务开始")
with open("ce模板.txt", "r", encoding='utf-8') as f:
gettext = f.readlines()
count = 0
reserr = []
try:
for i in getDocxToTitleName(filename):
word = i
if (isinstance(word, str)):
yield word
continue
except Exception as e:
userLog.warning(e)
yield "文档结构检查----文件无法正常打开。可以尝试用WORD或WPS打开文件,进行修复并另存,用另存的文件再做一次尝试。"
userLog.warning("checkTitleName----文档无法打开,请检查文档内容")
outLog.mark_done(user_id, "checkTitleName")
return
for text in gettext:
count += 1
prompt = f'''
\n 这些是文章的标题,请问【{text}】在标题中是否可以配对的,若有请指出是哪个标题,若没有请回到不存在
'''
xushang = "回答格式{‘name’:‘名称’,'answer':‘回答’,“标题”:“标题”}请严格按照格式回答问题,不要做过多我解释"
yield f"文档结构检查----结构分析中{count}/{len(gettext)}"
strword = "\n".join(word) + prompt + xushang
messages = [{'role': 'user', 'content': [{'text': strword}]}]
runList = []
for rsp in bot.run(messages):
runList.append(rsp)
# print(rsp)
data = runList[len(runList) - 1][0]["content"]
parsed_data = json_repair.loads(data.replace('`', ''))
if (parsed_data["answer"] == "不存在"):
reserr.append(text)
userLog.info("文档结构检查----文档结构存在异常:" + text.replace('\n', ''))
resInfo = "文档结构存在异常:
"
if (len(reserr) > 0):
for i in reserr:
resInfo += "**" + i.replace('\n', '') + "**
"
yield resInfo
else:
yield "**文档结构未发现异常**"
userLog.info("文档结构检查----文档结构未发现异常")
outLog.mark_done(user_id, "checkTitleName")