From 4bf1729d208cfd421de75732e497f6599e9abfcb Mon Sep 17 00:00:00 2001
From: shuaikangzhou <863909694@qq.com>
Date: Sun, 10 Dec 2023 18:55:17 +0800
Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8F=AF=E8=87=AA=E5=AE=9A?=
=?UTF-8?q?=E4=B9=89=E9=80=89=E6=8B=A9=E5=AF=BC=E5=87=BAHTML=E7=9A=84?=
=?UTF-8?q?=E6=B6=88=E6=81=AF=E7=B1=BB=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 505 +++++++++++++++--------------
app/main/__init__.py | 9 -
app/ui_pc/contact/contactInfo.py | 25 +-
app/ui_pc/contact/export_dialog.py | 92 ++++++
readme.md | 4 +-
5 files changed, 377 insertions(+), 258 deletions(-)
delete mode 100644 app/main/__init__.py
create mode 100644 app/ui_pc/contact/export_dialog.py
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 1ca25f4..20a6370 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -1,7 +1,7 @@
import csv
import html
import os
-
+from re import findall
from PyQt5.QtCore import pyqtSignal, QThread
from PyQt5.QtWidgets import QFileDialog
@@ -58,10 +58,11 @@ class Output(QThread):
CSV_ALL = 3
CONTACT_CSV = 4
- def __init__(self, contact, parent=None, type_=DOCX):
+ def __init__(self, contact, type_=DOCX, message_types={}, parent=None):
super().__init__(parent)
self.Child0 = None
self.last_timestamp = 0
+ self.message_types = message_types
self.sec = 2 # 默认1000秒
self.contact = contact
self.ta_username = contact.wxid if contact else ''
@@ -122,7 +123,7 @@ class Output(QThread):
elif self.output_type == self.CONTACT_CSV:
self.contact_to_csv()
else:
- self.Child = ChildThread(self.contact, type_=self.output_type)
+ self.Child = ChildThread(self.contact, type_=self.output_type,message_types=self.message_types)
self.Child.progressSignal.connect(self.progress)
self.Child.rangeSignal.connect(self.rangeSignal)
self.Child.okSignal.connect(self.okSignal)
@@ -144,27 +145,85 @@ class ChildThread(QThread):
DOCX = 1
HTML = 2
- def __init__(self, contact, parent=None, type_=DOCX):
+ def __init__(self, contact, type_=DOCX, message_types={}, parent=None):
super().__init__(parent)
self.contact = contact
+ self.message_types = message_types
self.last_timestamp = 0
self.sec = 2 # 默认1000秒
self.msg_id = 0
self.output_type = type_
+
def is_5_min(self, timestamp):
if abs(timestamp - self.last_timestamp) > 300:
self.last_timestamp = timestamp
return True
return False
- def text(self, doc, isSend, message, status):
+ def text(self, doc, message):
+ type_ = message[2]
+ str_content = message[7]
+ str_time = message[8]
+ is_send = message[4]
+ avatar = 'myhead.png' if is_send else 'tahead.png'
+ timestamp = message[5]
+ str_content = escape_js_and_html(str_content)
+ if self.is_5_min(timestamp):
+ doc.write(
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ )
+ emojiText = findall(r"(\[.+?\])", str_content)
+ for emoji_text in emojiText:
+ if emoji_text in emoji:
+ str_content = str_content.replace(emoji_text, emoji[emoji_text])
+ doc.write(
+ f'''{{ type:{type_}, text: '{str_content}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ )
+
+ def image(self, doc, message):
+ type_ = message[2]
+ str_content = message[7]
+ str_time = message[8]
+ is_send = message[4]
+ avatar = 'myhead.png' if is_send else 'tahead.png'
+ timestamp = message[5]
+ BytesExtra = message[10]
+ str_content = escape_js_and_html(str_content)
+ image_path = hard_link_db.get_image(str_content, BytesExtra, thumb=False)
+ image_thumb_path = hard_link_db.get_image(str_content, BytesExtra, thumb=True)
+ if image_path is None and image_thumb_path is not None:
+ image_path = image_thumb_path
+ if image_path is None and image_thumb_path is None:
+ return
+ image_path = path.get_relative_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
+ image_path = image_path.replace('\\', '/')
+ # print(f"tohtml:---{image_path}")
+ if self.is_5_min(timestamp):
+ doc.write(
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ )
+ doc.write(
+ f'''{{ type:{type_}, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ )
return
- def image(self, doc, isSend, Type, content, imgPath):
- return
-
- def emoji(self, doc, isSend, content, imgPath):
+ def emoji(self, doc, message):
+ origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
+ str_content = message[7]
+ str_time = message[8]
+ is_send = message[4]
+ avatar = 'myhead.png' if is_send else 'tahead.png'
+ timestamp = message[5]
+ emoji_path = get_emoji(str_content, thumb=True, output_path=origin_docx_path + '/emoji')
+ emoji_path = './emoji/' + os.path.basename(emoji_path)
+ if self.is_5_min(timestamp):
+ doc.write(
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ )
+ doc.write(
+ f'''{{ type:{3}, text: '{emoji_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ )
return
def wx_file(self, doc, isSend, content, status):
@@ -176,11 +235,55 @@ class ChildThread(QThread):
def reply(self, doc, isSend, content, status):
return
- def pat_a_pat(self, doc, isSend, content, status):
- return
+ def system_msg(self, doc, message):
+ str_content = message[7]
+ is_send = message[4]
+ str_content = escape_js_and_html(str_content.lstrip('').rstrip(''))
+ doc.write(
+ f'''{{ type:0, text: '{str_content}',is_send:{is_send},avatar_path:''}},'''
+ )
- def video(self, doc, isSend, content, status, img_path):
- return
+ def video(self, doc, message):
+ origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
+ type_ = message[2]
+ str_content = message[7]
+ str_time = message[8]
+ is_send = message[4]
+ BytesExtra = message[10]
+ avatar = 'myhead.png' if is_send else 'tahead.png'
+ timestamp = message[5]
+ video_path = hard_link_db.get_video(str_content, BytesExtra, thumb=False)
+ image_path = hard_link_db.get_video(str_content, BytesExtra, thumb=True)
+ if video_path is None and image_path is not None:
+ print(video_path, image_path)
+ image_path = path.get_relative_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
+ print(image_path)
+ image_path = image_path.replace('\\', '/')
+ # print(f"tohtml:---{image_path}")
+ if self.is_5_min(timestamp):
+ doc.write(
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ )
+ doc.write(
+ f'''{{ type:3, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ )
+ return
+ if video_path is None and image_path is None:
+ return
+ video_path = f'{MePC().wx_dir}/{video_path}'
+ if os.path.exists(video_path):
+ new_path = origin_docx_path + '/video/' + os.path.basename(video_path)
+ if not os.path.exists(new_path):
+ shutil.copy(video_path, os.path.join(origin_docx_path, 'video'))
+ video_path = f'./video/{os.path.basename(video_path)}'
+ video_path = video_path.replace('\\', '/')
+ if self.is_5_min(timestamp):
+ doc.write(
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ )
+ doc.write(
+ f'''{{ type:{type_}, text: '{video_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ )
def to_csv(self):
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
@@ -224,7 +327,152 @@ class ChildThread(QThread):
messages = msg_db.get_messages(self.contact.wxid)
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.html"
f = open(filename, 'w', encoding='utf-8')
- html_head = '''
+ f.write(html_head)
+ MePC().avatar.save(os.path.join(origin_docx_path, 'myhead.png'))
+ self.contact.avatar.save(os.path.join(origin_docx_path, 'tahead.png'))
+ self.rangeSignal.emit(len(messages))
+ total_steps = len(messages)
+ for index, message in enumerate(messages):
+ type_ = message[2]
+ self.progressSignal.emit(int((index+1) / total_steps * 100))
+ if type_ == 1 and self.message_types.get(type_):
+ self.text(f, message)
+ elif type_ == 3 and self.message_types.get(type_):
+ self.image(f, message)
+ elif type_ == 43 and self.message_types.get(type_):
+ self.video(f, message)
+ elif type_ == 47 and self.message_types.get(type_):
+ self.emoji(f, message)
+ elif type_ == 10000 and self.message_types.get(type_):
+ self.system_msg(f, message)
+ f.write(html_end)
+ f.close()
+ self.okSignal.emit(1)
+
+ def run(self):
+ if self.output_type == Output.DOCX:
+ return
+ elif self.output_type == Output.CSV:
+ self.to_csv()
+ 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()
+
+
+emoji = {
+ '[微笑]': '
',
+ '[撇嘴]': '
',
+ '[色]': '
',
+ '[发呆]': '
',
+ '[得意]': '
',
+ '[流泪]': '
',
+ '[害羞]': '
',
+ '[闭嘴]': '
',
+ '[睡]': '
',
+ '[大哭]': '
',
+ '[尴尬]': '
',
+ '[发怒]': '
',
+ '[调皮]': '
',
+ '[呲牙]': '
',
+ '[惊讶]': '
',
+ '[难过]': '
',
+ '[抓狂]': '
',
+ '[吐]': '
',
+ '[偷笑]': '
',
+ '[愉快]': '
',
+ '[白眼]': '
',
+ '[傲慢]': '
',
+ '[困]': '
',
+ '[惊恐]': '
',
+ '[憨笑]': '
',
+ '[悠闲]': '
',
+ '[咒骂]': '
',
+ '[疑问]': '
',
+ '[嘘]': '
',
+ '[晕]': '
',
+ '[衰]': '
',
+ '[骷髅]': '
',
+ '[敲打]': '
',
+ '[再见]': '
',
+ '[擦汗]': '
',
+ '[抠鼻]': '
',
+ '[鼓掌]': '
',
+ '[坏笑]': '
',
+ '[右哼哼]': '
',
+ '[鄙视]': '
',
+ '[委屈]': '
',
+ '[快哭了]': '
',
+ '[阴险]': '
',
+ '[亲亲]': '
',
+ '[可怜]': '
',
+ '[笑脸]': '
',
+ '[生病]': '
',
+ '[脸红]': '
',
+ '[破涕为笑]': '
',
+ '[恐惧]': '
',
+ '[失望]': '
',
+ '[无语]': '
',
+ '[嘿哈]': '
',
+ '[捂脸]': '
',
+ '[奸笑]': '
',
+ '[机智]': '
',
+ '[皱眉]': '
',
+ '[耶]': '
',
+ '[吃瓜]': '
',
+ '[加油]': '
',
+ '[汗]': '
',
+ '[天啊]': '
',
+ '[Emm]': '
',
+ '[社会社会]': '
',
+ '[旺柴]': '
',
+ '[好的]': '
',
+ '[打脸]': '
',
+ '[哇]': '
',
+ '[翻白眼]': '
',
+ '[666]': '
',
+ '[让我看看]': '
',
+ '[叹气]': '
',
+ '[苦涩]': '
',
+ '[裂开]': '
',
+ '[嘴唇]': '
',
+ '[爱心]': '
',
+ '[心碎]': '
',
+ '[拥抱]': '
',
+ '[强]': '
',
+ '[弱]': '
',
+ '[握手]': '
',
+ '[胜利]': '
',
+ '[抱拳]': '
',
+ '[勾引]': '
',
+ '[拳头]': '
',
+ '[OK]': '
',
+ '[合十]': '
',
+ '[啤酒]': '
',
+ '[咖啡]': '
',
+ '[蛋糕]': '
',
+ '[玫瑰]': '
',
+ '[凋谢]': '
',
+ '[菜刀]': '
',
+ '[炸弹]': '
',
+ '[便便]': '
',
+ '[月亮]': '
',
+ '[太阳]': '
',
+ '[庆 祝]': '
',
+ '[礼物]': '
',
+ '[红包]': '
',
+ '[發]': '
',
+ '[福]': '
',
+ '[烟花]': '
',
+ '[爆竹]': '
',
+ '[猪头]': '
',
+ '[跳跳]': '
',
+ '[发抖]': '
',
+ '[转圈]': '
'}
+html_head = '''
@@ -244,7 +492,7 @@ class ChildThread(QThread):
align-items: center;
justify-content: center;
}
-
+
.modal {
display: none;
position: fixed;
@@ -255,7 +503,7 @@ class ChildThread(QThread):
height: 100%;
background-color: rgba(0, 0, 0, 0.8);
}
-
+
.modal-image {
display: block;
max-width: 90%;
@@ -517,212 +765,7 @@ const chatContainer = document.getElementById('chat-container');
// Sample chat messages (replace this with your actual data)
const chatMessages = [
'''
- f.write(html_head)
- MePC().avatar.save(os.path.join(origin_docx_path, 'myhead.png'))
- self.contact.avatar.save(os.path.join(origin_docx_path, 'tahead.png'))
- self.rangeSignal.emit(len(messages))
- emoji = {
- '[微笑]': '
',
- '[撇嘴]': '
',
- '[色]': '
',
- '[发呆]': '
',
- '[得意]': '
',
- '[流泪]': '
',
- '[害羞]': '
',
- '[闭嘴]': '
',
- '[睡]': '
',
- '[大哭]': '
',
- '[尴尬]': '
',
- '[发怒]': '
',
- '[调皮]': '
',
- '[呲牙]': '
',
- '[惊讶]': '
',
- '[难过]': '
',
- '[抓狂]': '
',
- '[吐]': '
',
- '[偷笑]': '
',
- '[愉快]': '
',
- '[白眼]': '
',
- '[傲慢]': '
',
- '[困]': '
',
- '[惊恐]': '
',
- '[憨笑]': '
',
- '[悠闲]': '
',
- '[咒骂]': '
',
- '[疑问]': '
',
- '[嘘]': '
',
- '[晕]': '
',
- '[衰]': '
',
- '[骷髅]': '
',
- '[敲打]': '
',
- '[再见]': '
',
- '[擦汗]': '
',
- '[抠鼻]': '
',
- '[鼓掌]': '
',
- '[坏笑]': '
',
- '[右哼哼]': '
',
- '[鄙视]': '
',
- '[委屈]': '
',
- '[快哭了]': '
',
- '[阴险]': '
',
- '[亲亲]': '
',
- '[可怜]': '
',
- '[笑脸]': '
',
- '[生病]': '
',
- '[脸红]': '
',
- '[破涕为笑]': '
',
- '[恐惧]': '
',
- '[失望]': '
',
- '[无语]': '
',
- '[嘿哈]': '
',
- '[捂脸]': '
',
- '[奸笑]': '
',
- '[机智]': '
',
- '[皱眉]': '
',
- '[耶]': '
',
- '[吃瓜]': '
',
- '[加油]': '
',
- '[汗]': '
',
- '[天啊]': '
',
- '[Emm]': '
',
- '[社会社会]': '
',
- '[旺柴]': '
',
- '[好的]': '
',
- '[打脸]': '
',
- '[哇]': '
',
- '[翻白眼]': '
',
- '[666]': '
',
- '[让我看看]': '
',
- '[叹气]': '
',
- '[苦涩]': '
',
- '[裂开]': '
',
- '[嘴唇]': '
',
- '[爱心]': '
',
- '[心碎]': '
',
- '[拥抱]': '
',
- '[强]': '
',
- '[弱]': '
',
- '[握手]': '
',
- '[胜利]': '
',
- '[抱拳]': '
',
- '[勾引]': '
',
- '[拳头]': '
',
- '[OK]': '
',
- '[合十]': '
',
- '[啤酒]': '
',
- '[咖啡]': '
',
- '[蛋糕]': '
',
- '[玫瑰]': '
',
- '[凋谢]': '
',
- '[菜刀]': '
',
- '[炸弹]': '
',
- '[便便]': '
',
- '[月亮]': '
',
- '[太阳]': '
',
- '[庆 祝]': '
',
- '[礼物]': '
',
- '[红包]': '
',
- '[發]': '
',
- '[福]': '
',
- '[烟花]': '
',
- '[爆竹]': '
',
- '[猪头]': '
',
- '[跳跳]': '
',
- '[发抖]': '
',
- '[转圈]': '
'}
- from re import findall
- for index, message in enumerate(messages):
- type_ = message[2]
- str_content = message[7]
- str_time = message[8]
- # print(type_, type(type_))
- is_send = message[4]
- BytesExtra = message[10]
- # avatar = MePC().avatar_path if is_send else self.contact.avatar_path
- # avatar = avatar.replace('\\', '\\\\')
- avatar = 'myhead.png' if is_send else 'tahead.png'
- timestamp = message[5]
- self.progressSignal.emit(index)
- if type_ == 1:
- str_content = escape_js_and_html(str_content)
- if self.is_5_min(timestamp):
- f.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
- )
-
- emojiText = findall(r"(\[.+?\])", str_content)
- for emoji_text in emojiText:
- if emoji_text in emoji:
- str_content = str_content.replace(emoji_text, emoji[emoji_text])
- f.write(
- f'''{{ type:{type_}, text: '{str_content}',is_send:{is_send},avatar_path:'{avatar}'}},'''
- )
- elif type_ == 3:
- image_path = hard_link_db.get_image(str_content, BytesExtra, thumb=False)
- image_thumb_path = hard_link_db.get_image(str_content, BytesExtra, thumb=True)
- if image_path is None and image_thumb_path is not None:
- image_path = image_thumb_path
- if image_path is None and image_thumb_path is None:
- continue
- image_path = path.get_relative_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
- image_path = image_path.replace('\\', '/')
- # print(f"tohtml:---{image_path}")
- if self.is_5_min(timestamp):
- f.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
- )
- f.write(
- f'''{{ type:{type_}, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
- )
- elif type_ == 43:
- video_path = hard_link_db.get_video(str_content, BytesExtra, thumb=False)
- image_path = hard_link_db.get_video(str_content, BytesExtra, thumb=True)
- if video_path is None and image_path is not None:
- print(video_path, image_path)
- image_path = path.get_relative_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
- print(image_path)
- image_path = image_path.replace('\\', '/')
- # print(f"tohtml:---{image_path}")
- if self.is_5_min(timestamp):
- f.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
- )
- f.write(
- f'''{{ type:3, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
- )
- continue
- if video_path is None and image_path is None:
- continue
- video_path = f'{MePC().wx_dir}/{video_path}'
- if os.path.exists(video_path):
- new_path = origin_docx_path + '/video/' + os.path.basename(video_path)
- if not os.path.exists(new_path):
- shutil.copy(video_path, os.path.join(origin_docx_path, 'video'))
- video_path = f'./video/{os.path.basename(video_path)}'
- video_path = video_path.replace('\\', '/')
- if self.is_5_min(timestamp):
- f.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
- )
- f.write(
- f'''{{ type:{type_}, text: '{video_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
- )
- elif type_ == 47:
- emoji_path = get_emoji(str_content, thumb=True, output_path=origin_docx_path + '/emoji')
- emoji_path = './emoji/'+os.path.basename(emoji_path)
- if self.is_5_min(timestamp):
- f.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
- )
- f.write(
- f'''{{ type:{3}, text: '{emoji_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
- )
- elif type_ == 10000:
- str_content = escape_js_and_html(str_content.lstrip('').rstrip(''))
- f.write(
- f'''{{ type:0, text: '{str_content}',is_send:{is_send},avatar_path:''}},'''
- )
- html_end = '''
+html_end = '''
];
function renderMessages(messages) {
for (const message of messages) {
@@ -864,7 +907,7 @@ const chatMessages = [
modalImage.src = image.src;
console.log(image.src);
}
-
+
function hideModal() {
var modal = document.getElementById("modal");
modal.style.display = "none";
@@ -873,19 +916,3 @@ const chatMessages = [
'''
- f.write(html_end)
- f.close()
- self.okSignal.emit(1)
-
- def run(self):
- if self.output_type == Output.DOCX:
- return
- elif self.output_type == Output.CSV:
- self.to_csv()
- 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/main/__init__.py b/app/main/__init__.py
deleted file mode 100644
index d4d7b49..0000000
--- a/app/main/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-@File : __init__.py.py
-@Author : Shuaikang Zhou
-@Time : 2023/1/5 18:11
-@IDE : Pycharm
-@Version : Python3.10
-@comment : ···
-"""
diff --git a/app/ui_pc/contact/contactInfo.py b/app/ui_pc/contact/contactInfo.py
index 1d1b40b..2fe26b4 100644
--- a/app/ui_pc/contact/contactInfo.py
+++ b/app/ui_pc/contact/contactInfo.py
@@ -1,12 +1,13 @@
from PyQt5.QtCore import pyqtSignal, QUrl, QThread
from PyQt5.QtGui import QDesktopServices
-from PyQt5.QtWidgets import QWidget, QMenu, QAction, QToolButton, QMessageBox
+from PyQt5.QtWidgets import QWidget, QMenu, QAction, QToolButton, QMessageBox, QDialog
from app.DataBase.output_pc import Output
from app.ui_pc.Icon import Icon
from .contactInfoUi import Ui_Form
from .userinfo import userinfo
from ...person_pc import ContactPC
+from .export_dialog import ExportDialog
class ContactInfo(QWidget, Ui_Form):
@@ -17,7 +18,7 @@ class ContactInfo(QWidget, Ui_Form):
def __init__(self, contact, parent=None):
super(ContactInfo, self).__init__(parent)
self.setupUi(self)
- self.contact:ContactPC = contact
+ self.contact: ContactPC = contact
self.view_userinfo = userinfo.UserinfoController(self.contact)
self.btn_back.clicked.connect(self.back)
self.init_ui()
@@ -116,14 +117,22 @@ class ContactInfo(QWidget, Ui_Form):
return
self.outputThread = Output(self.Me, self.contact.wxid)
elif self.sender() == self.toCSVAct:
- self.outputThread = Output(self.contact, type_=Output.CSV)
+ # self.outputThread = Output(self.contact, type_=Output.CSV)
+ dialog = ExportDialog(self.contact,title='选择导出的消息类型', file_type='csv', parent=self)
+ result = dialog.exec_() # 使用exec_()获取用户的操作结果
elif self.sender() == self.toHtmlAct:
- self.outputThread = Output(self.contact, type_=Output.HTML)
+ dialog = ExportDialog(self.contact,title='选择导出的消息类型', file_type='html', parent=self)
+ result = dialog.exec_() # 使用exec_()获取用户的操作结果
+ # if result == QDialog.Accepted:
+ # self.result_label.setText("用户点击了导出按钮")
+ # else:
+ # self.result_label.setText("用户点击了取消按钮")
+ # self.outputThread = Output(self.contact, type_=Output.HTML)
- self.outputThread.progressSignal.connect(self.output_progress)
- self.outputThread.rangeSignal.connect(self.set_progressBar_range)
- self.outputThread.okSignal.connect(self.hide_progress_bar)
- self.outputThread.start()
+ # self.outputThread.progressSignal.connect(self.output_progress)
+ # self.outputThread.rangeSignal.connect(self.set_progressBar_range)
+ # self.outputThread.okSignal.connect(self.hide_progress_bar)
+ # self.outputThread.start()
def hide_progress_bar(self, int):
reply = QMessageBox(self)
diff --git a/app/ui_pc/contact/export_dialog.py b/app/ui_pc/contact/export_dialog.py
new file mode 100644
index 0000000..5365b36
--- /dev/null
+++ b/app/ui_pc/contact/export_dialog.py
@@ -0,0 +1,92 @@
+from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLayout, QCheckBox, QHBoxLayout, \
+ QProgressBar, QLabel, QMessageBox
+
+from app.DataBase.output_pc import Output
+
+types = {
+ '文本': 1,
+ '图片': 3,
+ '视频': 43,
+ '表情包': 47,
+ '拍一拍等系统消息': 10000
+}
+
+
+class ExportDialog(QDialog):
+ def __init__(self, contact=None, title="选择导出的类型", file_type="csv", parent=None):
+ super(ExportDialog, self).__init__(parent)
+
+ self.contact = contact
+ if file_type == 'html':
+ self.export_type = Output.HTML
+ self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True,
+ '拍一拍等系统消息': True} # 定义导出的数据类型,默认全部选择
+ elif file_type == 'csv':
+ self.export_type = Output.CSV
+ self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True} # 定义导出的数据类型,默认全部选择
+ else:
+ self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True} # 定义导出的数据类型,默认全部选择
+ self.setWindowTitle(title)
+ layout = QVBoxLayout(self)
+ self.resize(400, 300)
+ self.worker = None # 导出线程
+ self.progress_bar = QProgressBar(self)
+ self.progress_label = QLabel(self)
+ for export_type, default_state in self.export_choices.items():
+ checkbox = QCheckBox(export_type)
+ checkbox.setChecked(default_state)
+ layout.addWidget(checkbox)
+ layout.addWidget(self.progress_bar)
+ layout.addWidget(self.progress_label)
+ hlayout = QHBoxLayout(self)
+ self.export_button = QPushButton("导出")
+ self.export_button.clicked.connect(self.export_data)
+ hlayout.addWidget(self.export_button)
+
+ self.cancel_button = QPushButton("取消")
+ self.cancel_button.clicked.connect(self.reject) # 使用reject关闭对话框
+ hlayout.addWidget(self.cancel_button)
+ layout.addLayout(hlayout)
+ self.setLayout(layout)
+
+ def export_data(self):
+ self.export_button.setEnabled(False)
+ self.cancel_button.setEnabled(False)
+ # 在这里获取用户选择的导出数据类型
+ selected_types = {types[export_type]: checkbox.isChecked() for export_type, checkbox in
+ zip(self.export_choices.keys(), self.findChildren(QCheckBox))}
+
+ # 在这里根据用户选择的数据类型执行导出操作
+ print("选择的数据类型:", selected_types)
+ self.worker = Output(self.contact, type_=self.export_type,message_types=selected_types)
+ self.worker.progressSignal.connect(self.update_progress)
+ self.worker.okSignal.connect(self.export_finished)
+ self.worker.start()
+ # self.accept() # 使用accept关闭对话框
+ def export_finished(self):
+ self.export_button.setEnabled(True)
+ self.cancel_button.setEnabled(True)
+ reply = QMessageBox(self)
+ reply.setIcon(QMessageBox.Information)
+ reply.setWindowTitle('OK')
+ reply.setText(f"导出聊天记录成功\n在./data/目录下(跟exe文件在一起)")
+ reply.addButton("确认", QMessageBox.AcceptRole)
+ reply.addButton("取消", QMessageBox.RejectRole)
+ api = reply.exec_()
+ self.accept()
+ def update_progress(self, progress_percentage):
+ self.progress_bar.setValue(progress_percentage)
+ self.progress_label.setText(f"导出进度: {progress_percentage}%")
+
+
+if __name__ == '__main__':
+ import sys
+
+ app = QApplication(sys.argv)
+ dialog = ExportDialog()
+ result = dialog.exec_() # 使用exec_()获取用户的操作结果
+ if result == QDialog.Accepted:
+ print("用户点击了导出按钮")
+ else:
+ print("用户点击了取消按钮")
+ sys.exit(app.exec_())
diff --git a/readme.md b/readme.md
index 5380288..d911f1b 100644
--- a/readme.md
+++ b/readme.md
@@ -35,8 +35,8 @@
## 🍉功能
-- 🔒️🔑🔓️手机本地微信数据库🐶
-- 🔒️🔑🔓️PC端本地微信数据库🐶
+- 🔒️🔑🔓️手机本地微信数据库
+- 🔒️🔑🔓️PC端本地微信数据库
- 还原微信聊天界面
- 🗨文本✅
- 🏝图片✅