From cb571e937d98a2f9ab9d427ae2da0eedc0b962d8 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Fri, 24 Nov 2023 23:49:37 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BA=E8=A1=A8?= =?UTF-8?q?=E6=83=85=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/workspace.xml | 91 +++++++++++++++++--------------- app/DataBase/hard_link.py | 2 +- app/components/bubble_message.py | 6 ++- app/decrypt/decrypt.py | 11 ++-- app/ui_pc/chat/chat_info.py | 15 ++++++ app/{decrypt => util}/dat2pic.py | 0 app/util/emoji.py | 91 ++++++++++++++++++++++++++++++++ app/util/path.py | 2 +- main_pc.py | 4 +- 9 files changed, 164 insertions(+), 58 deletions(-) rename app/{decrypt => util}/dat2pic.py (100%) create mode 100644 app/util/emoji.py diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 4d06ea9..46daa98 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -4,13 +4,16 @@ - @@ -674,7 +676,8 @@ - diff --git a/app/DataBase/hard_link.py b/app/DataBase/hard_link.py index 1d0d367..18e8e5c 100644 --- a/app/DataBase/hard_link.py +++ b/app/DataBase/hard_link.py @@ -54,7 +54,7 @@ def get_md5_from_xml(content): def get_image(content, thumb=False): md5 = get_md5_from_xml(content) # md5 = 'bc37a58c32cb203ee9ac587b068e5853' - md5 = '41895664fc5a77878e2155fc96209a19' + # md5 = '41895664fc5a77878e2155fc96209a19' result = get_image_by_md5(binascii.unhexlify(md5)) if result: # print(result) diff --git a/app/components/bubble_message.py b/app/components/bubble_message.py index 3f8c18f..6b3c3a4 100644 --- a/app/components/bubble_message.py +++ b/app/components/bubble_message.py @@ -105,7 +105,7 @@ class OpenImageThread(QThread): class ImageMessage(QLabel): - def __init__(self, image, image_link='', max_width=480, max_height=240, parent=None): + def __init__(self, image, is_send, image_link='', max_width=480, max_height=240, parent=None): """ param:image 图像路径或者QPixmap对象 param:image_link='' 点击图像打开的文件路径 @@ -124,6 +124,8 @@ class ImageMessage(QLabel): self.image_path = image_link self.setMaximumWidth(self.max_width) self.setMaximumHeight(self.max_height) + if is_send: + self.setAlignment(Qt.AlignCenter | Qt.AlignRight) # self.setScaledContents(True) def set_image(self, pixmap): @@ -161,7 +163,7 @@ class BubbleMessage(QWidget): self.message = TextMessage(str_content, is_send) # self.message.setMaximumWidth(int(self.width() * 0.6)) elif Type == MessageType.Image: - self.message = ImageMessage(str_content) + self.message = ImageMessage(str_content, is_send) else: raise ValueError("未知的消息类型") diff --git a/app/decrypt/decrypt.py b/app/decrypt/decrypt.py index 8dac616..cbc113b 100644 --- a/app/decrypt/decrypt.py +++ b/app/decrypt/decrypt.py @@ -119,11 +119,6 @@ def batch_decrypt(key: str, db_path: Union[str, List[str]], out_path: str): if __name__ == '__main__': # 调用 decrypt 函数,并传入参数 key = "2aafab10af7940328bb92ac9d2a8ab5fc07a685646b14f2e9ae6948a7060c0fc" - db_path = "D:\Project\Python\PyWxDump\pywxdump\decrypted" - out_path = "test" - result = batch_decrypt(key, db_path, out_path) - for i in result: - if isinstance(i, str): - print(i) - else: - print(f'[+] "{i[1]}" -> "{i[2]}"') + db_path = "E:\86390\Documents\WeChat Files\wxid_27hqbq7vx5hf22\FileStorage\CustomEmotion\\71\\71CE49ED3CE9E57E43E07F802983BF45" + out_path = "./test/1.png" + print(decrypt(key, db_path, out_path)) diff --git a/app/ui_pc/chat/chat_info.py b/app/ui_pc/chat/chat_info.py index dd30c1e..20035e3 100644 --- a/app/ui_pc/chat/chat_info.py +++ b/app/ui_pc/chat/chat_info.py @@ -7,6 +7,7 @@ from app.DataBase import msg, hard_link from app.components.bubble_message import BubbleMessage, ChatWidget, Notice from app.person import MePC from app.util import get_abs_path +from app.util.emoji import get_emoji class ChatInfo(QWidget): @@ -113,6 +114,20 @@ class ChatInfo(QWidget): is_send ) self.chat_window.add_message_item(bubble_message, 0) + elif type_ == 47: + # return + if self.is_5_min(timestamp): + time_message = Notice(self.last_str_time) + self.last_str_time = str_time + self.chat_window.add_message_item(time_message, 0) + image_path = get_emoji(str_content, thumb=True) + bubble_message = BubbleMessage( + image_path, + avatar, + 3, + is_send + ) + self.chat_window.add_message_item(bubble_message, 0) except: print(message) traceback.print_exc() diff --git a/app/decrypt/dat2pic.py b/app/util/dat2pic.py similarity index 100% rename from app/decrypt/dat2pic.py rename to app/util/dat2pic.py diff --git a/app/util/emoji.py b/app/util/emoji.py new file mode 100644 index 0000000..47c0d97 --- /dev/null +++ b/app/util/emoji.py @@ -0,0 +1,91 @@ +import os +import xml.etree.ElementTree as ET + +import requests + +root_path = './data/emoji/' +if not os.path.exists('./data'): + os.mkdir('./data') +if not os.path.exists(root_path): + os.mkdir(root_path) + + +def get_image_format(header): + # 定义图片格式的 magic numbers + image_formats = { + b'\xFF\xD8\xFF': 'jpeg', + b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A': 'png', + b'\x47\x49\x46': 'gif', + b'\x42\x4D': 'bmp', + # 添加其他图片格式的 magic numbers + } + # 判断文件的图片格式 + for magic_number, image_format in image_formats.items(): + if header.startswith(magic_number): + return image_format + # 如果无法识别格式,返回 None + return None + + +def parser_xml(xml_string): + # Parse the XML string + root = ET.fromstring(xml_string) + emoji = root.find('./emoji') + # Accessing attributes of the 'emoji' element + fromusername = emoji.get('fromusername') + tousername = emoji.get('tousername') + md5 = emoji.get('md5') + cdnurl = emoji.get('cdnurl') + encrypturl = emoji.get('encrypturl') + thumburl = emoji.get('thumburl') + externurl = emoji.get('externurl') + width = emoji.get('width') + height = emoji.get('height') + return { + 'width': width, + 'height': height, + 'cdnurl': cdnurl, + 'thumburl': thumburl if thumburl else cdnurl, + 'md5': md5 + } + + +def download(url, output_dir, name, thumb=False): + resp = requests.get(url) + byte = resp.content + image_format = get_image_format(byte[:8]) + if image_format: + if thumb: + output_path = os.path.join(output_dir, 'th_' + name + '.' + image_format) + else: + output_path = os.path.join(output_dir, name + '.' + image_format) + else: + output_path = os.path.join(output_dir, name) + with open(output_path, 'wb') as f: + f.write(resp.content) + return output_path + + +def get_emoji(xml_string, thumb=True) -> str: + emoji_info = parser_xml(xml_string) + md5 = emoji_info['md5'] + image_format = ['.png', '.gif', '.jpeg'] + for f in image_format: + prefix = 'th_' if thumb else '' + file_path = os.path.join(root_path, prefix + md5 + f) + if os.path.exists(file_path): + return file_path + url = emoji_info['thumburl'] if thumb else emoji_info['cdnurl'] + print("下载表情包ing:", url) + return download(url, root_path, md5, thumb) + + +if __name__ == '__main__': + xml_string = ' ' + res1 = parser_xml(xml_string) + print(res1, res1['md5']) + # download(res1['cdnurl'], "./data/emoji/", res1['md5']) + # download(res1['thumburl'], "./data/emoji/", res1['md5'], True) + print(get_emoji(xml_string, True)) + print(get_emoji(xml_string, False)) +# http://vweixinf.tc.qq.com/110/20403/stodownload?m=3a4d439aba02dce4834b2c54e9f15597&filekey=3043020101042f302d02016e0402534804203361346434333961626130326463653438333462326335346539663135353937020213f0040d00000004627466730000000131&hy=SH&storeid=323032313037323030373236313130303039653236646365316535316534383236386234306230303030303036653033303034666233&ef=3&bizid=1022 diff --git a/app/util/path.py b/app/util/path.py index 52a290c..537c78e 100644 --- a/app/util/path.py +++ b/app/util/path.py @@ -1,7 +1,7 @@ import os -from app.decrypt import dat2pic from app.person_pc import MePC +from app.util import dat2pic if not os.path.exists('./data/image'): os.mkdir('./data/image') diff --git a/main_pc.py b/main_pc.py index 54fe820..1211d61 100644 --- a/main_pc.py +++ b/main_pc.py @@ -15,7 +15,7 @@ class ViewController(QWidget): def __init__(self): super().__init__() self.setWindowTitle('解密') - self.setWindowIcon(QIcon('./app/data/icons/logo.svg')) + self.setWindowIcon(QIcon(':/icons/icons/logo.svg')) self.viewMainWIndow = None self.viewDecrypt = None # 创建加载动画 @@ -46,7 +46,7 @@ class ViewController(QWidget): # print(username) self.viewMainWIndow.username = username # self.viewMainWIn.exitSignal.connect(self.loadDecryptView) # 不需要回到登录界面可以省略 - + self.viewMainWIndow.show() end = time.time() print('ok', end - start)