From 5f11483d1ab84d3bb2390796fedede999e1f6b81 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Mon, 27 Nov 2023 21:23:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AF=BC=E5=87=BA=E6=89=80?= =?UTF-8?q?=E6=9C=89=E8=81=8A=E5=A4=A9=E8=AE=B0=E5=BD=95=E5=88=B0CSV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/misc.xml | 3 ++ app/DataBase/msg.py | 20 +++++++++ app/DataBase/output_pc.py | 89 +++++++++++++++++++++++-------------- app/ui_pc/chat/chat_info.py | 1 + app/ui_pc/mainview.py | 22 +++++++-- app/ui_pc/mainwindow.py | 18 +++++--- app/ui_pc/mainwindow.ui | 18 ++++++-- app/util/emoji.py | 2 + main_pc.py | 7 +-- 9 files changed, 129 insertions(+), 51 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 3b8148a..3505565 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,7 @@ + + \ No newline at end of file diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index 6300236..71ad68f 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -67,6 +67,26 @@ def get_messages(username_): return result +def get_messages_all(): + sql = ''' + select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime + from MSG + order by CreateTime + ''' + result = [] + for cur in cursor: + try: + lock.acquire(True) + cur.execute(sql) + result_ = cur.fetchall() + # print(len(result)) + result += result_ + finally: + lock.release() + result.sort(key=lambda x: x[5]) + return result + + def get_message_by_num(username_, local_id): sql = ''' select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py index f085765..30c1520 100644 --- a/app/DataBase/output_pc.py +++ b/app/DataBase/output_pc.py @@ -4,7 +4,6 @@ import os from PyQt5.QtCore import pyqtSignal, QThread from . import msg -from ..log import log from ..person_pc import MePC if not os.path.exists('./data/聊天记录'): @@ -22,55 +21,55 @@ class Output(QThread): CSV = 0 DOCX = 1 HTML = 2 + CSV_ALL = 3 def __init__(self, contact, parent=None, type_=DOCX): super().__init__(parent) + self.Child0 = None self.last_timestamp = 0 self.sec = 2 # 默认1000秒 self.contact = contact - self.ta_username = contact.wxid + self.ta_username = contact.wxid if contact else '' self.msg_id = 0 self.output_type = type_ self.total_num = 0 self.num = 0 - @log - def to_csv(self, conRemark, path): - - self.okSignal.emit('ok') - - def to_html(self): - - self.okSignal.emit('ok') - - def is_5_min(self, timestamp): - if abs(timestamp - self.last_timestamp) > 300: - self.last_timestamp = timestamp - - return True - return False - def progress(self, value): self.progressSignal.emit(value) + def to_csv_all(self): + origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/" + if not os.path.exists(origin_docx_path): + os.mkdir(origin_docx_path) + filename = f"{os.path.abspath('.')}/data/聊天记录/messages.csv" + # columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"] + columns = ['localId', 'TalkerId', 'Type', 'SubType', + 'IsSender', 'CreateTime', 'Status', 'StrContent', + 'StrTime'] + messages = msg.get_messages_all() + # 写入CSV文件 + with open(filename, mode='w', newline='', encoding='utf-8') as file: + writer = csv.writer(file) + writer.writerow(columns) + # 写入数据 + writer.writerows(messages) + self.okSignal.emit(1) + def run(self): if self.output_type == self.DOCX: return - elif self.output_type == self.CSV: - # print("线程导出csv") - self.Child0 = ChildThread(self.contact, type_=ChildThread.CSV) + elif self.output_type == self.CSV_ALL: + self.to_csv_all() + else: + self.Child0 = ChildThread(self.contact, type_=self.output_type) self.Child0.progressSignal.connect(self.progress) self.Child0.rangeSignal.connect(self.rangeSignal) self.Child0.okSignal.connect(self.okSignal) - self.Child0.run() - elif self.output_type == self.HTML: - # self.to_html() - self.Child0 = ChildThread(self.contact, type_=ChildThread.HTML) - self.Child0.progressSignal.connect(self.progress) - self.Child0.rangeSignal.connect(self.rangeSignal) - self.Child0.okSignal.connect(self.okSignal) - self.Child0.run() - # self.okSignal.emit(1) + self.Child0.start() + + def cancel(self): + self.requestInterruption() class ChildThread(QThread): @@ -96,7 +95,6 @@ class ChildThread(QThread): def is_5_min(self, timestamp): if abs(timestamp - self.last_timestamp) > 300: self.last_timestamp = timestamp - return True return False @@ -142,6 +140,24 @@ class ChildThread(QThread): writer.writerows(messages) self.okSignal.emit('ok') + def to_csv_all(self): + origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/" + if not os.path.exists(origin_docx_path): + os.mkdir(origin_docx_path) + filename = f"{os.path.abspath('.')}/data/聊天记录/messages.csv" + # columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"] + columns = ['localId', 'TalkerId', 'Type', 'SubType', + 'IsSender', 'CreateTime', 'Status', 'StrContent', + 'StrTime'] + messages = msg.get_messages_all() + # 写入CSV文件 + with open(filename, mode='w', newline='', encoding='utf-8') as file: + writer = csv.writer(file) + writer.writerow(columns) + # 写入数据 + writer.writerows(messages) + self.okSignal.emit(1) + def to_html(self): origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}" if not os.path.exists(origin_docx_path): @@ -734,9 +750,14 @@ const chatMessages = [ self.okSignal.emit(1) def run(self): - if self.output_type == self.DOCX: + if self.output_type == Output.DOCX: return - elif self.output_type == self.CSV: + elif self.output_type == Output.CSV: self.to_csv() - elif self.output_type == self.HTML: + elif self.output_type == Output.HTML: self.to_html_() + elif self.output_type == Output.CSV_ALL: + self.to_csv_all() + + def cancel(self): + self.requestInterruption() diff --git a/app/ui_pc/chat/chat_info.py b/app/ui_pc/chat/chat_info.py index dca49b0..1129d61 100644 --- a/app/ui_pc/chat/chat_info.py +++ b/app/ui_pc/chat/chat_info.py @@ -43,6 +43,7 @@ class ChatInfo(QWidget): def show_finish(self, ok): self.setScrollBarPos() + self.show_chat_thread.quit() def verticalScrollBar(self, pos): """ diff --git a/app/ui_pc/mainview.py b/app/ui_pc/mainview.py index ec71313..31afd92 100644 --- a/app/ui_pc/mainview.py +++ b/app/ui_pc/mainview.py @@ -21,6 +21,7 @@ from . import mainwindow from .chat import ChatWindow from .contact import ContactWindow from .tool.tool_window import ToolWindow +from ..DataBase.output_pc import Output from ..person_pc import MePC # 美化样式表 @@ -68,6 +69,8 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): # username = '' def __init__(self, username, parent=None): super(MainWinController, self).__init__(parent) + self.outputThread0 = None + self.outputThread = None self.setupUi(self) self.setWindowIcon(Icon.MainWindow_Icon) self.setStyleSheet(Stylesheet) @@ -101,12 +104,15 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): ) def init_ui(self): + self.menu_output.setIcon(Icon.Output) + self.action_output_CSV.setIcon(Icon.ToCSV) + self.action_output_CSV.triggered.connect(self.output) self.action_help_contact.triggered.connect( - lambda: QDesktopServices.openUrl(QUrl("http://8.146.206.114/post/4"))) + lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/4"))) self.action_help_chat.triggered.connect( - lambda: QDesktopServices.openUrl(QUrl("http://8.146.206.114/post/4"))) + lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/4"))) self.action_help_decrypt.triggered.connect( - lambda: QDesktopServices.openUrl(QUrl("http://8.146.206.114/post/4"))) + lambda: QDesktopServices.openUrl(QUrl("https://blog.lc044.love/post/4"))) self.listWidget.setVisible(False) self.stackedWidget.setVisible(False) self.listWidget.currentRowChanged.connect(self.setCurrentIndex) @@ -180,6 +186,16 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow): self.listWidget.setVisible(True) self.stackedWidget.setVisible(True) + def output(self): + if self.sender() == self.action_output_CSV: + self.outputThread = Output(None, type_=Output.CSV_ALL) + self.outputThread.okSignal.connect( + lambda x: self.message('聊天记录导出成功\n./data/聊天记录/messages.csv')) + self.outputThread.start() + + def message(self, msg): + QMessageBox.about(self, "提醒", msg) + def about(self): """ 关于 diff --git a/app/ui_pc/mainwindow.py b/app/ui_pc/mainwindow.py index 4c20bfa..83b97eb 100644 --- a/app/ui_pc/mainwindow.py +++ b/app/ui_pc/mainwindow.py @@ -90,11 +90,13 @@ class Ui_MainWindow(object): self.menubar.setObjectName("menubar") self.menu_F = QtWidgets.QMenu(self.menubar) self.menu_F.setObjectName("menu_F") - self.menu = QtWidgets.QMenu(self.menubar) + self.menu_data = QtWidgets.QMenu(self.menubar) font = QtGui.QFont() font.setFamily("微软雅黑") - self.menu.setFont(font) - self.menu.setObjectName("menu") + self.menu_data.setFont(font) + self.menu_data.setObjectName("menu_data") + self.menu_output = QtWidgets.QMenu(self.menu_data) + self.menu_output.setObjectName("menu_output") self.menu_2 = QtWidgets.QMenu(self.menubar) self.menu_2.setObjectName("menu_2") self.menu_about = QtWidgets.QMenu(self.menubar) @@ -120,16 +122,20 @@ class Ui_MainWindow(object): self.action_help_chat.setObjectName("action_help_chat") self.action_help_contact = QtWidgets.QAction(MainWindow) self.action_help_contact.setObjectName("action_help_contact") + self.action_output_CSV = QtWidgets.QAction(MainWindow) + self.action_output_CSV.setObjectName("action_output_CSV") self.menu_F.addSeparator() self.menu_F.addSeparator() self.menu_F.addAction(self.action_3) self.menu_F.addAction(self.action_4) + self.menu_output.addAction(self.action_output_CSV) + self.menu_data.addAction(self.menu_output.menuAction()) self.menu_2.addAction(self.action_help_decrypt) self.menu_2.addAction(self.action_help_chat) self.menu_2.addAction(self.action_help_contact) self.menu_about.addAction(self.action_desc) self.menubar.addAction(self.menu_F.menuAction()) - self.menubar.addAction(self.menu.menuAction()) + self.menubar.addAction(self.menu_data.menuAction()) self.menubar.addAction(self.menu_2.menuAction()) self.menubar.addAction(self.menu_about.menuAction()) self.menubar.addAction(self.menu_3.menuAction()) @@ -155,7 +161,8 @@ class Ui_MainWindow(object): item.setText(_translate("MainWindow", "新建项目")) self.listWidget.setSortingEnabled(__sortingEnabled) self.menu_F.setTitle(_translate("MainWindow", "文件(F)")) - self.menu.setTitle(_translate("MainWindow", "编辑")) + self.menu_data.setTitle(_translate("MainWindow", "数据")) + self.menu_output.setTitle(_translate("MainWindow", "导出聊天记录(全部)")) self.menu_2.setTitle(_translate("MainWindow", "帮助")) self.menu_about.setTitle(_translate("MainWindow", "关于")) self.menu_3.setTitle(_translate("MainWindow", "不显示或者显示异常请重启应用")) @@ -165,3 +172,4 @@ class Ui_MainWindow(object): self.action_desc.setText(_translate("MainWindow", "说明")) self.action_help_chat.setText(_translate("MainWindow", "聊天相关")) self.action_help_contact.setText(_translate("MainWindow", "好友相关")) + self.action_output_CSV.setText(_translate("MainWindow", "CSV")) diff --git a/app/ui_pc/mainwindow.ui b/app/ui_pc/mainwindow.ui index e504ff8..de53612 100644 --- a/app/ui_pc/mainwindow.ui +++ b/app/ui_pc/mainwindow.ui @@ -183,15 +183,22 @@ - + 微软雅黑 - 编辑 + 数据 + + + 导出聊天记录(全部) + + + + @@ -213,7 +220,7 @@ - + @@ -254,6 +261,11 @@ 好友相关 + + + CSV + + diff --git a/app/util/emoji.py b/app/util/emoji.py index f932843..092e2dc 100644 --- a/app/util/emoji.py +++ b/app/util/emoji.py @@ -52,6 +52,8 @@ def parser_xml(xml_string): def download(url, output_dir, name, thumb=False): + if not url: + return ':/icons/icons/404.png' resp = requests.get(url) byte = resp.content image_format = get_image_format(byte[:8]) diff --git a/main_pc.py b/main_pc.py index ecf7076..d6e1531 100644 --- a/main_pc.py +++ b/main_pc.py @@ -2,7 +2,7 @@ import ctypes import sys import time -from PyQt5.QtGui import QIcon, QMovie +from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import * from app.ui_pc import mainview @@ -18,11 +18,6 @@ class ViewController(QWidget): self.setWindowIcon(QIcon(':/icons/icons/logo.png')) self.viewMainWIndow = None self.viewDecrypt = None - # 创建加载动画 - loading_label = QLabel() - movie = QMovie("./app/data/loading.gif") # 替换为你的加载动画文件路径 - loading_label.setMovie(movie) - movie.start() def loadPCDecryptView(self): """