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;