PyWxDump/pywxdump/api/api.py

705 lines
25 KiB
Python
Raw Normal View History

2024-01-03 21:34:34 +08:00
# -*- coding: utf-8 -*-#
# -------------------------------------------------------------------------------
# Name: chat_api.py
# Description:
# Author: xaoyaoo
# Date: 2024/01/02
# -------------------------------------------------------------------------------
2024-01-04 09:26:58 +08:00
import base64
2024-02-23 23:47:50 +08:00
import json
import logging
2024-01-04 09:26:58 +08:00
import os
2024-02-26 00:54:14 +08:00
import re
import time
2024-01-20 21:00:17 +08:00
import shutil
2024-01-04 09:26:58 +08:00
2024-01-26 17:45:38 +08:00
from flask import Flask, request, render_template, g, Blueprint, send_file, make_response, session
from pywxdump import analyzer, read_img_dat, read_audio, get_wechat_db, get_core_db
from pywxdump.analyzer.export_chat import get_contact, get_room_user_list
2024-01-03 21:34:34 +08:00
from pywxdump.api.rjson import ReJson, RqJson
2024-02-28 18:37:04 +08:00
from pywxdump.api.utils import read_session, save_session, error9999, gen_base64
2024-02-20 12:35:38 +08:00
from pywxdump import read_info, VERSION_LIST, batch_decrypt, BiasAddr, merge_db, decrypt_merge, merge_real_time_db
2024-01-16 19:25:33 +08:00
import pywxdump
2024-01-05 16:45:58 +08:00
2024-01-04 11:28:26 +08:00
# app = Flask(__name__, static_folder='../ui/web/dist', static_url_path='/')
2024-01-03 21:34:34 +08:00
2024-01-16 18:33:35 +08:00
api = Blueprint('api', __name__, template_folder='../ui/web', static_folder='../ui/web/assets/', )
2024-01-04 11:28:26 +08:00
api.debug = False
2024-01-03 21:34:34 +08:00
2024-01-04 11:28:26 +08:00
@api.route('/api/init', methods=["GET", 'POST'])
@error9999
2024-01-03 21:34:34 +08:00
def init():
"""
2024-01-19 17:03:28 +08:00
初始化 设置微信数据库路径图片路径解密需要的数据库
2024-01-03 21:34:34 +08:00
:return:
"""
2024-02-04 17:40:52 +08:00
msg_path = request.json.get("msg_path", "").strip().strip("'").strip('"')
micro_path = request.json.get("micro_path", "").strip().strip("'").strip('"')
media_path = request.json.get("media_path", "").strip().strip("'").strip('"')
2024-02-04 17:40:52 +08:00
wx_path = request.json.get("wx_path", "").strip().strip("'").strip('"')
key = request.json.get("key", "").strip().strip("'").strip('"')
my_wxid = request.json.get("my_wxid", "").strip().strip("'").strip('"')
init_type = request.json.get("init_type", "").strip()
if init_type == "last":
save_msg_path = read_session(g.sf, "msg_path")
save_micro_path = read_session(g.sf, "micro_path")
save_my_wxid = read_session(g.sf, "my_wxid")
2024-02-20 12:35:38 +08:00
if save_msg_path and save_micro_path and os.path.exists(save_msg_path) and os.path.exists(
save_micro_path):
2024-02-20 12:35:38 +08:00
try:
a = get_real_time_msg()
except Exception as e:
pass
return ReJson(0, {"msg_path": save_msg_path, "micro_path": save_micro_path, "is_init": True})
else:
return ReJson(1002, body="上次初始化的路径不存在")
if key: # 如果key不为空表示是解密模式
if not wx_path:
return ReJson(1002)
if not os.path.exists(wx_path):
return ReJson(1001, body=wx_path)
out_path = os.path.join(g.tmp_path, "decrypted", my_wxid) if my_wxid else os.path.join(g.tmp_path, "decrypted")
if os.path.exists(out_path):
shutil.rmtree(out_path)
code, merge_save_path = decrypt_merge(wx_path=wx_path, key=key, outpath=out_path)
time.sleep(1)
if code:
save_session(g.sf, "msg_path", merge_save_path)
save_session(g.sf, "micro_path", merge_save_path)
save_session(g.sf, "media_path", merge_save_path)
save_session(g.sf, "wx_path", wx_path)
save_session(g.sf, "key", key)
save_session(g.sf, "my_wxid", my_wxid)
rdata = {
"msg_path": merge_save_path,
"micro_path": merge_save_path,
"media_path": merge_save_path,
"wx_path": wx_path,
"key": key,
"my_wxid": my_wxid,
"is_init": True,
}
return ReJson(0, rdata)
else:
return ReJson(2001, body=merge_save_path)
else:
if not msg_path or not micro_path:
return ReJson(1002, body="msg_path and micro_path is required")
if not os.path.exists(msg_path) or not os.path.exists(micro_path):
return ReJson(1001)
save_session(g.sf, "msg_path", msg_path)
save_session(g.sf, "micro_path", micro_path)
save_session(g.sf, "media_path", media_path)
save_session(g.sf, "wx_path", wx_path)
save_session(g.sf, "key", "")
save_session(g.sf, "my_wxid", my_wxid)
rdata = {
"msg_path": msg_path,
"micro_path": micro_path,
"media_path": media_path,
"wx_path": wx_path,
"key": "",
"my_wxid": my_wxid,
"is_init": True,
}
return ReJson(0, rdata)
2024-01-03 21:34:34 +08:00
2024-01-16 19:25:33 +08:00
@api.route('/api/version', methods=["GET", 'POST'])
2024-01-22 18:59:25 +08:00
@error9999
2024-01-16 19:25:33 +08:00
def version():
"""
版本
:return:
"""
return ReJson(0, pywxdump.__version__)
2024-01-03 21:34:34 +08:00
2024-01-04 11:28:26 +08:00
@api.route('/api/contact_list', methods=["GET", 'POST'])
2024-01-22 18:59:25 +08:00
@error9999
2024-01-03 21:34:34 +08:00
def contact_list():
"""
获取联系人列表
:return:
"""
2024-01-22 18:59:25 +08:00
# 获取联系人列表
# 从header中读取micro_path
micro_path = request.headers.get("micro_path")
if not micro_path:
micro_path = read_session(g.sf, "micro_path")
start = request.json.get("start")
limit = request.json.get("limit")
2024-01-03 21:34:34 +08:00
2024-01-22 18:59:25 +08:00
contact_list = analyzer.get_contact_list(micro_path)
2024-01-30 00:21:33 +08:00
# save_session(g.sf, "user_list", contact_list)
2024-01-22 18:59:25 +08:00
if limit:
contact_list = contact_list[int(start):int(start) + int(limit)]
return ReJson(0, contact_list)
2024-01-03 21:34:34 +08:00
2024-01-04 11:28:26 +08:00
@api.route('/api/chat_count', methods=["GET", 'POST'])
2024-01-03 21:34:34 +08:00
def chat_count():
"""
2024-02-04 11:35:13 +08:00
获取每个联系人的聊天记录数量
2024-01-03 21:34:34 +08:00
:return:
"""
try:
# 获取联系人列表
# 从header中读取micro_path
msg_path = request.headers.get("msg_path")
if not msg_path:
msg_path = read_session(g.sf, "msg_path")
2024-01-05 20:40:26 +08:00
username = request.json.get("username", "")
contact_list = analyzer.get_chat_count(msg_path, username)
2024-01-03 21:34:34 +08:00
return ReJson(0, contact_list)
except Exception as e:
return ReJson(9999, msg=str(e))
2024-01-04 11:28:26 +08:00
@api.route('/api/contact_count_list', methods=["GET", 'POST'])
2024-01-03 21:34:34 +08:00
def contact_count_list():
"""
2024-02-04 11:35:13 +08:00
获取联系人列表以及聊天记录数量
2024-01-03 21:34:34 +08:00
:return:
"""
try:
# 获取联系人列表
# 从header中读取micro_path
msg_path = request.headers.get("msg_path")
micro_path = request.headers.get("micro_path")
if not msg_path:
msg_path = read_session(g.sf, "msg_path")
2024-01-03 21:34:34 +08:00
if not micro_path:
micro_path = read_session(g.sf, "micro_path")
2024-01-03 21:34:34 +08:00
start = request.json.get("start")
limit = request.json.get("limit")
word = request.json.get("word", "")
contact_list = analyzer.get_contact_list(micro_path)
chat_count = analyzer.get_chat_count(msg_path)
for contact in contact_list:
contact["chat_count"] = chat_count.get(contact["username"], 0)
# 去重
contact_list = [dict(t) for t in {tuple(d.items()) for d in contact_list}]
2024-01-03 21:34:34 +08:00
# 降序
contact_list = sorted(contact_list, key=lambda x: x["chat_count"], reverse=True)
2024-01-30 00:21:33 +08:00
# save_session(g.sf, "user_list", contact_list)
2024-01-03 21:34:34 +08:00
if word and word != "" and word != "undefined" and word != "null":
contact_list = [contact for contact in contact_list if
word in contact["account"] or word in contact["describe"] or word in contact[
"nickname"] or word in contact["remark"] or word in contact["username"]]
if limit:
contact_list = contact_list[int(start):int(start) + int(limit)]
return ReJson(0, contact_list)
except Exception as e:
return ReJson(9999, msg=str(e))
@api.route('/api/msgs_user_list', methods=['GET', 'POST'])
@error9999
def get_msg_user_list():
2024-02-04 11:35:13 +08:00
"""
获取消息联系人列表
:return:
"""
msg_path = request.headers.get("msg_path")
micro_path = request.headers.get("micro_path")
if not msg_path:
msg_path = read_session(g.sf, "msg_path")
if not micro_path:
micro_path = read_session(g.sf, "micro_path")
wxid = request.json.get("wxid")
# msg_list = analyzer.get_msg_list(msg_path, wxid, start_index=start, page_size=limit)
my_wxid = read_session(g.sf, "my_wxid")
userlist = []
if wxid.endswith("@chatroom"):
# 群聊
userlist = get_room_user_list(msg_path, wxid)
else:
# 单聊
user = get_contact(micro_path, wxid)
my_user = get_contact(micro_path, my_wxid)
userlist.append(user)
userlist.append(my_user)
return ReJson(0, {"user_list": userlist})
@api.route('/api/msgs_list', methods=['GET', 'POST'])
@error9999
def get_msg_list():
msg_path = request.headers.get("msg_path")
micro_path = request.headers.get("micro_path")
if not msg_path:
msg_path = read_session(g.sf, "msg_path")
if not micro_path:
micro_path = read_session(g.sf, "micro_path")
start = request.json.get("start")
limit = request.json.get("limit")
wxid = request.json.get("wxid")
my_wxid = read_session(g.sf, "my_wxid")
msg_list = analyzer.get_msg_list(msg_path, wxid, start_index=start, page_size=limit)
return ReJson(0, {"msg_list": msg_list, 'my_wxid': my_wxid})
2024-01-03 21:34:34 +08:00
2024-02-23 23:47:50 +08:00
def func_get_msgs(start, limit, wxid, msg_path, micro_path):
2024-01-04 00:53:50 +08:00
if not msg_path:
msg_path = read_session(g.sf, "msg_path")
2024-01-04 00:53:50 +08:00
if not micro_path:
micro_path = read_session(g.sf, "micro_path")
2024-02-23 23:47:50 +08:00
2024-01-04 00:53:50 +08:00
msg_list = analyzer.get_msg_list(msg_path, wxid, start_index=start, page_size=limit)
# row_data = {"MsgSvrID": MsgSvrID, "type_name": type_name, "is_sender": IsSender, "talker": talker,
# "room_name": StrTalker, "content": content, "CreateTime": CreateTime}
contact_list = analyzer.get_contact_list(micro_path)
userlist = {}
my_wxid = read_session(g.sf, "my_wxid")
2024-01-04 00:53:50 +08:00
if wxid.endswith("@chatroom"):
# 群聊
talkers = [msg["talker"] for msg in msg_list] + [wxid, my_wxid]
2024-01-04 00:53:50 +08:00
talkers = list(set(talkers))
for user in contact_list:
if user["username"] in talkers:
userlist[user["username"]] = user
else:
# 单聊
for user in contact_list:
if user["username"] == wxid or user["username"] == my_wxid:
2024-01-04 00:53:50 +08:00
userlist[user["username"]] = user
if len(userlist) == 2:
break
2024-02-23 23:47:50 +08:00
return {"msg_list": msg_list, "user_list": userlist, "my_wxid": my_wxid}
2024-01-04 00:53:50 +08:00
2024-02-23 23:47:50 +08:00
@api.route('/api/msgs', methods=["GET", 'POST'])
@error9999
def get_msgs():
msg_path = request.headers.get("msg_path")
micro_path = request.headers.get("micro_path")
if not msg_path:
msg_path = read_session(g.sf, "msg_path")
if not micro_path:
micro_path = read_session(g.sf, "micro_path")
start = request.json.get("start")
limit = request.json.get("limit")
wxid = request.json.get("wxid")
rdata = func_get_msgs(start, limit, wxid, msg_path, micro_path)
return ReJson(0, rdata)
2024-01-03 21:34:34 +08:00
2024-02-20 12:35:38 +08:00
@api.route('/api/realtimemsg', methods=["GET", "POST"])
@error9999
def get_real_time_msg():
"""
获取实时消息 使用 merge_real_time_db()函数
:return:
"""
save_msg_path = read_session(g.sf, "msg_path")
save_media_path = read_session(g.sf, "media_path")
wx_path = read_session(g.sf, "wx_path")
key = read_session(g.sf, "key")
if not save_msg_path or not save_media_path or not wx_path or not key:
return ReJson(1002, body="msg_path or media_path or wx_path or key is required")
media_paths = get_core_db(wx_path, ["MediaMSG"])
msg_paths = get_core_db(wx_path, ["MSG"])
if not media_paths[0] or not msg_paths[0]:
return ReJson(1001, body="media_paths or msg_paths is required")
media_paths = media_paths[1]
media_paths.sort()
msg_paths = msg_paths[1]
msg_paths.sort()
merge_real_time_db(key=key, db_path=media_paths[-1], merge_path=save_media_path)
merge_real_time_db(key=key, db_path=msg_paths[-1], merge_path=save_msg_path)
return ReJson(0, "success")
2024-01-04 11:28:26 +08:00
@api.route('/api/img', methods=["GET", 'POST'])
2024-02-22 18:58:45 +08:00
@error9999
2024-01-04 09:26:58 +08:00
def get_img():
"""
获取图片
:return:
"""
if request.method == "GET":
img_path = request.args.get("img_path")
elif request.method == "POST":
img_path = request.json.get("img_path")
else:
return ReJson(1003, msg="Unsupported method")
2024-01-04 09:26:58 +08:00
if not img_path:
return ReJson(1002)
wx_path = read_session(g.sf, "wx_path")
img_tmp_path = os.path.join(g.tmp_path, "img")
img_path_all = os.path.join(wx_path, img_path)
2024-01-04 09:26:58 +08:00
if os.path.exists(img_path_all):
fomt, md5, out_bytes = read_img_dat(img_path_all)
2024-02-22 18:04:34 +08:00
imgsavepath = os.path.join(img_tmp_path, img_path + "_" + ".".join([md5, fomt]))
if not os.path.exists(os.path.dirname(imgsavepath)):
os.makedirs(os.path.dirname(imgsavepath))
with open(imgsavepath, "wb") as f:
f.write(out_bytes)
return send_file(imgsavepath)
2024-01-04 09:26:58 +08:00
else:
2024-01-19 17:03:28 +08:00
return ReJson(1001, body=img_path_all)
2024-01-26 17:45:38 +08:00
@api.route('/api/video/<path:videoPath>', methods=["GET", 'POST'])
def get_video(videoPath):
wx_path = read_session(g.sf, "wx_path")
2024-01-26 17:45:38 +08:00
all_video_path = os.path.join(wx_path, videoPath)
if not os.path.exists(all_video_path):
return ReJson(5002)
return send_file(all_video_path)
2024-01-04 11:28:26 +08:00
@api.route('/api/file_info', methods=["GET", 'POST'])
def get_file_info():
file_path = request.args.get("file_path")
file_path = request.json.get("file_path", file_path)
if not file_path:
return ReJson(1002)
wx_path = read_session(g.sf, "wx_path")
all_file_path = os.path.join(wx_path, file_path)
if not os.path.exists(all_file_path):
return ReJson(5002)
file_name = os.path.basename(all_file_path)
file_size = os.path.getsize(all_file_path)
return ReJson(0, {"file_name": file_name, "file_size": str(file_size)})
@api.route('/api/file/<path:filePath>', methods=["GET", 'POST'])
def get_file(filePath):
wx_path = read_session(g.sf, "wx_path")
all_file_path = os.path.join(wx_path, filePath)
if not os.path.exists(all_file_path):
return ReJson(5002)
return send_file(all_file_path)
2024-01-26 17:45:38 +08:00
2024-01-14 18:14:28 +08:00
@api.route('/api/audio/<path:savePath>', methods=["GET", 'POST'])
def get_audio(savePath):
# savePath = request.args.get("savePath")
# savePath = request.json.get("savePath", savePath)
savePath = "audio/" + savePath # 这个是从url中获取的
MsgSvrID = savePath.split("_")[-1].replace(".wav", "")
if not savePath:
2024-01-04 09:48:11 +08:00
return ReJson(1002)
media_path = read_session(g.sf, "media_path")
wave_data = read_audio(MsgSvrID, is_wave=True, DB_PATH=media_path)
2024-01-04 09:48:11 +08:00
if not wave_data:
return ReJson(1001)
2024-01-14 18:14:28 +08:00
# 判断savePath路径的文件夹是否存在
2024-01-14 19:32:47 +08:00
savePath = os.path.join(g.tmp_path, savePath)
2024-01-14 18:14:28 +08:00
if not os.path.exists(os.path.dirname(savePath)):
os.makedirs(os.path.dirname(savePath))
with open(savePath, "wb") as f:
f.write(wave_data)
return send_file(savePath)
2024-01-04 09:48:11 +08:00
2024-01-05 16:45:58 +08:00
2024-01-14 20:21:06 +08:00
# 导出聊天记录
@api.route('/api/export', methods=["GET", 'POST'])
2024-01-22 18:59:25 +08:00
@error9999
2024-01-14 20:21:06 +08:00
def export():
"""
导出聊天记录
:return:
"""
export_type = request.json.get("export_type")
start_time = request.json.get("start_time", 0)
end_time = request.json.get("end_time", 0)
2024-01-14 20:21:06 +08:00
chat_type = request.json.get("chat_type")
username = request.json.get("username")
wx_path = request.json.get("wx_path", read_session(g.sf, "wx_path"))
key = request.json.get("key", read_session(g.sf, "key"))
2024-01-16 19:25:33 +08:00
if not export_type or not isinstance(export_type, str):
2024-01-14 20:21:06 +08:00
return ReJson(1002)
2024-01-14 20:27:50 +08:00
# 导出路径
outpath = os.path.join(g.tmp_path, "export", export_type)
2024-01-14 20:27:50 +08:00
if not os.path.exists(outpath):
os.makedirs(outpath)
if export_type == "endb": # 导出加密数据库
2024-01-20 21:00:17 +08:00
# 获取微信文件夹路径
if not wx_path:
return ReJson(1002)
if not os.path.exists(wx_path):
return ReJson(1001, body=wx_path)
# 分割wx_path的文件名和父目录
code, wxdbpaths = get_core_db(wx_path)
if not code:
return ReJson(2001, body=wxdbpaths)
2024-01-20 21:00:17 +08:00
for wxdb in wxdbpaths:
# 复制wxdb->outpath, os.path.basename(wxdb)
shutil.copy(wxdb, os.path.join(outpath, os.path.basename(wxdb)))
2024-01-20 21:00:17 +08:00
return ReJson(0, body=outpath)
2024-01-16 19:25:33 +08:00
elif export_type == "dedb":
if isinstance(start_time, int) and isinstance(end_time, int):
msg_path = read_session(g.sf, "msg_path")
micro_path = read_session(g.sf, "micro_path")
media_path = read_session(g.sf, "media_path")
dbpaths = [msg_path, msg_path, micro_path]
dbpaths = list(set(dbpaths))
mergepath = merge_db(dbpaths, os.path.join(outpath, "merge.db"), start_time, end_time)
return ReJson(0, body=mergepath)
# if msg_path == media_path and msg_path == media_path:
# shutil.copy(msg_path, os.path.join(outpath, "merge.db"))
# return ReJson(0, body=msg_path)
# else:
# dbpaths = [msg_path, msg_path, micro_path]
# dbpaths = list(set(dbpaths))
# mergepath = merge_db(dbpaths, os.path.join(outpath, "merge.db"), start_time, end_time)
# return ReJson(0, body=mergepath)
else:
return ReJson(1002, body={"start_time": start_time, "end_time": end_time})
2024-01-16 19:25:33 +08:00
elif export_type == "csv":
2024-01-20 22:13:44 +08:00
outpath = os.path.join(outpath, username)
2024-01-14 20:27:50 +08:00
if not os.path.exists(outpath):
os.makedirs(outpath)
2024-01-20 22:13:44 +08:00
code, ret = analyzer.export_csv(username, outpath, read_session(g.sf, "msg_path"))
2024-01-14 20:27:50 +08:00
if code:
return ReJson(0, ret)
else:
return ReJson(2001, body=ret)
2024-01-16 19:25:33 +08:00
elif export_type == "json":
2024-01-20 22:13:44 +08:00
outpath = os.path.join(outpath, username)
if not os.path.exists(outpath):
os.makedirs(outpath)
code, ret = analyzer.export_json(username, outpath, read_session(g.sf, "msg_path"))
if code:
return ReJson(0, ret)
else:
return ReJson(2001, body=ret)
2024-01-16 19:25:33 +08:00
elif export_type == "html":
2024-02-23 23:47:50 +08:00
outpath = os.path.join(outpath, username)
if os.path.exists(outpath):
shutil.rmtree(outpath)
if not os.path.exists(outpath):
os.makedirs(outpath)
# chat_type_tups = []
# for ct in chat_type:
# tup = analyzer.get_name_typeid(ct)
# if tup:
# chat_type_tups += tup
# if not chat_type_tups:
# return ReJson(1002)
# 复制文件 html
export_html = os.path.join(os.path.dirname(pywxdump.VERSION_LIST_PATH), "ui", "export")
2024-02-26 00:54:14 +08:00
indexhtml_path = os.path.join(export_html, "index.html")
assets_path = os.path.join(export_html, "assets")
if not os.path.exists(indexhtml_path) or not os.path.exists(assets_path):
return ReJson(1001)
js_path = ""
css_path = ""
for file in os.listdir(assets_path):
if file.endswith('.js'):
js_path = os.path.join(assets_path, file)
elif file.endswith('.css'):
css_path = os.path.join(assets_path, file)
2024-02-23 23:47:50 +08:00
else:
2024-02-26 00:54:14 +08:00
continue
# 读取html,js,css
with open(indexhtml_path, 'r', encoding='utf-8') as f:
html = f.read()
with open(js_path, 'r', encoding='utf-8') as f:
js = f.read()
with open(css_path, 'r', encoding='utf-8') as f:
css = f.read()
html = re.sub(r'<script .*?></script>', '', html) # 删除所有的script标签
html = re.sub(r'<link rel="stylesheet" .*?>', '', html) # 删除所有的link标签
html = html.replace('</head>', f'<style>{css}</style></head>')
html = html.replace('</head>', f'<script type="module" crossorigin>{js}</script></head>')
# END 生成index.html
2024-02-23 23:47:50 +08:00
rdata = func_get_msgs(0, 10000000, username, "", "")
msg_list = rdata["msg_list"]
for i in range(len(msg_list)):
if msg_list[i]["type_name"] == "语音":
savePath = msg_list[i]["content"]["src"]
MsgSvrID = savePath.split("_")[-1].replace(".wav", "")
if not savePath:
2024-02-28 18:37:04 +08:00
continue
2024-02-23 23:47:50 +08:00
media_path = read_session(g.sf, "media_path")
wave_data = read_audio(MsgSvrID, is_wave=True, DB_PATH=media_path)
if not wave_data:
2024-02-28 18:37:04 +08:00
continue
2024-02-23 23:47:50 +08:00
# 判断savePath路径的文件夹是否存在
savePath = os.path.join(outpath, savePath)
if not os.path.exists(os.path.dirname(savePath)):
os.makedirs(os.path.dirname(savePath))
with open(savePath, "wb") as f:
f.write(wave_data)
elif msg_list[i]["type_name"] == "图片":
img_path = msg_list[i]["content"]["src"]
wx_path = read_session(g.sf, "wx_path")
img_path_all = os.path.join(wx_path, img_path)
if os.path.exists(img_path_all):
fomt, md5, out_bytes = read_img_dat(img_path_all)
imgsavepath = os.path.join(outpath, "img", img_path + "_" + ".".join([md5, fomt]))
if not os.path.exists(os.path.dirname(imgsavepath)):
os.makedirs(os.path.dirname(imgsavepath))
with open(imgsavepath, "wb") as f:
f.write(out_bytes)
msg_list[i]["content"]["src"] = os.path.join("img", img_path + "_" + ".".join([md5, fomt]))
rdata["msg_list"] = msg_list
rdata["myuserdata"] = rdata["user_list"][rdata["my_wxid"]]
rdata["myuserdata"]["chat_count"] = len(rdata["msg_list"])
save_data = rdata
save_json_path = os.path.join(outpath, "data")
if not os.path.exists(save_json_path):
os.makedirs(save_json_path)
with open(os.path.join(save_json_path, "msg_user.json"), "w", encoding="utf-8") as f:
json.dump(save_data, f, ensure_ascii=False)
2024-02-28 17:58:38 +08:00
json_base64 = gen_base64(os.path.join(save_json_path, "msg_user.json"))
2024-02-28 18:37:04 +08:00
html = html.replace('"./data/msg_user.json"', f'"{json_base64}"')
2024-02-26 00:54:14 +08:00
with open(os.path.join(outpath, "index.html"), 'w', encoding='utf-8') as f:
f.write(html)
2024-02-23 23:47:50 +08:00
return ReJson(0, outpath)
2024-01-16 19:25:33 +08:00
elif export_type == "pdf":
pass
elif export_type == "docx":
pass
else:
return ReJson(1002)
2024-01-14 20:27:50 +08:00
return ReJson(9999, "")
2024-01-14 20:21:06 +08:00
# 这部分为专业工具的api
@api.route('/api/wxinfo', methods=["GET", 'POST'])
2024-01-22 18:59:25 +08:00
@error9999
def get_wxinfo():
"""
获取微信信息
:return:
"""
import pythoncom
pythoncom.CoInitialize()
wxinfos = read_info(VERSION_LIST)
pythoncom.CoUninitialize()
return ReJson(0, wxinfos)
2024-01-11 11:39:17 +08:00
@api.route('/api/decrypt', methods=["GET", 'POST'])
2024-01-22 18:59:25 +08:00
@error9999
2024-01-11 11:39:17 +08:00
def decrypt():
"""
解密
:return:
"""
key = request.json.get("key")
if not key:
return ReJson(1002)
wxdb_path = request.json.get("wxdbPath")
if not wxdb_path:
return ReJson(1002)
out_path = request.json.get("outPath")
if not out_path:
out_path = g.tmp_path
wxinfos = batch_decrypt(key, wxdb_path, out_path=out_path)
return ReJson(0, str(wxinfos))
2024-01-12 12:05:47 +08:00
@api.route('/api/biasaddr', methods=["GET", 'POST'])
2024-01-22 18:59:25 +08:00
@error9999
2024-01-12 12:05:47 +08:00
def biasaddr():
"""
BiasAddr
:return:
"""
mobile = request.json.get("mobile")
name = request.json.get("name")
account = request.json.get("account")
key = request.json.get("key", "")
wxdbPath = request.json.get("wxdbPath", "")
if not mobile or not name or not account:
return ReJson(1002)
rdata = BiasAddr(account, mobile, name, key, wxdbPath).run()
2024-01-12 12:05:47 +08:00
return ReJson(0, str(rdata))
2024-01-11 11:39:17 +08:00
@api.route('/api/merge', methods=["GET", 'POST'])
2024-01-22 18:59:25 +08:00
@error9999
def merge():
"""
合并
:return:
"""
wxdb_path = request.json.get("dbPath")
if not wxdb_path:
return ReJson(1002)
out_path = request.json.get("outPath")
if not out_path:
return ReJson(1002)
rdata = merge_db(wxdb_path, out_path)
return ReJson(0, str(rdata))
2024-01-11 11:39:17 +08:00
# END 这部分为专业工具的api
2024-02-22 17:36:49 +08:00
# 关于、帮助、设置
2024-02-22 17:19:18 +08:00
@api.route('/api/check_update', methods=["GET", 'POST'])
@error9999
def check_update():
"""
检查更新
:return:
"""
url = "https://api.github.com/repos/xaoyaoo/PyWxDump/tags"
try:
import requests
res = requests.get(url)
if res.status_code == 200:
data = res.json()
NEW_VERSION = data[0].get("name")
if NEW_VERSION[1:] != pywxdump.__version__:
2024-02-22 18:04:34 +08:00
msg = "有新版本"
2024-02-22 17:19:18 +08:00
else:
2024-02-22 18:04:34 +08:00
msg = "已经是最新版本"
return ReJson(0, body={"msg": msg, "latest_version": NEW_VERSION,
"latest_url": "https://github.com/xaoyaoo/PyWxDump/releases/tag/" + NEW_VERSION})
2024-02-22 17:19:18 +08:00
else:
return ReJson(2001, body="status_code is not 200")
except Exception as e:
return ReJson(9999, msg=str(e))
2024-02-22 17:36:49 +08:00
# END 关于、帮助、设置
2024-02-22 17:19:18 +08:00
2024-01-04 11:28:26 +08:00
@api.route('/')
2024-01-22 18:59:25 +08:00
@error9999
2024-01-04 11:28:26 +08:00
def index():
return render_template('index.html')