mirror of
https://github.com/LC044/WeChatMsg
synced 2025-02-22 10:52:18 +08:00
Merge branch 'master' into master
This commit is contained in:
commit
050920d2c0
@ -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
|
||||
'''
|
||||
@ -126,19 +126,19 @@ class Msg:
|
||||
lock.release()
|
||||
return result
|
||||
|
||||
def get_messages_by_keyword(self, username_, keyword, num=5):
|
||||
def get_messages_by_keyword(self, username_, keyword, num=5, max_len=10):
|
||||
if not self.open_flag:
|
||||
return None
|
||||
sql = '''
|
||||
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID
|
||||
from MSG
|
||||
where StrTalker=? and Type=1 and StrContent like ?
|
||||
where StrTalker=? and Type=1 and LENGTH(StrContent)<? and StrContent like ?
|
||||
order by CreateTime desc
|
||||
'''
|
||||
temp = []
|
||||
try:
|
||||
lock.acquire(True)
|
||||
self.cursor.execute(sql, [username_, f'%{keyword}%'])
|
||||
self.cursor.execute(sql, [username_, max_len, f'%{keyword}%'])
|
||||
messages = self.cursor.fetchall()
|
||||
finally:
|
||||
lock.release()
|
||||
@ -213,4 +213,4 @@ if __name__ == '__main__':
|
||||
pprint(msg.get_message_by_num('wxid_0o18ef858vnu22', local_id))
|
||||
print(msg.get_messages_by_keyword(wxid, '干嘛'))
|
||||
pprint(msg.get_messages_by_keyword(wxid, '干嘛')[0])
|
||||
print(msg.get_first_time_of_message('wxid_0o18ef858vnu22'))
|
||||
print(msg.get_first_time_of_message('wxid_fervbwign7m822'))
|
||||
|
@ -5,13 +5,23 @@ 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
|
||||
from ..util import path
|
||||
|
||||
os.makedirs('./data/聊天记录', exist_ok=True)
|
||||
|
||||
|
||||
def makedirs(path):
|
||||
os.makedirs(path,exist_ok=True)
|
||||
os.makedirs(os.path.join(path, 'image'), exist_ok=True)
|
||||
os.makedirs(os.path.join(path, 'emoji'), exist_ok=True)
|
||||
os.makedirs(os.path.join(path, 'video'), exist_ok=True)
|
||||
os.makedirs(os.path.join(path, 'voice'), exist_ok=True)
|
||||
os.makedirs(os.path.join(path, 'file'), exist_ok=True)
|
||||
|
||||
|
||||
def escape_js_and_html(input_str):
|
||||
# 转义HTML特殊字符
|
||||
html_escaped = html.escape(input_str, quote=False)
|
||||
@ -65,8 +75,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 +177,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)
|
||||
@ -434,7 +448,7 @@ class ChildThread(QThread):
|
||||
|
||||
def to_html_(self):
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
os.makedirs(origin_docx_path, exist_ok=True)
|
||||
makedirs(origin_docx_path)
|
||||
messages = msg_db.get_messages(self.contact.wxid)
|
||||
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.html"
|
||||
f = open(filename, 'w', encoding='utf-8')
|
||||
@ -671,6 +685,13 @@ input {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.emoji_img {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
position: relative;
|
||||
bottom: -6px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -723,6 +744,116 @@ const chatMessages = [
|
||||
MePC().avatar.save(os.path.join(origin_docx_path, 'myhead.png'))
|
||||
self.contact.avatar.save(os.path.join(origin_docx_path, 'tahead.png'))
|
||||
self.rangeSignal.emit(len(messages))
|
||||
emoji = {
|
||||
'[微笑]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_1@2x.png" id="微笑" class="emoji_img">',
|
||||
'[撇嘴]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_2@2x.png" id="撇嘴" class="emoji_img">',
|
||||
'[色]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_3@2x.png" id="色" class="emoji_img">',
|
||||
'[发呆]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_4@2x.png" id="发呆" class="emoji_img">',
|
||||
'[得意]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_5@2x.png" id="得意" class="emoji_img">',
|
||||
'[流泪]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_6@2x.png" id="流泪" class="emoji_img">',
|
||||
'[害羞]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_7@2x.png" id="害羞" class="emoji_img">',
|
||||
'[闭嘴]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_8@2x.png" id="闭嘴" class="emoji_img">',
|
||||
'[睡]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_9@2x.png" id="睡" class="emoji_img">',
|
||||
'[大哭]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_10@2x.png" id="大哭" class="emoji_img">',
|
||||
'[尴尬]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_11@2x.png" id="尴尬" class="emoji_img">',
|
||||
'[发怒]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_12@2x.png" id="发怒" class="emoji_img">',
|
||||
'[调皮]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_13@2x.png" id="调皮" class="emoji_img">',
|
||||
'[呲牙]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_14@2x.png" id="呲牙" class="emoji_img">',
|
||||
'[惊讶]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_15@2x.png" id="惊讶" class="emoji_img">',
|
||||
'[难过]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_16@2x.png" id="难过" class="emoji_img">',
|
||||
'[抓狂]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_19@2x.png" id="抓狂" class="emoji_img">',
|
||||
'[吐]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_20@2x.png" id="吐" class="emoji_img">',
|
||||
'[偷笑]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_21@2x.png" id="偷笑" class="emoji_img">',
|
||||
'[愉快]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_22@2x.png" id="愉快" class="emoji_img">',
|
||||
'[白眼]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_23@2x.png" id="白 眼" class="emoji_img">',
|
||||
'[傲慢]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_24@2x.png" id="傲慢" class="emoji_img">',
|
||||
'[困]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_26@2x.png" id="困" class="emoji_img">',
|
||||
'[惊恐]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_27@2x.png" id="惊恐" class="emoji_img">',
|
||||
'[憨笑]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_29@2x.png" id="憨笑" class="emoji_img">',
|
||||
'[悠闲]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_30@2x.png" id="悠闲" class="emoji_img">',
|
||||
'[咒骂]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_32@2x.png" id="咒骂" class="emoji_img">',
|
||||
'[疑问]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_33@2x.png" id="疑问" class="emoji_img">',
|
||||
'[嘘]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_34@2x.png" id="嘘" class="emoji_img">',
|
||||
'[晕]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_35@2x.png" id="晕" class="emoji_img">',
|
||||
'[衰]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_37@2x.png" id="衰" class="emoji_img">',
|
||||
'[骷髅]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_38@2x.png" id="骷髅" class="emoji_img">',
|
||||
'[敲打]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_39@2x.png" id="敲打" class="emoji_img">',
|
||||
'[再见]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_40@2x.png" id="再见" class="emoji_img">',
|
||||
'[擦汗]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_41@2x.png" id="擦汗" class="emoji_img">',
|
||||
'[抠鼻]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_42@2x.png" id="抠鼻" class="emoji_img">',
|
||||
'[鼓掌]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_43@2x.png" id="鼓掌" class="emoji_img">',
|
||||
'[坏笑]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_45@2x.png" id="坏笑" class="emoji_img">',
|
||||
'[右哼哼]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_47@2x.png" id="右哼哼" class="emoji_img">',
|
||||
'[鄙视]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_49@2x.png" id="鄙视" class="emoji_img">',
|
||||
'[委屈]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_50@2x.png" id="委屈" class="emoji_img">',
|
||||
'[快哭了]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_51@2x.png" id="快哭了" class="emoji_img">',
|
||||
'[阴险]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_52@2x.png" id="阴险" class="emoji_img">',
|
||||
'[亲亲]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_53@2x.png" id="亲亲" class="emoji_img">',
|
||||
'[可怜]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_55@2x.png" id="可怜" class="emoji_img">',
|
||||
'[笑脸]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Happy.png" id="笑脸" class="emoji_img">',
|
||||
'[生病]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Sick.png" id="生病" class="emoji_img">',
|
||||
'[脸红]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Flushed.png" id="脸红" class="emoji_img">',
|
||||
'[破涕为笑]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Lol.png" id="破涕为笑" class="emoji_img">',
|
||||
'[恐惧]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Terror.png" id="恐惧" class="emoji_img">',
|
||||
'[失望]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/LetDown.png" id="失望" class="emoji_img">',
|
||||
'[无语]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Duh.png" id="无语" class="emoji_img">',
|
||||
'[嘿哈]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_04.png" id="嘿哈" class="emoji_img">',
|
||||
'[捂脸]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_05.png" id="捂脸" class="emoji_img">',
|
||||
'[奸笑]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_02.png" id="奸笑" class="emoji_img">',
|
||||
'[机智]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_06.png" id="机智" class="emoji_img">',
|
||||
'[皱眉]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_12.png" id="皱眉" class="emoji_img">',
|
||||
'[耶]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_11.png" id="耶" class="emoji_img">',
|
||||
'[吃瓜]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Watermelon.png" id="吃瓜" class="emoji_img">',
|
||||
'[加油]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Addoil.png" id="加油" class="emoji_img">',
|
||||
'[汗]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Sweat.png" id="汗" class="emoji_img">',
|
||||
'[天啊]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Shocked.png" id="天啊" class="emoji_img">',
|
||||
'[Emm]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Cold.png" id="Emm" class="emoji_img">',
|
||||
'[社会社会]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Social.png" id="社会社会" class="emoji_img">',
|
||||
'[旺柴]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Yellowdog.png" id="旺柴" class="emoji_img">',
|
||||
'[好的]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/NoProb.png" id="好的" class="emoji_img">',
|
||||
'[打脸]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Slap.png" id="打脸" class="emoji_img">',
|
||||
'[哇]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Wow.png" id="哇" class="emoji_img">',
|
||||
'[翻白眼]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Boring.png" id="翻白眼" class="emoji_img">',
|
||||
'[666]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/666.png" id="666" class="emoji_img">',
|
||||
'[让我看看]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/LetMeSee.png" id="让我看看" class="emoji_img">',
|
||||
'[叹气]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Sigh.png" id="叹气" class="emoji_img">',
|
||||
'[苦涩]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Hurt.png" id="苦涩" class="emoji_img">',
|
||||
'[裂开]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Broken.png" id="裂开" class="emoji_img">',
|
||||
'[嘴唇]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_66@2x.png" id="嘴唇" class="emoji_img">',
|
||||
'[爱心]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_67@2x.png" id="爱心" class="emoji_img">',
|
||||
'[心碎]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_68@2x.png" id="心碎" class="emoji_img">',
|
||||
'[拥抱]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_79@2x.png" id="拥抱" class="emoji_img">',
|
||||
'[强]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_80@2x.png" id="强" class="emoji_img">',
|
||||
'[弱]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_81@2x.png" id="弱" class="emoji_img">',
|
||||
'[握手]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_82@2x.png" id="握手" class="emoji_img">',
|
||||
'[胜利]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_83@2x.png" id="胜利" class="emoji_img">',
|
||||
'[抱拳]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_84@2x.png" id="抱拳" class="emoji_img">',
|
||||
'[勾引]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_85@2x.png" id="勾引" class="emoji_img">',
|
||||
'[拳头]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_86@2x.png" id="拳头" class="emoji_img">',
|
||||
'[OK]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_90@2x.png" id="OK" class="emoji_img">',
|
||||
'[合十]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Worship.png" id="合十" class="emoji_img">',
|
||||
'[啤酒]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_58@2x.png" id="啤酒" class="emoji_img">',
|
||||
'[咖啡]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_61@2x.png" id="咖啡" class="emoji_img">',
|
||||
'[蛋糕]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_69@2x.png" id="蛋糕" class="emoji_img">',
|
||||
'[玫瑰]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_64@2x.png" id="玫 瑰" class="emoji_img">',
|
||||
'[凋谢]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_65@2x.png" id="凋谢" class="emoji_img">',
|
||||
'[菜刀]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_56@2x.png" id="菜刀" class="emoji_img">',
|
||||
'[炸弹]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_71@2x.png" id="炸弹" class="emoji_img">',
|
||||
'[便便]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_75@2x.png" id="便便" class="emoji_img">',
|
||||
'[月亮]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_76@2x.png" id="月亮" class="emoji_img">',
|
||||
'[太阳]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_77@2x.png" id="太阳" class="emoji_img">',
|
||||
'[庆 祝]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Party.png" id="庆祝" class="emoji_img">',
|
||||
'[礼物]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_78@2x.png" id="礼物" class="emoji_img">',
|
||||
'[红包]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_09.png" id="红包" class="emoji_img">',
|
||||
'[發]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_16.png" id="發" class="emoji_img">',
|
||||
'[福]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/2_15.png" id="福" class="emoji_img">',
|
||||
'[烟花]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Fireworks.png" id="烟花" class="emoji_img">',
|
||||
'[爆竹]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/newemoji/Firecracker.png" id="爆竹" class="emoji_img">',
|
||||
'[猪头]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_63@2x.png" id="猪头" class="emoji_img">',
|
||||
'[跳跳]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_93@2x.png" id="跳跳" class="emoji_img">',
|
||||
'[发抖]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_94@2x.png" id="发抖" class="emoji_img">',
|
||||
'[转圈]': '<img src="https://res.wx.qq.com/t/wx_fed/we-emoji/res/v1.2.8/assets/Expression/Expression_96@2x.png" id="转圈" class="emoji_img">'}
|
||||
from re import findall
|
||||
for index, message in enumerate(messages):
|
||||
type_ = message[2]
|
||||
str_content = message[7]
|
||||
@ -740,6 +871,11 @@ const chatMessages = [
|
||||
f.write(
|
||||
f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
|
||||
)
|
||||
|
||||
emojiText = findall(r"(\[.+?\])", str_content)
|
||||
for emoji_text in emojiText:
|
||||
if emoji_text in emoji:
|
||||
str_content = str_content.replace(emoji_text, emoji[emoji_text])
|
||||
f.write(
|
||||
f'''{{ type:{type_}, text: '{str_content}',is_send:{is_send},avatar_path:'{avatar}'}},'''
|
||||
)
|
||||
@ -753,9 +889,8 @@ const chatMessages = [
|
||||
match = re.search(pattern2, str_content)
|
||||
if match:
|
||||
continue
|
||||
|
||||
image_path = hard_link_db.get_image(content=str_content, thumb=False)
|
||||
image_path = get_abs_path(image_path)
|
||||
image_path = path.get_relative_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
|
||||
image_path = image_path.replace('\\', '/')
|
||||
# print(f"tohtml:---{image_path}")
|
||||
if self.is_5_min(timestamp):
|
||||
|
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
|
@ -19,6 +19,13 @@ wordcloud_height = 720
|
||||
def wordcloud(wxid):
|
||||
import jieba
|
||||
txt_messages = msg_db.get_messages_by_type(wxid, MsgType.TEXT)
|
||||
if not txt_messages:
|
||||
return {
|
||||
'chart_data': None,
|
||||
'keyword': "没有聊天你想分析啥",
|
||||
'max_num': "0",
|
||||
'dialogs': []
|
||||
}
|
||||
text = ''.join(map(lambda x: x[7], txt_messages))
|
||||
total_msg_len = len(text)
|
||||
# 使用jieba进行分词,并加入停用词
|
||||
@ -26,7 +33,7 @@ def wordcloud(wxid):
|
||||
# 统计词频
|
||||
word_count = Counter(words)
|
||||
# 过滤停用词
|
||||
stopwords_file = './app/data/stopwords.txt'
|
||||
stopwords_file = './app000/data/stopwords.txt'
|
||||
try:
|
||||
with open(stopwords_file, "r", encoding="utf-8") as stopword_file:
|
||||
stopwords = set(stopword_file.read().splitlines())
|
||||
@ -65,7 +72,7 @@ def wordcloud(wxid):
|
||||
'chart_data': w.dump_options_with_quotes(),
|
||||
'keyword': keyword,
|
||||
'max_num': str(max_num),
|
||||
'dialogs': msg_db.get_messages_by_keyword(wxid, keyword, num=5)
|
||||
'dialogs': msg_db.get_messages_by_keyword(wxid, keyword, num=5, max_len=12)
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
version = '0.2.6'
|
||||
version = '0.2.7'
|
||||
contact = '474379264'
|
||||
description = [
|
||||
'1. 支持获取个人信息<br>',
|
||||
'2. 支持显示聊天界面<br>',
|
||||
'3. 支持导出聊天记录<br> * csv<br> * html<br>',
|
||||
'4. 查找联系人<br>',
|
||||
'5. 生成年度报告<br>',
|
||||
]
|
||||
|
File diff suppressed because it is too large
Load Diff
2561
app/resources/stopwords.txt
Normal file
2561
app/resources/stopwords.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -50,14 +50,15 @@ def decode_dat(file_path, out_path):
|
||||
|
||||
if decode_code == -1:
|
||||
return
|
||||
filename = os.path.basename(file_path)
|
||||
if file_type == 1:
|
||||
pic_name = os.path.basename(file_path)[:-4] + ".jpg"
|
||||
elif file_type == 3:
|
||||
pic_name = file_path[:-4] + ".png"
|
||||
pic_name = filename[:-4] + ".png"
|
||||
elif file_type == 5:
|
||||
pic_name = file_path[:-4] + ".gif"
|
||||
pic_name = filename[:-4] + ".gif"
|
||||
else:
|
||||
pic_name = file_path[:-4] + ".jpg"
|
||||
pic_name = filename[:-4] + ".jpg"
|
||||
file_outpath = os.path.join(out_path, pic_name)
|
||||
if os.path.exists(file_outpath):
|
||||
return file_outpath
|
||||
|
@ -7,16 +7,26 @@ from app.util import dat2pic
|
||||
os.makedirs('./data/image', exist_ok=True)
|
||||
|
||||
|
||||
def get_abs_path(path):
|
||||
def get_abs_path(path, base_path="/data/image"):
|
||||
# return os.path.join(os.getcwd(), 'app/data/icons/404.png')
|
||||
if path:
|
||||
base_path = os.getcwd() + "/data/image"
|
||||
output_path = dat2pic.decode_dat(os.path.join(MePC().wx_dir, path), base_path) # './data/image')
|
||||
base_path = os.getcwd() + base_path
|
||||
output_path = dat2pic.decode_dat(os.path.join(MePC().wx_dir, path), base_path)
|
||||
return output_path if output_path else ':/icons/icons/404.png'
|
||||
else:
|
||||
return ':/icons/icons/404.png'
|
||||
|
||||
|
||||
def get_relative_path(path, base_path):
|
||||
if path:
|
||||
base_path = os.getcwd() + base_path
|
||||
output_path = dat2pic.decode_dat(os.path.join(MePC().wx_dir, path), base_path)
|
||||
relative_path = './image/'+os.path.basename(output_path) if output_path else 'https://www.bing.com/images/search?view=detailV2&ccid=Zww6woP3&id=CCC91337C740656E800E51247E928ACD3052FECF&thid=OIP.Zww6woP3Em49TdSG_lnggAHaEK&mediaurl=https%3a%2f%2fmeekcitizen.files.wordpress.com%2f2018%2f09%2f404.jpg%3fw%3d656&exph=360&expw=640&q=404&simid=608040792714530493&FORM=IRPRST&ck=151E7337A86F1B9C5C5DB08B15B90809&selectedIndex=21&itb=0'
|
||||
return relative_path
|
||||
else:
|
||||
return ':/icons/icons/404.png'
|
||||
|
||||
|
||||
def mkdir(path):
|
||||
if not os.path.exists(path):
|
||||
os.mkdir(path)
|
||||
@ -44,4 +54,3 @@ def wx_path():
|
||||
return wx_location
|
||||
except FileNotFoundError:
|
||||
return '.'
|
||||
|
||||
|
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)
|
@ -42,16 +42,16 @@ def index0():
|
||||
@app.route('/home')
|
||||
def home():
|
||||
try:
|
||||
data = {
|
||||
'sub_title': '二零二三年度报告',
|
||||
'avatar_path': contact.avatar_path,
|
||||
'nickname': contact.remark,
|
||||
'first_time': msg_db.get_first_time_of_message(contact.wxid)[1],
|
||||
}
|
||||
return render_template('home.html', **data)
|
||||
except IndexError:
|
||||
first_message, first_time = msg_db.get_first_time_of_message(contact.wxid)
|
||||
except TypeError:
|
||||
return set_text('咱就是说,一次都没聊过就别分析了')
|
||||
|
||||
data = {
|
||||
'sub_title': '二零二三年度报告',
|
||||
'avatar_path': contact.avatar_path,
|
||||
'nickname': contact.remark,
|
||||
'first_time': first_time,
|
||||
}
|
||||
return render_template('home.html', **data)
|
||||
|
||||
|
||||
@app.route('/wordcloud')
|
||||
|
BIN
chat_window1.png
BIN
chat_window1.png
Binary file not shown.
Before Width: | Height: | Size: 178 KiB |
@ -9,7 +9,7 @@ from PyQt5.QtWidgets import *
|
||||
from app.log import logger
|
||||
from app.ui_pc import mainview
|
||||
from app.ui_pc.tool.pc_decrypt import pc_decrypt
|
||||
|
||||
from app.config import version
|
||||
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("WeChatReport")
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ class ViewController(QWidget):
|
||||
self.viewMainWindow = mainview.MainWinController(username=username)
|
||||
self.viewMainWindow.exitSignal.connect(self.close)
|
||||
try:
|
||||
self.viewMainWindow.setWindowTitle("留痕")
|
||||
self.viewMainWindow.setWindowTitle(f"留痕-{version}")
|
||||
self.viewMainWindow.show()
|
||||
end = time.time()
|
||||
print('ok', '本次加载用了', end - start, 's')
|
||||
|
@ -294,7 +294,8 @@ python main.py
|
||||
|
||||
---
|
||||
|
||||
> 声明:该项目有且仅有一个目的:“留痕”——我的数据我做主,前提是“我的数据”其次才是“我做主”,禁止任何人以任何形式将其用于任何非法用途,对于使用该程序所造成的任何后果,所有创作者不承担任何责任🙄
|
||||
> 声明:该项目有且仅有一个目的:“留痕”——我的数据我做主,前提是“我的数据”其次才是“我做主”,禁止任何人以任何形式将其用于任何非法用途,对于使用该程序所造成的任何后果,所有创作者不承担任何责任🙄<br>
|
||||
> 该软件不会对您使用的微信造成任何影响,更不会对他人的微信造成任何影响,不能找回删除的聊天记录,任何企图篡改微信聊天数据的想法都是无稽之谈。本项目所有功能均建立在”前言“的基础之上,基于该项目的所有开发者均不能接受任何有悖于”前言“的功能需求,违者后果自负。
|
||||
|
||||
[](https://star-history.com/?utm_source=bestxtools.com#LC044/WeChatMsg&Date)
|
||||
|
||||
|
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@ -12,3 +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
|
||||
|
Loading…
Reference in New Issue
Block a user