Skip to content

Commit

Permalink
支持导出表情包
Browse files Browse the repository at this point in the history
  • Loading branch information
LC044 committed Dec 9, 2023
1 parent f3499b3 commit c5d4ee6
Show file tree
Hide file tree
Showing 9 changed files with 443 additions and 665 deletions.
1 change: 0 additions & 1 deletion app/DataBase/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ def get_avatar_buffer(self, userName):
lock.acquire(True)
self.cursor.execute(sql, [userName])
result = self.cursor.fetchall()
# print(result[0][0])
if result:
return result[0][0]
finally:
Expand Down
1 change: 0 additions & 1 deletion app/DataBase/msg.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ def get_messages_by_keyword(self, username_, keyword, num=5, max_len=10):
(msg1[4], msg1[5], msg1[7].split(keyword), msg1[8]),
(msg2[4], msg2[5], msg2[7], msg2[8])
))

return res

def get_messages_by_days(self, username_, year_='2023'):
Expand Down
290 changes: 27 additions & 263 deletions app/DataBase/output_pc.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from ..DataBase import hard_link_db
from ..person_pc import MePC
from ..util import path
import shutil

from ..util.emoji import get_emoji

os.makedirs('./data/聊天记录', exist_ok=True)

Expand Down Expand Up @@ -73,8 +76,9 @@ def progress(self, value):
def to_csv_all(self):
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/"
os.makedirs(origin_docx_path, exist_ok=True)
filename = QFileDialog.getSaveFileName(None, "save file", os.path.join(os.getcwd(),'messages.csv'), "csv files (*.csv);;all files(*.*)")
if not filename:
filename = QFileDialog.getSaveFileName(None, "save file", os.path.join(os.getcwd(), 'messages.csv'),
"csv files (*.csv);;all files(*.*)")
if not filename[0]:
return
filename = filename[0]
# columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"]
Expand All @@ -93,12 +97,14 @@ def to_csv_all(self):
self.okSignal.emit(1)

def contact_to_csv(self):
filename = QFileDialog.getSaveFileName(None, "save file", os.path.join(os.getcwd(),'contacts.csv'), "csv files (*.csv);;all files(*.*)")
if not filename:
filename = QFileDialog.getSaveFileName(None, "save file", os.path.join(os.getcwd(), 'contacts.csv'),
"csv files (*.csv);;all files(*.*)")
if not filename[0]:
return
filename = filename[0]
# columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"]
columns = ['UserName','Alias', 'Type', 'Remark', 'NickName', 'PYInitial', 'RemarkPYInitial', 'smallHeadImgUrl', 'bigHeadImgUrl']
columns = ['UserName', 'Alias', 'Type', 'Remark', 'NickName', 'PYInitial', 'RemarkPYInitial', 'smallHeadImgUrl',
'bigHeadImgUrl']
contacts = micro_msg_db.get_contact()
# 写入CSV文件
with open(filename, mode='w', newline='', encoding='utf-8') as file:
Expand Down Expand Up @@ -212,263 +218,6 @@ def to_csv_all(self):
writer.writerows(messages)
self.okSignal.emit(1)

def to_html(self):
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
os.makedirs(origin_docx_path, exist_ok=True)
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')
html_head = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
padding: 0;
margin: 0;
}
body{
height: 100vh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.container{
height: 760px;
width: 900px;
border-radius: 4px;
border: 0.5px solid #e0e0e0;
background-color: #f5f5f5;
display: flex;
flex-flow: column;
overflow: hidden;
}
.content{
width: calc(100% - 40px);
padding: 20px;
overflow-y: scroll;
flex: 1;
}
.content:hover::-webkit-scrollbar-thumb{
background:rgba(0,0,0,0.1);
}
.bubble{
max-width: 400px;
padding: 10px;
border-radius: 5px;
position: relative;
color: #000;
word-wrap:break-word;
word-break:normal;
}
.item-left .bubble{
margin-left: 15px;
background-color: #fff;
}
.item-left .bubble:before{
content: "";
position: absolute;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-top: 10px solid transparent;
border-right: 10px solid #fff;
border-bottom: 10px solid transparent;
left: -20px;
}
.item-right .bubble{
margin-right: 15px;
background-color: #9eea6a;
}
.item-right .bubble:before{
content: "";
position: absolute;
width: 0;
height: 0;
border-left: 10px solid #9eea6a;
border-top: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid transparent;
right: -20px;
}
.item{
margin-top: 15px;
display: flex;
width: 100%;
}
.item.item-right{
justify-content: flex-end;
}
.item.item-center{
justify-content: center;
}
.item.item-center span{
font-size: 12px;
padding: 2px 4px;
color: #fff;
background-color: #dadada;
border-radius: 3px;
-moz-user-select:none; /*火狐*/
-webkit-user-select:none; /*webkit浏览器*/
-ms-user-select:none; /*IE10*/
-khtml-user-select:none; /*早期浏览器*/
user-select:none;
}
.avatar img{
width: 42px;
height: 42px;
border-radius: 50%;
}
.input-area{
border-top:0.5px solid #e0e0e0;
height: 150px;
display: flex;
flex-flow: column;
background-color: #fff;
}
textarea{
flex: 1;
padding: 5px;
font-size: 14px;
border: none;
cursor: pointer;
overflow-y: auto;
overflow-x: hidden;
outline:none;
resize:none;
}
.button-area{
display: flex;
height: 40px;
margin-right: 10px;
line-height: 40px;
padding: 5px;
justify-content: flex-end;
}
.button-area button{
width: 80px;
border: none;
outline: none;
border-radius: 4px;
float: right;
cursor: pointer;
}
/* 设置滚动条的样式 */
::-webkit-scrollbar {
width:10px;
}
/* 滚动槽 */
::-webkit-scrollbar-track {
-webkit-box-shadow:inset006pxrgba(0,0,0,0.3);
border-radius:8px;
}
/* 滚动条滑块 */
::-webkit-scrollbar-thumb {
border-radius:10px;
background:rgba(0,0,0,0);
-webkit-box-shadow:inset006pxrgba(0,0,0,0.5);
}
</style>
</head>
<body>
<div class="container" id="container" onscroll="handleScroll()">
<div class="content">
'''
f.write(html_head)
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))
for index, message in enumerate(messages):
type_ = message[2]
str_content = message[7]
str_time = message[8]
# print(type_, type(type_))
is_send = message[4]
avatar = MePC().avatar_path if is_send else self.contact.avatar_path
timestamp = message[5]
self.progressSignal.emit(index)
if type_ == 1:
if self.is_5_min(timestamp):
f.write(
f'''
<div class="item item-center"><span>{str_time}</span></div>
'''
)
if is_send:
f.write(
f'''
<div class="item item-right">
<div class="bubble bubble-right">{str_content}</div>
<div class="avatar">
<img src="myhead.png" />
</div>
</div>
'''
)
else:
f.write(
f'''
<div class="item item-left">
<div class="avatar">
<img src="tahead.png" />
</div>
<div class="bubble bubble-left">{str_content}
</div>
</div>
'''
)
html_end = '''
</div>
</div>
<script>
const container = document.getElementById('container');
const content = document.getElementById('content');
const totalItems = 1000;
const itemsPerPage = 20;
const itemHeight = 50;
function updateContent() {
const scrollTop = container.scrollTop;
const startIndex = Math.floor(scrollTop / itemHeight);
const endIndex = Math.min(startIndex + itemsPerPage, totalItems);
// Remove existing items
content.innerHTML = '';
// Add new items
for (let i = startIndex; i < endIndex; i++) {
const item = document.createElement('div');
item.className = 'item';
item.textContent = `Item ${i}`;
content.appendChild(item);
}
// Update container height to show correct scrollbar
container.style.height = totalItems * itemHeight + 'px';
}
function handleScroll() {
updateContent();
}
// Initial content rendering
updateContent();
</script>
</body>
</html>
'''
f.write(html_end)
f.close()
self.okSignal.emit(1)

def to_html_(self):
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
makedirs(origin_docx_path)
Expand Down Expand Up @@ -921,7 +670,12 @@ def to_html_(self):
)
elif type_ == 43:
video_path = hard_link_db.get_video(content=str_content, thumb=False)
video_path = f'file:///{path.wx_path()}/{MePC().wxid}/{video_path}'
video_path = f'{MePC().wx_dir}/{video_path}'
if os.path.exists(video_path):
new_path = origin_docx_path + '/video/' + os.path.basename(video_path)
if not os.path.exists(new_path):
shutil.copy(video_path, os.path.join(origin_docx_path, 'video'))
video_path = f'./video/{os.path.basename(video_path)}'
video_path = video_path.replace('\\', '/')
if self.is_5_min(timestamp):
f.write(
Expand All @@ -930,6 +684,16 @@ def to_html_(self):
f.write(
f'''{{ type:{type_}, text: '{video_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
)
elif type_ == 47:
emoji_path = get_emoji(str_content, thumb=True, output_path=origin_docx_path + '/emoji')
emoji_path = './emoji/'+os.path.basename(emoji_path)
if self.is_5_min(timestamp):
f.write(
f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
)
f.write(
f'''{{ type:{3}, text: '{emoji_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
)
elif type_ == 10000:
str_content = escape_js_and_html(str_content.lstrip('<revokemsg>').rstrip('</revokemsg>'))
f.write(
Expand Down
25 changes: 15 additions & 10 deletions app/ui_pc/tool/pc_decrypt/decryptUi.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ def setupUi(self, Dialog):
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
self.label_3.setObjectName("label_3")
self.verticalLayout.addWidget(self.label_3)
self.label_9 = QtWidgets.QLabel(Dialog)
self.label_9.setAlignment(QtCore.Qt.AlignCenter)
self.label_9.setObjectName("label_9")
self.verticalLayout.addWidget(self.label_9)
self.gridLayout_2 = QtWidgets.QGridLayout()
self.gridLayout_2.setObjectName("gridLayout_2")
self.gridLayout = QtWidgets.QGridLayout()
Expand All @@ -63,16 +67,16 @@ def setupUi(self, Dialog):
self.gridLayout.addWidget(self.label_7, 1, 0, 1, 1)
self.lineEdit = QtWidgets.QLineEdit(Dialog)
self.lineEdit.setStyleSheet("background:transparent;\n"
"\n"
" border-radius:5px;\n"
" border-top: 0px solid #b2e281;\n"
" border-bottom: 2px solid black;\n"
" border-right: 0px solid #b2e281;\n"
" border-left: 0px solid #b2e281;\n"
"\n"
"\n"
" border-style:outset\n"
" ")
"\n"
" border-radius:5px;\n"
" border-top: 0px solid #b2e281;\n"
" border-bottom: 2px solid black;\n"
" border-right: 0px solid #b2e281;\n"
" border-left: 0px solid #b2e281;\n"
"\n"
"\n"
" border-style:outset\n"
" ")
self.lineEdit.setFrame(False)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 4, 1, 1, 1)
Expand Down Expand Up @@ -178,6 +182,7 @@ def retranslateUi(self, Dialog):
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.btn_help.setText(_translate("Dialog", "使用说明"))
self.label_3.setText(_translate("Dialog", "解密数据库"))
self.label_9.setText(_translate("Dialog", "以下内容为自动获取,如获取失败请手动填写"))
self.label_7.setText(_translate("Dialog", "版本"))
self.label_5.setText(_translate("Dialog", "微信昵称"))
self.label_6.setText(_translate("Dialog", "密钥"))
Expand Down
Loading

0 comments on commit c5d4ee6

Please sign in to comment.