WeChatMsg/app/ui/mainview.py

654 lines
26 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""
@File : mainview.py
@Author : Shuaikang Zhou
@Time : 2022/12/13 15:07
@IDE : Pycharm
@Version : Python3.10
@comment : 主窗口
"""
import json
import os.path
2024-03-02 20:08:04 +08:00
import subprocess
import sys
import traceback
2024-03-04 11:19:08 +08:00
import requests
import time
2024-03-02 20:08:04 +08:00
from urllib.parse import urljoin
2024-02-14 19:07:44 +08:00
from PyQt5.QtCore import pyqtSignal, QThread, QSize, QUrl, Qt
2024-01-22 22:21:55 +08:00
from PyQt5.QtGui import QPixmap, QIcon, QDesktopServices
2024-03-04 11:19:08 +08:00
from PyQt5.QtWidgets import QMainWindow, QLabel, QMessageBox
from Custom_Widgets.Widgets import *
from app.DataBase import misc_db, micro_msg_db, close_db
from app.ui.Icon import Icon
2024-03-04 11:19:08 +08:00
from .interface import *
2024-02-09 18:00:06 +08:00
from app.ui.chat import ChatWindow
from app.ui.contact import ContactWindow
from app.ui.tool.tool_window import ToolWindow
2024-03-04 11:19:08 +08:00
from app.ui.home.home_window import HomeWindow, ReportThread
from app.ui.tool.setting.setting import ErrorThread
from app.ui.tool.pc_decrypt.pc_decrypt import DecryptThread, InfoThread
from app.ui.tool.get_bias_addr.get_bias_addr import BiasThread
from app.ui.chat.chat_info import ShowChatThread
from app.ui.chat.chat_window import ShowContactThread, ShowThread
from app.ui.menu.export import ShowContactExportThread, export_types, export_file_format
from app.util import path
from app.config import SERVER_API_URL
from app.decrypt.get_bias_addr import BiasAddr
2024-01-06 13:04:55 +08:00
from .menu.export import ExportDialog
2024-02-08 20:37:44 +08:00
from app.util.exporter.output import Output
2023-12-23 19:07:15 +08:00
from ..components.QCursorGif import QCursorGif
2024-03-04 11:19:08 +08:00
from ..config import INFO_FILE_PATH, DB_DIR, about, SERVER_API_URL, version
from ..log import logger
2023-12-30 19:26:24 +08:00
from ..person import Me
2024-03-04 11:19:08 +08:00
from app.DataBase import micro_msg_db, misc_db
from app.util.exporter.output import Output
from app.components import ScrollBar
from app.components.export_contact_item import ContactQListWidgetItem
from app.config import OUTPUT_DIR
from app.person import Contact
from app.ui.menu.exportUi import Ui_Dialog
from app.ui.menu.export_time_range import TimeRangeDialog
2024-01-16 21:28:38 +08:00
try:
2024-03-04 11:19:08 +08:00
from app.ui.menu.about_dialog import version, UpdateThread, AboutDialog
2024-01-16 21:28:38 +08:00
except ModuleNotFoundError:
logger.error(f'Python版本错误:Python>=3.10,仅支持3.10、3.11、3.12')
2024-01-17 21:49:47 +08:00
raise ValueError('Python版本错误:Python>=3.10,仅支持3.10、3.11、3.12')
2024-01-24 20:02:01 +08:00
2024-02-01 21:12:10 +08:00
class Avatar(QLabel):
def __init__(self, parent=None):
super().__init__(parent)
2024-03-04 11:19:08 +08:00
def mouseDoubleClickEvent(self, e):
2024-02-01 21:12:10 +08:00
super().mouseDoubleClickEvent()
QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/7"))
2024-03-04 11:19:08 +08:00
def mousePressEvent(self, e):
2024-02-01 21:12:10 +08:00
super().mousePressEvent(e)
QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/7"))
2024-02-21 22:41:11 +08:00
2024-03-04 11:19:08 +08:00
class MainWinController(QMainWindow, Ui_MainWindow):
exitSignal = pyqtSignal(bool)
okSignal = pyqtSignal(bool)
2024-03-04 11:19:08 +08:00
DecryptSignal = pyqtSignal(bool)
get_wxidSignal = pyqtSignal(str)
versionErrorSignal = pyqtSignal(str)
def __init__(self, parent=None):
super(MainWinController, self).__init__(parent)
self.outputThread0 = None
self.outputThread = None
2024-03-04 11:19:08 +08:00
self.setupUi(self)
2024-03-04 11:19:08 +08:00
self.load_flag = False
self.load_data()
self.load_num = 0
2024-03-04 11:19:08 +08:00
loadJsonStyle(self, self, jsonFiles=["app/ui/style.json"])
self.toolBtn.clicked.connect(lambda: self.centerMenuContainer.expandMenu())
# self.msgBtn.clicked.connect(lambda: self.centerMenuContainer.expandMenu())
# self.friendBtn.clicked.connect(lambda: self.centerMenuContainer.expandMenu())
# self.userBtn.clicked.connect(lambda: self.centerMenuContainer.expandMenu())
self.msgBtn.clicked.connect(lambda: self.centerMenuContainer.collapseMenu())
self.friendBtn.clicked.connect(lambda: self.centerMenuContainer.collapseMenu())
self.userBtn.clicked.connect(lambda: self.centerMenuContainer.collapseMenu())
self.aboutBtn.clicked.connect(lambda: self.centerMenuContainer.collapseMenu())
self.settingBtn.clicked.connect(lambda: self.centerMenuContainer.collapseMenu())
self.helpBtn.clicked.connect(lambda: self.centerMenuContainer.collapseMenu())
self.prepare_about()
self.version_list = None
self.versionText.setText(f"留痕-V{version}")
self.closeCenterMenuBtn.clicked.connect(lambda: self.centerMenuContainer.collapseMenu())
self.closeNotificationBtn.clicked.connect(lambda: self.popupNotificationsContainer.collapseMenu())
self.exportAllBtn.clicked.connect(self.output)
self.exportFriendBtn.clicked.connect(self.output)
self.updateBtn.clicked.connect(self.update)
self.questionBtn.clicked.connect(
lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/7")))
self.toolQuestionBtn.clicked.connect(
lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/4")))
self.friendQuestionBtn.clicked.connect(
lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/7")))
self.msgQuestionBtn.clicked.connect(
lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/7")))
self.mainContentsPages.setCurrentWidget(self.aboutMainPage)
self.reportBtn.clicked.connect(self.report)
self.stopWordBtn.clicked.connect(self.add_stopwords)
self.newWordBtn.clicked.connect(self.add_new_words)
self.read_data()
self.sendErrorBtn.clicked.connect(self.send_error_log)
self.setBtnVisible(0)
self.toolBtn.clicked.connect(lambda: self.setBtnVisible(1))
self.decryptBtn.clicked.connect(lambda: self.setBtnVisible(1))
self.decryptBtn2.clicked.connect(lambda: self.setBtnVisible(2))
self.dataBtn.clicked.connect(lambda: self.setBtnVisible(3))
self.msgBtn.clicked.connect(lambda: self.setBtnVisible(4))
self.friendBtn.clicked.connect(lambda: self.setBtnVisible(5))
self.userBtn.clicked.connect(lambda: self.setBtnVisible(6))
self.aboutBtn.clicked.connect(lambda: self.setBtnVisible(7))
self.settingBtn.clicked.connect(lambda: self.setBtnVisible(8))
self.helpBtn.clicked.connect(lambda: self.setBtnVisible(9))
self.startDecryptBtn.clicked.connect(self.decrypt)
self.getInfoBtn.clicked.connect(self.get_info)
self.dbDirBtn.clicked.connect(self.select_db_dir)
self.lineEdit.returnPressed.connect(self.set_wxid)
self.lineEdit.textChanged.connect(self.set_wxid_)
self.startDecryptBiasBtn.clicked.connect(self.get_bias_addr)
self.friendView = ContactWindow(parent=self.friendMainPage)
self.msgView = ChatWindow(parent=self.msgMainPage)
self.statisticBtn.clicked.connect(self.statistic)
self.moodBtn.clicked.connect(self.mood)
self.userReportBtn.clicked.connect(self.user_report)
self.contacts = []
self.btn_select_all.clicked.connect(self.select_all)
self.select_all_flag = False
self.exportBatchBtn.clicked.connect(self.export_data)
self.comboBox_time.activated.connect(self.set_export_date)
self.export_choices = {"文本": True, "图片": True, "语音": False, "视频": False, "表情包": False,
'音乐与音频': False, '分享卡片': False, '文件': False,
'转账': False, '音视频通话': False,'拍一拍等系统消息': True}
self.checkBox_word.setEnabled(False)
self.checkBox_word.setText('Docx(暂时不可用)')
self.worker = None
for export_type, default_state in self.export_choices.items():
checkbox = QCheckBox(export_type)
checkbox.setObjectName('message_type')
checkbox.setChecked(default_state)
self.messageTypeVerticalLayout.addWidget(checkbox)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.messageTypeVerticalLayout.addItem(spacerItem1)
self.timer = QTimer(self)
self.time = 0
self.total_msg_num = 99999
self.num = 0
self.timer.timeout.connect(self.update_elapsed_time)
self.show_thread = ShowContactExportThread()
self.show_thread.showSingal.connect(self.show_contact)
self.show_thread.start()
self.listWidget.setVerticalScrollBar(ScrollBar())
self.listWidget.itemClicked.connect(self.setCurrentIndex)
self.visited = set()
self.now_index = 0
self.time_range = None
def setBtnVisible(self, index=0):
self.getInfoBtn.setVisible(False)
self.dbDirBtn.setVisible(False)
self.startDecryptBtn.setVisible(False)
self.startDecryptBiasBtn.setVisible(False)
self.statisticBtn.setVisible(False)
self.moodBtn.setVisible(False)
self.reportBtn.setVisible(False)
self.userReportBtn.setVisible(False)
self.exportAllBtn.setVisible(False)
self.exportBatchBtn.setVisible(False)
self.exportFriendBtn.setVisible(False)
self.stopWordBtn.setVisible(False)
self.newWordBtn.setVisible(False)
if index == 1:
self.getInfoBtn.setVisible(True)
self.dbDirBtn.setVisible(True)
self.startDecryptBtn.setVisible(True)
if index == 2:
self.startDecryptBiasBtn.setVisible(True)
if index == 3:
self.exportAllBtn.setVisible(True)
self.exportBatchBtn.setVisible(True)
self.exportFriendBtn.setVisible(True)
if index == 5:
self.statisticBtn.setVisible(True)
self.moodBtn.setVisible(True)
self.userReportBtn.setVisible(True)
if index == 6:
self.reportBtn.setVisible(True)
if index == 8:
self.stopWordBtn.setVisible(True)
self.newWordBtn.setVisible(True)
def load_data(self):
2024-02-17 21:34:46 +08:00
if os.path.exists(INFO_FILE_PATH):
with open(INFO_FILE_PATH, 'r', encoding='utf-8') as f:
dic = json.loads(f.read())
wxid = dic.get('wxid')
if wxid:
2023-12-30 19:26:24 +08:00
me = Me()
me.wxid = dic.get('wxid')
me.name = dic.get('name')
me.nickName = dic.get('name')
me.remark = dic.get('name')
me.mobile = dic.get('mobile')
me.wx_dir = dic.get('wx_dir')
2024-03-01 01:17:47 +08:00
me.token = dic.get('token')
self.set_my_info(wxid)
self.load_flag = True
else:
2024-01-17 20:04:59 +08:00
pass
def set_my_info(self, wxid):
self.avatar = QPixmap()
2024-02-29 16:36:32 +08:00
img_bytes = misc_db.get_avatar_buffer(wxid)
if not img_bytes:
return
if img_bytes[:4] == b'\x89PNG':
self.avatar.loadFromData(img_bytes, format='PNG')
else:
self.avatar.loadFromData(img_bytes, format='jfif')
self.avatar.scaled(60, 60)
2023-12-29 21:50:17 +08:00
contact_info_list = micro_msg_db.get_contact_by_username(wxid)
2024-01-30 21:45:28 +08:00
if not contact_info_list:
close_db()
import shutil
try:
2024-02-17 21:34:46 +08:00
shutil.rmtree(DB_DIR)
2024-01-30 21:45:28 +08:00
except:
pass
2024-03-04 11:19:08 +08:00
self.message_error("数据库错误请删除app文件夹后重启电脑再运行软件")
2024-01-30 21:45:28 +08:00
return
2023-12-30 19:26:24 +08:00
me = Me()
me.set_avatar(img_bytes)
2023-12-29 21:50:17 +08:00
me.smallHeadImgUrl = contact_info_list[7]
self.myavatar.setScaledContents(True)
self.myavatar.setPixmap(self.avatar)
def output(self):
2024-03-04 11:19:08 +08:00
if self.sender() == self.exportAllBtn:
self.outputThread = Output(None, type_=Output.CSV_ALL)
self.outputThread.okSignal.connect(
2024-03-04 11:19:08 +08:00
lambda x: self.message_notification('聊天记录导出成功'))
self.outputThread.start()
2024-03-04 11:19:08 +08:00
elif self.sender() == self.exportFriendBtn:
self.outputThread = Output(None, type_=Output.CONTACT_CSV)
self.outputThread.okSignal.connect(
2024-03-04 11:19:08 +08:00
lambda x: self.message_notification('联系人导出成功'))
self.outputThread.start()
2024-03-04 11:19:08 +08:00
def countLine(self, text):
text = text.replace('<br>', '\n')
lines = len(text.split('\n'))
return lines - 1
def message_notification(self, msg):
self.notificationType.setText("通知")
self.notificationContent.setText(msg)
self.popupNotificationsContainer.setFixedHeight(104 + 22 * self.countLine(msg))
self.popupNotificationsContainer.expandMenu()
def message_error(self, msg):
self.notificationType.setText("错误")
self.notificationContent.setText(msg)
self.popupNotificationsContainer.setFixedHeight(104 + 22 * self.countLine(msg))
self.popupNotificationsContainer.expandMenu()
def prepare_about(self):
self.aboutText.setText(about)
self.aboutText.adjustSize()
2024-01-17 20:20:32 +08:00
def update(self):
self.update_thread = UpdateThread()
self.update_thread.updateSignal.connect(self.show_update)
self.update_thread.start()
def show_update(self, update_info):
if not update_info.get('update_available'):
2024-03-04 11:19:08 +08:00
self.message_notification("当前已是最新版本")
# return
detail = f'''当前版本:{version},最新版本:{update_info.get('latest_version')}
更新内容:{update_info.get('description')}
<a href='{update_info.get('download_url')}'>点击下载</a>
2024-01-17 20:20:32 +08:00
'''
2024-03-04 11:19:08 +08:00
self.message_notification(detail)
def decrypt_success(self):
2024-03-04 11:19:08 +08:00
self.message_notification("解密成功,请重新启动")
self.close()
def close(self) -> bool:
close_db()
2024-01-15 19:51:08 +08:00
super().close()
self.exitSignal.emit(True)
2024-03-02 23:04:15 +08:00
2024-03-04 11:19:08 +08:00
# 我的年度报告相关
def report(self):
time_range = ['2023-01-01 00:00:00', '2024-02-10 00:00:00']
self.reportProgress.setText('正在生成报告\n如需查看报告请点击访问 http://127.0.0.1:21314/ 查看')
self.report_thread = ReportThread(Me(), time_range)
self.report_thread.start()
QDesktopServices.openUrl(QUrl(f"http://127.0.0.1:21314/"))
# 设置相关
def read_data(self):
os.makedirs('./app/data', exist_ok=True)
stopwords = ['裂开', '苦涩', '叹气', '凋谢', '让我看看', '', '奋斗', '疑问', '擦汗', '抠鼻', '鄙视', '勾引',
'奸笑', '嘿哈', '捂脸', '机智', '加油', '吃瓜', '尴尬', '炸弹', '旺柴']
new_words = ['YYDS', '666', '显眼包', '遥遥领先']
if os.path.exists('./app/data/stopwords.txt'):
with open('./app/data/stopwords.txt', 'r', encoding='utf-8') as f:
stopwords = set(f.read().splitlines())
self.stopWordTextEdit.setPlainText(' '.join(stopwords))
else:
self.stopWordTextEdit.setPlainText(' '.join(stopwords))
stopwords = '\n'.join(stopwords)
with open('./app/data/stopwords.txt', 'w', encoding='utf-8') as f:
f.write(stopwords)
if os.path.exists('./app/data/new_words.txt'):
with open('./app/data/new_words.txt', 'r', encoding='utf-8') as f:
stopwords = set(f.read().splitlines())
self.newWordTextEdit.setPlainText(' '.join(new_words))
else:
self.newWordTextEdit.setPlainText(' '.join(new_words))
stopwords = '\n'.join(stopwords)
with open('./app/data/new_words.txt', 'w', encoding='utf-8') as f:
f.write(stopwords)
def add_stopwords(self):
text = self.stopWordTextEdit.toPlainText()
stopwords = '\n'.join(text.split())
with open('./app/data/stopwords.txt', 'w', encoding='utf-8') as f:
f.write(stopwords)
self.message_notification("停用词添加成功")
def add_new_words(self):
text = self.newWordTextEdit.toPlainText()
new_words = '\n'.join(text.split())
with open('./app/data/new_words.txt', 'w', encoding='utf-8') as f:
f.write(new_words)
self.message_notification("自定义词添加成功")
def send_error_log(self):
self.send_thread = ErrorThread()
self.send_thread.signal.connect(self.show_resp)
self.send_thread.start()
def show_resp(self, msg):
if msg.get('code') == 200:
self.message_notification(f"日志发送成功\n{msg.get('message')}")
else:
self.message_notification(f"{msg.get('code')}:{msg.get('errmsg')}")
# 自动解密相关
def get_info(self):
self.get_info_thread = InfoThread(self.version_list)
self.get_info_thread.signal.connect(self.set_info)
self.get_info_thread.start()
def set_info(self, result):
if result[0] == -1:
self.message_error("请登录微信")
elif result[0] == -2:
self.versionErrorSignal.emit(result[1])
self.message_error("微信版本不匹配\n请手动填写信息")
elif result[0] == -3:
self.message_error("WeChat WeChatWin.dll Not Found")
elif result[0] == -10086:
self.message_error("未知错误,请收集错误信息")
else:
self.ready = True
self.info = result[0]
self.label_key.setText(self.info['key'])
self.lineEdit.setText(self.info['wxid'])
self.label_name.setText(self.info['name'])
self.label_phone.setText(self.info['mobile'])
self.label_pid.setText(str(self.info['pid']))
self.label_version.setText(self.info['version'])
self.lineEdit.setFocus()
self.getInfoCheckBox.setCheckable(True)
self.getInfoCheckBox.setChecked(True)
self.get_wxidSignal.emit(self.info['wxid'])
directory = os.path.join(path.wx_path(), self.info['wxid'])
if os.path.exists(directory):
self.label_db_dir.setText(directory)
self.wx_dir = directory
self.setPathCheckBox.setCheckable(True)
self.setPathCheckBox.setChecked(True)
self.ready = True
if self.ready:
self.label_ready.setText('已就绪')
if self.wx_dir and os.path.exists(os.path.join(self.wx_dir)):
self.label_ready.setText('已就绪')
def set_wxid_(self):
self.info['wxid'] = self.lineEdit.text()
def set_wxid(self):
self.info['wxid'] = self.lineEdit.text()
self.message_notification("wxid修改成功")
def select_db_dir(self):
directory = QFileDialog.getExistingDirectory(
self, "选取微信文件保存目录——能看到Msg文件夹",
path.wx_path()
)
db_dir = os.path.join(directory, 'Msg')
if not os.path.exists(db_dir):
self.message_error("文件夹选择错误\n一般以wxid_xxx结尾")
return
2024-03-02 23:04:15 +08:00
2024-03-04 11:19:08 +08:00
self.label_db_dir.setText(directory)
self.wx_dir = directory
self.setPathCheckBox.setCheckable(True)
self.setPathCheckBox.setChecked(True)
if self.ready:
self.label_ready.setText('已就绪')
2024-03-02 20:08:04 +08:00
2024-03-04 11:19:08 +08:00
def decrypt(self):
if not self.ready:
self.message_error("请先获取信息")
return
if not self.wx_dir:
self.message_error("请先选择微信安装路径")
return
if self.lineEdit.text() == 'None':
self.message_error("请填入wxid")
return
db_dir = os.path.join(self.wx_dir, 'Msg')
if self.ready:
if not os.path.exists(db_dir):
self.message_error("文件夹选择错误\n一般以wxid_xxx结尾")
return
if self.info.get('key') == 'None':
self.message_error("密钥错误\n请查看教程解决相关问题")
close_db()
self.thread2 = DecryptThread(db_dir, self.info['key'])
self.thread2.maxNumSignal.connect(self.setProgressBarMaxNum)
self.thread2.signal.connect(self.progressBar_view)
self.thread2.okSignal.connect(self.btnExitClicked)
self.thread2.errorSignal.connect(
lambda x: self.message_error("错误\n请检查微信版本是否为最新和微信路径是否正确\n或者关闭微信多开")
)
self.thread2.start()
def btnEnterClicked(self):
self.progressBar_view(self.max_val)
self.DecryptSignal.emit(True)
def setProgressBarMaxNum(self, max_val):
self.max_val = max_val
self.progressBar.setRange(0, max_val)
def progressBar_view(self, value):
self.progressBar.setProperty('value', value)
def btnExitClicked(self):
dic = {
'wxid': self.info['wxid'],
'wx_dir': self.wx_dir,
'name': self.info['name'],
'mobile': self.info['mobile']
}
2024-03-02 20:08:04 +08:00
try:
2024-03-04 11:19:08 +08:00
with open(INFO_FILE_PATH, "w", encoding="utf-8") as f:
json.dump(dic, f, ensure_ascii=False, indent=4)
2024-03-02 20:08:04 +08:00
except:
2024-03-04 11:19:08 +08:00
with open('./info.json', 'w', encoding='utf-8') as f:
f.write(json.dumps(dic))
self.progressBar_view(self.max_val)
self.DecryptSignal.emit(True)
self.close()
# 手动解密相关
def upload(self, version_data):
url = urljoin(SERVER_API_URL, 'wxBiasAddr')
2024-03-02 20:08:04 +08:00
try:
2024-03-04 11:19:08 +08:00
requests.post(url, json=version_data)
print('版本信息上传成功')
2024-03-02 20:08:04 +08:00
except:
2024-03-04 11:19:08 +08:00
pass
def get_bias_addr(self):
account = self.lineEdit_wx_alias.text()
mobile = self.lineEdit_tel.text()
name = self.lineEdit_wx_name.text()
if not all([account, mobile, name]):
self.message_error("请把所有信息填写完整")
return
key = None
db_path = "test"
self.thread = BiasThread(account, mobile, name, key, db_path)
self.thread.signal.connect(self.set_bias_addr)
self.thread.start()
def set_bias_addr(self, data):
self.upload(data)
self.biasAddrSignal.emit(data)
# 好友相关
def statistic(self):
self.friendView.stackedWidget.currentWidget().analysis()
def mood(self):
self.friendView.stackedWidget.currentWidget().emotionale_Analysis()
def user_report(self):
self.friendView.stackedWidget.currentWidget().annual_report()
# 数据导出相关
def set_export_date(self):
date_range = self.comboBox_time.currentText()
if date_range == '全部时间':
pass
elif date_range == '最近三个月':
from datetime import datetime, timedelta
today = datetime.now()
today_date = today.date()
today_midnight = datetime.combine(today_date, datetime.min.time()) + timedelta(days=1)
today_midnight_timestamp = int(today_midnight.timestamp())
three_months_ago = today - timedelta(days=90)
three_months_ago_date = three_months_ago.date()
three_months_ago_midnight = datetime.combine(three_months_ago_date, datetime.min.time())
three_months_ago_midnight_timestamp = int(three_months_ago_midnight.timestamp())
self.time_range = (three_months_ago_midnight_timestamp, today_midnight_timestamp)
elif date_range == '自定义时间':
self.time_range_view = TimeRangeDialog(parent=self)
self.time_range_view.date_range_signal.connect(self.set_time_range)
self.time_range_view.show()
self.comboBox_time.setCurrentIndex(0)
def set_time_range(self, time_range):
self.time_range = time_range
self.comboBox_time.setCurrentIndex(2)
def export_data(self):
self.exportBatchBtn.setEnabled(False)
selected_types = {export_types[export_type]: checkbox.isChecked() for export_type, checkbox in
zip(self.export_choices.keys(), self.findChildren(QCheckBox, 'message_type'))}
print("选择的数据类型:", selected_types)
file_types = []
for checkbox in [self.checkBox_txt, self.checkBox_csv, self.checkBox_html, self.checkBox_word]:
if checkbox.isChecked():
file_types.append(export_file_format[checkbox.text()])
select_contacts = []
count = self.listWidget.count()
for i in range(count):
item = self.listWidget.item(i)
if item.is_select:
select_contacts.append(self.contacts[i])
print("选择的文件格式:", file_types)
self.worker = Output(select_contacts, type_=Output.Batch, message_types=selected_types, sub_type=file_types,
time_range=self.time_range)
self.worker.okSignal.connect(self.export_finished)
self.worker.rangeSignal.connect(self.set_total_msg_num)
self.worker.nowContact.connect(self.update_progress)
self.worker.start()
self.timer.start(1000)
self.start_time = time.time()
def set_total_msg_num(self, num):
self.total_msg_num = num
def setCurrentIndex(self, item):
item.select()
item.dis_select()
def select_all(self):
self.select_all_flag = not self.select_all_flag
print('全选', self.select_all_flag)
if self.select_all_flag:
count = self.listWidget.count()
for i in range(count):
item = self.listWidget.item(i)
item.force_select()
self.btn_select_all.setText('全不选')
else:
count = self.listWidget.count()
for i in range(count):
item = self.listWidget.item(i)
item.force_dis_select()
self.btn_select_all.setText('全选')
def export_finished(self):
self.exportBatchBtn.setEnabled(True)
self.time = 0
end_time = time.time()
print(f'总耗时:{end_time - self.start_time}s')
self.message_notification(f"导出聊天记录成功\n{OUTPUT_DIR}目录下(跟exe文件在一起)\n{os.path.normpath(os.path.join(os.getcwd(), OUTPUT_DIR))}")
def show_contact(self, contact):
contact_item = ContactQListWidgetItem(contact.remark, contact.smallHeadImgUrl, contact.smallHeadImgBLOG)
self.listWidget.addItem(contact_item)
self.listWidget.setItemWidget(contact_item, contact_item.widget)
self.contacts.append(contact)
def update_elapsed_time(self):
self.time += 1
self.label_time.setText(f"耗时: {self.time}s")
def update_progress(self, remark):
self.num += 1
progress_percentage = int((self.num) / self.total_msg_num * 100)
self.exportProgressBar.setValue(progress_percentage)
self.label_process.setText(f"导出进度: {progress_percentage}% {remark}")