85 lines
4.8 KiB
Python
85 lines
4.8 KiB
Python
from pathlib import Path
|
|
import shutil
|
|
|
|
ROOT = Path(__file__).parent
|
|
for label, project in [('source', Path('C:/kefu/wechat_rpa')), ('production', Path('C:/wechat_rpa'))]:
|
|
backup = ROOT / 'before-voice-integration' / label
|
|
backup.mkdir(parents=True, exist_ok=True)
|
|
path = project / 'wxwork_db.py'
|
|
shutil.copy2(path, backup / path.name)
|
|
text = path.read_text(encoding='utf-8')
|
|
text = text.replace(' self.db_base = db_base\n', ' self.db_base = db_base\n self._voice_reader = None\n', 1)
|
|
needle = ' content = parse_content(msg.get("content"))\n'
|
|
assert text.count(needle) == 1
|
|
text = text.replace(needle, ''' from voice_messages import is_voice, cached_voice_fields
|
|
voice_fields = {}
|
|
if is_voice(msg):
|
|
voice_fields = cached_voice_fields(getattr(self, "_conns", {}).get(user_dir),
|
|
str(user_dir), conv_id, msg.get("server_id"), msg.get("content"))
|
|
content = voice_fields.get("content", parse_content(msg.get("content")))
|
|
''')
|
|
needle = ' "dedup_key": f"{user_dir}:{conv_id}:{stable_id}",\n'
|
|
assert text.count(needle) == 1
|
|
text = text.replace(needle, needle + ' **voice_fields,\n')
|
|
needle = ' if not messages:\n return None\n lines = []\n'
|
|
assert text.count(needle) == 1
|
|
text = text.replace(needle, ''' if not messages:
|
|
return None
|
|
# ASR runs on a separate worker. Only this unanswered customer batch is queued.
|
|
if any(int(m.get("content_type") or 0) in (4, 16) for m in messages):
|
|
if getattr(self, "_voice_reader", None) is None and getattr(self, "db_base", None):
|
|
from voice_messages import VoiceMessageReader
|
|
self._voice_reader = VoiceMessageReader(self.db_base)
|
|
if getattr(self, "_voice_reader", None) is not None:
|
|
self._voice_reader.prepare(messages)
|
|
lines = []
|
|
''')
|
|
needle = ' def close(self):\n self._closed = True\n'
|
|
assert text.count(needle) == 1
|
|
text = text.replace(needle, needle + ''' voice_reader = getattr(self, "_voice_reader", None)
|
|
if voice_reader is not None:
|
|
voice_reader.close()
|
|
self._voice_reader = None
|
|
''')
|
|
path.write_text(text, encoding='utf-8')
|
|
if label == 'production':
|
|
shutil.copy2('C:/kefu/wechat_rpa/voice_messages.py', project / 'voice_messages.py')
|
|
|
|
# Protocol integration uses the current exact DB snapshot, not the original event's media placeholder.
|
|
path = Path('C:/wechat_rpa/protocol_engine.py')
|
|
shutil.copy2(path, ROOT / 'before-voice-integration' / 'production' / path.name)
|
|
text = path.read_text(encoding='utf-8')
|
|
text = text.replace("def _is_text_message(message):\n try:", "def _is_text_message(message):\n from voice_messages import verified_transcript\n if verified_transcript(message):return True\n try:", 1)
|
|
needle = " manual_reason=_unanswered_manual_reason(context)\n if not _is_text_message(state):manual_reason=manual_reason or MANUAL_NON_TEXT_REASON\n"
|
|
assert text.count(needle) == 1
|
|
text = text.replace(needle, ''' from voice_messages import voice_batch_status, unanswered_messages
|
|
voice = voice_batch_status(context)
|
|
manual_reason = ''
|
|
if voice['status'] == 'pending':
|
|
now = time.time()
|
|
with self._lock:
|
|
if state.get('voice_wait_key') != voice['key']:
|
|
state.update(voice_wait_key=voice['key'], voice_wait_started_at=now)
|
|
waited = now - float(state.get('voice_wait_started_at') or now)
|
|
if waited < 180:
|
|
state.update(ready_at=now+2, reply_text='', staged_reply_text='')
|
|
if waited < 180:
|
|
self._stage(key,'voice_transcribing',voice['reason']);return
|
|
manual_reason='语音转文字等待超时,尚未取得可核验文字,请人工处理'
|
|
elif voice['status'] == 'error':
|
|
manual_reason=voice['reason']
|
|
else:
|
|
state.pop('voice_wait_key',None);state.pop('voice_wait_started_at',None)
|
|
manual_reason=manual_reason or _unanswered_manual_reason(context)
|
|
current=(context or {}).get('last_message') or {}
|
|
if current.get('dedup_key')!=state.get('dedup_key') or not _is_text_message(current):
|
|
manual_reason=manual_reason or MANUAL_NON_TEXT_REASON
|
|
if not manual_reason:
|
|
# The current question/risk check and archive receive the same transcribed batch as the model.
|
|
batch=unanswered_messages(context)
|
|
state.update(staged_user_text='\\n'.join(str(m.get('content') or '') for m in batch),
|
|
last_lines=[str(m.get('content') or '') for m in batch])
|
|
''')
|
|
path.write_text(text, encoding='utf-8')
|
|
print('Voice DB and protocol integration applied to both variants; original files backed up.')
|