59 lines
4.4 KiB
Python
59 lines
4.4 KiB
Python
from pathlib import Path
|
||
import hashlib
|
||
import json
|
||
import shutil
|
||
|
||
folder = Path(__file__).parent
|
||
root = Path('C:/wechat_rpa')
|
||
read = lambda name: json.loads((folder / name).read_text(encoding='utf-8-sig'))
|
||
plan = read('review-voice-release-plan.json')
|
||
tests = read('frozen-review-voice-tests.json')
|
||
notifications = read('frozen-review-voice-notifications.json')
|
||
frozen = read('frozen-release-qa.json')
|
||
integrity = read('nsis-payload-integrity.json')
|
||
asr = read('frozen-offline-asr.json')
|
||
assert plan['finalized'] and plan['version'] == '1.4.27'
|
||
assert tests['tests_run'] > 0 and not any(tests[k] for k in ('failures', 'errors', 'skipped', 'blocked_external_actions'))
|
||
assert notifications['ok'] and notifications['passed'] == plan['notificationExpectedTests']
|
||
assert not notifications['skipped'] and not notifications['blocked_external_actions']
|
||
assert frozen['sourceManifestMatches'] and frozen['privateFilesExcluded'] and frozen['uiAssetsMatchSource']
|
||
assert integrity['crcPassed'] and integrity['completeDeflateStream'] and not integrity['missingFiles']
|
||
assert asr['ok'] and len(asr['results']) == 3
|
||
assert not asr['site_packages_leaks'] and not asr['escaped_dlls']
|
||
for name, digest in read('build-source-manifest.json').items():
|
||
assert hashlib.sha256((root / name).read_bytes()).hexdigest() == digest, name
|
||
old = root / 'releases/甄AI客服-安装包-v1.4.26.exe'
|
||
assert hashlib.sha256(old.read_bytes()).hexdigest() == plan['previousInstallerSha256']
|
||
installer = root / 'dist/installer/甄AI客服-安装包-v1.4.27.exe'
|
||
release = root / 'releases' / installer.name
|
||
digest = hashlib.sha256(installer.read_bytes()).hexdigest()
|
||
assert digest == integrity['installerSha256']
|
||
if release.exists():
|
||
assert hashlib.sha256(release.read_bytes()).hexdigest() == digest
|
||
else:
|
||
shutil.copy2(installer, release)
|
||
assert hashlib.sha256(release.read_bytes()).hexdigest() == digest
|
||
report = {'version': '1.4.27', 'installer': str(release), 'bytes': release.stat().st_size,
|
||
'sha256': digest, 'frozenRegressionTests': tests['tests_run'],
|
||
'frozenNotificationTests': notifications['passed'], 'frozenAsrFormats': 3,
|
||
'realMessagesSent': 0, 'existingSettingsChanged': False, 'installed': False,
|
||
'cloudDeploymentNeeded': False, 'oldInstallerPreserved': True}
|
||
(folder / 'release-v1.4.27.json').write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding='utf-8')
|
||
(folder / 'RESULT.md').write_text(f'''# 审核提醒、人工完成与语音转文字 v1.4.27
|
||
|
||
待审核和需人工(包括模型失败、媒体无法读取、发送失败、回执待核对)统一进入绑定医疗助理提醒链路;相同待处理会话复用提醒,不重复发送结果未知的通知。当前托管账号直接回复客户后核验账号、会话、服务器消息及发送日志,任务显示“人工已完成”。旧 AI 草稿作废,后续来信重新生成并逐条风控;回复提醒本身不审批客户任务。
|
||
|
||
语音优先读取当前账号精确服务器消息 ID 对应的企业微信转写缓存;缺失时,仅对该消息精确引用的本账号本地音频进行离线识别。模型及 SILK/AMR/WAV 解码组件已内置,不运行时下载模型或上传音频。文字与同批补充内容共同进入问答和风控。转写变动时旧草稿和批准失效,重新生成。
|
||
|
||
索引与识别在后台执行。等待语音的任务让出主循环,其他会话继续处理;语音等待和人工状态持久化,数据库暂时繁忙或重启不会绕过等待/人工处理。180 秒仍未取得文字或识别失败时转需人工并提醒。没有本机音频且无转写缓存时不会编造语音内容。
|
||
|
||
最终源码集成 700 项通过。实际 EXE 内冻结模块回归 {tests['tests_run']} 项、提醒回归 {notifications['passed']} 项通过;实际包内依赖及模型对三格式合成中文音频离线识别成功,无构建环境依赖回退。安装包 CRC、压缩流、全部文件哈希及私有文件排除检查通过。
|
||
|
||
安装包:`{release}`
|
||
|
||
SHA256:`{digest}`
|
||
|
||
两目录已定向修复;生产版本为 1.4.27,视觉源码目录保留自己的版本序列。旧 1.4.26 安装包保留。未自动安装、重启、修改用户配置/队列或发送真实消息;无需管理端部署。退出托盘中的旧客户端后安装新版并重新打开。现有绑定收件人和开启状态不自动更改。
|
||
''', encoding='utf-8')
|
||
print(json.dumps(report, ensure_ascii=False))
|