phoenixray2000
728dbb72df
feat(export): 支持 CSV 计划导出和稳定导出索引 ( #114 )
...
两个核心增强:
1. **CSV 计划导出工作流** (`--write-plan-csv` / `--from-plan-csv`)
- 支持 blacklist (export=0 跳过) / whitelist (export=1 导出) 两种模式
- `--size-mode estimate|scan` 控制是否扫本地附件
- UTF-8 BOM 编码, Excel/WPS 直接打开
- 解决了之前"动不动全量导出"的痛点
2. **`_export_index.json` 稳定导出索引**
- 用 username 追踪当前 JSON 文件
- 联系人备注/群名变化时自动重命名旧文件 (而不是产生孤儿)
- 同名联系人冲突时自动追加 `__<username>` 后缀
- atomic write (tmp + os.replace), bootstrap from existing files
3. **JSON metadata 扩展**
- 新增 `date_first_msg / date_last_msg / contact_remark / contact_nick_name / contact_tags / contact_memo`
测试: 717 行, 20 tests pass, 覆盖 CRUD 索引、黑白名单、命名冲突、incremental rename、UTF-8 BOM。
2026-05-19 02:20:30 +08:00
xincheng
5c3e6adfcd
Add Windows GUI and WXWork export support
2026-05-17 07:07:07 +08:00
xincheng
ecc1cfca64
增加企业微信的解密
2026-05-17 06:24:08 +08:00
Belugary
989badd14f
feat: 给 transcribe_voice 工具加持久化缓存 ( #58 )
...
Whisper 本地推理在 CPU 下每条语音数秒到数十秒,且同一段 voice_data
产出相同 text,非常适合缓存。新增 voice_transcriptions.json 持久化
存储,命中时跳过 DB 查询、SILK 解码和 Whisper 推理全链路。
关键技术选择:
- 缓存 key 用 json.dumps([username, local_id]),即使 username 含
分隔符也不冲突
- 写入走 tmp + os.replace 原子替换,进程中断不会损坏主文件
- 条目记录 model_size,Whisper 默认模型升级后旧条目自动失效
- 空转录也缓存(配合 model_size 失效),避免静音片段每次重跑
- threading.Lock 防御并发 load/save 竞态
- 首次 OSError 写 stderr 警告一次,后续静默避免刷屏
小的行为改进:resolve_username 移到 whisper/pysilk 导入探测之前,
bad chat_name 情况下不再需要 whisper 已安装也能给出"找不到聊天对象"
的错误提示。
15 个新测试:持久化 roundtrip、UTF-8 保留、corrupt JSON 容错、原子
写、写前失败不污染主文件、并发 load/save、缓存命中跳过重活、model
不匹配视为 miss、key 对含分隔符 username 的防御。全部通过。
2026-04-25 00:19:08 +08:00
btc-z
edf2c0940a
feat: 新增聊天导出与语音转录 CLI 脚本 ( #57 )
...
* feat: 新增聊天导出与语音转录 CLI 脚本
新增两个独立 CLI 脚本,用于将单个聊天导出为结构化 JSON、并批量
填充语音消息的 Whisper 转录。区别于 MCP 工具:这些脚本面向离线
导出/归档,适合一次性拉取大量消息,或在会话外喂给其他 LLM/索引
管线使用。
- export_chat.py:跨分片合并某个聊天的全部消息,按时间排序后输出
紧凑 JSON(type 为 text 时省略,is_group 仅群聊保留等)。复用
mcp_server 中的消息解析/发送者解析辅助函数。
- transcribe_chat.py:读入 export_chat.py 产出的 JSON,对所有尚
未转录的 voice 消息调用 Whisper,原地写回 transcription 字段。
幂等(已有 transcription 的消息跳过)、崩溃安全(每条写回一次
输出文件)。
- .gitignore:新增 *.json 通配,避免本地导出文件被误提交。
config.example.json 已被跟踪,不受影响。
修复:transcribe_chat.py 原先调用 _silk_to_wav 时缺少 local_id
参数(commit c149389 将 local_id 加入签名用于文件名唯一化),
本 PR 中已补齐。
* docs: 新增聊天导出 JSON 数据格式文档
新增 docs/chat_export_format.md,描述 export_chat.py 与
transcribe_chat.py 产出的 JSON schema:顶层字段、消息对象的必填/
可选字段、默认值省略规则,以及加载与过滤的 Python 示例。
与现有 docs/macos-*.md 指南风格一致,避免在脚本 docstring 中堆叠
大段表格。export_chat.py 的 docstring 加一行指针指向本文档。
* docs: 聊天导出格式文档翻译为中文
与 docs/macos-*.md 既有指南保持一致的语言风格,将
docs/chat_export_format.md 翻译为中文。JSON 字段名、Python
代码示例等技术标识保持英文不变。
* fix: 回应 PR #57 review — 崩溃处理、幂等性、schema 补全
根据 review (#57 ) 的反馈:
- export_chat.py: _resolve_chat_context 返回 None 时的崩溃改为友好
退出,并在 resolve 成功后打印 display_name (username),便于用户
核对 resolve_username 的模糊匹配结果。
- export_chat.py: _query_messages 的 limit=999999 改为 None,避免
超长历史被悄悄截断(_query_messages 对 None 会省略 LIMIT 子句)。
- export_chat.py: 输出 JSON 顶层新增 username 字段,让
transcribe_chat.py 可以跳过二次模糊匹配,避免同名联系人漂移。
- transcribe_chat.py: 优先读取 JSON 顶层的 username,旧导出文件
(无 username)回退到按 chat 名解析,保持向后兼容。
- transcribe_chat.py: 删除未使用的 import io / import wave,将循环
内的 import datetime 提至模块顶部。
- export_chat.py: _decode_sticker_desc 的 varint 单字节简化给出
注释说明局限,以及对 create_time 排序加 "or 0" 防御。
- export_chat.py / transcribe_chat.py: 模块 docstring 翻译为中文,
与 docs/macos-*.md 保持一致。
- docs/chat_export_format.md: 同步补充 username 字段说明。
- .gitignore: 将 *.json 收窄为 *_export*.json / *_transcribed*.json,
避免误屏蔽未来的 config/fixtures,同时匹配导出工具实际产出的
文件名。
2026-04-25 00:16:37 +08:00
btc-z
02bc9c1840
feat: 新增语音 MCP 工具 + macOS 密钥提取修复 ( #53 )
...
* feat: 新增语音 MCP 工具 + macOS 密钥提取修复
- 新增 get_voice_messages / decode_voice / transcribe_voice MCP 工具
- 语音数据存储在 media_0.db VoiceInfo 表(SILK v3 格式)
- decode_voice 解码为 WAV 文件(saved to decoded_voices/)
- transcribe_voice 通过 Whisper 自动识别语言转录
- 新增 get_chat_history oldest_first 参数,支持从最早消息开始分页
- 修复 macOS 下 check_wechat_running / ensure_keys 逻辑
- 改用 pgrep 检测微信进程,绕过不支持 macOS 的 Python 扫描器
- 无 all_keys.json 时打印清晰引导,提示运行 C 版扫描器
- 新增 Makefile(build / keys / decrypt / web 快捷命令)
- .gitignore 补充 find_all_keys_macos 二进制和 decoded_voices/
* fix: 语音查询支持多分片 media DB + 文件名唯一化
解决 PR #53 review 的阻塞项 #1,顺手修 #3、#6。
#1 `_get_media_db_path()` 硬编码 `media_0.db`
- 新增模块级 `MEDIA_DB_KEYS`,镜像 `MSG_DB_KEYS` 的分片发现逻辑
- `_fetch_voice_row` 遍历所有分片,按 `(chat_name_id, local_id)`
首个命中即返回;单条语音在 media DB 家族内唯一,命中即可停
- `get_voice_messages` 从每个分片各取 `LIMIT limit`,合并排序后
截断到 `limit`。选择"每分片取 limit 条再合并"而非"按
max(create_time) 排序后逐个取到 limit 即停止":后者假设分片
间时间不重叠,一旦 WeChat 改分片策略就会静默丢消息;前者工作
量 O(N 分片 × limit),在任何分片布局下都正确
#3 输出文件名冲突
- `_silk_to_wav` 增加 `local_id` 参数,输出 `{user}_{time}_{lid}.wav`,
同一秒内两条语音不会互相覆盖;两个调用方都已在作用域内持有
`local_id`
#6 `_fetch_voice_row` 的 `local_id=None` 死分支
- 随 #1 的重写一并删除,`local_id` 改为必填位置参数
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
* refactor: macOS 密钥提取分层下沉到 find_all_keys.py
解决 PR #53 review 的阻塞项 #2。
review 里提到"跟 PR #51 冲突"实测不存在 —— PR #51 当前 0 文件改动
(fork 分支已与上游同步),但架构建议本身是对的:macOS 处理应集中
在 `find_all_keys.py`,而不是在 `main.py` 提前 return 截胡。
- `main.py:ensure_keys()` 移除 darwin 专属提前返回分支,macOS 走
和其他平台相同的 `extract_keys()` 路径
- `find_all_keys.py:_load_impl()` 在 darwin 分支抛出带
`sudo ./find_all_keys_macos` 操作指引的 RuntimeError;非 macOS
的平台兜底分支保留
- `main.py` 里已有 `except RuntimeError` 会打印并 `sys.exit(1)`,
用户可见行为不变
未来若有 PR 在 `find_all_keys.py` 加 macOS 自动编译 / dispatch,
直接替换这段 RuntimeError 即可,不再需要改 `main.py`。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
* chore: Makefile 支持 PYTHON 变量覆盖
解决 PR #53 review 的非阻塞项 #7。
原 Makefile 硬编码 `.venv/bin/python3`,没有 venv 的用户跑 `make
decrypt` 直接报错。引入 `PYTHON ?= .venv/bin/python3`:默认行为
不变(仍走 venv),想用系统 Python 的用户 `PYTHON=python3 make
decrypt` 即可。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
* docs: 回应 PR #53 review #4 — 澄清 silk-python 与 pysilk 包名关系
验证:本项目 import 的 `pysilk` 实际由 `pip install silk-python`
(synodriver/pysilk) 提供;pypi 上另有同名 `pysilk==0.0.1` 是无内容
的占位包,不可用。错误消息里 `pip install silk-python` 已经是对的,
但 reader 看到 `import pysilk` 仍会困惑,所以:
- `_silk_to_wav` 的 import 处加一行注释,点名所用的是
synodriver 版本,并提醒 pypi 上还有 pilk / pysilk 两个同类包
- `decode_voice` / `transcribe_voice` 的 docstring 加 "依赖:" 行,
明确 "pip install silk-python (import 名为 pysilk)",MCP 客户端
读 tool 描述就能看到正确的安装命令
未新增 requirements.txt 条目:voice 支持是可选功能(tool 内
try/except ImportError 懒加载),保持非必需依赖的语义。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com >
2026-04-23 14:10:22 +08:00
xincheng
a84698b9fc
Add GUI, packaging and export/voice tools
...
Introduce a tkinter GUI and tooling to produce a single executable and export/convert message data. Adds app_gui.py (GUI launcher that runs decrypt/export/voice subtasks), export_messages.py (export messages to CSV/HTML/JSON), voice_to_mp3.py (extract SILK_V3 voice blobs and convert to MP3 via pilk + ffmpeg), WeChatDecrypt.spec and build.bat (PyInstaller spec and convenience build script), and EXE_USAGE.md (usage for the standalone exe). Update config.py to detect the application base directory when packaged, update README.md to document the GUI and packaging flow, and add pilk/pyinstaller to requirements.txt. Also expand .gitignore with common IDE/build/temp patterns and add output/data directories to ignore. These changes enable one-file packaging and provide end-user tools for decrypting, exporting and converting audio.
2026-04-04 06:12:03 +08:00
ylytdeng
da7525db95
Add image decryption and inline preview for WeChat V2 format
...
Support all three .dat encryption formats:
- Old XOR format: single-byte XOR, auto-detect key from magic bytes
- V1 format: AES-ECB with fixed key (md5("0")[:16]) + XOR tail
- V2 format (2025-08+): AES-128-ECB + raw middle + XOR tail
New files:
- decode_image.py: unified image decryption module (XOR/V1/V2)
- find_image_key.py: extract AES key from WeChat process memory
- find_image_key_monitor.py: continuous monitoring version for key capture
monitor_web.py changes:
- Inline image preview in Web UI with async decryption
- MonitorDBCache for mtime-based DB decryption caching
- username-to-DB mapping for image resolution chain
- /img/ endpoint for serving decoded images
- SSE image_update events for real-time preview updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-02 00:30:01 +08:00
joshua-deng
4c91eb34ef
WeChat 4.0 database decryptor and real-time message monitor
...
Extract encryption keys from Weixin.exe process memory, decrypt all
SQLCipher 4 databases, and monitor new messages via Web UI with ~100ms latency.
2026-02-28 12:03:38 +08:00