diff --git a/.gitignore b/.gitignore index 5379ef4..424d9f6 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ app/DataBase/Msg/* *.db *.pyc *.log +*.spec test* \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 2da2981..2cbcd56 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,12 +4,19 @@ @@ -115,15 +123,15 @@ - @@ -684,7 +691,8 @@ - diff --git a/app/config.py b/app/config.py index 0ac877c..893f17d 100644 --- a/app/config.py +++ b/app/config.py @@ -3,6 +3,6 @@ contact = '474379264' description = [ '1. 支持获取个人信息\n', '2. 支持显示聊天界面\n', - '3. 支持导出scv格式的聊天记录\n', + '3. 支持导出聊天记录\n * csv\n * html\n', '4. 查找联系人\n', ] diff --git a/app/decrypt/get_wx_info.py b/app/decrypt/get_wx_info.py index 52f844f..296c1ee 100644 --- a/app/decrypt/get_wx_info.py +++ b/app/decrypt/get_wx_info.py @@ -123,13 +123,25 @@ def read_info(version_list, is_logging=False): return result +import os +import sys + + +def resource_path(relative_path): + """ Get absolute path to resource, works for dev and for PyInstaller """ + base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__))) + return os.path.join(base_path, relative_path) + + @log def get_info(): VERSION_LIST_PATH = "app/decrypt/version_list.json" - - with open(VERSION_LIST_PATH, "r", encoding="utf-8") as f: - VERSION_LIST = json.load(f) - + try: + with open(VERSION_LIST_PATH, "r", encoding="utf-8") as f: + VERSION_LIST = json.load(f) + except: + with open(resource_path(VERSION_LIST_PATH), "r", encoding="utf-8") as f: + VERSION_LIST = json.load(f) result = read_info(VERSION_LIST, True) # 读取微信信息 return result diff --git a/app/log/logger.py b/app/log/logger.py index 08512ed..36b8e85 100644 --- a/app/log/logger.py +++ b/app/log/logger.py @@ -5,19 +5,21 @@ import traceback from functools import wraps filename = time.strftime("%Y-%m-%d", time.localtime(time.time())) -if not os.path.exists('./app/log/logs'): - os.mkdir('./app/log/logs') logger = logging.getLogger('test') logger.setLevel(level=logging.DEBUG) formatter = logging.Formatter('%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') -file_handler = logging.FileHandler(f'./app/log/logs/{filename}-log.log') +try: + if not os.path.exists('./app/log/logs'): + os.mkdir('./app/log/logs') + file_handler = logging.FileHandler(f'./app/log/logs/{filename}-log.log') +except: + file_handler = logging.FileHandler(f'{filename}-log.log') + file_handler.setLevel(level=logging.INFO) file_handler.setFormatter(formatter) - stream_handler = logging.StreamHandler() stream_handler.setLevel(logging.DEBUG) stream_handler.setFormatter(formatter) - logger.addHandler(file_handler) logger.addHandler(stream_handler) diff --git a/app/ui_pc/__init__.py b/app/ui_pc/__init__.py index 5cbf985..e69de29 100644 --- a/app/ui_pc/__init__.py +++ b/app/ui_pc/__init__.py @@ -1,3 +0,0 @@ -from . import mainview - -__all__ = ['mainview'] diff --git a/app/ui_pc/mainview.py b/app/ui_pc/mainview.py index 7db9025..f6a1ee1 100644 --- a/app/ui_pc/mainview.py +++ b/app/ui_pc/mainview.py @@ -9,10 +9,9 @@ """ import json import os.path -from random import randint from PyQt5.QtCore import * -from PyQt5.QtGui import QPixmap +from PyQt5.QtGui import QPixmap, QFont from PyQt5.QtWidgets import * from app import config @@ -21,7 +20,7 @@ from app.Ui.Icon import Icon from . import mainwindow from .chat import ChatWindow from .contact import ContactWindow -from .tool import ToolWindow +from .tool.tool_window import ToolWindow from ..person import MePC # 美化样式表 @@ -78,6 +77,7 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): self.load_data() self.load_num = 0 self.label = QLabel(self) + self.label.setGeometry((self.width() - 300) // 2, (self.height() - 100) // 2, 300, 100) self.label.setPixmap(QPixmap('./app/data/icons/loading.svg')) @@ -120,19 +120,13 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): self.stackedWidget.addWidget(self.chat_window) self.contact_window = ContactWindow() self.stackedWidget.addWidget(self.contact_window) - label = QLabel('我是页面') + label = QLabel('该功能暂不支持哦') + label.setFont(QFont("微软雅黑", 50)) label.setAlignment(Qt.AlignCenter) - # 设置label的背景颜色(这里随机) - # 这里加了一个margin边距(方便区分QStackedWidget和QLabel的颜色) - label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % ( - randint(0, 255), randint(0, 255), randint(0, 255))) self.stackedWidget.addWidget(label) tool_window.load_finish_signal.connect(self.loading) self.contact_window.load_finish_signal.connect(self.loading) self.chat_window.load_finish_signal.connect(self.loading) - # self.load_thread = LoadWindowThread() - # self.load_thread.okSignal.connect(self.load_window) - # self.load_thread.start() def setCurrentIndex(self, row): self.stackedWidget.setCurrentIndex(row) diff --git a/app/ui_pc/tool/__init__.py b/app/ui_pc/tool/__init__.py index 8fe2f8e..8b13789 100644 --- a/app/ui_pc/tool/__init__.py +++ b/app/ui_pc/tool/__init__.py @@ -1,3 +1 @@ -from .tool_window import ToolWindow -__all__ = ['ToolWindow'] diff --git a/app/ui_pc/tool/pc_decrypt/decryptUi.py b/app/ui_pc/tool/pc_decrypt/decryptUi.py index d4b0b8d..18ba2e7 100644 --- a/app/ui_pc/tool/pc_decrypt/decryptUi.py +++ b/app/ui_pc/tool/pc_decrypt/decryptUi.py @@ -1,4 +1,9 @@ # -*- coding: utf-8 -*- +from PyQt5.QtCore import Qt, QSize, QCoreApplication, QMetaObject +from PyQt5.QtGui import QFont +from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy, QLabel, QGridLayout, QPushButton, \ + QCheckBox, QLineEdit, QProgressBar + # Form implementation generated from reading ui file 'decryptUi.ui' # @@ -8,49 +13,46 @@ # run again. Do not edit this file unless you know what you are doing. -from PyQt5 import QtCore, QtGui, QtWidgets - - class Ui_Dialog(object): def setupUi(self, Dialog): Dialog.setObjectName("Dialog") Dialog.resize(611, 519) - font = QtGui.QFont() + font = QFont() font.setFamily("微软雅黑") Dialog.setFont(font) - Dialog.setLayoutDirection(QtCore.Qt.LeftToRight) - self.horizontalLayout_4 = QtWidgets.QHBoxLayout(Dialog) + Dialog.setLayoutDirection(Qt.LeftToRight) + self.horizontalLayout_4 = QHBoxLayout(Dialog) self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.verticalLayout_2 = QtWidgets.QVBoxLayout() + self.verticalLayout_2 = QVBoxLayout() self.verticalLayout_2.setObjectName("verticalLayout_2") - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_2.addItem(spacerItem) - self.horizontalLayout_3 = QtWidgets.QHBoxLayout() + self.horizontalLayout_3 = QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") - spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem1) - self.verticalLayout = QtWidgets.QVBoxLayout() + self.verticalLayout = QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") - self.label_3 = QtWidgets.QLabel(Dialog) - font = QtGui.QFont() + self.label_3 = QLabel(Dialog) + font = QFont() font.setFamily("一纸情书") font.setPointSize(20) self.label_3.setFont(font) - self.label_3.setAlignment(QtCore.Qt.AlignCenter) + self.label_3.setAlignment(Qt.AlignCenter) self.label_3.setObjectName("label_3") self.verticalLayout.addWidget(self.label_3) - self.gridLayout_2 = QtWidgets.QGridLayout() + self.gridLayout_2 = QGridLayout() self.gridLayout_2.setObjectName("gridLayout_2") - self.gridLayout = QtWidgets.QGridLayout() + self.gridLayout = QGridLayout() self.gridLayout.setObjectName("gridLayout") - self.label_phone = QtWidgets.QLabel(Dialog) + self.label_phone = QLabel(Dialog) self.label_phone.setText("") self.label_phone.setObjectName("label_phone") self.gridLayout.addWidget(self.label_phone, 2, 1, 1, 1) - self.label_7 = QtWidgets.QLabel(Dialog) + self.label_7 = QLabel(Dialog) self.label_7.setObjectName("label_7") self.gridLayout.addWidget(self.label_7, 1, 0, 1, 1) - self.lineEdit = QtWidgets.QLineEdit(Dialog) + self.lineEdit = QLineEdit(Dialog) self.lineEdit.setStyleSheet("background:transparent;\n" "\n" " border-radius:5px;\n" @@ -65,43 +67,43 @@ class Ui_Dialog(object): self.lineEdit.setFrame(False) self.lineEdit.setObjectName("lineEdit") self.gridLayout.addWidget(self.lineEdit, 4, 1, 1, 1) - self.label_5 = QtWidgets.QLabel(Dialog) + self.label_5 = QLabel(Dialog) self.label_5.setObjectName("label_5") self.gridLayout.addWidget(self.label_5, 3, 0, 1, 1) - self.label_6 = QtWidgets.QLabel(Dialog) + self.label_6 = QLabel(Dialog) self.label_6.setObjectName("label_6") self.gridLayout.addWidget(self.label_6, 5, 0, 1, 1) - self.label_key = QtWidgets.QLabel(Dialog) - self.label_key.setMaximumSize(QtCore.QSize(400, 16777215)) + self.label_key = QLabel(Dialog) + self.label_key.setMaximumSize(QSize(400, 16777215)) self.label_key.setText("") self.label_key.setObjectName("label_key") self.gridLayout.addWidget(self.label_key, 5, 1, 1, 1) - self.label = QtWidgets.QLabel(Dialog) + self.label = QLabel(Dialog) self.label.setObjectName("label") self.gridLayout.addWidget(self.label, 0, 0, 1, 1) - self.label_2 = QtWidgets.QLabel(Dialog) + self.label_2 = QLabel(Dialog) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1) - self.label_pid = QtWidgets.QLabel(Dialog) + self.label_pid = QLabel(Dialog) self.label_pid.setText("") self.label_pid.setObjectName("label_pid") self.gridLayout.addWidget(self.label_pid, 0, 1, 1, 1) - self.label_name = QtWidgets.QLabel(Dialog) + self.label_name = QLabel(Dialog) self.label_name.setText("") self.label_name.setObjectName("label_name") self.gridLayout.addWidget(self.label_name, 3, 1, 1, 1) - self.label_4 = QtWidgets.QLabel(Dialog) + self.label_4 = QLabel(Dialog) self.label_4.setObjectName("label_4") self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1) - self.label_version = QtWidgets.QLabel(Dialog) + self.label_version = QLabel(Dialog) self.label_version.setText("") self.label_version.setObjectName("label_version") self.gridLayout.addWidget(self.label_version, 1, 1, 1, 1) - self.label_8 = QtWidgets.QLabel(Dialog) + self.label_8 = QLabel(Dialog) self.label_8.setObjectName("label_8") self.gridLayout.addWidget(self.label_8, 6, 0, 1, 1) - self.label_db_dir = QtWidgets.QLabel(Dialog) - self.label_db_dir.setMaximumSize(QtCore.QSize(400, 300)) + self.label_db_dir = QLabel(Dialog) + self.label_db_dir.setMaximumSize(QSize(400, 300)) self.label_db_dir.setText("") self.label_db_dir.setObjectName("label_db_dir") self.gridLayout.addWidget(self.label_db_dir, 6, 1, 1, 1) @@ -109,58 +111,58 @@ class Ui_Dialog(object): self.gridLayout.setColumnStretch(0, 1) self.gridLayout.setColumnStretch(1, 10) self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 2, 1) - self.btn_getinfo = QtWidgets.QPushButton(Dialog) - self.btn_getinfo.setMinimumSize(QtCore.QSize(0, 60)) + self.btn_getinfo = QPushButton(Dialog) + self.btn_getinfo.setMinimumSize(QSize(0, 60)) self.btn_getinfo.setObjectName("btn_getinfo") self.gridLayout_2.addWidget(self.btn_getinfo, 0, 1, 1, 1) - self.checkBox = QtWidgets.QCheckBox(Dialog) + self.checkBox = QCheckBox(Dialog) self.checkBox.setText("") self.checkBox.setObjectName("checkBox") self.gridLayout_2.addWidget(self.checkBox, 0, 2, 1, 1) - self.btn_db_dir = QtWidgets.QPushButton(Dialog) - self.btn_db_dir.setMinimumSize(QtCore.QSize(0, 60)) + self.btn_db_dir = QPushButton(Dialog) + self.btn_db_dir.setMinimumSize(QSize(0, 60)) self.btn_db_dir.setObjectName("btn_db_dir") self.gridLayout_2.addWidget(self.btn_db_dir, 1, 1, 1, 1) - self.checkBox_2 = QtWidgets.QCheckBox(Dialog) + self.checkBox_2 = QCheckBox(Dialog) self.checkBox_2.setText("") self.checkBox_2.setObjectName("checkBox_2") self.gridLayout_2.addWidget(self.checkBox_2, 1, 2, 1, 1) self.verticalLayout.addLayout(self.gridLayout_2) - self.horizontalLayout_2 = QtWidgets.QHBoxLayout() + self.horizontalLayout_2 = QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") - spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + spacerItem2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem2) - self.pushButton_3 = QtWidgets.QPushButton(Dialog) - self.pushButton_3.setMinimumSize(QtCore.QSize(0, 60)) - self.pushButton_3.setMaximumSize(QtCore.QSize(100, 16777215)) + self.pushButton_3 = QPushButton(Dialog) + self.pushButton_3.setMinimumSize(QSize(0, 60)) + self.pushButton_3.setMaximumSize(QSize(100, 16777215)) self.pushButton_3.setObjectName("pushButton_3") self.horizontalLayout_2.addWidget(self.pushButton_3) - spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + spacerItem3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_2.addItem(spacerItem3) self.verticalLayout.addLayout(self.horizontalLayout_2) - self.horizontalLayout = QtWidgets.QHBoxLayout() + self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") - self.label_ready = QtWidgets.QLabel(Dialog) + self.label_ready = QLabel(Dialog) self.label_ready.setObjectName("label_ready") self.horizontalLayout.addWidget(self.label_ready) - self.progressBar = QtWidgets.QProgressBar(Dialog) + self.progressBar = QProgressBar(Dialog) self.progressBar.setProperty("value", 50) self.progressBar.setObjectName("progressBar") self.horizontalLayout.addWidget(self.progressBar) self.verticalLayout.addLayout(self.horizontalLayout) self.horizontalLayout_3.addLayout(self.verticalLayout) - spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + spacerItem4 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout_3.addItem(spacerItem4) self.verticalLayout_2.addLayout(self.horizontalLayout_3) - spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) + spacerItem5 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_2.addItem(spacerItem5) self.horizontalLayout_4.addLayout(self.verticalLayout_2) self.retranslateUi(Dialog) - QtCore.QMetaObject.connectSlotsByName(Dialog) + QMetaObject.connectSlotsByName(Dialog) def retranslateUi(self, Dialog): - _translate = QtCore.QCoreApplication.translate + _translate = QCoreApplication.translate Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.label_3.setText(_translate("Dialog", "解密数据库")) self.label_7.setText(_translate("Dialog", "版本")) diff --git a/app/ui_pc/tool/pc_decrypt/pc_decrypt.py b/app/ui_pc/tool/pc_decrypt/pc_decrypt.py index 1af9bd0..08f8384 100644 --- a/app/ui_pc/tool/pc_decrypt/pc_decrypt.py +++ b/app/ui_pc/tool/pc_decrypt/pc_decrypt.py @@ -3,10 +3,9 @@ import os.path import time import traceback -from PyQt5 import QtWidgets -from PyQt5.QtCore import * -from PyQt5.QtGui import * -from PyQt5.QtWidgets import * +from PyQt5.QtCore import pyqtSignal, QThread +from PyQt5.QtGui import QIcon +from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog from app.decrypt import get_wx_info, decrypt from app.log import logger @@ -21,7 +20,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog): super(DecryptControl, self).__init__(parent) self.setupUi(self) self.setWindowTitle('解密') - self.setWindowIcon(QIcon('./app/data/icons/logo.svg')) + self.setWindowIcon(QIcon(':/icons/logo.svg')) self.pushButton_3.clicked.connect(self.decrypt) self.btn_getinfo.clicked.connect(self.get_info) self.btn_db_dir.clicked.connect(self.select_db_dir) @@ -71,7 +70,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog): QMessageBox.information(self, "ok", f"wxid修改成功{self.info['wxid']}") def select_db_dir(self): - directory = QtWidgets.QFileDialog.getExistingDirectory( + directory = QFileDialog.getExistingDirectory( self, "选取微信安装目录——能看到Msg文件夹", "C:/") # 起始路径 db_dir = os.path.join(directory, 'Msg') @@ -136,8 +135,12 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog): 'name': self.info['name'], 'mobile': self.info['mobile'] } - with open('./app/data/info.json', 'w', encoding='utf-8') as f: - f.write(json.dumps(dic)) + try: + with open('./app/data/info.json', 'w', encoding='utf-8') as f: + f.write(json.dumps(dic)) + except: + with open('./info.json', 'w', encoding='utf-8') as f: + f.write(json.dumps(dic)) self.DecryptSignal.emit('ok') self.close() @@ -159,8 +162,13 @@ class DecryptThread(QThread): def run(self): # data.decrypt(self.db_path, self.key) output_dir = 'app/DataBase/Msg' - if not os.path.exists(output_dir): - os.mkdir(output_dir) + try: + if not os.path.exists(output_dir): + os.mkdir(output_dir) + except: + os.mkdir('app') + os.mkdir('app/DataBase') + os.mkdir('app/DataBase/Msg') tasks = [] if os.path.exists(self.db_path): for root, dirs, files in os.walk(self.db_path): diff --git a/decrypt_window.py b/decrypt_window.py index 4151aa7..f267d74 100644 --- a/decrypt_window.py +++ b/decrypt_window.py @@ -1,8 +1,7 @@ import ctypes import sys -from PyQt5.QtGui import QIcon -from PyQt5.QtWidgets import * +from PyQt5.QtWidgets import QApplication, QMessageBox, QWidget from app.ui_pc.tool.pc_decrypt import pc_decrypt @@ -12,8 +11,7 @@ ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("WeChatReport") class ViewController(QWidget): def __init__(self): super().__init__() - self.setWindowTitle('解密') - self.setWindowIcon(QIcon('./app/data/icons/logo.svg')) + self.viewMainWIn = None self.viewDecrypt = None diff --git a/requirements_decrypt.txt b/requirements_decrypt.txt new file mode 100644 index 0000000..35358e7 --- /dev/null +++ b/requirements_decrypt.txt @@ -0,0 +1,9 @@ +PyQt5 +psutil +pycryptodomex +pywin32 +pymem +silk-python +pyaudio +fuzzywuzzy +python-Levenshtein \ No newline at end of file