From 55425daa44e7091d6244e45038c1ea8443cb5487 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Tue, 21 Nov 2023 21:48:54 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E8=81=8A=E5=A4=A9=E5=9B=BE=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 185 ++++++++++++++---------- app/components/bubble_message.py | 22 ++- app/decrypt/dat2pic.py | 30 ++-- app/ui_pc/tool/pc_decrypt/pc_decrypt.py | 2 +- app/util/path.py | 10 +- 5 files changed, 143 insertions(+), 106 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 4978b11..e734d87 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,15 +4,12 @@ - @@ -674,7 +683,8 @@ - @@ -693,9 +703,24 @@ file://$PROJECT_DIR$/app/decrypt/decrypt.py - 103 + 107 + + file://$PROJECT_DIR$/app/person.py + 100 + + + file://$PROJECT_DIR$/app/person.py + 98 + + + file://$PROJECT_DIR$/app/person.py + 99 + diff --git a/app/components/bubble_message.py b/app/components/bubble_message.py index fc26e4b..f0bbe55 100644 --- a/app/components/bubble_message.py +++ b/app/components/bubble_message.py @@ -104,25 +104,35 @@ class OpenImageThread(QThread): class ImageMessage(QLabel): - def __init__(self, image, image_link='', max_width=480, max_height=720, parent=None): + def __init__(self, image, image_link='', max_width=480, max_height=240, parent=None): """ param:image 图像路径或者QPixmap对象 param:image_link='' 点击图像打开的文件路径 """ super().__init__(parent) self.image = QLabel(self) - + self.max_width = max_width + self.max_height = max_height if isinstance(image, str): - self.setPixmap(QPixmap(image)) + pixmap = QPixmap(image) self.image_path = image elif isinstance(image, QPixmap): - self.setPixmap(image) + pixmap = image + self.set_image(pixmap) if image_link: self.image_path = image_link - self.setMaximumWidth(max_width) - self.setMaximumHeight(max_height) + self.setMaximumWidth(self.max_width) + self.setMaximumHeight(self.max_height) # self.setScaledContents(True) + def set_image(self, pixmap): + # 计算调整后的大小 + adjusted_width = min(pixmap.width(), self.max_width) + adjusted_height = min(pixmap.height(), self.max_height) + self.setPixmap(pixmap.scaled(adjusted_width, adjusted_height, Qt.KeepAspectRatio)) + # 调整QLabel的大小以适应图片的宽高,但不超过最大宽高 + self.setFixedSize(adjusted_width, adjusted_height) + def mousePressEvent(self, event): if event.buttons() == Qt.LeftButton: # 左键按下 print('打开图像', self.image_path) diff --git a/app/decrypt/dat2pic.py b/app/decrypt/dat2pic.py index f66abd6..04e2be9 100644 --- a/app/decrypt/dat2pic.py +++ b/app/decrypt/dat2pic.py @@ -1,5 +1,5 @@ - import os + # 图片字节头信息, # [0][1]为jpg头信息, # [2][3]为png头信息, @@ -21,7 +21,7 @@ def get_code(file_path): return -1, -1 dat_file = open(file_path, "rb") dat_read = dat_file.read(2) - print(dat_read) + # print(dat_read) head_index = 0 while head_index < len(pic_head): # 使用第一个头信息字节来计算加密码 @@ -33,7 +33,7 @@ def get_code(file_path): dat_file.close() return head_index, code head_index = head_index + 1 - + dat_file.close() print("not jpg, png, gif") return -1, -1 @@ -49,26 +49,22 @@ def decode_dat(file_path, out_path): if decode_code == -1: return if file_type == 1: - pic_name = file_path.split("\\")[-1][:-4] + ".jpg" + pic_name = os.path.basename(file_path)[:-4] + ".jpg" elif file_type == 3: pic_name = file_path[:-4] + ".png" elif file_type == 5: pic_name = file_path[:-4] + ".gif" else: pic_name = file_path[:-4] + ".jpg" - - dat_file = open(file_path, "rb") file_outpath = os.path.join(out_path, pic_name) - print(pic_name) - print(file_outpath) - pic_write = open(file_outpath, "wb") - for dat_data in dat_file: - for dat_byte in dat_data: - pic_data = dat_byte ^ decode_code - pic_write.write(bytes([pic_data])) - print(pic_name + "完成") - dat_file.close() - pic_write.close() + with open(file_path, 'rb') as file_in: + data = file_in.read() + # 对数据进行异或加密/解密 + encrypted_data = bytes([byte ^ decode_code for byte in data]) + with open(file_outpath, 'wb') as file_out: + file_out.write(encrypted_data) + print(file_path, '->', file_outpath) + return file_outpath def find_datfile(dir_path, out_path): @@ -88,4 +84,4 @@ if __name__ == "__main__": outpath = "D:\\test" if not os.path.exists(outpath): os.mkdir(outpath) - find_datfile(path, outpath) \ No newline at end of file + find_datfile(path, outpath) diff --git a/app/ui_pc/tool/pc_decrypt/pc_decrypt.py b/app/ui_pc/tool/pc_decrypt/pc_decrypt.py index 99cbb33..1af9bd0 100644 --- a/app/ui_pc/tool/pc_decrypt/pc_decrypt.py +++ b/app/ui_pc/tool/pc_decrypt/pc_decrypt.py @@ -72,7 +72,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog): def select_db_dir(self): directory = QtWidgets.QFileDialog.getExistingDirectory( - self, "选取微信安装目录——能看到All Users文件夹", + self, "选取微信安装目录——能看到Msg文件夹", "C:/") # 起始路径 db_dir = os.path.join(directory, 'Msg') if not os.path.exists(db_dir): diff --git a/app/util/path.py b/app/util/path.py index ab32b28..3fe80c5 100644 --- a/app/util/path.py +++ b/app/util/path.py @@ -1,11 +1,17 @@ import os +from app.decrypt import dat2pic from app.person import MePC +if not os.path.exists('./data/image'): + os.mkdir('./data/image') + def get_abs_path(path): - return os.path.join(os.getcwd(), 'app/data/icons/404.png') + # return os.path.join(os.getcwd(), 'app/data/icons/404.png') if path: - return os.path.join(MePC().wx_dir, path) + # if os.path.exists(os.path.join()) + output_path = dat2pic.decode_dat(os.path.join(MePC().wx_dir, path), './data/image') + return output_path else: return os.path.join(os.getcwd(), 'app/data/icons/404.png') From 12b14316ce7fe54d1930096561803559dd8deb3f Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Tue, 21 Nov 2023 22:23:23 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AF=BC=E5=87=BAHTML?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 47 +- app/DataBase/msg.py | 12 +- app/DataBase/output_pc.py | 232 + app/data/html/0.html | 290 -- app/data/html/1.html | 707 --- app/data/html/2.html | 1228 ----- app/data/html/3.html | 652 --- app/data/html/4.html | 1232 ----- app/data/html/5.html | 7567 ------------------------------ app/data/html/6.html | 1344 ------ app/data/html/index.html | 252 - app/person.py | 3 + app/ui_pc/chat/chat_info.py | 1 + app/ui_pc/contact/contactInfo.py | 13 +- 14 files changed, 279 insertions(+), 13301 deletions(-) delete mode 100644 app/data/html/0.html delete mode 100644 app/data/html/1.html delete mode 100644 app/data/html/2.html delete mode 100644 app/data/html/3.html delete mode 100644 app/data/html/4.html delete mode 100644 app/data/html/5.html delete mode 100644 app/data/html/6.html delete mode 100644 app/data/html/index.html diff --git a/.idea/workspace.xml b/.idea/workspace.xml index e734d87..9a2cc1b 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,12 +4,21 @@ - @@ -684,7 +692,8 @@ - @@ -708,17 +717,17 @@ file://$PROJECT_DIR$/app/person.py - 100 + 103 file://$PROJECT_DIR$/app/person.py - 98 + 101 file://$PROJECT_DIR$/app/person.py - 99 + 102 diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index e15b142..3232526 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -49,10 +49,14 @@ def get_messages(username_): ''' result = [] for cur in cursor: - cur.execute(sql, [username_]) - result_ = cur.fetchall() - # print(len(result)) - result += result_ + try: + lock.acquire(True) + cur.execute(sql, [username_]) + result_ = cur.fetchall() + # print(len(result)) + result += result_ + finally: + lock.release() result.sort(key=lambda x: x[5]) return result diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py index c1e3940..b46f312 100644 --- a/app/DataBase/output_pc.py +++ b/app/DataBase/output_pc.py @@ -5,6 +5,7 @@ from PyQt5.QtCore import pyqtSignal, QThread from . import msg from ..log import log +from ..person import MePC if not os.path.exists('./data/聊天记录'): os.mkdir('./data/聊天记录') @@ -24,6 +25,7 @@ class Output(QThread): def __init__(self, contact, parent=None, type_=DOCX): super().__init__(parent) + self.last_timestamp = 0 self.sec = 2 # 默认1000秒 self.contact = contact self.ta_username = contact.wxid @@ -51,9 +53,239 @@ class Output(QThread): df.to_csv(filename, encoding='utf-8') self.okSignal.emit('ok') + def to_html(self): + origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}" + if not os.path.exists(origin_docx_path): + os.mkdir(origin_docx_path) + messages = msg.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 = ''' + + + + + Title + + + +
+
+ ''' + 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')) + for message in messages: + type_ = message[2] + str_content = message[7] + str_time = message[8] + # print(type_, type(type_)) + is_send = message[4] + avatar = MePC().avatar_path if is_send else self.contact.avatar_path + timestamp = message[5] + if type_ == 1: + if self.is_5_min(timestamp): + f.write( + f''' +
{str_time}
+ ''' + ) + if is_send: + f.write( + f''' +
+
{str_content}
+
+ +
+
+ ''' + ) + else: + f.write( + f''' +
+
+ +
+
{str_content} +
+
+ ''' + ) + html_end = ''' + +
+
+ + + ''' + f.write(html_end) + f.close() + 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 run(self): if self.output_type == self.DOCX: return elif self.output_type == self.CSV: # print("线程导出csv") self.to_csv(self.ta_username, "path") + elif self.output_type == self.HTML: + self.to_html() diff --git a/app/data/html/0.html b/app/data/html/0.html deleted file mode 100644 index d377192..0000000 --- a/app/data/html/0.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - - - - - - - 年度聊天报告 - - - - - - - - - - - - - - -
- - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

- 未眠人 -

-

- 二零二二年度报告 -

- -
-
- - - - - -
-
- avatar -
-
-
-

- 小学生 -

-
-
-
-

- 我们第一次聊天发生在 -

-

- 2023-09-18 20:39:08 -

-
- - 距今已有 - - - 626 天 - - - 6 时 - - - 26 分 - - - 26 秒 - -
-
-
-
-
-
-
-
- 进入 -
-
-
-
-
-
-
-
- - - - - - - \ No newline at end of file diff --git a/app/data/html/1.html b/app/data/html/1.html deleted file mode 100644 index 9e2e3a0..0000000 --- a/app/data/html/1.html +++ /dev/null @@ -1,707 +0,0 @@ - - - - - - - - - - - 年度聊天报告 - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Norcy
-
-
-
-
进入
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

过去的日子里

-

我们一共发送了 - 91835条消息

-

总计 - 388161

-

 

-

- 我们的聊天似乎没有规律

-

- 八月份我们一共发送了11629条信息

-

- 对你的话说不完

-

 

-

但 - 六月份只有2139条信息

-

 大概,我们有时候也想静静

-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/app/data/html/2.html b/app/data/html/2.html deleted file mode 100644 index df93a6f..0000000 --- a/app/data/html/2.html +++ /dev/null @@ -1,1228 +0,0 @@ - - - - - - - - - - - 年度聊天报告 - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

二零二二

-

你说的最多的是

-
-
-
-
-
-
-
- - - - -
-
- 5 - 9 - 5 - -
-
-
-
    -
  • -
    -
    我 - 喜欢这个衣服 -
    -
    -
    - 它就是好看啊
    -
    -
  • -
  • -
    -
    我还是 - 喜欢大城市 -
    -
    -
    - 很繁华
    -
    -
  • -
  • -
    -
    也不知道你为啥不 - 喜欢 -
    -
    -
    - 也没有吧
    -
    -
  • -
  • -
    -
    但是我 - 喜欢火锅 -
    -
    -
    - 吃,使劲吃
    -
    -
  • -
-
-
-
-
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/app/data/html/3.html b/app/data/html/3.html deleted file mode 100644 index 1d17efd..0000000 --- a/app/data/html/3.html +++ /dev/null @@ -1,652 +0,0 @@ - - - - - - - - - - - 年度聊天报告 - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
-

在TA的音乐品味中 

-

也藏着高冷的一面 

-

这首有些小众的 

-

- 《夏天的味道(Cover 石头剪刀布)》

-

在今年TA一共听了 - 15次 

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-

 

-

2022-03-12 - 04:36:10 

-

- 这么晚了你们还在聊天 -

-

这天一定有你们 - 难忘的回忆 吧 -

-
-

 

-

你们都是 - 夜猫子 

-

- 凌晨01:00 -

-

你们共发送了 - 8517 条信息 -

- -
- -
- -
-

2022-03-12 04:36:10 

- -
- - - - - -
-
- avatar: -
-
-
-

- : 无语了也不知道我这大晚上干嘛不睡觉,生生接住了这波狗粮

-
-
- - - - - - -
-
-

- 快睡觉 :

-
-
-
- avatar: -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - -
-
-
- - - \ No newline at end of file diff --git a/app/data/html/4.html b/app/data/html/4.html deleted file mode 100644 index 472bb91..0000000 --- a/app/data/html/4.html +++ /dev/null @@ -1,1232 +0,0 @@ - - - - - - - - - - - 年度聊天报告 - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
-

2018

-

TA在网易云音乐听到的最多的歌词是

-
-
-
-
-
-
-
- - - - - - -
-
- 7 - 6 - 5 - -
-
-
-
    -
  • -
    -
    - 天使在人间是该藏好翅膀 -
    -
    -
    - Tank《专属天使》
    -
    -
  • -
  • -
    -
    你是魔鬼中的 - 天使, 所以送我心碎的方式 -
    -
    -
    - 田馥甄《魔鬼中的天使》
    -
    -
  • -
  • -
    -
    请 - 天使来唱歌, 当我很不快乐 -
    -
    -
    - S.H.E《天使在唱歌》
    -
    -
  • -
  • -
    -
    谁人又为 - 天使忧愁 -
    -
    -
    - 梁汉文《七友》
    -
    -
  • -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

- 5月1日

-

大概是很特别的一天

-

这一天里

-

你们的对话充满了 - 积极情感

-

从早上9点 到晚上12点

-

你们共发送了 - 2294 - 条信息 -

-

信息数量 - 全年最高 -

-
-
-
- -
-
-
-
-
- - - - - -
-
-
- - - \ No newline at end of file diff --git a/app/data/html/5.html b/app/data/html/5.html deleted file mode 100644 index e3a95ff..0000000 --- a/app/data/html/5.html +++ /dev/null @@ -1,7567 +0,0 @@ - - - - - - - - - - - 年度聊天报告 - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

1月29日

-

这一天Ta走了

-

- 17498

-

 在你好友排名 - 第一

-

 

-

你知道

-

- 这一天Ta去哪了吗?

-
-
-
-
-
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/app/data/html/6.html b/app/data/html/6.html deleted file mode 100644 index 1e42b5f..0000000 --- a/app/data/html/6.html +++ /dev/null @@ -1,1344 +0,0 @@ - - - - - - - - - - - 年度聊天报告 - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -

这一年

-

我们有 - 230天在聊天

-

有你在的日子里

-

都很有 - 意义

-
-

这一年

-

一共发送了 - 3454个表情包

-

Ta最常用的表情包是 -

- -

一共 - 184次 -

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/app/data/html/index.html b/app/data/html/index.html deleted file mode 100644 index dfb2b00..0000000 --- a/app/data/html/index.html +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - - - - - - - - -
-
-
    -
  •  
  • -
  •  
  • -
  •  
  • -
  •  
  • -
  •  
  • -
  •  
  • -
  •  
  • -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
- - - - \ No newline at end of file diff --git a/app/person.py b/app/person.py index e52aa89..1e67791 100644 --- a/app/person.py +++ b/app/person.py @@ -55,6 +55,7 @@ def singleton(cls): class MePC: def __init__(self): self.avatar = QPixmap(Icon.Default_avatar_path) + self.avatar_path = 'D:\Project\Python\WeChatMsg\\app\data\icons\default_avatar.svg' self.wxid = '' self.wx_dir = '' self.name = '' @@ -82,6 +83,7 @@ class ContactPC: self.smallHeadImgUrl = contact_info.get('smallHeadImgUrl') self.smallHeadImgBLOG = b'' self.avatar = QPixmap() + self.avatar_path = 'D:\Project\Python\WeChatMsg\\app\data\icons\default_avatar.svg' def set_avatar(self, img_bytes): if not img_bytes: @@ -91,6 +93,7 @@ class ContactPC: self.avatar.loadFromData(img_bytes, format='PNG') else: self.avatar.loadFromData(img_bytes, format='jfif') + self.avatar.scaled(60, 60, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) diff --git a/app/ui_pc/chat/chat_info.py b/app/ui_pc/chat/chat_info.py index d5a7958..dd2bf1e 100644 --- a/app/ui_pc/chat/chat_info.py +++ b/app/ui_pc/chat/chat_info.py @@ -100,6 +100,7 @@ class ChatInfo(QWidget): ) self.chat_window.add_message_item(bubble_message, 0) elif type_ == 3: + return if self.is_5_min(timestamp): time_message = Notice(self.last_str_time) self.last_str_time = str_time diff --git a/app/ui_pc/contact/contactInfo.py b/app/ui_pc/contact/contactInfo.py index 107977c..afc7e36 100644 --- a/app/ui_pc/contact/contactInfo.py +++ b/app/ui_pc/contact/contactInfo.py @@ -114,12 +114,13 @@ class ContactInfo(QWidget, Ui_Form): self.outputThread = Output(self.contact, type_=Output.CSV) print('导出csv') elif self.sender() == self.toHtmlAct: - print('功能暂未实现') - QMessageBox.warning(self, - "别急别急", - "马上就实现该功能" - ) - return + self.outputThread = Output(self.contact, type_=Output.HTML) + # print('功能暂未实现') + # QMessageBox.warning(self, + # "别急别急", + # "马上就实现该功能" + # ) + # return self.outputThread.progressSignal.connect(self.output_progress) self.outputThread.rangeSignal.connect(self.set_progressBar_range) self.outputThread.okSignal.connect(self.hide_progress_bar) From 3414d74bed0445d4eea76a11ef7083dbc6b64577 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Wed, 22 Nov 2023 00:22:50 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8DHTML=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 31 +- app/DataBase/msg.py | 2 +- app/DataBase/output_pc.py | 879 +++++++++++++++++++++++-------- app/ui_pc/chat/chat_info.py | 2 +- app/ui_pc/contact/contactInfo.py | 8 +- 5 files changed, 676 insertions(+), 246 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 9a2cc1b..c914993 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,19 +4,10 @@ - @@ -693,7 +683,8 @@ - diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index 3232526..dd61e0d 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -67,7 +67,7 @@ def get_message_by_num(username_, local_id): from MSG where StrTalker = ? and localId < ? order by CreateTime desc - limit 30 + limit 10 ''' result = [] try: diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py index b46f312..5f445a0 100644 --- a/app/DataBase/output_pc.py +++ b/app/DataBase/output_pc.py @@ -54,224 +54,7 @@ class Output(QThread): self.okSignal.emit('ok') def to_html(self): - origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}" - if not os.path.exists(origin_docx_path): - os.mkdir(origin_docx_path) - messages = msg.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 = ''' - - - - - Title - - - -
-
- ''' - 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')) - for message in messages: - type_ = message[2] - str_content = message[7] - str_time = message[8] - # print(type_, type(type_)) - is_send = message[4] - avatar = MePC().avatar_path if is_send else self.contact.avatar_path - timestamp = message[5] - if type_ == 1: - if self.is_5_min(timestamp): - f.write( - f''' -
{str_time}
- ''' - ) - if is_send: - f.write( - f''' -
-
{str_content}
-
- -
-
- ''' - ) - else: - f.write( - f''' -
-
- -
-
{str_content} -
-
- ''' - ) - html_end = ''' - -
-
- - - ''' - f.write(html_end) - f.close() self.okSignal.emit('ok') def is_5_min(self, timestamp): @@ -281,6 +64,9 @@ class Output(QThread): return True return False + def progress(self, value): + self.progressSignal.emit(value) + def run(self): if self.output_type == self.DOCX: return @@ -288,4 +74,661 @@ class Output(QThread): # print("线程导出csv") self.to_csv(self.ta_username, "path") elif self.output_type == self.HTML: - self.to_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) + + +class ChildThread(QThread): + """ + 子线程,用于导出部分聊天记录 + """ + progressSignal = pyqtSignal(int) + rangeSignal = pyqtSignal(int) + okSignal = pyqtSignal(int) + i = 1 + CSV = 0 + DOCX = 1 + HTML = 2 + + def __init__(self, contact, parent=None, type_=DOCX): + super().__init__(parent) + self.contact = contact + 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): + return + + def image(self, doc, isSend, Type, content, imgPath): + return + + def emoji(self, doc, isSend, content, imgPath): + return + + def wx_file(self, doc, isSend, content, status): + return + + def retract_message(self, doc, isSend, content, status): + return + + def reply(self, doc, isSend, content, status): + return + + def pat_a_pat(self, doc, isSend, content, status): + return + + def video(self, doc, isSend, content, status, img_path): + return + + def to_html(self): + origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}" + if not os.path.exists(origin_docx_path): + os.mkdir(origin_docx_path) + messages = msg.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 = ''' + + + + + Title + + + +
+
+ ''' + 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)) + 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] + avatar = MePC().avatar_path if is_send else self.contact.avatar_path + timestamp = message[5] + self.progressSignal.emit(index) + if type_ == 1: + if self.is_5_min(timestamp): + f.write( + f''' +
{str_time}
+ ''' + ) + if is_send: + f.write( + f''' +
+
{str_content}
+
+ +
+
+ ''' + ) + else: + f.write( + f''' +
+
+ +
+
{str_content} +
+
+ ''' + ) + html_end = ''' + +
+
+ + + + ''' + f.write(html_end) + f.close() + 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): + os.mkdir(origin_docx_path) + messages = msg.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 = ''' + + + + + + Chat Records + + + +
+
+
昨天 12:35
+
你已添加了凡繁烦,现在可以开始聊天了。
+
+
+ +
+
您好,我在武汉,你可以直接送过来吗,我有时间的话,可以自己过去拿
!!!
123 +
+
+ +
+
hello
你好呀
+
+ +
+
+
+ 昨天 13:15 +
+ +
+ +
+
+
+ +
+ +
+ + +
+ + + +''' + f.write(html_end) + f.close() + self.okSignal.emit(1) + + def run(self): + if self.output_type == self.DOCX: + return + elif self.output_type == self.CSV: + return + elif self.output_type == self.HTML: + self.to_html_() diff --git a/app/ui_pc/chat/chat_info.py b/app/ui_pc/chat/chat_info.py index dd2bf1e..8ea9eaa 100644 --- a/app/ui_pc/chat/chat_info.py +++ b/app/ui_pc/chat/chat_info.py @@ -100,7 +100,7 @@ class ChatInfo(QWidget): ) self.chat_window.add_message_item(bubble_message, 0) elif type_ == 3: - return + # return if self.is_5_min(timestamp): time_message = Notice(self.last_str_time) self.last_str_time = str_time diff --git a/app/ui_pc/contact/contactInfo.py b/app/ui_pc/contact/contactInfo.py index afc7e36..402a34b 100644 --- a/app/ui_pc/contact/contactInfo.py +++ b/app/ui_pc/contact/contactInfo.py @@ -115,12 +115,7 @@ class ContactInfo(QWidget, Ui_Form): print('导出csv') elif self.sender() == self.toHtmlAct: self.outputThread = Output(self.contact, type_=Output.HTML) - # print('功能暂未实现') - # QMessageBox.warning(self, - # "别急别急", - # "马上就实现该功能" - # ) - # return + self.outputThread.progressSignal.connect(self.output_progress) self.outputThread.rangeSignal.connect(self.set_progressBar_range) self.outputThread.okSignal.connect(self.hide_progress_bar) @@ -140,5 +135,6 @@ class ContactInfo(QWidget, Ui_Form): self.view_userinfo.progressBar.setProperty('value', value) def set_progressBar_range(self, value): + print('进度条范围', value) self.view_userinfo.progressBar.setVisible(True) self.view_userinfo.progressBar.setRange(0, value) From af652a5adfb01af3b1889a4600d9c03d79cdbee4 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Wed, 22 Nov 2023 00:25:50 +0800 Subject: [PATCH 4/6] update readme --- .idea/workspace.xml | 28 ++++++++++++---------------- readme.md | 3 +++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index c914993..9d6b5b0 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,12 +4,8 @@ - @@ -684,7 +679,8 @@ - diff --git a/readme.md b/readme.md index b42b8a9..d0d25c1 100644 --- a/readme.md +++ b/readme.md @@ -22,7 +22,10 @@ - 安卓 or 苹果都可以哦 - 破解💻PC端微信数据库 - 还原微信聊天界面 + - 文本 + - 图片 - 导出聊天记录 + - HTML(文本) - Word文档 - CSV文档 - 分析聊天数据,做成可视化年报 From 4bd0e1aac536307d7a75c270cc8baecba3faedd5 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Wed, 22 Nov 2023 21:12:14 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E8=BF=87=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 28 ++++++++------- app/data/icons/loading.svg | 1 + app/decrypt/dat2pic.py | 2 ++ app/ui_pc/chat/chat_info.py | 1 - app/ui_pc/mainview.py | 71 +++++++++++++++++++------------------ main_pc.py | 20 +++++++---- 6 files changed, 70 insertions(+), 53 deletions(-) create mode 100644 app/data/icons/loading.svg diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 9d6b5b0..2da2981 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,8 +4,12 @@ @@ -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