From ca491c3b3a73d5f1ca7c3fbf1684ed8899dd854f Mon Sep 17 00:00:00 2001 From: STDquantum <405720329@qq.com> Date: Fri, 5 Jan 2024 19:16:54 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=8E=BB=E9=99=A4parseBytes=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E5=AD=97=E6=AE=B5=E5=90=8D=E7=A7=B0=EF=BC=8C=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E7=BB=93=E6=9E=9C=E6=9B=B4=E7=AE=80=E6=B4=81=EF=BC=9B?= =?UTF-8?q?=E6=8A=8A=E5=AF=B9protobuf=E7=9A=84=E4=BE=9D=E8=B5=96=E5=8E=BB?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/DataBase/hard_link.py | 151 ++++++++++++++++++++++------- app/DataBase/msg.py | 23 +++-- app/DataBase/package_msg.py | 86 ++++++++-------- app/util/compress_content.py | 12 +-- app/util/file.py | 13 ++- app/util/music.py | 2 +- app/util/protocbuf/__init__.py | 0 app/util/protocbuf/msg.proto | 18 ---- app/util/protocbuf/msg_pb2.py | 54 ----------- app/util/protocbuf/readme.md | 34 ------- app/util/protocbuf/roomdata.proto | 19 ---- app/util/protocbuf/roomdata_pb2.py | 45 --------- requirements.txt | 2 - 13 files changed, 181 insertions(+), 278 deletions(-) delete mode 100644 app/util/protocbuf/__init__.py delete mode 100644 app/util/protocbuf/msg.proto delete mode 100644 app/util/protocbuf/msg_pb2.py delete mode 100644 app/util/protocbuf/readme.md delete mode 100644 app/util/protocbuf/roomdata.proto delete mode 100644 app/util/protocbuf/roomdata_pb2.py diff --git a/app/DataBase/hard_link.py b/app/DataBase/hard_link.py index 22e93f82..cb3157b4 100644 --- a/app/DataBase/hard_link.py +++ b/app/DataBase/hard_link.py @@ -41,7 +41,7 @@ def __setVals__(self, data, off): def __readString(self): try: length = self.__readUleb() - res = self.__data[self.__off: self.__off + length] + res = self.__data[self.__off : self.__off + length] self.__add(length) except: raise @@ -78,12 +78,36 @@ def __readUleb(self): def __readData(self): try: length = self.__readUleb() - data = self.__data[self.__off: self.__off + length] + data = self.__data[self.__off : self.__off + length] self.__add(length) return data except: raise + def __readChar(self): + c = None + try: + c = self.__data[self.__off] + self.__add() + except: + raise + return c + + def __readUlong(self): + i = 0 + j = 0 + l = 0 + while True: + assert i < 64 + try: + j = self.__readChar() + except: + raise + l = l | (j & 0x7F) << i + if (j & 0x80) == 0: + return l + i = i + 7 + def __init__(self, data=None, off=0): self.__data = data self.__off = off @@ -111,10 +135,8 @@ def readStruct(self, struct_type): if key == 0: break op = None - fieldName = "" if key in current_dict: - op = current_dict[key][1] - fieldName = current_dict[key][0] + op = current_dict[key] else: break if isinstance(op, dict): @@ -122,31 +144,56 @@ def readStruct(self, struct_type): res[key] = [] current_struct = self.__readData() recursion = tencent_struct(current_struct) - res[key].append((fieldName, recursion.readStruct(op))) + res[key].append(recursion.readStruct(op)) elif op != "": - res[key] = (fieldName, self.__contenttype__[op](self)) + res[key] = self.__contenttype__[op](self) else: break except: raise return res - __struct1__ = {1: ("", "I"), 2: ("", "I")} + __bytesExtraStruct1__ = {1: "I", 2: "I"} - __msgInfo__ = {1: ("", "I"), 2: ("msg_info", "s")} + __bytesExtraMsgInfo__ = {1: "I", 2: "s"} __bytesExtra__ = { - 1: ("", __struct1__), - 3: ("msg_info_struct", __msgInfo__), + 1: __bytesExtraStruct1__, + 3: __bytesExtraMsgInfo__, } - __struct2__ = {1: ("", "s"), 2: ("", "s")} + __extraBufStruct1__ = {1: "s", 2: "s"} __extraBuf__ = { - 1: ("", __struct2__), + 1: __extraBufStruct1__, } - def get_bytesExta_Content(self, data=None, off=0): + __chatRoomMember__ = { + 1: "s", + 2: "s", + 3: "I", + } + """ + field1: wxid, + field2: displayName, + field3: state + """ + + __chatRoomData__ = { + 1: __chatRoomMember__, + 2: "I", + 3: "I", + 4: "I", + 5: "I", + 6: "L", + 7: "L", + 8: "L", + } + """ + field5: roomCapacity + """ + + def get_bytesExtra_Content(self, data=None, off=0): self.__setVals__(data, off) try: return self.readStruct("__bytesExtra__") @@ -160,16 +207,24 @@ def get_extraBuf_Content(self, data=None, off=0): except: raise + def get_chatRoomData_Content(self, data=None, off=0): + self.__setVals__(data, off) + try: + return self.readStruct("__chatRoomData__") + except: + raise + __contenttype__ = { "s": __readString, "I": __readUleb, "P": __readData, + "L": __readUlong, } -def parseBytes(content: bytes): +def parseBytesExtra(content: bytes): try: - bytesExtra = tencent_struct().get_bytesExta_Content(content) + bytesExtra = tencent_struct().get_bytesExtra_Content(content) return bytesExtra except: pass @@ -183,6 +238,30 @@ def parseExtraBuf(content: bytes): pass +def parseChatRoomData(content: bytes): + """ + return { + 1: { + 1: wxid, + 2: displayName, + 3: state + }, # chatRoomMember + 2: int, + 3: int, + 4: int, + 5: int, # roomCapacity + 6: long, + 7: long, + 8: long, + } + """ + try: + extraBuf = tencent_struct().get_chatRoomData_Content(content) + return extraBuf + except: + pass + + def decodeExtraBuf(extra_buf_content: bytes): off = 0 types = [b"\x04", b"\x18", b"\x17", b"\x02", b"\x05"] @@ -198,56 +277,56 @@ def decodeExtraBuf(extra_buf_content: bytes): "759378AD": "手机号", "74752C06": "性别", } - res = {'手机号': {'18': ''}} + res = {"手机号": {"18": ""}} while off < len(extra_buf_content): length = 4 # 块头 - trunk_head = extra_buf_content[off: off + length] + trunk_head = extra_buf_content[off : off + length] off += length trunk_head = binascii.hexlify(trunk_head).decode().upper() if trunk_head in trunkName: trunk_head = trunkName[trunk_head] res[trunk_head] = {} - char = extra_buf_content[off: off + 1] + char = extra_buf_content[off : off + 1] off += 1 field = binascii.hexlify(char).decode() if char == b"\x04": # 四个字节的int,小端序 length = 4 - intContent = extra_buf_content[off: off + length] + intContent = extra_buf_content[off : off + length] off += 4 intContent = int.from_bytes(intContent, "little") res[trunk_head][field] = intContent elif char == b"\x18": # utf-16字符串 length = 4 - lengthContent = extra_buf_content[off: off + length] + lengthContent = extra_buf_content[off : off + length] off += 4 lengthContent = int.from_bytes(lengthContent, "little") - strContent = extra_buf_content[off: off + lengthContent] + strContent = extra_buf_content[off : off + lengthContent] off += lengthContent res[trunk_head][field] = strContent.decode("utf-16").rstrip("\x00") elif char == b"\x17": # utf-8 protobuf length = 4 - lengthContent = extra_buf_content[off: off + length] + lengthContent = extra_buf_content[off : off + length] off += 4 lengthContent = int.from_bytes(lengthContent, "little") - strContent = extra_buf_content[off: off + lengthContent] + strContent = extra_buf_content[off : off + lengthContent] off += lengthContent res[trunk_head][field] = parseExtraBuf(strContent) elif char == b"\x02": # 一个字节的int - content = extra_buf_content[off: off + 1] + content = extra_buf_content[off : off + 1] off += 1 res[trunk_head][field] = int.from_bytes(content, "little") elif char == b"\x05": # 暂时不知道有啥用,固定8个字节,先当int处理 length = 8 - content = extra_buf_content[off: off + length] + content = extra_buf_content[off : off + length] off += length res[trunk_head][field] = int.from_bytes(content, "little") # print(res) return { - 'region': (res['国家']['18'], res['省份']['18'], res['市']['18']), - 'signature': res['个性签名']['18'], - 'telephone': res['手机号']['18'], - 'gender': res['性别']['04'] + "region": (res["国家"]["18"], res["省份"]["18"], res["市"]["18"]), + "signature": res["个性签名"]["18"], + "telephone": res["手机号"]["18"], + "gender": res["性别"]["04"], } @@ -337,10 +416,10 @@ def get_video_by_md5(self, md5: bytes): video_db_lock.release() def get_image(self, content, bytesExtra, thumb=False): - bytesDict = parseBytes(bytesExtra) + bytesDict = parseBytesExtra(bytesExtra) for msginfo in bytesDict[3]: - if msginfo[1][1][1] == (3 if thumb else 4): - pathh = msginfo[1][2][1] # wxid\FileStorage\... + if msginfo[1] == (3 if thumb else 4): + pathh = msginfo[2] # wxid\FileStorage\... pathh = "\\".join(pathh.split("\\")[1:]) return pathh md5 = get_md5_from_xml(content) @@ -357,10 +436,10 @@ def get_image(self, content, bytesExtra, thumb=False): return dat_image def get_video(self, content, bytesExtra, thumb=False): - bytesDict = parseBytes(bytesExtra) + bytesDict = parseBytesExtra(bytesExtra) for msginfo in bytesDict[3]: - if msginfo[1][1][1] == (3 if thumb else 4): - pathh = msginfo[1][2][1] # wxid\FileStorage\... + if msginfo[1] == (3 if thumb else 4): + pathh = msginfo[2] # wxid\FileStorage\... pathh = "\\".join(pathh.split("\\")[1:]) return pathh md5 = get_md5_from_xml(content, type_="video") diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index d1a7c44f..4e01fe68 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -4,10 +4,10 @@ import threading import traceback -from app.DataBase.hard_link import parseBytes +from app.DataBase.hard_link import parseBytesExtra from app.log import logger from app.util.compress_content import parser_reply -from app.util.protocbuf.msg_pb2 import MessageBytesExtra +from app.DataBase.hard_link import parseBytesExtra db_path = "./app/Database/Msg/MSG.db" lock = threading.Lock() @@ -66,12 +66,11 @@ def add_sender(self, messages): if is_sender: pass else: - msgbytes = MessageBytesExtra() - msgbytes.ParseFromString(message[10]) - for tmp in msgbytes.message2: - if tmp.field1 != 1: + msgbytes = parseBytesExtra(message[10]) + for tmp in msgbytes[3]: + if tmp[1] != 1: continue - wxid = tmp.field2 + wxid = tmp[2] new_message = (*message, wxid) new_messages.append(new_message) return new_messages @@ -651,12 +650,12 @@ def __del__(self): else: show_display_name = appinfo.find('appname').text print(title, des, url, show_display_name) - bytesDict = parseBytes(msg[10]) + bytesDict = parseBytesExtra(msg[10]) for msginfo in bytesDict[3]: print(msginfo) - if msginfo[1][1][1] == 3: - thumb = msginfo[1][2][1] + if msginfo[1] == 3: + thumb = msginfo[2] print(thumb) - if msginfo[1][1][1] == 4: - app_logo = msginfo[1][2][1] + if msginfo[1] == 4: + app_logo = msginfo[2] print('logo',app_logo) \ No newline at end of file diff --git a/app/DataBase/package_msg.py b/app/DataBase/package_msg.py index 3b96d71e..d6fa45fe 100644 --- a/app/DataBase/package_msg.py +++ b/app/DataBase/package_msg.py @@ -1,9 +1,8 @@ import threading from app.DataBase import msg_db, micro_msg_db, misc_db -from app.util.protocbuf.msg_pb2 import MessageBytesExtra -from app.util.protocbuf.roomdata_pb2 import ChatRoomData from app.person import Contact, Me, ContactDefault +from app.DataBase.hard_link import parseBytesExtra, parseChatRoomData lock = threading.Lock() @@ -25,9 +24,9 @@ def __init__(self): self.ChatRoomMap = {} def get_package_message_all(self): - ''' + """ 获取完整的聊天记录 - ''' + """ updated_messages = [] # 用于存储修改后的消息列表 messages = msg_db.get_messages_all() @@ -46,26 +45,25 @@ def get_package_message_all(self): row_list.append(info[3]) row_list.append(info[4]) else: - row_list.append('') - row_list.append('') + row_list.append("") + row_list.append("") # 判断是否是群聊 - if strtalker.__contains__('@chatroom'): + if strtalker.__contains__("@chatroom"): # 自己发送 if row[4] == 1: - row_list.append('我') + row_list.append("我") else: # 存在BytesExtra为空的情况,此时消息类型应该为提示性消息。跳过不处理 if row[10] is None: continue # 解析BytesExtra - msgbytes = MessageBytesExtra() - msgbytes.ParseFromString(row[10]) - wxid = '' - for tmp in msgbytes.message2: - if tmp.field1 != 1: + msgbytes = parseBytesExtra(row[10]) + wxid = "" + for tmp in msgbytes[3]: + if tmp[1] != 1: continue - wxid = tmp.field2 - sender = '' + wxid = tmp[2] + sender = "" # 获取群聊成员列表 membersMap = self.get_chatroom_member_list(strtalker) if membersMap is not None: @@ -82,17 +80,17 @@ def get_package_message_all(self): row_list.append(sender) else: if row[4] == 1: - row_list.append('我') + row_list.append("我") else: if info is not None: row_list.append(info[4]) else: - row_list.append('') + row_list.append("") updated_messages.append(tuple(row_list)) return updated_messages - + def get_package_message_by_wxid(self, chatroom_wxid): - ''' + """ 获取一个群聊的聊天记录 return list a[0]: localId, @@ -108,43 +106,42 @@ def get_package_message_by_wxid(self, chatroom_wxid): a[10]: BytesExtra, a[11]: CompressContent, a[12]: msg_sender, (ContactPC 或 ContactDefault 类型,这个才是群聊里的信息发送人,不是群聊或者自己是发送者没有这个字段) - ''' + """ updated_messages = [] # 用于存储修改后的消息列表 chatroom_members = self.get_chatroom_member_list(chatroom_wxid) messages = msg_db.get_messages(chatroom_wxid) for row in messages: message = list(row) - if message[4] == 1: # 自己发送的就没必要解析了 + if message[4] == 1: # 自己发送的就没必要解析了 message.append(Me()) updated_messages.append(message) continue - if message[10] is None: # BytesExtra是空的跳过 + if message[10] is None: # BytesExtra是空的跳过 message.append(ContactDefault(wxid)) updated_messages.append(message) continue - msgbytes = MessageBytesExtra() - msgbytes.ParseFromString(message[10]) - wxid = '' - for tmp in msgbytes.message2: - if tmp.field1 != 1: + msgbytes = parseBytesExtra(row[10]) + wxid = "" + for tmp in msgbytes[3]: + if tmp[1] != 1: continue - wxid = tmp.field2 - if wxid == "": # 系统消息里面 wxid 不存在 + wxid = tmp[2] + if wxid == "": # 系统消息里面 wxid 不存在 message.append(ContactDefault(wxid)) updated_messages.append(message) continue contact_info_list = micro_msg_db.get_contact_by_username(wxid) - if contact_info_list is None: # 群聊中已退群的联系人不会保存在数据库里 + if contact_info_list is None: # 群聊中已退群的联系人不会保存在数据库里 message.append(ContactDefault(wxid)) updated_messages.append(message) continue contact_info = { - 'UserName': contact_info_list[0], - 'Alias': contact_info_list[1], - 'Type': contact_info_list[2], - 'Remark': contact_info_list[3], - 'NickName': contact_info_list[4], - 'smallHeadImgUrl': contact_info_list[7] + "UserName": contact_info_list[0], + "Alias": contact_info_list[1], + "Type": contact_info_list[2], + "Remark": contact_info_list[3], + "NickName": contact_info_list[4], + "smallHeadImgUrl": contact_info_list[7], } contact = Contact(contact_info) contact.smallHeadImgBLOG = misc_db.get_avatar_buffer(contact.wxid) @@ -155,9 +152,9 @@ def get_package_message_by_wxid(self, chatroom_wxid): def get_chatroom_member_list(self, strtalker): membermap = {} - ''' + """ 获取群聊成员 - ''' + """ try: lock.acquire(True) if strtalker in self.ChatRoomMap: @@ -167,17 +164,18 @@ def get_chatroom_member_list(self, strtalker): if chatroom is None: return None # 解析RoomData数据 - parsechatroom = ChatRoomData() - parsechatroom.ParseFromString(chatroom[1]) + parsechatroom = parseChatRoomData(chatroom[1]) # 群成员数据放入字典存储 - for mem in parsechatroom.members: - if mem.displayName is not None and len(mem.displayName) > 0: - membermap[mem.wxID] = mem.displayName + print(parsechatroom[7]) + for mem in parsechatroom[1]: + if mem[2] is not None and len(mem[2]) > 0: + membermap[mem[1]] = mem[2] # wxid -> displayname self.ChatRoomMap[strtalker] = membermap finally: lock.release() return membermap + if __name__ == "__main__": p = PackageMsg() - print(p.get_package_message_by_wxid("48615079469@chatroom")) + print(p.get_package_message_by_wxid("18508451193@chatroom")) diff --git a/app/util/compress_content.py b/app/util/compress_content.py index f8397e4f..52e80891 100644 --- a/app/util/compress_content.py +++ b/app/util/compress_content.py @@ -8,7 +8,7 @@ from urllib.parse import urlparse from bs4 import BeautifulSoup -from app.DataBase.hard_link import parseBytes +from app.DataBase.hard_link import parseBytesExtra from ..util.file import get_file @@ -149,15 +149,15 @@ def share_card(bytesExtra, compress_content_): else: if appinfo is not None: show_display_name = appinfo.find('appname').text - bytesDict = parseBytes(bytesExtra) + bytesDict = parseBytesExtra(bytesExtra) app_logo = '' thumbnail = '' for msginfo in bytesDict[3]: - if msginfo[1][1][1] == 3: - thumbnail = msginfo[1][2][1] + if msginfo[1] == 3: + thumbnail = msginfo[2] thumbnail = "\\".join(thumbnail.split('\\')[1:]) - if msginfo[1][1][1] == 4: - app_logo = msginfo[1][2][1] + if msginfo[1] == 4: + app_logo = msginfo[2] app_logo = "\\".join(app_logo.split('\\')[1:]) if sourceusername is not None: from app.DataBase import micro_msg_db # 放上面会导致循环依赖 diff --git a/app/util/file.py b/app/util/file.py index 8c8562f0..cb1f48f0 100644 --- a/app/util/file.py +++ b/app/util/file.py @@ -5,7 +5,7 @@ import requests from app.log import log, logger -from app.util.protocbuf.msg_pb2 import MessageBytesExtra +from app.DataBase.hard_link import parseBytesExtra from ..person import Me root_path = './data/files/' @@ -22,14 +22,13 @@ def __init__(self): def get_file(bytes_extra, file_name, output_path=root_path) -> str: try: - msg_bytes = MessageBytesExtra() - msg_bytes.ParseFromString(bytes_extra) + msg_bytes = parseBytesExtra(bytes_extra) file_path = '' real_path = '' - if len(msg_bytes.message2) > 0: - for filed in msg_bytes.message2: - if filed.field1 == 4: - file_original_path = filed.field2 + if len(msg_bytes[3]) > 0: + for filed in msg_bytes[3]: + if filed[1] == 4: + file_original_path = filed[2] file_path = os.path.join(output_path, file_name) if os.path.exists(file_path): # print('文件' + file_path + '已存在') diff --git a/app/util/music.py b/app/util/music.py index 6ad9296e..873f5546 100644 --- a/app/util/music.py +++ b/app/util/music.py @@ -3,7 +3,7 @@ import shutil from app.log import log, logger -from app.util.protocbuf.msg_pb2 import MessageBytesExtra +from app.DataBase.hard_link import parseBytesExtra import requests from urllib.parse import urlparse, parse_qs import re diff --git a/app/util/protocbuf/__init__.py b/app/util/protocbuf/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/app/util/protocbuf/msg.proto b/app/util/protocbuf/msg.proto deleted file mode 100644 index 1d88cecb..00000000 --- a/app/util/protocbuf/msg.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; -package app.protobuf; -option go_package=".;proto"; - -message SubMessage1 { - int32 field1 = 1; - int32 field2 = 2; -} - -message SubMessage2 { - int32 field1 = 1; - string field2 = 2; -} - -message MessageBytesExtra { - SubMessage1 message1 = 1; - repeated SubMessage2 message2 = 3; -} diff --git a/app/util/protocbuf/msg_pb2.py b/app/util/protocbuf/msg_pb2.py deleted file mode 100644 index f5f31c5c..00000000 --- a/app/util/protocbuf/msg_pb2.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: msg.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tmsg.proto\x12\x0c\x61pp.protobuf\"-\n\x0bSubMessage1\x12\x0e\n\x06\x66ield1\x18\x01 \x01(\x05\x12\x0e\n\x06\x66ield2\x18\x02 \x01(\x05\"-\n\x0bSubMessage2\x12\x0e\n\x06\x66ield1\x18\x01 \x01(\x05\x12\x0e\n\x06\x66ield2\x18\x02 \x01(\t\"m\n\x11MessageBytesExtra\x12+\n\x08message1\x18\x01 \x01(\x0b\x32\x19.app.protobuf.SubMessage1\x12+\n\x08message2\x18\x03 \x03(\x0b\x32\x19.app.protobuf.SubMessage2b\x06proto3') - - - -_SUBMESSAGE1 = DESCRIPTOR.message_types_by_name['SubMessage1'] -_SUBMESSAGE2 = DESCRIPTOR.message_types_by_name['SubMessage2'] -_MESSAGEBYTESEXTRA = DESCRIPTOR.message_types_by_name['MessageBytesExtra'] -SubMessage1 = _reflection.GeneratedProtocolMessageType('SubMessage1', (_message.Message,), { - 'DESCRIPTOR' : _SUBMESSAGE1, - '__module__' : 'msg_pb2' - # @@protoc_insertion_point(class_scope:app.protobuf.SubMessage1) - }) -_sym_db.RegisterMessage(SubMessage1) - -SubMessage2 = _reflection.GeneratedProtocolMessageType('SubMessage2', (_message.Message,), { - 'DESCRIPTOR' : _SUBMESSAGE2, - '__module__' : 'msg_pb2' - # @@protoc_insertion_point(class_scope:app.protobuf.SubMessage2) - }) -_sym_db.RegisterMessage(SubMessage2) - -MessageBytesExtra = _reflection.GeneratedProtocolMessageType('MessageBytesExtra', (_message.Message,), { - 'DESCRIPTOR' : _MESSAGEBYTESEXTRA, - '__module__' : 'msg_pb2' - # @@protoc_insertion_point(class_scope:app.protobuf.MessageBytesExtra) - }) -_sym_db.RegisterMessage(MessageBytesExtra) - -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _SUBMESSAGE1._serialized_start=27 - _SUBMESSAGE1._serialized_end=72 - _SUBMESSAGE2._serialized_start=74 - _SUBMESSAGE2._serialized_end=119 - _MESSAGEBYTESEXTRA._serialized_start=121 - _MESSAGEBYTESEXTRA._serialized_end=230 -# @@protoc_insertion_point(module_scope) diff --git a/app/util/protocbuf/readme.md b/app/util/protocbuf/readme.md deleted file mode 100644 index 15b3c631..00000000 --- a/app/util/protocbuf/readme.md +++ /dev/null @@ -1,34 +0,0 @@ -# 说明 - -## 解析 -```shell -protoc --decode_raw < msg_data.txt -``` - -## 根据解析结果,设置.proto文件 -```shell -1 { - 1: 16 - 2: 0 -} -3 { - 1: 1 - 2: "wxid_4b1t09d63spw22" -} -3 { - 1: 7 - 2: "\n\t\n\t\t2\n\t\n\t\n\t\tc6680ab2c57499a1a22e44a7eada76e8_\n\t\n\t1\n\t198\n\tv1_Gj7hfmi5\n\t\n\t\t\n\t\n\n" -} -3 { - 1: 2 - 2: "c13acbc95512d1a59bb686d684fd64d8" -} -3 { - 1: 4 - 2: "yiluoAK_47\\FileStorage\\Cache\\2023-08\\2286b5852db82f6cbd9c2084ccd52358" -} -``` -## 生成python文件 -```shell -protoc --python_out=. msg.proto -``` \ No newline at end of file diff --git a/app/util/protocbuf/roomdata.proto b/app/util/protocbuf/roomdata.proto deleted file mode 100644 index 36b1f9ca..00000000 --- a/app/util/protocbuf/roomdata.proto +++ /dev/null @@ -1,19 +0,0 @@ -syntax = "proto3"; -package app.protobuf; -option go_package=".;proto"; - -message ChatRoomData { - message ChatRoomMember { - string wxID = 1; - string displayName = 2; - int32 state = 3; - } - repeated ChatRoomMember members = 1; - int32 field_2 = 2; - int32 field_3 = 3; - int32 field_4 = 4; - int32 room_capacity = 5; - int32 field_6 = 6; - int64 field_7 = 7; - int64 field_8 = 8; -} \ No newline at end of file diff --git a/app/util/protocbuf/roomdata_pb2.py b/app/util/protocbuf/roomdata_pb2.py deleted file mode 100644 index 7800214b..00000000 --- a/app/util/protocbuf/roomdata_pb2.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: roomdata.proto -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0eroomdata.proto\x12\x0c\x61pp.protobuf\"\x8b\x02\n\x0c\x43hatRoomData\x12:\n\x07members\x18\x01 \x03(\x0b\x32).app.protobuf.ChatRoomData.ChatRoomMember\x12\x0f\n\x07\x66ield_2\x18\x02 \x01(\x05\x12\x0f\n\x07\x66ield_3\x18\x03 \x01(\x05\x12\x0f\n\x07\x66ield_4\x18\x04 \x01(\x05\x12\x15\n\rroom_capacity\x18\x05 \x01(\x05\x12\x0f\n\x07\x66ield_6\x18\x06 \x01(\x05\x12\x0f\n\x07\x66ield_7\x18\x07 \x01(\x03\x12\x0f\n\x07\x66ield_8\x18\x08 \x01(\x03\x1a\x42\n\x0e\x43hatRoomMember\x12\x0c\n\x04wxID\x18\x01 \x01(\t\x12\x13\n\x0b\x64isplayName\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\x05\x62\x06proto3') - - - -_CHATROOMDATA = DESCRIPTOR.message_types_by_name['ChatRoomData'] -_CHATROOMDATA_CHATROOMMEMBER = _CHATROOMDATA.nested_types_by_name['ChatRoomMember'] -ChatRoomData = _reflection.GeneratedProtocolMessageType('ChatRoomData', (_message.Message,), { - - 'ChatRoomMember' : _reflection.GeneratedProtocolMessageType('ChatRoomMember', (_message.Message,), { - 'DESCRIPTOR' : _CHATROOMDATA_CHATROOMMEMBER, - '__module__' : 'roomdata_pb2' - # @@protoc_insertion_point(class_scope:app.protobuf.ChatRoomData.ChatRoomMember) - }) - , - 'DESCRIPTOR' : _CHATROOMDATA, - '__module__' : 'roomdata_pb2' - # @@protoc_insertion_point(class_scope:app.protobuf.ChatRoomData) - }) -_sym_db.RegisterMessage(ChatRoomData) -_sym_db.RegisterMessage(ChatRoomData.ChatRoomMember) - -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _CHATROOMDATA._serialized_start=33 - _CHATROOMDATA._serialized_end=300 - _CHATROOMDATA_CHATROOMMEMBER._serialized_start=234 - _CHATROOMDATA_CHATROOMMEMBER._serialized_end=300 -# @@protoc_insertion_point(module_scope) diff --git a/requirements.txt b/requirements.txt index 00a21069..326fae12 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,8 +12,6 @@ requests flask==3.0.0 pyecharts==2.0.1 jieba==0.42.1 -google==3.0.0 -protobuf==4.25.1 soupsieve==2.5 lz4==4.3.2 pilk==0.2.4 From 4416fea90699d221437eae6fabeb34490e10db99 Mon Sep 17 00:00:00 2001 From: STDquantum <405720329@qq.com> Date: Fri, 5 Jan 2024 19:17:56 +0800 Subject: [PATCH 2/6] =?UTF-8?q?Revert=20"=E5=8E=BB=E9=99=A4parseBytes?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E5=AD=97=E6=AE=B5=E5=90=8D=E7=A7=B0=EF=BC=8C?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=BB=93=E6=9E=9C=E6=9B=B4=E7=AE=80=E6=B4=81?= =?UTF-8?q?=EF=BC=9B=E6=8A=8A=E5=AF=B9protobuf=E7=9A=84=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E5=8E=BB=E9=99=A4"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ca491c3b3a73d5f1ca7c3fbf1684ed8899dd854f. --- app/DataBase/hard_link.py | 151 +++++++---------------------- app/DataBase/msg.py | 23 ++--- app/DataBase/package_msg.py | 86 ++++++++-------- app/util/compress_content.py | 12 +-- app/util/file.py | 13 +-- app/util/music.py | 2 +- app/util/protocbuf/__init__.py | 0 app/util/protocbuf/msg.proto | 18 ++++ app/util/protocbuf/msg_pb2.py | 54 +++++++++++ app/util/protocbuf/readme.md | 34 +++++++ app/util/protocbuf/roomdata.proto | 19 ++++ app/util/protocbuf/roomdata_pb2.py | 45 +++++++++ requirements.txt | 2 + 13 files changed, 278 insertions(+), 181 deletions(-) create mode 100644 app/util/protocbuf/__init__.py create mode 100644 app/util/protocbuf/msg.proto create mode 100644 app/util/protocbuf/msg_pb2.py create mode 100644 app/util/protocbuf/readme.md create mode 100644 app/util/protocbuf/roomdata.proto create mode 100644 app/util/protocbuf/roomdata_pb2.py diff --git a/app/DataBase/hard_link.py b/app/DataBase/hard_link.py index cb3157b4..22e93f82 100644 --- a/app/DataBase/hard_link.py +++ b/app/DataBase/hard_link.py @@ -41,7 +41,7 @@ def __setVals__(self, data, off): def __readString(self): try: length = self.__readUleb() - res = self.__data[self.__off : self.__off + length] + res = self.__data[self.__off: self.__off + length] self.__add(length) except: raise @@ -78,36 +78,12 @@ def __readUleb(self): def __readData(self): try: length = self.__readUleb() - data = self.__data[self.__off : self.__off + length] + data = self.__data[self.__off: self.__off + length] self.__add(length) return data except: raise - def __readChar(self): - c = None - try: - c = self.__data[self.__off] - self.__add() - except: - raise - return c - - def __readUlong(self): - i = 0 - j = 0 - l = 0 - while True: - assert i < 64 - try: - j = self.__readChar() - except: - raise - l = l | (j & 0x7F) << i - if (j & 0x80) == 0: - return l - i = i + 7 - def __init__(self, data=None, off=0): self.__data = data self.__off = off @@ -135,8 +111,10 @@ def readStruct(self, struct_type): if key == 0: break op = None + fieldName = "" if key in current_dict: - op = current_dict[key] + op = current_dict[key][1] + fieldName = current_dict[key][0] else: break if isinstance(op, dict): @@ -144,56 +122,31 @@ def readStruct(self, struct_type): res[key] = [] current_struct = self.__readData() recursion = tencent_struct(current_struct) - res[key].append(recursion.readStruct(op)) + res[key].append((fieldName, recursion.readStruct(op))) elif op != "": - res[key] = self.__contenttype__[op](self) + res[key] = (fieldName, self.__contenttype__[op](self)) else: break except: raise return res - __bytesExtraStruct1__ = {1: "I", 2: "I"} + __struct1__ = {1: ("", "I"), 2: ("", "I")} - __bytesExtraMsgInfo__ = {1: "I", 2: "s"} + __msgInfo__ = {1: ("", "I"), 2: ("msg_info", "s")} __bytesExtra__ = { - 1: __bytesExtraStruct1__, - 3: __bytesExtraMsgInfo__, + 1: ("", __struct1__), + 3: ("msg_info_struct", __msgInfo__), } - __extraBufStruct1__ = {1: "s", 2: "s"} + __struct2__ = {1: ("", "s"), 2: ("", "s")} __extraBuf__ = { - 1: __extraBufStruct1__, + 1: ("", __struct2__), } - __chatRoomMember__ = { - 1: "s", - 2: "s", - 3: "I", - } - """ - field1: wxid, - field2: displayName, - field3: state - """ - - __chatRoomData__ = { - 1: __chatRoomMember__, - 2: "I", - 3: "I", - 4: "I", - 5: "I", - 6: "L", - 7: "L", - 8: "L", - } - """ - field5: roomCapacity - """ - - def get_bytesExtra_Content(self, data=None, off=0): + def get_bytesExta_Content(self, data=None, off=0): self.__setVals__(data, off) try: return self.readStruct("__bytesExtra__") @@ -207,24 +160,16 @@ def get_extraBuf_Content(self, data=None, off=0): except: raise - def get_chatRoomData_Content(self, data=None, off=0): - self.__setVals__(data, off) - try: - return self.readStruct("__chatRoomData__") - except: - raise - __contenttype__ = { "s": __readString, "I": __readUleb, "P": __readData, - "L": __readUlong, } -def parseBytesExtra(content: bytes): +def parseBytes(content: bytes): try: - bytesExtra = tencent_struct().get_bytesExtra_Content(content) + bytesExtra = tencent_struct().get_bytesExta_Content(content) return bytesExtra except: pass @@ -238,30 +183,6 @@ def parseExtraBuf(content: bytes): pass -def parseChatRoomData(content: bytes): - """ - return { - 1: { - 1: wxid, - 2: displayName, - 3: state - }, # chatRoomMember - 2: int, - 3: int, - 4: int, - 5: int, # roomCapacity - 6: long, - 7: long, - 8: long, - } - """ - try: - extraBuf = tencent_struct().get_chatRoomData_Content(content) - return extraBuf - except: - pass - - def decodeExtraBuf(extra_buf_content: bytes): off = 0 types = [b"\x04", b"\x18", b"\x17", b"\x02", b"\x05"] @@ -277,56 +198,56 @@ def decodeExtraBuf(extra_buf_content: bytes): "759378AD": "手机号", "74752C06": "性别", } - res = {"手机号": {"18": ""}} + res = {'手机号': {'18': ''}} while off < len(extra_buf_content): length = 4 # 块头 - trunk_head = extra_buf_content[off : off + length] + trunk_head = extra_buf_content[off: off + length] off += length trunk_head = binascii.hexlify(trunk_head).decode().upper() if trunk_head in trunkName: trunk_head = trunkName[trunk_head] res[trunk_head] = {} - char = extra_buf_content[off : off + 1] + char = extra_buf_content[off: off + 1] off += 1 field = binascii.hexlify(char).decode() if char == b"\x04": # 四个字节的int,小端序 length = 4 - intContent = extra_buf_content[off : off + length] + intContent = extra_buf_content[off: off + length] off += 4 intContent = int.from_bytes(intContent, "little") res[trunk_head][field] = intContent elif char == b"\x18": # utf-16字符串 length = 4 - lengthContent = extra_buf_content[off : off + length] + lengthContent = extra_buf_content[off: off + length] off += 4 lengthContent = int.from_bytes(lengthContent, "little") - strContent = extra_buf_content[off : off + lengthContent] + strContent = extra_buf_content[off: off + lengthContent] off += lengthContent res[trunk_head][field] = strContent.decode("utf-16").rstrip("\x00") elif char == b"\x17": # utf-8 protobuf length = 4 - lengthContent = extra_buf_content[off : off + length] + lengthContent = extra_buf_content[off: off + length] off += 4 lengthContent = int.from_bytes(lengthContent, "little") - strContent = extra_buf_content[off : off + lengthContent] + strContent = extra_buf_content[off: off + lengthContent] off += lengthContent res[trunk_head][field] = parseExtraBuf(strContent) elif char == b"\x02": # 一个字节的int - content = extra_buf_content[off : off + 1] + content = extra_buf_content[off: off + 1] off += 1 res[trunk_head][field] = int.from_bytes(content, "little") elif char == b"\x05": # 暂时不知道有啥用,固定8个字节,先当int处理 length = 8 - content = extra_buf_content[off : off + length] + content = extra_buf_content[off: off + length] off += length res[trunk_head][field] = int.from_bytes(content, "little") # print(res) return { - "region": (res["国家"]["18"], res["省份"]["18"], res["市"]["18"]), - "signature": res["个性签名"]["18"], - "telephone": res["手机号"]["18"], - "gender": res["性别"]["04"], + 'region': (res['国家']['18'], res['省份']['18'], res['市']['18']), + 'signature': res['个性签名']['18'], + 'telephone': res['手机号']['18'], + 'gender': res['性别']['04'] } @@ -416,10 +337,10 @@ def get_video_by_md5(self, md5: bytes): video_db_lock.release() def get_image(self, content, bytesExtra, thumb=False): - bytesDict = parseBytesExtra(bytesExtra) + bytesDict = parseBytes(bytesExtra) for msginfo in bytesDict[3]: - if msginfo[1] == (3 if thumb else 4): - pathh = msginfo[2] # wxid\FileStorage\... + if msginfo[1][1][1] == (3 if thumb else 4): + pathh = msginfo[1][2][1] # wxid\FileStorage\... pathh = "\\".join(pathh.split("\\")[1:]) return pathh md5 = get_md5_from_xml(content) @@ -436,10 +357,10 @@ def get_image(self, content, bytesExtra, thumb=False): return dat_image def get_video(self, content, bytesExtra, thumb=False): - bytesDict = parseBytesExtra(bytesExtra) + bytesDict = parseBytes(bytesExtra) for msginfo in bytesDict[3]: - if msginfo[1] == (3 if thumb else 4): - pathh = msginfo[2] # wxid\FileStorage\... + if msginfo[1][1][1] == (3 if thumb else 4): + pathh = msginfo[1][2][1] # wxid\FileStorage\... pathh = "\\".join(pathh.split("\\")[1:]) return pathh md5 = get_md5_from_xml(content, type_="video") diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index 4e01fe68..d1a7c44f 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -4,10 +4,10 @@ import threading import traceback -from app.DataBase.hard_link import parseBytesExtra +from app.DataBase.hard_link import parseBytes from app.log import logger from app.util.compress_content import parser_reply -from app.DataBase.hard_link import parseBytesExtra +from app.util.protocbuf.msg_pb2 import MessageBytesExtra db_path = "./app/Database/Msg/MSG.db" lock = threading.Lock() @@ -66,11 +66,12 @@ def add_sender(self, messages): if is_sender: pass else: - msgbytes = parseBytesExtra(message[10]) - for tmp in msgbytes[3]: - if tmp[1] != 1: + msgbytes = MessageBytesExtra() + msgbytes.ParseFromString(message[10]) + for tmp in msgbytes.message2: + if tmp.field1 != 1: continue - wxid = tmp[2] + wxid = tmp.field2 new_message = (*message, wxid) new_messages.append(new_message) return new_messages @@ -650,12 +651,12 @@ def __del__(self): else: show_display_name = appinfo.find('appname').text print(title, des, url, show_display_name) - bytesDict = parseBytesExtra(msg[10]) + bytesDict = parseBytes(msg[10]) for msginfo in bytesDict[3]: print(msginfo) - if msginfo[1] == 3: - thumb = msginfo[2] + if msginfo[1][1][1] == 3: + thumb = msginfo[1][2][1] print(thumb) - if msginfo[1] == 4: - app_logo = msginfo[2] + if msginfo[1][1][1] == 4: + app_logo = msginfo[1][2][1] print('logo',app_logo) \ No newline at end of file diff --git a/app/DataBase/package_msg.py b/app/DataBase/package_msg.py index d6fa45fe..3b96d71e 100644 --- a/app/DataBase/package_msg.py +++ b/app/DataBase/package_msg.py @@ -1,8 +1,9 @@ import threading from app.DataBase import msg_db, micro_msg_db, misc_db +from app.util.protocbuf.msg_pb2 import MessageBytesExtra +from app.util.protocbuf.roomdata_pb2 import ChatRoomData from app.person import Contact, Me, ContactDefault -from app.DataBase.hard_link import parseBytesExtra, parseChatRoomData lock = threading.Lock() @@ -24,9 +25,9 @@ def __init__(self): self.ChatRoomMap = {} def get_package_message_all(self): - """ + ''' 获取完整的聊天记录 - """ + ''' updated_messages = [] # 用于存储修改后的消息列表 messages = msg_db.get_messages_all() @@ -45,25 +46,26 @@ def get_package_message_all(self): row_list.append(info[3]) row_list.append(info[4]) else: - row_list.append("") - row_list.append("") + row_list.append('') + row_list.append('') # 判断是否是群聊 - if strtalker.__contains__("@chatroom"): + if strtalker.__contains__('@chatroom'): # 自己发送 if row[4] == 1: - row_list.append("我") + row_list.append('我') else: # 存在BytesExtra为空的情况,此时消息类型应该为提示性消息。跳过不处理 if row[10] is None: continue # 解析BytesExtra - msgbytes = parseBytesExtra(row[10]) - wxid = "" - for tmp in msgbytes[3]: - if tmp[1] != 1: + msgbytes = MessageBytesExtra() + msgbytes.ParseFromString(row[10]) + wxid = '' + for tmp in msgbytes.message2: + if tmp.field1 != 1: continue - wxid = tmp[2] - sender = "" + wxid = tmp.field2 + sender = '' # 获取群聊成员列表 membersMap = self.get_chatroom_member_list(strtalker) if membersMap is not None: @@ -80,17 +82,17 @@ def get_package_message_all(self): row_list.append(sender) else: if row[4] == 1: - row_list.append("我") + row_list.append('我') else: if info is not None: row_list.append(info[4]) else: - row_list.append("") + row_list.append('') updated_messages.append(tuple(row_list)) return updated_messages - + def get_package_message_by_wxid(self, chatroom_wxid): - """ + ''' 获取一个群聊的聊天记录 return list a[0]: localId, @@ -106,42 +108,43 @@ def get_package_message_by_wxid(self, chatroom_wxid): a[10]: BytesExtra, a[11]: CompressContent, a[12]: msg_sender, (ContactPC 或 ContactDefault 类型,这个才是群聊里的信息发送人,不是群聊或者自己是发送者没有这个字段) - """ + ''' updated_messages = [] # 用于存储修改后的消息列表 chatroom_members = self.get_chatroom_member_list(chatroom_wxid) messages = msg_db.get_messages(chatroom_wxid) for row in messages: message = list(row) - if message[4] == 1: # 自己发送的就没必要解析了 + if message[4] == 1: # 自己发送的就没必要解析了 message.append(Me()) updated_messages.append(message) continue - if message[10] is None: # BytesExtra是空的跳过 + if message[10] is None: # BytesExtra是空的跳过 message.append(ContactDefault(wxid)) updated_messages.append(message) continue - msgbytes = parseBytesExtra(row[10]) - wxid = "" - for tmp in msgbytes[3]: - if tmp[1] != 1: + msgbytes = MessageBytesExtra() + msgbytes.ParseFromString(message[10]) + wxid = '' + for tmp in msgbytes.message2: + if tmp.field1 != 1: continue - wxid = tmp[2] - if wxid == "": # 系统消息里面 wxid 不存在 + wxid = tmp.field2 + if wxid == "": # 系统消息里面 wxid 不存在 message.append(ContactDefault(wxid)) updated_messages.append(message) continue contact_info_list = micro_msg_db.get_contact_by_username(wxid) - if contact_info_list is None: # 群聊中已退群的联系人不会保存在数据库里 + if contact_info_list is None: # 群聊中已退群的联系人不会保存在数据库里 message.append(ContactDefault(wxid)) updated_messages.append(message) continue contact_info = { - "UserName": contact_info_list[0], - "Alias": contact_info_list[1], - "Type": contact_info_list[2], - "Remark": contact_info_list[3], - "NickName": contact_info_list[4], - "smallHeadImgUrl": contact_info_list[7], + 'UserName': contact_info_list[0], + 'Alias': contact_info_list[1], + 'Type': contact_info_list[2], + 'Remark': contact_info_list[3], + 'NickName': contact_info_list[4], + 'smallHeadImgUrl': contact_info_list[7] } contact = Contact(contact_info) contact.smallHeadImgBLOG = misc_db.get_avatar_buffer(contact.wxid) @@ -152,9 +155,9 @@ def get_package_message_by_wxid(self, chatroom_wxid): def get_chatroom_member_list(self, strtalker): membermap = {} - """ + ''' 获取群聊成员 - """ + ''' try: lock.acquire(True) if strtalker in self.ChatRoomMap: @@ -164,18 +167,17 @@ def get_chatroom_member_list(self, strtalker): if chatroom is None: return None # 解析RoomData数据 - parsechatroom = parseChatRoomData(chatroom[1]) + parsechatroom = ChatRoomData() + parsechatroom.ParseFromString(chatroom[1]) # 群成员数据放入字典存储 - print(parsechatroom[7]) - for mem in parsechatroom[1]: - if mem[2] is not None and len(mem[2]) > 0: - membermap[mem[1]] = mem[2] # wxid -> displayname + for mem in parsechatroom.members: + if mem.displayName is not None and len(mem.displayName) > 0: + membermap[mem.wxID] = mem.displayName self.ChatRoomMap[strtalker] = membermap finally: lock.release() return membermap - if __name__ == "__main__": p = PackageMsg() - print(p.get_package_message_by_wxid("18508451193@chatroom")) + print(p.get_package_message_by_wxid("48615079469@chatroom")) diff --git a/app/util/compress_content.py b/app/util/compress_content.py index 52e80891..f8397e4f 100644 --- a/app/util/compress_content.py +++ b/app/util/compress_content.py @@ -8,7 +8,7 @@ from urllib.parse import urlparse from bs4 import BeautifulSoup -from app.DataBase.hard_link import parseBytesExtra +from app.DataBase.hard_link import parseBytes from ..util.file import get_file @@ -149,15 +149,15 @@ def share_card(bytesExtra, compress_content_): else: if appinfo is not None: show_display_name = appinfo.find('appname').text - bytesDict = parseBytesExtra(bytesExtra) + bytesDict = parseBytes(bytesExtra) app_logo = '' thumbnail = '' for msginfo in bytesDict[3]: - if msginfo[1] == 3: - thumbnail = msginfo[2] + if msginfo[1][1][1] == 3: + thumbnail = msginfo[1][2][1] thumbnail = "\\".join(thumbnail.split('\\')[1:]) - if msginfo[1] == 4: - app_logo = msginfo[2] + if msginfo[1][1][1] == 4: + app_logo = msginfo[1][2][1] app_logo = "\\".join(app_logo.split('\\')[1:]) if sourceusername is not None: from app.DataBase import micro_msg_db # 放上面会导致循环依赖 diff --git a/app/util/file.py b/app/util/file.py index cb1f48f0..8c8562f0 100644 --- a/app/util/file.py +++ b/app/util/file.py @@ -5,7 +5,7 @@ import requests from app.log import log, logger -from app.DataBase.hard_link import parseBytesExtra +from app.util.protocbuf.msg_pb2 import MessageBytesExtra from ..person import Me root_path = './data/files/' @@ -22,13 +22,14 @@ def __init__(self): def get_file(bytes_extra, file_name, output_path=root_path) -> str: try: - msg_bytes = parseBytesExtra(bytes_extra) + msg_bytes = MessageBytesExtra() + msg_bytes.ParseFromString(bytes_extra) file_path = '' real_path = '' - if len(msg_bytes[3]) > 0: - for filed in msg_bytes[3]: - if filed[1] == 4: - file_original_path = filed[2] + if len(msg_bytes.message2) > 0: + for filed in msg_bytes.message2: + if filed.field1 == 4: + file_original_path = filed.field2 file_path = os.path.join(output_path, file_name) if os.path.exists(file_path): # print('文件' + file_path + '已存在') diff --git a/app/util/music.py b/app/util/music.py index 873f5546..6ad9296e 100644 --- a/app/util/music.py +++ b/app/util/music.py @@ -3,7 +3,7 @@ import shutil from app.log import log, logger -from app.DataBase.hard_link import parseBytesExtra +from app.util.protocbuf.msg_pb2 import MessageBytesExtra import requests from urllib.parse import urlparse, parse_qs import re diff --git a/app/util/protocbuf/__init__.py b/app/util/protocbuf/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/app/util/protocbuf/msg.proto b/app/util/protocbuf/msg.proto new file mode 100644 index 00000000..1d88cecb --- /dev/null +++ b/app/util/protocbuf/msg.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package app.protobuf; +option go_package=".;proto"; + +message SubMessage1 { + int32 field1 = 1; + int32 field2 = 2; +} + +message SubMessage2 { + int32 field1 = 1; + string field2 = 2; +} + +message MessageBytesExtra { + SubMessage1 message1 = 1; + repeated SubMessage2 message2 = 3; +} diff --git a/app/util/protocbuf/msg_pb2.py b/app/util/protocbuf/msg_pb2.py new file mode 100644 index 00000000..f5f31c5c --- /dev/null +++ b/app/util/protocbuf/msg_pb2.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: msg.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\tmsg.proto\x12\x0c\x61pp.protobuf\"-\n\x0bSubMessage1\x12\x0e\n\x06\x66ield1\x18\x01 \x01(\x05\x12\x0e\n\x06\x66ield2\x18\x02 \x01(\x05\"-\n\x0bSubMessage2\x12\x0e\n\x06\x66ield1\x18\x01 \x01(\x05\x12\x0e\n\x06\x66ield2\x18\x02 \x01(\t\"m\n\x11MessageBytesExtra\x12+\n\x08message1\x18\x01 \x01(\x0b\x32\x19.app.protobuf.SubMessage1\x12+\n\x08message2\x18\x03 \x03(\x0b\x32\x19.app.protobuf.SubMessage2b\x06proto3') + + + +_SUBMESSAGE1 = DESCRIPTOR.message_types_by_name['SubMessage1'] +_SUBMESSAGE2 = DESCRIPTOR.message_types_by_name['SubMessage2'] +_MESSAGEBYTESEXTRA = DESCRIPTOR.message_types_by_name['MessageBytesExtra'] +SubMessage1 = _reflection.GeneratedProtocolMessageType('SubMessage1', (_message.Message,), { + 'DESCRIPTOR' : _SUBMESSAGE1, + '__module__' : 'msg_pb2' + # @@protoc_insertion_point(class_scope:app.protobuf.SubMessage1) + }) +_sym_db.RegisterMessage(SubMessage1) + +SubMessage2 = _reflection.GeneratedProtocolMessageType('SubMessage2', (_message.Message,), { + 'DESCRIPTOR' : _SUBMESSAGE2, + '__module__' : 'msg_pb2' + # @@protoc_insertion_point(class_scope:app.protobuf.SubMessage2) + }) +_sym_db.RegisterMessage(SubMessage2) + +MessageBytesExtra = _reflection.GeneratedProtocolMessageType('MessageBytesExtra', (_message.Message,), { + 'DESCRIPTOR' : _MESSAGEBYTESEXTRA, + '__module__' : 'msg_pb2' + # @@protoc_insertion_point(class_scope:app.protobuf.MessageBytesExtra) + }) +_sym_db.RegisterMessage(MessageBytesExtra) + +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _SUBMESSAGE1._serialized_start=27 + _SUBMESSAGE1._serialized_end=72 + _SUBMESSAGE2._serialized_start=74 + _SUBMESSAGE2._serialized_end=119 + _MESSAGEBYTESEXTRA._serialized_start=121 + _MESSAGEBYTESEXTRA._serialized_end=230 +# @@protoc_insertion_point(module_scope) diff --git a/app/util/protocbuf/readme.md b/app/util/protocbuf/readme.md new file mode 100644 index 00000000..15b3c631 --- /dev/null +++ b/app/util/protocbuf/readme.md @@ -0,0 +1,34 @@ +# 说明 + +## 解析 +```shell +protoc --decode_raw < msg_data.txt +``` + +## 根据解析结果,设置.proto文件 +```shell +1 { + 1: 16 + 2: 0 +} +3 { + 1: 1 + 2: "wxid_4b1t09d63spw22" +} +3 { + 1: 7 + 2: "\n\t\n\t\t2\n\t\n\t\n\t\tc6680ab2c57499a1a22e44a7eada76e8_\n\t\n\t1\n\t198\n\tv1_Gj7hfmi5\n\t\n\t\t\n\t\n\n" +} +3 { + 1: 2 + 2: "c13acbc95512d1a59bb686d684fd64d8" +} +3 { + 1: 4 + 2: "yiluoAK_47\\FileStorage\\Cache\\2023-08\\2286b5852db82f6cbd9c2084ccd52358" +} +``` +## 生成python文件 +```shell +protoc --python_out=. msg.proto +``` \ No newline at end of file diff --git a/app/util/protocbuf/roomdata.proto b/app/util/protocbuf/roomdata.proto new file mode 100644 index 00000000..36b1f9ca --- /dev/null +++ b/app/util/protocbuf/roomdata.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package app.protobuf; +option go_package=".;proto"; + +message ChatRoomData { + message ChatRoomMember { + string wxID = 1; + string displayName = 2; + int32 state = 3; + } + repeated ChatRoomMember members = 1; + int32 field_2 = 2; + int32 field_3 = 3; + int32 field_4 = 4; + int32 room_capacity = 5; + int32 field_6 = 6; + int64 field_7 = 7; + int64 field_8 = 8; +} \ No newline at end of file diff --git a/app/util/protocbuf/roomdata_pb2.py b/app/util/protocbuf/roomdata_pb2.py new file mode 100644 index 00000000..7800214b --- /dev/null +++ b/app/util/protocbuf/roomdata_pb2.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: roomdata.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0eroomdata.proto\x12\x0c\x61pp.protobuf\"\x8b\x02\n\x0c\x43hatRoomData\x12:\n\x07members\x18\x01 \x03(\x0b\x32).app.protobuf.ChatRoomData.ChatRoomMember\x12\x0f\n\x07\x66ield_2\x18\x02 \x01(\x05\x12\x0f\n\x07\x66ield_3\x18\x03 \x01(\x05\x12\x0f\n\x07\x66ield_4\x18\x04 \x01(\x05\x12\x15\n\rroom_capacity\x18\x05 \x01(\x05\x12\x0f\n\x07\x66ield_6\x18\x06 \x01(\x05\x12\x0f\n\x07\x66ield_7\x18\x07 \x01(\x03\x12\x0f\n\x07\x66ield_8\x18\x08 \x01(\x03\x1a\x42\n\x0e\x43hatRoomMember\x12\x0c\n\x04wxID\x18\x01 \x01(\t\x12\x13\n\x0b\x64isplayName\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\x05\x62\x06proto3') + + + +_CHATROOMDATA = DESCRIPTOR.message_types_by_name['ChatRoomData'] +_CHATROOMDATA_CHATROOMMEMBER = _CHATROOMDATA.nested_types_by_name['ChatRoomMember'] +ChatRoomData = _reflection.GeneratedProtocolMessageType('ChatRoomData', (_message.Message,), { + + 'ChatRoomMember' : _reflection.GeneratedProtocolMessageType('ChatRoomMember', (_message.Message,), { + 'DESCRIPTOR' : _CHATROOMDATA_CHATROOMMEMBER, + '__module__' : 'roomdata_pb2' + # @@protoc_insertion_point(class_scope:app.protobuf.ChatRoomData.ChatRoomMember) + }) + , + 'DESCRIPTOR' : _CHATROOMDATA, + '__module__' : 'roomdata_pb2' + # @@protoc_insertion_point(class_scope:app.protobuf.ChatRoomData) + }) +_sym_db.RegisterMessage(ChatRoomData) +_sym_db.RegisterMessage(ChatRoomData.ChatRoomMember) + +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + _CHATROOMDATA._serialized_start=33 + _CHATROOMDATA._serialized_end=300 + _CHATROOMDATA_CHATROOMMEMBER._serialized_start=234 + _CHATROOMDATA_CHATROOMMEMBER._serialized_end=300 +# @@protoc_insertion_point(module_scope) diff --git a/requirements.txt b/requirements.txt index 326fae12..00a21069 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,8 @@ requests flask==3.0.0 pyecharts==2.0.1 jieba==0.42.1 +google==3.0.0 +protobuf==4.25.1 soupsieve==2.5 lz4==4.3.2 pilk==0.2.4 From f6ef6a8357d805fa2418ed330470a464136ca04e Mon Sep 17 00:00:00 2001 From: STDquantum <405720329@qq.com> Date: Fri, 5 Jan 2024 20:06:23 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E5=88=A0=E6=8E=89=E8=87=AA=E5=B7=B1?= =?UTF-8?q?=E5=86=99=E7=9A=84protobuf=EF=BC=9Bextrabuf=E6=8F=90=E9=80=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/DataBase/hard_link.py | 263 +++++------------------------ app/DataBase/msg.py | 15 +- app/resources/data/template.html | 10 +- app/util/compress_content.py | 15 +- app/util/protocbuf/extrabuf.proto | 11 ++ app/util/protocbuf/extrabuf_pb2.py | 29 ++++ 6 files changed, 109 insertions(+), 234 deletions(-) create mode 100644 app/util/protocbuf/extrabuf.proto create mode 100644 app/util/protocbuf/extrabuf_pb2.py diff --git a/app/DataBase/hard_link.py b/app/DataBase/hard_link.py index 22e93f82..a7bf1b92 100644 --- a/app/DataBase/hard_link.py +++ b/app/DataBase/hard_link.py @@ -5,6 +5,8 @@ import xml.etree.ElementTree as ET from app.log import log +from app.util.protocbuf.extrabuf_pb2 import ExtraBuf +from app.util.protocbuf.msg_pb2 import MessageBytesExtra image_db_lock = threading.Lock() video_db_lock = threading.Lock() @@ -30,224 +32,47 @@ def get_md5_from_xml(content, type_="img"): return None -class tencent_struct: - def __setVals__(self, data, off): - if data: - self.__data = data - if self.__data: - self.__size = len(self.__data) - self.__off = off - - def __readString(self): - try: - length = self.__readUleb() - res = self.__data[self.__off: self.__off + length] - self.__add(length) - except: - raise - return res.decode("utf-8") - - def __readUleb(self): - try: - i = self.__data[self.__off] - self.__add() - if i & 0x80: - j = self.__data[self.__off] - i = i & 0x7F - i = i | (j << 7) - self.__add() - if i & 0x4000: - j = self.__data[self.__off] - i = i & 0x3FFF - i = i | (j << 14) - self.__add() - if i & 0x200000: - j = self.__data[self.__off] - i = i & 0x1FFFFF - i = i | (j << 21) - self.__add() - if i & 0x10000000: - j = self.__data[self.__off] - i = i & 0xFFFFFFF - i = i | (j << 28) - self.__add() - return i - except: - raise - - def __readData(self): - try: - length = self.__readUleb() - data = self.__data[self.__off: self.__off + length] - self.__add(length) - return data - except: - raise - - def __init__(self, data=None, off=0): - self.__data = data - self.__off = off - if self.__data: - self.__size = len(self.__data) - else: - self.__size = 0 - - def __add(self, value=1): - self.__off += value - if self.__off > self.__size: - raise "偏移量超出size" - - def readStruct(self, struct_type): - current_dict = None - if isinstance(struct_type, str): - current_dict = getattr(self, struct_type) - else: - current_dict = struct_type - res = {} - try: - while self.__off < self.__size: - key = self.__readUleb() - key = key >> 3 - if key == 0: - break - op = None - fieldName = "" - if key in current_dict: - op = current_dict[key][1] - fieldName = current_dict[key][0] - else: - break - if isinstance(op, dict): - if not key in res: - res[key] = [] - current_struct = self.__readData() - recursion = tencent_struct(current_struct) - res[key].append((fieldName, recursion.readStruct(op))) - elif op != "": - res[key] = (fieldName, self.__contenttype__[op](self)) - else: - break - except: - raise - return res - - __struct1__ = {1: ("", "I"), 2: ("", "I")} - - __msgInfo__ = {1: ("", "I"), 2: ("msg_info", "s")} - - __bytesExtra__ = { - 1: ("", __struct1__), - 3: ("msg_info_struct", __msgInfo__), - } - - __struct2__ = {1: ("", "s"), 2: ("", "s")} - - __extraBuf__ = { - 1: ("", __struct2__), - } - - def get_bytesExta_Content(self, data=None, off=0): - self.__setVals__(data, off) - try: - return self.readStruct("__bytesExtra__") - except: - raise - - def get_extraBuf_Content(self, data=None, off=0): - self.__setVals__(data, off) - try: - return self.readStruct("__extraBuf__") - except: - raise - - __contenttype__ = { - "s": __readString, - "I": __readUleb, - "P": __readData, - } - - -def parseBytes(content: bytes): - try: - bytesExtra = tencent_struct().get_bytesExta_Content(content) - return bytesExtra - except: - pass - - -def parseExtraBuf(content: bytes): - try: - extraBuf = tencent_struct().get_extraBuf_Content(content) - return extraBuf - except: - pass - - def decodeExtraBuf(extra_buf_content: bytes): - off = 0 - types = [b"\x04", b"\x18", b"\x17", b"\x02", b"\x05"] trunkName = { - "46CF10C4": "个性签名", - "A4D9024A": "国家", - "E2EAA8D1": "省份", - "1D025BBF": "市", - "81AE19B4": "朋友圈背景url", - "F917BCC0": "公司名称", - "4EB96D85": "企业微信属性", - "0E719F13": "备注图片", - "759378AD": "手机号", - "74752C06": "性别", + b"\x46\xCF\x10\xC4": "个性签名", + b"\xA4\xD9\x02\x4A": "国家", + b"\xE2\xEA\xA8\xD1": "省份", + b"\x1D\x02\x5B\xBF": "市", + # b"\x81\xAE\x19\xB4": "朋友圈背景url", + # b"\xF9\x17\xBC\xC0": "公司名称", + # b"\x4E\xB9\x6D\x85": "企业微信属性", + # b"\x0E\x71\x9F\x13": "备注图片", + b"\x75\x93\x78\xAD": "手机号", + b"\x74\x75\x2C\x06": "性别", } - res = {'手机号': {'18': ''}} - while off < len(extra_buf_content): - length = 4 # 块头 - trunk_head = extra_buf_content[off: off + length] - off += length - trunk_head = binascii.hexlify(trunk_head).decode().upper() - if trunk_head in trunkName: - trunk_head = trunkName[trunk_head] - res[trunk_head] = {} - char = extra_buf_content[off: off + 1] + res = {"手机号": ""} + off = 0 + for key in trunkName: + trunk_head = trunkName[key] + try: + off = extra_buf_content.index(key) + 4 + except: + pass + char = extra_buf_content[off : off + 1] off += 1 - field = binascii.hexlify(char).decode() if char == b"\x04": # 四个字节的int,小端序 - length = 4 - intContent = extra_buf_content[off: off + length] + intContent = extra_buf_content[off : off + 4] off += 4 intContent = int.from_bytes(intContent, "little") - res[trunk_head][field] = intContent + res[trunk_head] = intContent elif char == b"\x18": # utf-16字符串 - length = 4 - lengthContent = extra_buf_content[off: off + length] - off += 4 - lengthContent = int.from_bytes(lengthContent, "little") - strContent = extra_buf_content[off: off + lengthContent] - off += lengthContent - res[trunk_head][field] = strContent.decode("utf-16").rstrip("\x00") - elif char == b"\x17": # utf-8 protobuf - length = 4 - lengthContent = extra_buf_content[off: off + length] + lengthContent = extra_buf_content[off : off + 4] off += 4 lengthContent = int.from_bytes(lengthContent, "little") - strContent = extra_buf_content[off: off + lengthContent] + strContent = extra_buf_content[off : off + lengthContent] off += lengthContent - res[trunk_head][field] = parseExtraBuf(strContent) - elif char == b"\x02": # 一个字节的int - content = extra_buf_content[off: off + 1] - off += 1 - res[trunk_head][field] = int.from_bytes(content, "little") - elif char == b"\x05": # 暂时不知道有啥用,固定8个字节,先当int处理 - length = 8 - content = extra_buf_content[off: off + length] - off += length - res[trunk_head][field] = int.from_bytes(content, "little") - # print(res) + res[trunk_head] = strContent.decode("utf-16").rstrip("\x00") return { - 'region': (res['国家']['18'], res['省份']['18'], res['市']['18']), - 'signature': res['个性签名']['18'], - 'telephone': res['手机号']['18'], - 'gender': res['性别']['04'] + "region": (res["国家"], res["省份"], res["市"]), + "signature": res["个性签名"], + "telephone": res["手机号"], + "gender": res["性别"], } @@ -337,12 +162,14 @@ def get_video_by_md5(self, md5: bytes): video_db_lock.release() def get_image(self, content, bytesExtra, thumb=False): - bytesDict = parseBytes(bytesExtra) - for msginfo in bytesDict[3]: - if msginfo[1][1][1] == (3 if thumb else 4): - pathh = msginfo[1][2][1] # wxid\FileStorage\... - pathh = "\\".join(pathh.split("\\")[1:]) - return pathh + msg_bytes = MessageBytesExtra() + msg_bytes.ParseFromString(bytesExtra) + for tmp in msg_bytes.message2: + if tmp.field1 != (3 if thumb else 4): + continue + pathh = tmp.field2 # wxid\FileStorage\... + pathh = "\\".join(pathh.split("\\")[1:]) + return pathh md5 = get_md5_from_xml(content) if not md5: return None @@ -357,12 +184,14 @@ def get_image(self, content, bytesExtra, thumb=False): return dat_image def get_video(self, content, bytesExtra, thumb=False): - bytesDict = parseBytes(bytesExtra) - for msginfo in bytesDict[3]: - if msginfo[1][1][1] == (3 if thumb else 4): - pathh = msginfo[1][2][1] # wxid\FileStorage\... - pathh = "\\".join(pathh.split("\\")[1:]) - return pathh + msg_bytes = MessageBytesExtra() + msg_bytes.ParseFromString(bytesExtra) + for tmp in msg_bytes.message2: + if tmp.field1 != (3 if thumb else 4): + continue + pathh = tmp.field2 # wxid\FileStorage\... + pathh = "\\".join(pathh.split("\\")[1:]) + return pathh md5 = get_md5_from_xml(content, type_="video") if not md5: return None diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index d1a7c44f..4c67639d 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -4,7 +4,6 @@ import threading import traceback -from app.DataBase.hard_link import parseBytes from app.log import logger from app.util.compress_content import parser_reply from app.util.protocbuf.msg_pb2 import MessageBytesExtra @@ -651,12 +650,12 @@ def __del__(self): else: show_display_name = appinfo.find('appname').text print(title, des, url, show_display_name) - bytesDict = parseBytes(msg[10]) - for msginfo in bytesDict[3]: - print(msginfo) - if msginfo[1][1][1] == 3: - thumb = msginfo[1][2][1] + msg_bytes = MessageBytesExtra() + msg_bytes.ParseFromString(msg[10]) + for tmp in msg_bytes.message2: + if tmp.field1 == 3: + thumb = tmp.field2 print(thumb) - if msginfo[1][1][1] == 4: - app_logo = msginfo[1][2][1] + if tmp.field2 == 4: + app_logo = tmp.field2 print('logo',app_logo) \ No newline at end of file diff --git a/app/resources/data/template.html b/app/resources/data/template.html index 939bb7ac..92b55fdc 100644 --- a/app/resources/data/template.html +++ b/app/resources/data/template.html @@ -465,6 +465,12 @@ margin-left: 5px; } } + +.system-msg>.emoji_img { + width: 18px; + height: 18px; +} + .emoji_img { width: 22px; height: 22px; @@ -802,7 +808,7 @@ // 从数据列表中取出对应范围的元素并添加到容器中 for (let i = startIndex; i < endIndex && i < chatMessages.length; i++) { const message = chatMessages[i]; - if (i == startIndex) { // 判断一下在页面顶部多加一个时间 + if (i == startIndex && (reachedBottom ? !/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(chatMessages[i - 1].text) : 1)) { // 判断一下在页面顶部多加一个时间 if (!/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(message.text)) { // 时间戳转成时间 function timestampToTime(timestamp) { @@ -843,7 +849,7 @@ } else if (message.type == 0) { messageElement.className = "item item-center"; - messageElement.innerHTML = `${message.text}`; + messageElement.innerHTML = `${replaceEmoji(message.text)}`; } else if (message.type == 3) { // displayname 和 img diff --git a/app/util/compress_content.py b/app/util/compress_content.py index f8397e4f..bb6ab148 100644 --- a/app/util/compress_content.py +++ b/app/util/compress_content.py @@ -8,7 +8,7 @@ from urllib.parse import urlparse from bs4 import BeautifulSoup -from app.DataBase.hard_link import parseBytes +from app.util.protocbuf.msg_pb2 import MessageBytesExtra from ..util.file import get_file @@ -149,15 +149,16 @@ def share_card(bytesExtra, compress_content_): else: if appinfo is not None: show_display_name = appinfo.find('appname').text - bytesDict = parseBytes(bytesExtra) + msg_bytes = MessageBytesExtra() + msg_bytes.ParseFromString(bytesExtra) app_logo = '' thumbnail = '' - for msginfo in bytesDict[3]: - if msginfo[1][1][1] == 3: - thumbnail = msginfo[1][2][1] + for tmp in msg_bytes.message2: + if tmp.field1 == 3: + thumbnail = tmp.field2 thumbnail = "\\".join(thumbnail.split('\\')[1:]) - if msginfo[1][1][1] == 4: - app_logo = msginfo[1][2][1] + if tmp.field2 == 4: + app_logo = tmp.field2 app_logo = "\\".join(app_logo.split('\\')[1:]) if sourceusername is not None: from app.DataBase import micro_msg_db # 放上面会导致循环依赖 diff --git a/app/util/protocbuf/extrabuf.proto b/app/util/protocbuf/extrabuf.proto new file mode 100644 index 00000000..d9120689 --- /dev/null +++ b/app/util/protocbuf/extrabuf.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package app.protobuf; +option go_package=".;proto"; + +message ExtraBuf { + message Struct { + string field1 = 1; + string field2 = 2; + } + repeated Struct content = 1; +} \ No newline at end of file diff --git a/app/util/protocbuf/extrabuf_pb2.py b/app/util/protocbuf/extrabuf_pb2.py new file mode 100644 index 00000000..76a5afbb --- /dev/null +++ b/app/util/protocbuf/extrabuf_pb2.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: extrabuf.proto +# Protobuf Python Version: 4.25.0 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0e\x65xtrabuf.proto\x12\x0c\x61pp.protobuf\"d\n\x08\x45xtraBuf\x12.\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x1d.app.protobuf.ExtraBuf.Struct\x1a(\n\x06Struct\x12\x0e\n\x06\x66ield1\x18\x01 \x01(\t\x12\x0e\n\x06\x66ield2\x18\x02 \x01(\tB\tZ\x07.;protob\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'extrabuf_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'Z\007.;proto' + _globals['_EXTRABUF']._serialized_start=32 + _globals['_EXTRABUF']._serialized_end=132 + _globals['_EXTRABUF_STRUCT']._serialized_start=92 + _globals['_EXTRABUF_STRUCT']._serialized_end=132 +# @@protoc_insertion_point(module_scope) From ce3e130481eac333333843ff0e2fef1585027664 Mon Sep 17 00:00:00 2001 From: STDquantum <405720329@qq.com> Date: Fri, 5 Jan 2024 20:10:44 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E4=BC=BC=E4=B9=8E=E7=8E=B0=E5=9C=A8?= =?UTF-8?q?=E5=B9=B6=E4=B8=8D=E9=9C=80=E8=A6=81extrabuf=E9=82=A3=E4=B8=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/DataBase/hard_link.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/DataBase/hard_link.py b/app/DataBase/hard_link.py index a7bf1b92..cc6ab0d3 100644 --- a/app/DataBase/hard_link.py +++ b/app/DataBase/hard_link.py @@ -5,7 +5,6 @@ import xml.etree.ElementTree as ET from app.log import log -from app.util.protocbuf.extrabuf_pb2 import ExtraBuf from app.util.protocbuf.msg_pb2 import MessageBytesExtra image_db_lock = threading.Lock() From 7406f71b55fe48cad07d2ac9598408a5ef068ab8 Mon Sep 17 00:00:00 2001 From: STDquantum <405720329@qq.com> Date: Fri, 5 Jan 2024 20:11:11 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E5=88=A0=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/util/protocbuf/extrabuf.proto | 11 ----------- app/util/protocbuf/extrabuf_pb2.py | 29 ----------------------------- 2 files changed, 40 deletions(-) delete mode 100644 app/util/protocbuf/extrabuf.proto delete mode 100644 app/util/protocbuf/extrabuf_pb2.py diff --git a/app/util/protocbuf/extrabuf.proto b/app/util/protocbuf/extrabuf.proto deleted file mode 100644 index d9120689..00000000 --- a/app/util/protocbuf/extrabuf.proto +++ /dev/null @@ -1,11 +0,0 @@ -syntax = "proto3"; -package app.protobuf; -option go_package=".;proto"; - -message ExtraBuf { - message Struct { - string field1 = 1; - string field2 = 2; - } - repeated Struct content = 1; -} \ No newline at end of file diff --git a/app/util/protocbuf/extrabuf_pb2.py b/app/util/protocbuf/extrabuf_pb2.py deleted file mode 100644 index 76a5afbb..00000000 --- a/app/util/protocbuf/extrabuf_pb2.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: extrabuf.proto -# Protobuf Python Version: 4.25.0 -"""Generated protocol buffer code.""" -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -from google.protobuf.internal import builder as _builder -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0e\x65xtrabuf.proto\x12\x0c\x61pp.protobuf\"d\n\x08\x45xtraBuf\x12.\n\x07\x63ontent\x18\x01 \x03(\x0b\x32\x1d.app.protobuf.ExtraBuf.Struct\x1a(\n\x06Struct\x12\x0e\n\x06\x66ield1\x18\x01 \x01(\t\x12\x0e\n\x06\x66ield2\x18\x02 \x01(\tB\tZ\x07.;protob\x06proto3') - -_globals = globals() -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'extrabuf_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - _globals['DESCRIPTOR']._options = None - _globals['DESCRIPTOR']._serialized_options = b'Z\007.;proto' - _globals['_EXTRABUF']._serialized_start=32 - _globals['_EXTRABUF']._serialized_end=132 - _globals['_EXTRABUF_STRUCT']._serialized_start=92 - _globals['_EXTRABUF_STRUCT']._serialized_end=132 -# @@protoc_insertion_point(module_scope) From 51b5b637c57ed7613cd8d688c96b72ef772686b5 Mon Sep 17 00:00:00 2001 From: STDquantum <405720329@qq.com> Date: Fri, 5 Jan 2024 20:25:52 +0800 Subject: [PATCH 6/6] .avatar user-select:none --- app/resources/data/template.html | 1 + 1 file changed, 1 insertion(+) diff --git a/app/resources/data/template.html b/app/resources/data/template.html index 92b55fdc..83c48197 100644 --- a/app/resources/data/template.html +++ b/app/resources/data/template.html @@ -173,6 +173,7 @@ width: 42px; height: 42px; border-radius: 50%; + user-select: none; } .chat-video video{ margin-right: 18px;