解决多次解密导致的消息重复的问题

This commit is contained in:
shuaikangzhou 2023-12-16 20:06:43 +08:00
parent 360419ead9
commit 40c57c5891
10 changed files with 112 additions and 87 deletions

View File

@ -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"]

View File

@ -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'

View File

@ -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:

View File

@ -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 = '''

View File

@ -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('\\', '/')

View File

@ -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

View File

@ -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)

View File

@ -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) # 使用一个数据库文件作为模板
# 合并数据库

View File

@ -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 '.'

View File

@ -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