mirror of
https://github.com/LC044/WeChatMsg
synced 2025-02-21 01:52:35 +08:00
解决多次解密导致的消息重复的问题
This commit is contained in:
parent
360419ead9
commit
40c57c5891
@ -15,9 +15,20 @@ from .media_msg import MediaMsg
|
||||
from .misc import Misc
|
||||
from .msg import Msg
|
||||
from .msg import MsgType
|
||||
|
||||
misc_db = Misc()
|
||||
msg_db = Msg()
|
||||
micro_msg_db = MicroMsg()
|
||||
hard_link_db = HardLink()
|
||||
media_msg_db = MediaMsg()
|
||||
__all__ = ["data", 'output', 'misc_db', 'micro_msg_db', 'msg_db', 'hard_link_db','MsgType', "media_msg_db"]
|
||||
|
||||
|
||||
def close_db():
|
||||
misc_db.close()
|
||||
msg_db.close()
|
||||
micro_msg_db.close()
|
||||
hard_link_db.close()
|
||||
media_msg_db.close()
|
||||
|
||||
|
||||
__all__ = ['output', 'misc_db', 'micro_msg_db', 'msg_db', 'hard_link_db', 'MsgType', "media_msg_db"]
|
||||
|
@ -100,7 +100,17 @@ class MediaMsg:
|
||||
return transtext
|
||||
except:
|
||||
return ""
|
||||
def close(self):
|
||||
if self.open_flag:
|
||||
try:
|
||||
lock.acquire(True)
|
||||
self.open_flag = False
|
||||
self.DB.close()
|
||||
finally:
|
||||
lock.release()
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
db_path = './Msg/MediaMSG.db'
|
||||
|
@ -3,8 +3,6 @@ import sqlite3
|
||||
import threading
|
||||
|
||||
lock = threading.Lock()
|
||||
DB = None
|
||||
cursor = None
|
||||
db_path = "./app/Database/Msg/MicroMsg.db"
|
||||
|
||||
|
||||
@ -22,61 +20,6 @@ def singleton(cls):
|
||||
def is_database_exist():
|
||||
return os.path.exists(db_path)
|
||||
|
||||
lockMSG = threading.Lock()
|
||||
DBMSG = None
|
||||
cursorMSG = None
|
||||
db_msg_path = "./app/Database/Msg/MSG.db"
|
||||
|
||||
@singleton
|
||||
class MicroMSGMsg:
|
||||
def __init__(self):
|
||||
self.DBMSG = None
|
||||
self.cursorMSG = None
|
||||
self.open_flag = False
|
||||
self.init_database()
|
||||
|
||||
def init_database(self):
|
||||
if not self.open_flag:
|
||||
if os.path.exists(db_msg_path):
|
||||
self.DBMSG = sqlite3.connect(db_msg_path, check_same_thread=False)
|
||||
# '''创建游标'''
|
||||
self.cursorMSG = self.DBMSG.cursor()
|
||||
self.open_flag = True
|
||||
if lockMSG.locked():
|
||||
lockMSG.release()
|
||||
|
||||
def get_contact(self, contacts):
|
||||
if not self.open_flag:
|
||||
return None
|
||||
try:
|
||||
lockMSG.acquire(True)
|
||||
sql = '''select StrTalker, MAX(CreateTime) from MSG group by StrTalker'''
|
||||
self.cursorMSG.execute(sql)
|
||||
res = self.cursorMSG.fetchall()
|
||||
res = {StrTalker: CreateTime for StrTalker, CreateTime in res}
|
||||
contacts = [list(cur_contact) for cur_contact in contacts]
|
||||
for i, cur_contact in enumerate(contacts):
|
||||
if cur_contact[0] in res:
|
||||
contacts[i].append(res[cur_contact[0]])
|
||||
else:
|
||||
contacts[i].append(0)
|
||||
contacts.sort(key=lambda cur_contact: cur_contact[-1], reverse=True)
|
||||
finally:
|
||||
lockMSG.release()
|
||||
return contacts
|
||||
|
||||
def close(self):
|
||||
if self.open_flag:
|
||||
try:
|
||||
lockMSG.acquire(True)
|
||||
self.open_flag = False
|
||||
self.DBMSG.close()
|
||||
finally:
|
||||
lockMSG.release()
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
|
||||
@singleton
|
||||
class MicroMsg:
|
||||
@ -116,7 +59,8 @@ class MicroMsg:
|
||||
result = self.cursor.fetchall()
|
||||
finally:
|
||||
lock.release()
|
||||
return MicroMSGMsg().get_contact(result)
|
||||
from app.DataBase import msg_db
|
||||
return msg_db.get_contact(result)
|
||||
|
||||
def get_contact_by_username(self, username):
|
||||
if not self.open_flag:
|
||||
|
@ -208,7 +208,25 @@ class Msg:
|
||||
))
|
||||
print(keyword,res)
|
||||
return res
|
||||
|
||||
def get_contact(self, contacts):
|
||||
if not self.open_flag:
|
||||
return None
|
||||
try:
|
||||
lock.acquire(True)
|
||||
sql = '''select StrTalker, MAX(CreateTime) from MSG group by StrTalker'''
|
||||
self.cursor.execute(sql)
|
||||
res = self.cursor.fetchall()
|
||||
finally:
|
||||
lock.release()
|
||||
res = {StrTalker: CreateTime for StrTalker, CreateTime in res}
|
||||
contacts = [list(cur_contact) for cur_contact in contacts]
|
||||
for i, cur_contact in enumerate(contacts):
|
||||
if cur_contact[0] in res:
|
||||
contacts[i].append(res[cur_contact[0]])
|
||||
else:
|
||||
contacts[i].append(0)
|
||||
contacts.sort(key=lambda cur_contact: cur_contact[-1], reverse=True)
|
||||
return contacts
|
||||
def get_messages_by_days(self, username_, is_Annual_report_=False, year_='2023'):
|
||||
if is_Annual_report_:
|
||||
sql = '''
|
||||
|
@ -365,6 +365,7 @@ class ChildThread(QThread):
|
||||
image_path = path.get_relative_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
|
||||
image_path = image_path
|
||||
try:
|
||||
# todo 网络图片问题
|
||||
print(origin_docx_path + image_path[1:])
|
||||
os.utime(origin_docx_path + image_path[1:], (timestamp, timestamp))
|
||||
image_path = image_path.replace('\\', '/')
|
||||
|
@ -168,7 +168,7 @@ def get_key(db_path, addr_len):
|
||||
return key_bytes
|
||||
|
||||
def verify_key(key, wx_db_path):
|
||||
if not wx_db_path:
|
||||
if wx_db_path == "None":
|
||||
return True
|
||||
KEY_SIZE = 32
|
||||
DEFAULT_PAGESIZE = 4096
|
||||
@ -287,6 +287,8 @@ def read_info(version_list, is_logging=False):
|
||||
print("=" * 32)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
@ -297,7 +299,6 @@ def resource_path(relative_path):
|
||||
return os.path.join(base_path, relative_path)
|
||||
|
||||
|
||||
|
||||
def get_info(VERSION_LIST):
|
||||
result = read_info(VERSION_LIST, True) # 读取微信信息
|
||||
return result
|
||||
|
@ -15,7 +15,7 @@ from PyQt5.QtGui import QPixmap, QFont, QDesktopServices, QIcon
|
||||
from PyQt5.QtWidgets import QMainWindow, QLabel, QListWidgetItem, QMessageBox
|
||||
|
||||
from app import config
|
||||
from app.DataBase import msg_db, misc_db, micro_msg_db, hard_link_db
|
||||
from app.DataBase import msg_db, misc_db, micro_msg_db, hard_link_db, close_db
|
||||
from app.ui.Icon import Icon
|
||||
from . import mainwindow
|
||||
from .chat import ChatWindow
|
||||
@ -234,12 +234,19 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
QMessageBox.about(self, "解密成功", "请重新启动")
|
||||
self.close()
|
||||
|
||||
def closeEvent(self, event):
|
||||
reply = QMessageBox.question(self, '确认退出', '确定要退出吗?',
|
||||
QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.No)
|
||||
|
||||
if reply == QMessageBox.Yes:
|
||||
close_db()
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
def close(self) -> bool:
|
||||
close_db()
|
||||
super().close()
|
||||
misc_db.close()
|
||||
msg_db.close()
|
||||
micro_msg_db.close()
|
||||
hard_link_db.close()
|
||||
self.contact_window.close()
|
||||
self.exitSignal.emit(True)
|
||||
|
||||
|
@ -7,7 +7,7 @@ from PyQt5.QtCore import pyqtSignal, QThread, QUrl, QFile, QIODevice, QTextStrea
|
||||
from PyQt5.QtGui import QDesktopServices
|
||||
from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog
|
||||
|
||||
from app.DataBase import msg_db, misc_db
|
||||
from app.DataBase import msg_db, misc_db, media_msg_db, close_db
|
||||
from app.DataBase.merge import merge_databases, merge_MediaMSG_databases
|
||||
from app.decrypt import get_wx_info, decrypt
|
||||
from app.log import logger
|
||||
@ -131,6 +131,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
|
||||
return
|
||||
if self.info.get('key') == 'none':
|
||||
QMessageBox.critical(self, "错误", "密钥错误\n请检查微信版本是否为最新和微信路径是否正确")
|
||||
close_db()
|
||||
self.label_tip.setVisible(True)
|
||||
self.label_tip.setText('点我之后没有反应那就多等儿吧,不要再点了')
|
||||
self.thread2 = DecryptThread(db_dir, self.info['key'])
|
||||
@ -171,6 +172,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
|
||||
'name': self.info['name'],
|
||||
'mobile': self.info['mobile']
|
||||
}
|
||||
|
||||
try:
|
||||
os.makedirs('./app/data', exist_ok=True)
|
||||
with open('./app/data/info.json', 'w', encoding='utf-8') as f:
|
||||
@ -183,6 +185,8 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
|
||||
# 源数据库文件列表
|
||||
source_databases = [f"app/DataBase/Msg/MSG{i}.db" for i in range(1, 200)]
|
||||
import shutil
|
||||
if os.path.exists(target_database):
|
||||
os.remove(target_database)
|
||||
shutil.copy2("app/DataBase/Msg/MSG0.db", target_database) # 使用一个数据库文件作为模板
|
||||
# 合并数据库
|
||||
try:
|
||||
@ -193,6 +197,8 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
|
||||
# 音频数据库文件
|
||||
target_database = "app/DataBase/Msg/MediaMSG.db"
|
||||
# 源数据库文件列表
|
||||
if os.path.exists(target_database):
|
||||
os.remove(target_database)
|
||||
source_databases = [f"app/DataBase/Msg/MediaMSG{i}.db" for i in range(1, 200)]
|
||||
shutil.copy2("app/DataBase/Msg/MediaMSG0.db", target_database) # 使用一个数据库文件作为模板
|
||||
# 合并数据库
|
||||
|
@ -35,23 +35,47 @@ def mkdir(path):
|
||||
|
||||
def wx_path():
|
||||
try:
|
||||
## 获取当前用户名
|
||||
user_home = os.environ.get("USERPROFILE")
|
||||
## 找到3ebffe94.ini配置文件
|
||||
f = open(user_home + '\\AppData\\Roaming\\Tencent\\WeChat\\All Users\\config\\3ebffe94.ini', encoding='utf-8')
|
||||
txt = f.read()
|
||||
f.close()
|
||||
# 打开Windows注册表
|
||||
reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
|
||||
"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
|
||||
# 获取“我的文档”路径的注册表键值
|
||||
documents_path_value = winreg.QueryValueEx(reg_key, "Personal")
|
||||
# 输出路径
|
||||
##读取文件将路径放到wx_location变量里
|
||||
if txt == 'MyDocument:':
|
||||
wx_location = documents_path_value[0] + '\WeChat Files'
|
||||
else:
|
||||
wx_location = txt + "\WeChat Files"
|
||||
return wx_location
|
||||
is_w_dir = False
|
||||
|
||||
try:
|
||||
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Tencent\WeChat", 0, winreg.KEY_READ)
|
||||
value, _ = winreg.QueryValueEx(key, "FileSavePath")
|
||||
winreg.CloseKey(key)
|
||||
w_dir = value
|
||||
is_w_dir = True
|
||||
except Exception as e:
|
||||
w_dir = "MyDocument:"
|
||||
|
||||
if not is_w_dir:
|
||||
try:
|
||||
user_profile = os.environ.get("USERPROFILE")
|
||||
path_3ebffe94 = os.path.join(user_profile, "AppData", "Roaming", "Tencent", "WeChat", "All Users",
|
||||
"config",
|
||||
"3ebffe94.ini")
|
||||
with open(path_3ebffe94, "r", encoding="utf-8") as f:
|
||||
w_dir = f.read()
|
||||
is_w_dir = True
|
||||
except Exception as e:
|
||||
w_dir = "MyDocument:"
|
||||
|
||||
if w_dir == "MyDocument:":
|
||||
try:
|
||||
# 打开注册表路径
|
||||
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER,
|
||||
r"Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders")
|
||||
documents_path = winreg.QueryValueEx(key, "Personal")[0] # 读取文档实际目录路径
|
||||
winreg.CloseKey(key) # 关闭注册表
|
||||
documents_paths = os.path.split(documents_path)
|
||||
if "%" in documents_paths[0]:
|
||||
w_dir = os.environ.get(documents_paths[0].replace("%", ""))
|
||||
w_dir = os.path.join(w_dir, os.path.join(*documents_paths[1:]))
|
||||
# print(1, w_dir)
|
||||
else:
|
||||
w_dir = documents_path
|
||||
except Exception as e:
|
||||
profile = os.environ.get("USERPROFILE")
|
||||
w_dir = os.path.join(profile, "Documents")
|
||||
msg_dir = os.path.join(w_dir, "WeChat Files")
|
||||
return msg_dir
|
||||
except FileNotFoundError:
|
||||
return '.'
|
||||
|
5
main.py
5
main.py
@ -6,6 +6,7 @@ import traceback
|
||||
from PyQt5.QtGui import QFont
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
from app.DataBase import close_db
|
||||
from app.log import logger
|
||||
from app.ui import mainview
|
||||
from app.ui.tool.pc_decrypt import pc_decrypt
|
||||
@ -51,7 +52,9 @@ class ViewController(QWidget):
|
||||
def show_success(self):
|
||||
QMessageBox.about(self, "解密成功", "数据库文件存储在\napp/DataBase/Msg\n文件夹下")
|
||||
|
||||
|
||||
def close(self) -> bool:
|
||||
close_db()
|
||||
super().close()
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
font = QFont('微软雅黑', 12) # 使用 Times New Roman 字体,字体大小为 14
|
||||
|
Loading…
Reference in New Issue
Block a user