mirror of https://github.com/jackwener/wx-cli.git
fix: 统一路径分隔符为正斜杠,修复 macOS/Linux 兼容性
all_keys.json 中的 key 统一使用 `/` 作为路径分隔符, 消除 Windows 反斜杠硬编码,确保跨平台兼容。 涉及文件: find_all_keys.py, decrypt_db.py, monitor.py, monitor_web.py, mcp_server.py, decode_image.py, latency_test.py Fixes #17 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>feat/daemon-cli
parent
1294953681
commit
2b03a81a8f
|
|
@ -313,7 +313,7 @@ class ImageResolver:
|
|||
|
||||
def get_image_md5(self, local_id):
|
||||
"""通过 local_id 查 message_resource.db 获取图片文件 MD5"""
|
||||
path = self.cache.get("message\\message_resource.db")
|
||||
path = self.cache.get("message/message_resource.db")
|
||||
if not path:
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ def main():
|
|||
for f in files:
|
||||
if f.endswith('.db') and not f.endswith('-wal') and not f.endswith('-shm'):
|
||||
path = os.path.join(root, f)
|
||||
rel = os.path.relpath(path, DB_DIR)
|
||||
rel = os.path.relpath(path, DB_DIR).replace('\\', '/')
|
||||
sz = os.path.getsize(path)
|
||||
db_files.append((rel, path, sz))
|
||||
|
||||
|
|
@ -142,8 +142,8 @@ def main():
|
|||
total_bytes = 0
|
||||
|
||||
for rel, path, sz in db_files:
|
||||
# 用反斜杠格式查找key (json中的key是Windows路径)
|
||||
rel_key = rel.replace('/', '\\')
|
||||
# 统一用正斜杠查找key
|
||||
rel_key = rel.replace('\\', '/')
|
||||
if rel_key not in keys:
|
||||
print(f"SKIP: {rel} (无密钥)")
|
||||
failed += 1
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ def main():
|
|||
for f in files:
|
||||
if f.endswith('.db') and not f.endswith('-wal') and not f.endswith('-shm'):
|
||||
path = os.path.join(root, f)
|
||||
rel = os.path.relpath(path, DB_DIR)
|
||||
rel = os.path.relpath(path, DB_DIR).replace('\\', '/')
|
||||
sz = os.path.getsize(path)
|
||||
if sz < PAGE_SZ:
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ DECRYPTED = os.path.join(_cfg["decrypted_dir"], "session", "session.db")
|
|||
|
||||
with open(KEYS_FILE) as f:
|
||||
keys = json.load(f)
|
||||
enc_key = bytes.fromhex(keys["session\\session.db"]["enc_key"])
|
||||
enc_key = bytes.fromhex(keys["session/session.db"]["enc_key"])
|
||||
|
||||
session_db = os.path.join(DB_DIR, "session", "session.db")
|
||||
wal_path = session_db + "-wal"
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ class DBCache:
|
|||
tmp_path = info["path"]
|
||||
if not os.path.exists(tmp_path):
|
||||
continue
|
||||
rel_path = rel_key.replace('\\', os.sep)
|
||||
rel_path = rel_key.replace('/', os.sep)
|
||||
db_path = os.path.join(DB_DIR, rel_path)
|
||||
wal_path = db_path + "-wal"
|
||||
try:
|
||||
|
|
@ -177,7 +177,7 @@ class DBCache:
|
|||
def get(self, rel_key):
|
||||
if rel_key not in ALL_KEYS:
|
||||
return None
|
||||
rel_path = rel_key.replace('\\', os.sep)
|
||||
rel_path = rel_key.replace('/', os.sep)
|
||||
db_path = os.path.join(DB_DIR, rel_path)
|
||||
wal_path = db_path + "-wal"
|
||||
if not os.path.exists(db_path):
|
||||
|
|
@ -248,7 +248,7 @@ def get_contact_names():
|
|||
pass
|
||||
|
||||
# 实时解密
|
||||
path = _cache.get("contact\\contact.db")
|
||||
path = _cache.get("contact/contact.db")
|
||||
if path:
|
||||
try:
|
||||
_contact_names, _contact_full = _load_contacts_from(path)
|
||||
|
|
@ -332,7 +332,7 @@ def _parse_message_content(content, local_type, is_group):
|
|||
# 消息 DB 的 rel_keys(排除 fts/resource/media/biz)
|
||||
MSG_DB_KEYS = sorted([
|
||||
k for k in ALL_KEYS
|
||||
if k.startswith("message\\message_") and k.endswith(".db")
|
||||
if k.startswith("message/message_") and k.endswith(".db")
|
||||
and "fts" not in k and "resource" not in k
|
||||
])
|
||||
|
||||
|
|
@ -379,7 +379,7 @@ def get_recent_sessions(limit: int = 20) -> str:
|
|||
Args:
|
||||
limit: 返回的会话数量,默认20
|
||||
"""
|
||||
path = _cache.get("session\\session.db")
|
||||
path = _cache.get("session/session.db")
|
||||
if not path:
|
||||
return "错误: 无法解密 session.db"
|
||||
|
||||
|
|
@ -635,7 +635,7 @@ def get_new_messages() -> str:
|
|||
"""获取自上次调用以来的新消息。首次调用返回最近的会话状态。"""
|
||||
global _last_check_state
|
||||
|
||||
path = _cache.get("session\\session.db")
|
||||
path = _cache.get("session/session.db")
|
||||
if not path:
|
||||
return "错误: 无法解密 session.db"
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ def main():
|
|||
with open(KEYS_FILE) as f:
|
||||
keys = json.load(f)
|
||||
|
||||
session_key_info = keys.get("session\\session.db")
|
||||
session_key_info = keys.get("session/session.db")
|
||||
if not session_key_info:
|
||||
print("[ERROR] 找不到session.db的密钥")
|
||||
sys.exit(1)
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ def _build_emoji_lookup(keys_dict):
|
|||
"""从 emoticon.db 构建 emoji md5 → URL 映射(直接解密,不走 cache)"""
|
||||
global _emoji_lookup, _emoji_keys_dict, _emoji_last_refresh
|
||||
_emoji_keys_dict = keys_dict
|
||||
key_info = keys_dict.get("emoticon\\emoticon.db")
|
||||
key_info = keys_dict.get("emoticon/emoticon.db")
|
||||
if not key_info:
|
||||
print("[emoji] 无 emoticon.db key,跳过", flush=True)
|
||||
return
|
||||
|
|
@ -260,7 +260,7 @@ class MonitorDBCache:
|
|||
lock = self._get_lock(rel_key)
|
||||
with lock:
|
||||
enc_key = bytes.fromhex(self.keys[rel_key]["enc_key"])
|
||||
rel_path = rel_key.replace('\\', os.sep)
|
||||
rel_path = rel_key.replace('/', os.sep)
|
||||
db_path = os.path.join(DB_DIR, rel_path)
|
||||
wal_path = db_path + "-wal"
|
||||
|
||||
|
|
@ -273,7 +273,7 @@ class MonitorDBCache:
|
|||
except OSError:
|
||||
return None
|
||||
|
||||
out_name = rel_key.replace('\\', '_')
|
||||
out_name = rel_key.replace('/', '_')
|
||||
out_path = os.path.join(self.tmp_dir, out_name)
|
||||
|
||||
prev = self._state.get(rel_key)
|
||||
|
|
@ -313,7 +313,7 @@ def build_username_db_map():
|
|||
# 先获取每个 DB 的 mtime 用于排序
|
||||
db_mtimes = {}
|
||||
for i in range(5):
|
||||
rel_key = f"message\\message_{i}.db"
|
||||
rel_key = f"message/message_{i}.db"
|
||||
db_path = os.path.join(DB_DIR, "message", f"message_{i}.db")
|
||||
try:
|
||||
db_mtimes[rel_key] = os.path.getmtime(db_path)
|
||||
|
|
@ -326,7 +326,7 @@ def build_username_db_map():
|
|||
db_path = os.path.join(decrypted_msg_dir, f"message_{i}.db")
|
||||
if not os.path.exists(db_path):
|
||||
continue
|
||||
rel_key = f"message\\message_{i}.db"
|
||||
rel_key = f"message/message_{i}.db"
|
||||
try:
|
||||
conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
|
||||
for row in conn.execute("SELECT user_name FROM Name2Id").fetchall():
|
||||
|
|
@ -595,7 +595,7 @@ class SessionMonitor:
|
|||
# local_id 不全局唯一,需要同时匹配 create_time
|
||||
file_md5 = None
|
||||
for _try in range(2):
|
||||
res_path = self.db_cache.get("message\\message_resource.db")
|
||||
res_path = self.db_cache.get("message/message_resource.db")
|
||||
if not res_path:
|
||||
return None
|
||||
try:
|
||||
|
|
@ -620,7 +620,7 @@ class SessionMonitor:
|
|||
except Exception as e:
|
||||
if 'malformed' in str(e) and _try == 0:
|
||||
print(f" [img] resource DB malformed, 强制刷新...", flush=True)
|
||||
self.db_cache.invalidate("message\\message_resource.db")
|
||||
self.db_cache.invalidate("message/message_resource.db")
|
||||
continue
|
||||
print(f" [img] 查询 message_resource 失败: {e}", flush=True)
|
||||
return None
|
||||
|
|
@ -756,7 +756,7 @@ class SessionMonitor:
|
|||
if db_key not in self.db_cache.keys:
|
||||
return []
|
||||
enc_key = bytes.fromhex(self.db_cache.keys[db_key]["enc_key"])
|
||||
rel_path = db_key.replace('\\', os.sep)
|
||||
rel_path = db_key.replace('/', os.sep)
|
||||
db_path = os.path.join(DB_DIR, rel_path)
|
||||
wal_path = db_path + "-wal"
|
||||
if not os.path.exists(db_path):
|
||||
|
|
@ -1877,7 +1877,7 @@ def main():
|
|||
with open(KEYS_FILE) as f:
|
||||
keys = json.load(f)
|
||||
|
||||
enc_key = bytes.fromhex(keys["session\\session.db"]["enc_key"])
|
||||
enc_key = bytes.fromhex(keys["session/session.db"]["enc_key"])
|
||||
session_db = os.path.join(DB_DIR, "session", "session.db")
|
||||
|
||||
print("加载联系人...", flush=True)
|
||||
|
|
@ -1910,9 +1910,9 @@ def main():
|
|||
def _warmup():
|
||||
try:
|
||||
t0 = time.perf_counter()
|
||||
warmup_keys = ["message\\message_resource.db"]
|
||||
warmup_keys = ["message/message_resource.db"]
|
||||
for i in range(5):
|
||||
k = f"message\\message_{i}.db"
|
||||
k = f"message/message_{i}.db"
|
||||
if k in keys:
|
||||
warmup_keys.append(k)
|
||||
for k in warmup_keys:
|
||||
|
|
|
|||
Loading…
Reference in New Issue