重构导出csv

This commit is contained in:
xaoyaoo 2024-04-20 17:54:54 +08:00
parent aec195214c
commit cc337391bc
6 changed files with 106 additions and 10 deletions

View File

@ -23,6 +23,7 @@ from pywxdump import read_info, VERSION_LIST, batch_decrypt, BiasAddr, merge_db,
import pywxdump
from pywxdump.dbpreprocess import wxid2userinfo, ParsingMSG, get_user_list, get_recent_user_list, ParsingMediaMSG, \
download_file
from pywxdump.dbpreprocess import export_csv
# app = Flask(__name__, static_folder='../ui/web/dist', static_url_path='/')
@ -440,7 +441,7 @@ def get_file(filePath):
# start 导出聊天记录 *****************************************************************************************************
@api.route('/api/export_endb', methods=["GET", 'POST'])
def export_endb():
def get_export_endb():
"""
导出加密数据库
:return:
@ -472,7 +473,7 @@ def export_endb():
@api.route('/api/export_dedb', methods=["GET", "POST"])
def export_dedb():
def get_export_dedb():
"""
导出解密数据库
:return:
@ -483,15 +484,47 @@ def export_dedb():
key = request.json.get("key", read_session(g.sf, my_wxid, "key"))
wx_path = request.json.get("wx_path", read_session(g.sf, my_wxid, "wx_path"))
if not key:
return ReJson(1002, body=f"key is required: {key}")
if not wx_path:
return ReJson(1002, body=f"wx_path is required: {wx_path}")
if not os.path.exists(wx_path):
return ReJson(1001, body=f"wx_path not exists: {wx_path}")
outpath = os.path.join(g.tmp_path, "export", my_wxid, "dedb")
if not os.path.exists(outpath):
os.makedirs(outpath)
merge_path = read_session(g.sf, my_wxid, "merge_path")
assert isinstance(outpath, str) # 为了解决pycharm的警告, 无实际意义
shutil.copy(merge_path, os.path.join(outpath, os.path.basename(merge_path)))
code, merge_save_path = decrypt_merge(wx_path=wx_path, key=key, outpath=outpath)
time.sleep(1)
if code:
return ReJson(0, body=merge_save_path)
else:
return ReJson(2001, body=merge_save_path)
return ReJson(0, body=outpath)
@api.route('/api/export_csv', methods=["GET", 'POST'])
def get_export_csv():
"""
导出csv
:return:
"""
my_wxid = read_session(g.sf, "test", "last")
if not my_wxid: return ReJson(1001, body="my_wxid is required")
wxid = request.json.get("wxid")
if not wxid:
return ReJson(1002, body=f"username is required: {wxid}")
outpath = os.path.join(g.tmp_path, "export", my_wxid, "csv", wxid)
if not os.path.exists(outpath):
os.makedirs(outpath)
code, ret = export_csv(wxid, outpath, read_session(g.sf, my_wxid, "msg_path"))
if code:
return ReJson(0, ret)
else:
return ReJson(2001, body=ret)
@api.route('/api/export', methods=["GET", 'POST'])

View File

@ -13,6 +13,8 @@ from .parsingMediaMSG import ParsingMediaMSG
from .parsingOpenIMContact import ParsingOpenIMContact
from .utils import download_file
from .export.exportCSV import export_csv
def get_user_list(MicroMsg_db_path, OpenIMContact_db_path=None, word=None):
"""
@ -65,7 +67,7 @@ def wxid2userinfo(MicroMsg_db_path, OpenIMContact_db_path, wxid):
"""
获取联系人信息
:param MicroMsg_db_path: MicroMsg.db 文件路径
:param wxid: 微信id
:param wxid: 微信id,可以是单个id也可以是多个id使用list传入
:return: 联系人信息 {wxid: {wxid: wxid, nickname: nickname, remark: remark, account: account, describe: describe, headImgUrl: headImgUrl}}
"""
# 连接 MicroMsg.db 数据库,并执行查询

View File

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: exportCSV.py
# Description:
# Author: xaoyaoo
# Date: 2024/04/20
# -------------------------------------------------------------------------------
import csv
import json
import os
from ..parsingMSG import ParsingMSG
def export_csv(wxid, outpath, msg_path, page_size=5000):
if not os.path.exists(outpath):
outpath = os.path.join(os.getcwd(), "export" + os.sep + wxid)
if not os.path.exists(outpath):
os.makedirs(outpath)
pmsg = ParsingMSG(msg_path)
count = pmsg.msg_count(wxid)
chatCount = count.get(wxid, 0)
if chatCount == 0:
return False, "没有聊天记录"
if page_size > chatCount:
page_size = chatCount + 1
for i in range(0, chatCount, page_size):
start_index = i
data, wxid_list = pmsg.msg_list(wxid, start_index, page_size)
if len(data) == 0:
return False, "没有聊天记录"
save_path = os.path.join(outpath, f"{wxid}_{i}_{i + page_size}.csv")
with open(save_path, "w", encoding="utf-8", newline='') as f:
csv_writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL)
csv_writer.writerow(["id", "MsgSvrID", "type_name", "is_sender", "talker", "room_name", "content",
"CreateTime"])
for row in data:
id = row.get("id", "")
MsgSvrID = row.get("MsgSvrID", "")
type_name = row.get("type_name", "")
is_sender = row.get("is_sender", "")
talker = row.get("talker", "")
room_name = row.get("room_name", "")
content = row.get("content", "")
CreateTime = row.get("CreateTime", "")
content = json.dumps(content, ensure_ascii=False)
csv_writer.writerow([id, MsgSvrID, type_name, is_sender, talker, room_name, content, CreateTime])
return True, f"导出成功: {outpath}"
if __name__ == '__main__':
pass

View File

@ -50,7 +50,7 @@ class ParsingMSG(DatabaseBase):
"""
获取聊天记录数量,根据wxid获取单个联系人的聊天记录数量不传wxid则获取所有联系人的聊天记录数量
:param MSG_db_path: MSG.db 文件路径
:return: 聊天记录数量列表
:return: 聊天记录数量列表 {wxid: chat_count}
"""
if wxid:
sql = f"SELECT StrTalker, COUNT(*) FROM MSG WHERE StrTalker='{wxid}';"

View File

@ -42,7 +42,7 @@ class ParsingMicroMsg(DatabaseBase):
def wxid2userinfo(self, wxid):
"""
获取单个联系人信息
:param wxid: 微信id
:param wxid: 微信id,可以是单个id也可以是id列表
:return: 联系人信息
"""
if isinstance(wxid, str):

View File

@ -291,7 +291,7 @@ def merge_db(db_paths, save_path="merge.db", CreateTime: int = 0, endCreateTime:
def decrypt_merge(wx_path, key, outpath="", CreateTime: int = 0, endCreateTime: int = 0) -> (bool, str):
"""
解密合并数据库 msg.db, microMsg.db, media.db
解密合并数据库 msg.db, microMsg.db, media.db,注意会删除原数据库
:param wx_path: 微信路径 eg: C:\*******\WeChat Files\wxid_*********
:param key: 解密密钥
:return: (true,解密后的数据库路径) or (false,错误信息)