mirror of
https://github.com/LC044/WeChatMsg
synced 2024-11-09 09:31:18 +08:00
导出csv文件时,增加发送人名称、接受者名称、备注名字段
This commit is contained in:
parent
4a357dca24
commit
0aa1ac964f
@ -63,6 +63,37 @@ class MicroMsg:
|
||||
lock.release()
|
||||
return result
|
||||
|
||||
def get_contact_by_username(self, username):
|
||||
if not self.open_flag:
|
||||
return None
|
||||
try:
|
||||
lock.acquire(True)
|
||||
sql = '''SELECT UserName, Alias, Type, Remark, NickName, PYInitial, RemarkPYInitial, ContactHeadImgUrl.smallHeadImgUrl, ContactHeadImgUrl.bigHeadImgUrl
|
||||
FROM Contact
|
||||
INNER JOIN ContactHeadImgUrl ON Contact.UserName = ContactHeadImgUrl.usrName
|
||||
WHERE UserName = ?
|
||||
'''
|
||||
self.cursor.execute(sql, [username])
|
||||
result = self.cursor.fetchone()
|
||||
finally:
|
||||
lock.release()
|
||||
return result
|
||||
|
||||
def get_chatroom_info(self, chatroomname):
|
||||
'''
|
||||
获取群聊信息
|
||||
'''
|
||||
if not self.open_flag:
|
||||
return None
|
||||
try:
|
||||
lock.acquire(True)
|
||||
sql = '''SELECT ChatRoomName, RoomData FROM ChatRoom WHERE ChatRoomName = ?'''
|
||||
self.cursor.execute(sql, [chatroomname])
|
||||
result = self.cursor.fetchone()
|
||||
finally:
|
||||
lock.release()
|
||||
return result
|
||||
|
||||
def close(self):
|
||||
if self.open_flag:
|
||||
try:
|
||||
|
@ -72,7 +72,7 @@ class Msg:
|
||||
|
||||
def get_messages_all(self):
|
||||
sql = '''
|
||||
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID
|
||||
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra,StrTalker,Reserved1
|
||||
from MSG
|
||||
order by CreateTime
|
||||
'''
|
||||
|
@ -5,6 +5,7 @@ import os
|
||||
from PyQt5.QtCore import pyqtSignal, QThread
|
||||
|
||||
from . import msg_db
|
||||
from .package_msg import PackageMsg
|
||||
from ..DataBase import hard_link_db
|
||||
from ..person_pc import MePC
|
||||
from ..util import get_abs_path
|
||||
@ -65,8 +66,10 @@ class Output(QThread):
|
||||
# columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"]
|
||||
columns = ['localId', 'TalkerId', 'Type', 'SubType',
|
||||
'IsSender', 'CreateTime', 'Status', 'StrContent',
|
||||
'StrTime']
|
||||
messages = msg_db.get_messages_all()
|
||||
'StrTime', 'Remark', 'NickName', 'Sender']
|
||||
# messages = msg_db.get_messages_all()
|
||||
packagemsg = PackageMsg()
|
||||
messages = packagemsg.get_package_message_all()
|
||||
# 写入CSV文件
|
||||
with open(filename, mode='w', newline='', encoding='utf-8') as file:
|
||||
writer = csv.writer(file)
|
||||
@ -165,8 +168,10 @@ class ChildThread(QThread):
|
||||
# columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"]
|
||||
columns = ['localId', 'TalkerId', 'Type', 'SubType',
|
||||
'IsSender', 'CreateTime', 'Status', 'StrContent',
|
||||
'StrTime']
|
||||
messages = msg_db.get_messages_all()
|
||||
'StrTime', 'Remark', 'NickName', 'Sender']
|
||||
# messages = msg_db.get_messages_all()
|
||||
packagemsg = PackageMsg()
|
||||
messages = packagemsg.get_package_message_all()
|
||||
# 写入CSV文件
|
||||
with open(filename, mode='w', newline='', encoding='utf-8') as file:
|
||||
writer = csv.writer(file)
|
||||
|
103
app/DataBase/package_msg.py
Normal file
103
app/DataBase/package_msg.py
Normal file
@ -0,0 +1,103 @@
|
||||
import threading
|
||||
|
||||
from app.DataBase import msg_db, micro_msg_db
|
||||
from app.util.protocbuf.msg_pb2 import MessageBytesExtra
|
||||
from app.util.protocbuf.roomdata_pb2 import ChatRoomData
|
||||
|
||||
lock = threading.Lock()
|
||||
|
||||
|
||||
def singleton(cls):
|
||||
_instance = {}
|
||||
|
||||
def inner():
|
||||
if cls not in _instance:
|
||||
_instance[cls] = cls()
|
||||
return _instance[cls]
|
||||
|
||||
return inner
|
||||
|
||||
|
||||
@singleton
|
||||
class PackageMsg:
|
||||
def __init__(self):
|
||||
self.ChatRoomMap = {}
|
||||
|
||||
def get_package_message_all(self):
|
||||
'''
|
||||
获取完整的聊天记录
|
||||
'''
|
||||
updated_messages = [] # 用于存储修改后的消息列表
|
||||
|
||||
messages = msg_db.get_messages_all()
|
||||
for row in messages:
|
||||
row_list = list(row)
|
||||
# 删除不使用的几个字段
|
||||
del row_list[12]
|
||||
del row_list[11]
|
||||
del row_list[10]
|
||||
|
||||
strtalker = row[11]
|
||||
info = micro_msg_db.get_contact_by_username(strtalker)
|
||||
if info is not None:
|
||||
row_list.append(info[3])
|
||||
row_list.append(info[4])
|
||||
# 判断是否是群聊
|
||||
if strtalker.__contains__('@chatroom'):
|
||||
# 自己发送
|
||||
if row[12] == 1:
|
||||
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:
|
||||
continue
|
||||
wxid = tmp.field2
|
||||
sender = ''
|
||||
# 获取群聊成员列表
|
||||
membersMap = self.get_chatroom_member_list(strtalker)
|
||||
if membersMap is not None:
|
||||
if wxid in membersMap:
|
||||
sender = membersMap.get(wxid)
|
||||
else:
|
||||
senderinfo = micro_msg_db.get_contact_by_username(wxid)
|
||||
if senderinfo is not None:
|
||||
sender = senderinfo[4]
|
||||
membersMap[wxid] = senderinfo[4]
|
||||
if len(senderinfo[3]) > 0:
|
||||
sender = senderinfo[3]
|
||||
membersMap[wxid] = senderinfo[3]
|
||||
row_list.append(sender)
|
||||
updated_messages.append(tuple(row_list))
|
||||
return updated_messages
|
||||
|
||||
def get_chatroom_member_list(self, strtalker):
|
||||
membermap = {}
|
||||
'''
|
||||
获取群聊成员
|
||||
'''
|
||||
try:
|
||||
lock.acquire(True)
|
||||
if strtalker in self.ChatRoomMap:
|
||||
membermap = self.ChatRoomMap.get(strtalker)
|
||||
else:
|
||||
chatroom = micro_msg_db.get_chatroom_info(strtalker)
|
||||
if chatroom is None:
|
||||
return None
|
||||
# 解析RoomData数据
|
||||
parsechatroom = ChatRoomData()
|
||||
parsechatroom.ParseFromString(chatroom[1])
|
||||
# 群成员数据放入字典存储
|
||||
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
|
0
app/util/protocbuf/__init__.py
Normal file
0
app/util/protocbuf/__init__.py
Normal file
18
app/util/protocbuf/msg.proto
Normal file
18
app/util/protocbuf/msg.proto
Normal file
@ -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;
|
||||
}
|
54
app/util/protocbuf/msg_pb2.py
Normal file
54
app/util/protocbuf/msg_pb2.py
Normal file
@ -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)
|
34
app/util/protocbuf/readme.md
Normal file
34
app/util/protocbuf/readme.md
Normal file
@ -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: "<msgsource>\n\t<alnode>\n\t\t<fr>2</fr>\n\t</alnode>\n\t<sec_msg_node>\n\t\t<uuid>c6680ab2c57499a1a22e44a7eada76e8_</uuid>\n\t</sec_msg_node>\n\t<silence>1</silence>\n\t<membercount>198</membercount>\n\t<signature>v1_Gj7hfmi5</signature>\n\t<tmp_node>\n\t\t<publisher-id></publisher-id>\n\t</tmp_node>\n</msgsource>\n"
|
||||
}
|
||||
3 {
|
||||
1: 2
|
||||
2: "c13acbc95512d1a59bb686d684fd64d8"
|
||||
}
|
||||
3 {
|
||||
1: 4
|
||||
2: "yiluoAK_47\\FileStorage\\Cache\\2023-08\\2286b5852db82f6cbd9c2084ccd52358"
|
||||
}
|
||||
```
|
||||
## 生成python文件
|
||||
```shell
|
||||
protoc --python_out=. msg.proto
|
||||
```
|
19
app/util/protocbuf/roomdata.proto
Normal file
19
app/util/protocbuf/roomdata.proto
Normal file
@ -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;
|
||||
}
|
45
app/util/protocbuf/roomdata_pb2.py
Normal file
45
app/util/protocbuf/roomdata_pb2.py
Normal file
@ -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)
|
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
Loading…
Reference in New Issue
Block a user