fix: 改名/改备注/改群名时联系人缓存不刷新(issue #67)
之前 commite86e00d的修复只覆盖「新增联系人不在缓存」的场景: if username not in self.contact_names: refresh() 改名/改备注/改群名时 username 一直在缓存里,永远跳过刷新, 导致显示老名字。 改成检测 contact.db mtime 变化触发全量 reload,受 30 秒 cooldown 节流(避免微信高频写 contact.db 时 CPU 抖动)。三种变更场景统一覆盖: - 新增联系人(原 #46 /e86e00d场景) - 修改备注名(issue #67) - 修改群名 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -627,6 +627,10 @@ def _convert_hevc_to_jpeg(hevc_path, jpeg_path):
|
|||||||
# ============ 监听器 ============
|
# ============ 监听器 ============
|
||||||
|
|
||||||
class SessionMonitor:
|
class SessionMonitor:
|
||||||
|
# 改名/备注变更场景的刷新最小间隔(秒)。低于此间隔的 mtime 变化不触发
|
||||||
|
# 全量 reload,避免微信高频写 contact.db 时 CPU 抖动。30s 是经验值。
|
||||||
|
CONTACT_REFRESH_COOLDOWN = 30
|
||||||
|
|
||||||
def __init__(self, enc_key, session_db, contact_names, db_cache=None, username_db_map=None):
|
def __init__(self, enc_key, session_db, contact_names, db_cache=None, username_db_map=None):
|
||||||
self.enc_key = enc_key
|
self.enc_key = enc_key
|
||||||
self.session_db = session_db
|
self.session_db = session_db
|
||||||
@@ -639,6 +643,43 @@ class SessionMonitor:
|
|||||||
self.patched_pages = 0
|
self.patched_pages = 0
|
||||||
# 已显示消息去重: {(username, timestamp, base_msg_type), ...}
|
# 已显示消息去重: {(username, timestamp, base_msg_type), ...}
|
||||||
self._shown_keys = set()
|
self._shown_keys = set()
|
||||||
|
# contact.db mtime + 上次刷新时间,用于检测改名/备注变更
|
||||||
|
self._contact_db_mtime = 0
|
||||||
|
self._last_contact_refresh = 0
|
||||||
|
|
||||||
|
def _maybe_refresh_contacts(self):
|
||||||
|
"""检测 contact.db mtime 变化时全量 reload 联系人缓存。
|
||||||
|
|
||||||
|
覆盖三种变更场景:
|
||||||
|
- 新增联系人(之前 commit e86e00d 只覆盖了这种)
|
||||||
|
- 修改备注名(issue #67)
|
||||||
|
- 修改群名
|
||||||
|
|
||||||
|
受 CONTACT_REFRESH_COOLDOWN 节流,避免 contact.db 高频变更时反复 reload。
|
||||||
|
"""
|
||||||
|
if not self.db_cache:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
contact_path = self.db_cache.get(os.path.join("contact", "contact.db"))
|
||||||
|
except Exception as e:
|
||||||
|
print(f" [contact] 实时解密 contact.db 失败: {e}", flush=True)
|
||||||
|
return
|
||||||
|
if not contact_path:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
curr_mtime = os.path.getmtime(contact_path)
|
||||||
|
except OSError:
|
||||||
|
return
|
||||||
|
now = time.time()
|
||||||
|
if curr_mtime <= self._contact_db_mtime:
|
||||||
|
return # mtime 没变,跳过
|
||||||
|
if now - self._last_contact_refresh < self.CONTACT_REFRESH_COOLDOWN:
|
||||||
|
return # cooldown 中,等下次
|
||||||
|
refreshed = load_contact_names(contact_path)
|
||||||
|
if refreshed:
|
||||||
|
self.contact_names.update(refreshed)
|
||||||
|
self._contact_db_mtime = curr_mtime
|
||||||
|
self._last_contact_refresh = now
|
||||||
|
|
||||||
def resolve_image(self, username, timestamp):
|
def resolve_image(self, username, timestamp):
|
||||||
"""解密图片: username+timestamp → 解密后的图片文件名,失败返回 None"""
|
"""解密图片: username+timestamp → 解密后的图片文件名,失败返回 None"""
|
||||||
@@ -1369,22 +1410,11 @@ class SessionMonitor:
|
|||||||
is_new = prev and (curr['timestamp'] > prev['timestamp'] or
|
is_new = prev and (curr['timestamp'] > prev['timestamp'] or
|
||||||
(curr['timestamp'] == prev['timestamp'] and curr['msg_type'] != prev.get('msg_type')))
|
(curr['timestamp'] == prev['timestamp'] and curr['msg_type'] != prev.get('msg_type')))
|
||||||
if is_new:
|
if is_new:
|
||||||
|
# contact.db mtime 变化时刷新缓存:覆盖新增联系人、改名、改备注、群名
|
||||||
|
# 修改等场景(issue #46, #67)。受 cooldown 节流。
|
||||||
|
self._maybe_refresh_contacts()
|
||||||
display = self.contact_names.get(username, username)
|
display = self.contact_names.get(username, username)
|
||||||
is_group = '@chatroom' in username
|
is_group = '@chatroom' in username
|
||||||
# 新群/新联系人不在缓存中时,通过 db_cache 实时解密 contact.db 后重新加载
|
|
||||||
# (load_contact_names 默认读静态快照,新加的联系人不在里面,这里必须走实时解密)
|
|
||||||
if username not in self.contact_names:
|
|
||||||
fresh_contact_db = None
|
|
||||||
if self.db_cache:
|
|
||||||
try:
|
|
||||||
fresh_contact_db = self.db_cache.get(os.path.join("contact", "contact.db"))
|
|
||||||
except Exception as e:
|
|
||||||
print(f" [contact] 实时解密 contact.db 失败: {e}", flush=True)
|
|
||||||
refreshed = load_contact_names(fresh_contact_db)
|
|
||||||
self.contact_names.update(refreshed)
|
|
||||||
display = self.contact_names.get(username, username)
|
|
||||||
if username in refreshed:
|
|
||||||
print(f" [contact] 新增: {username} -> {display}", flush=True)
|
|
||||||
sender = ''
|
sender = ''
|
||||||
if is_group:
|
if is_group:
|
||||||
sender = self.contact_names.get(curr['sender'], curr['sender_name'] or curr['sender'])
|
sender = self.contact_names.get(curr['sender'], curr['sender_name'] or curr['sender'])
|
||||||
|
|||||||
Reference in New Issue
Block a user