diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 5d6e015..0000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-name: Bug report
-about: 帮助定位问题所在
-title: ''
-labels: ''
-assignees: ''
-
----
-
-**问题描述**
-请在此处提供对问题的详细描述。
-
-**复现步骤**
-请提供重现问题所需的步骤。(执行的命令)
-
-1. 步骤 1
-2. 步骤 2
-3. 步骤 3
-
-**预期行为**
-请清楚地描述您预期的行为。
-
-**实际行为**
-请描述实际的行为和问题出现的地方。
-
-**环境信息**
-- pywxdump版本:
-- 操作系统版本:
-- python版本:
-- 微信版本:
-
-
-
-**其他信息**
-请提供任何与问题相关的其他信息(文字,截图等)。
diff --git a/.github/workflows/auto-sync-gitee.yml b/.github/workflows/auto-sync-gitee.yml
deleted file mode 100644
index ad7583e..0000000
--- a/.github/workflows/auto-sync-gitee.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-#on:
-# push:
-# branches: [master]
-#name: Mirror GitHub Repos to Gitee
-#jobs:
-# run:
-# name: Sync-GitHub-to-Gitee
-# runs-on: ubuntu-latest
-# steps:
-# - name: Mirror the Github repos to Gitee.
-# uses: Yikun/hub-mirror-action@master
-# with:
-# src: github/xaoyaoo
-# dst: gitee/xaoyaoo
-# dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
-# dst_token: ${{ secrets.GITEE_TOKEN }}
-# force_update: true
-# src_account_type: org
-# dst_account_type: user
-# mappings: "dashboard=>dashboards"
-# static_list: "trader"
-# cache_path: /github/workspace/hub-mirror-cache
-
-name: Hello World Action
-
-on:
- push:
- branches: [ main ] # 触发条件:当主分支有新的推送时
-
-jobs:
- hello-job:
- runs-on: ubuntu-latest # 运行环境:最新的 Ubuntu 系统
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@v3 # 检出代码
-
- - name: Print Hello Message
- run: echo "Hello, world!" # 执行命令,打印消息
-
- - name: Print Date
- run: date # 执行命令,打印当前日期
\ No newline at end of file
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
deleted file mode 100644
index ef44427..0000000
--- a/.github/workflows/publish.yml
+++ /dev/null
@@ -1,134 +0,0 @@
-name: Publish
-
-on:
- # 当master分支有push时,触发action
- push:
- tags:
- - 'v*' # 以 'v' 开头的标签触发工作流程
-
-jobs:
- publish:
- name: Publish Pypi and Create Release
- if: github.repository == 'xaoyaoo/PyWxDump' # 仅在指定仓库的 tag 触发工作流程
- # 此作业在 Linux 上运行
- runs-on: windows-latest
-
- steps:
- - name: Checkout repository # 检出仓库
- uses: actions/checkout@v2 # 使用 GitHub 官方的 checkout action
-
- - name: Set git fetch depth # 设置 git fetch 深度
- run: |
- git fetch --prune --unshallow # 获取完整的 git 历史记录
-
- - name: Set up Python # 设置 Python 环境
- uses: actions/setup-python@v4
- with:
- python-version: '3.8'
- cache: 'pip' # caching pip dependencies
- - run: |
- python -m pip install --upgrade pip
- pip install build
- python -m pip install --upgrade twine
- pip install pyinstaller
- pip install -r requirements.txt
-
- - name: Set up Node.js # 设置 Node.js 环境
- uses: actions/setup-node@v2
- with:
- node-version: 20
-
- - name: Build Web UI # 构建 Web UI
- run: |
- cd ..
- git clone https://github.com/xaoyaoo/wxdump_web.git
- Compress-Archive -Path wxdump_web -DestinationPath wxdump_web.zip
- Compress-Archive -Path PyWxDump -DestinationPath PyWxDump.zip
- cd wxdump_web
- npm list -g
- npm install
- npm run build
-
- - name: copy web ui to pywxdump/ui/web
- run: |
- cd ..
- ls -l wxdump_web/dist
- cp -r wxdump_web/dist PyWxDump/pywxdump/ui/web
- ls -l PyWxDump/pywxdump/ui/web
- cd PyWxDump
-
-# - name: Build Export UI # 构建导出的 Web UI
-# run: |
-# cd ..
-# cd wxdump_web
-# cp src/main.ts src/t.ts
-# cp src/main.ts.export src/main.ts
-# npm install
-# npm run build
-#
-# - name: copy Export UI and Export UI to pywxdump/ui/web and pywxdump/ui/export
-# run: |
-# cd ..
-# ls -l wxdump_web/dist
-# cp -r wxdump_web/dist PyWxDump/pywxdump/ui/export
-# ls -l PyWxDump/pywxdump/ui/export
-# cd PyWxDump
-
- - name: Build package # 构建包
- run: |
- python -m build
- pip install -U .
-
- - name: Generate File pywxdump.spec # 生成 pywxdump.spec 文件
- run: |
- python tests/build_exe.py
- ls
- ls dist
- cat dist/pywxdump.spec
-
- - name: Build Executable
- run: |
- pyinstaller --clean --distpath=dist dist/pywxdump.spec
-
- - name: test
- run: |
- ls -l dist
- ls -l "${{ github.workspace }}"
-
- - name: Zip Executable
- run: |
- cd ..
- ls
- Compress-Archive -Path PyWxDump/dist/*.exe,PyWxDump/dist/*.whl -DestinationPath exe_whl.zip
- Compress-Archive -Path PyWxDump.zip,wxdump_web.zip -DestinationPath Source.zip
- ls
- cp exe_whl.zip PyWxDump/dist/exe_whl.zip
- cp Source.zip PyWxDump/dist/Source.zip
- ls PyWxDump/dist
- cd PyWxDump
-
- - name: Publish package with Twine # 使用 Twine 发布到 PyPI
- run: |
- twine upload dist/*.whl dist/*.tar.gz
- env:
- TWINE_USERNAME: __token__
- TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
-
- - name: Create Release
- id: create_release
- uses: softprops/action-gh-release@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: ${{ github.ref }}
- release_name: Release ${{ github.ref.tag }}
- body: |
- [Auto Release] Update PyWxDump to ${{ github.ref }}
- 详细更新日志请查看 [CHANGELOG.md](https://github.com/xaoyaoo/PyWxDump/blob/master/doc/CHANGELOG.md)
- draft: false
- prerelease: false
- files: |
- dist/*.exe
- dist/*.whl
- dist/exe_whl.zip
- dist/Source.zip
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index bcafc10..5147b19 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,3 +29,4 @@ dist-ssr
*.local
/pywxdump/ui/web/*
/pywxdump/ui/web/assets/*
+/pywxdump/wxdump_work
diff --git a/pywxdump/api/export/exportJSON.py b/pywxdump/api/export/exportJSON.py
index f04c179..06cf47c 100644
--- a/pywxdump/api/export/exportJSON.py
+++ b/pywxdump/api/export/exportJSON.py
@@ -5,6 +5,7 @@
# Author: xaoyaoo
# Date: 2024/04/20
# -------------------------------------------------------------------------------
+import datetime
import json
import os
from pywxdump.db import DBHandler
@@ -39,5 +40,135 @@ def export_json(wxid, outpath, db_config, my_wxid="我", indent=4):
return True, f"导出成功: {outpath}"
+def export_json_mini(wxid, outpath, db_config, my_wxid="我", indent=4):
+ # 确保输出目录存在
+ if not os.path.exists(outpath):
+ outpath = os.path.join(os.getcwd(), "export_mini" + os.sep + wxid)
+ os.makedirs(outpath, exist_ok=True)
+
+ db = DBHandler(db_config, my_wxid)
+
+ # 获取消息总数
+ count = db.get_msgs_count(wxid)
+ chatCount = count.get(wxid, 0)
+ if chatCount == 0:
+ return False, "没有聊天记录"
+
+ users = {}
+ page_size = chatCount + 1 # 保持与原函数一致的分页逻辑
+
+ for i in range(0, chatCount, page_size):
+ start_index = i
+ data, users_t = db.get_msgs(wxid, start_index, page_size)
+ users.update(users_t) # 合并用户信息
+
+ if not data:
+ continue
+
+ # 构建简化数据
+ mini_data = []
+ for msg in data:
+ # 获取昵称(优先用备注,没有则用昵称,最后用wxid)
+ user_info = users.get(msg.get("talker"), {})
+ nickname = user_info.get("remark") or user_info.get("nickname") or msg.get("talker")
+
+ mini_msg = {
+ "nickname": nickname,
+ "message": msg.get("msg", ""),
+ "time": msg.get("CreateTime", "")
+ }
+ mini_data.append(mini_msg)
+
+ # 保存简化后的文件
+ save_path = os.path.join(outpath, f"{wxid}_mini_{i}_{i + page_size}.json")
+ with open(save_path, "w", encoding="utf-8") as f:
+ json.dump(mini_data, f, ensure_ascii=False, indent=indent)
+
+ return True, f"简化版导出成功: {outpath}"
+
+
+def export_json_mini_time_limit(wxid, outpath, db_config, my_wxid="我",
+ start_createtime=None, end_createtime=None, indent=4):
+ """
+ 带时间过滤的简化版聊天记录导出
+
+ :param start_createtime: 开始时间(格式:2025-4-30 16:55:01)
+ :param end_createtime: 结束时间(格式:2025-4-30 16:55:01)
+ """
+ # 创建输出目录
+ if not os.path.exists(outpath):
+ outpath = os.path.join(os.getcwd(), "export_mini" + os.sep + wxid)
+ os.makedirs(outpath, exist_ok=True)
+
+ # 初始化数据库连接
+ db = DBHandler(db_config, my_wxid)
+
+ # 时间格式转换
+ def str_to_timestamp(time_str):
+ if not time_str:
+ return None
+ try:
+ dt = datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S")
+ return int(dt.timestamp())
+ except ValueError:
+ raise ValueError(f"无效时间格式: {time_str},示例: 2025-04-30 16:55:01")
+
+ start_ts = str_to_timestamp(start_createtime)
+ end_ts = str_to_timestamp(end_createtime)
+
+ # 获取消息数据(带时间过滤)
+ all_data = []
+ users = {}
+ page_size = 5000 # 每次获取5000条
+ start_index = 0
+
+ while True:
+ # 获取分页数据(自动包含时间过滤条件)
+ data, users_t = db.get_msgs(
+ wxid,
+ start_index=start_index,
+ page_size=page_size,
+ start_createtime=start_ts,
+ end_createtime=end_ts
+ )
+
+ if not data:
+ break
+
+ all_data.extend(data)
+ users.update(users_t)
+ start_index += page_size
+
+ if not all_data:
+ return False, "指定时间段内没有聊天记录"
+
+ # 构建简化数据结构
+ mini_data = []
+ for msg in all_data:
+ talker = msg.get("talker")
+ user_info = users.get(talker, {})
+
+ mini_msg = {
+ "sender": user_info.get("remark") or user_info.get("nickname") or talker,
+ "content": msg.get("msg", ""),
+ "timestamp": msg.get("CreateTime")
+ }
+ mini_data.append(mini_msg)
+
+ # 生成带时间范围的文件名
+ time_suffix = ""
+ if start_createtime or end_createtime:
+ start_part = start_createtime.replace(" ", "_").replace(":", "-") if start_createtime else "all"
+ end_part = end_createtime.replace(" ", "_").replace(":", "-") if end_createtime else "now"
+ time_suffix = f"_{start_part}_to_{end_part}"
+
+ save_path = os.path.join(outpath, f"{wxid}_mini{time_suffix}.json")
+ with open(save_path, "w", encoding="utf-8") as f:
+ json.dump(mini_data, f, ensure_ascii=False, indent=indent)
+
+ return True, f"导出成功: {save_path}"
+
+
+
if __name__ == '__main__':
pass
diff --git a/pywxdump/api/remote_server.py b/pywxdump/api/remote_server.py
index 630d996..9aa8d49 100644
--- a/pywxdump/api/remote_server.py
+++ b/pywxdump/api/remote_server.py
@@ -5,6 +5,7 @@
# Author: xaoyaoo
# Date: 2024/01/02
# -------------------------------------------------------------------------------
+import datetime
import os
import time
import shutil
@@ -22,6 +23,7 @@ from pywxdump.db import DBHandler
from pywxdump.db.utils import download_file, dat2img
from .export import export_csv, export_json, export_html
+from .export.exportJSON import export_json_mini, export_json_mini_time_limit
from .rjson import ReJson, RqJson
from .utils import error9999, gc, asyncError9999, rs_loger
@@ -134,11 +136,18 @@ def get_msgs(wxid: str = Body(...), start: int = Body(...), limit: int = Body(..
"""
my_wxid = gc.get_conf(gc.at, "last")
+
if not my_wxid: return ReJson(1001, body="my_wxid is required")
db_config = gc.get_conf(my_wxid, "db_config")
db = DBHandler(db_config, my_wxid=my_wxid)
- msgs, users = db.get_msgs(wxids=wxid, start_index=start, page_size=limit)
+
+ start_createtime = datetime.datetime.strptime("2025-04-28 00:54:33",
+ "%Y-%m-%d %H:%M:%S").timestamp()
+ end_createtime = datetime.datetime.now().timestamp()
+ msgs, users = db.get_msgs(wxids=wxid, start_index=start, page_size=limit,) #
+
+
return ReJson(0, {"msg_list": msgs, "user_list": users})
@@ -457,13 +466,16 @@ def get_export_json(wxid: str = Body(..., embed=True)):
if not os.path.exists(outpath):
os.makedirs(outpath)
- code, ret = export_json(wxid, outpath, db_config, my_wxid=my_wxid)
+ code, ret = export_json_mini_time_limit(wxid, outpath, db_config, my_wxid=my_wxid,start_createtime="2025-4-29 00:00:00", end_createtime="2025-4-30 00:00:00")
if code:
return ReJson(0, ret)
else:
return ReJson(2001, body=ret)
+
+
+
class ExportHtmlRequest(BaseModel):
wxid: str
diff --git a/pywxdump/cli.py b/pywxdump/cli.py
index 9e436f0..6fb3801 100644
--- a/pywxdump/cli.py
+++ b/pywxdump/cli.py
@@ -367,7 +367,7 @@ class MainApi(BaseSubMainClass):
def console_run():
# 检查是否需要显示帮助信息
if len(sys.argv) == 1:
- sys.argv.append(MainUi.mode)
+ sys.argv.append(MainApi.mode)
elif len(sys.argv) == 2 and sys.argv[1] not in models.keys():
sys.argv.append('-h')
main_parser.print_help()
diff --git a/pywxdump/db/__init__.py b/pywxdump/db/__init__.py
index e20180a..737069b 100644
--- a/pywxdump/db/__init__.py
+++ b/pywxdump/db/__init__.py
@@ -59,6 +59,8 @@ class DBHandler(MicroHandler, MediaHandler, OpenIMContactHandler, PublicMsgHandl
"talker": talker, "room_name": StrTalker, "msg": msg, "src": src, "extra": {},
"CreateTime": CreateTime, }
"""
+
+
msgs0, wxid_list0 = self.get_msg_list(wxids=wxids, start_index=start_index, page_size=page_size,
msg_type=msg_type,
msg_sub_type=msg_sub_type, start_createtime=start_createtime,
diff --git a/pywxdump/db/dbMSG.py b/pywxdump/db/dbMSG.py
index ed2f075..4d9e0d3 100644
--- a/pywxdump/db/dbMSG.py
+++ b/pywxdump/db/dbMSG.py
@@ -103,9 +103,16 @@ class MsgHandler(DatabaseBase):
f"{sql_sub_type}"
f"{sql_start_createtime}"
f"{sql_end_createtime}"
- f"ORDER BY CreateTime ASC LIMIT ?,?"
+ f"ORDER BY CreateTime ASC LIMIT ? OFFSET ?"
)
- param = param + (start_index, page_size)
+
+ param = param + ( page_size,start_index)
+ # # 测试
+ # print(sql + "\n" + " ".join([str(i) for i in param]))
+ # print(sql + "\n" + " ".join([str(i) for i in param]))
+ # print(sql + "\n" + " ".join([str(i) for i in param]))
+
+
result = self.execute(sql, param)
if not result:
return [], []
diff --git a/pywxdump/ui/.github/workflows/auto_build.yml b/pywxdump/ui/.github/workflows/auto_build.yml
new file mode 100644
index 0000000..7285a40
--- /dev/null
+++ b/pywxdump/ui/.github/workflows/auto_build.yml
@@ -0,0 +1,28 @@
+name: Build and Deploy Vue App
+
+on:
+ push:
+ branches:
+ - web
+
+jobs:
+ build:
+ runs-on: windows-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v2
+ with:
+ node-version: 20
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Build the app
+ run: npm run build
+
+ - name: Cheak dist
+ run: ls dist
diff --git a/pywxdump/ui/.gitignore b/pywxdump/ui/.gitignore
new file mode 100644
index 0000000..9768ad7
--- /dev/null
+++ b/pywxdump/ui/.gitignore
@@ -0,0 +1,34 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+tsconfig.app.tsbuildinfo
+tsconfig.node.tsbuildinfo
+
+/public/data/
\ No newline at end of file
diff --git a/pywxdump/ui/.vscode/extensions.json b/pywxdump/ui/.vscode/extensions.json
new file mode 100644
index 0000000..c0a6e5a
--- /dev/null
+++ b/pywxdump/ui/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
+}
diff --git a/pywxdump/ui/README.md b/pywxdump/ui/README.md
new file mode 100644
index 0000000..c046b31
--- /dev/null
+++ b/pywxdump/ui/README.md
@@ -0,0 +1 @@
+## 这是[PyWxDump](https://github.com/xaoyaoo/PyWxDump)的Web版,用于在浏览器中查看微信聊天记录。
\ No newline at end of file
diff --git a/pywxdump/ui/env.d.ts b/pywxdump/ui/env.d.ts
new file mode 100644
index 0000000..7332cfa
--- /dev/null
+++ b/pywxdump/ui/env.d.ts
@@ -0,0 +1,6 @@
+///
{{ direction }}
+ + +{{ direction }}
+ + +{{ direction }}
+ +{{ direction }}
+ +{{ direction }}
+{{ direction }}
+ +{{ direction }}
+ +{{ direction }}
+ +{{ direction }}
+ +{{ direction }}
+ +{{ direction }}
+ +{{ direction }}
+ +{{ direction }}
+{{ direction }}
+ +如需提前体验更多功能,请多多支持,多多鼓励!
+当前版本:{{ version }}
+ +当前版本:{{ version }}
+ +当前版本:{{ version }}
+ +当前版本:{{ version }}
+ +当前版本:{{ version }}
+ +2025-04-27至2025-04-29
+ +群成员围绕中国大学生计算机设计大赛参赛作品《文书宝典——智能公文库与写作平台》展开密集讨论,涉及文档编写、PPT制作、答辩视频准备等工作。
+关于计算机设计大赛的技术实现参考文章
+项目核心技术要点汇总文档
+你用ai直接生成的吗
+ +不完全是,有些是昨晚提取的,今早列上
+[日期]
+ +{topic['summary']}
+{tut['summary']}
+{ans['content']}
+{qa['question']['content']}
+ +[日期]
+ +[简要总结(50-100字)]
+[内容简介]
+[问题内容]
+ +[回答内容]
+