新增聊天记录导出csv格式

This commit is contained in:
shuaikangzhou 2023-11-16 22:39:59 +08:00
parent d6192132f1
commit 38080499cd
10 changed files with 189 additions and 105 deletions

View File

@ -5,9 +5,16 @@
</component>
<component name="ChangeListManager">
<list default="true" id="84e65474-7da9-466d-baf3-cc88dde3ffdd" name="变更" comment="修复情感分析数值显示过长的bug">
<change afterPath="$PROJECT_DIR$/app/data/icons/search.svg" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/DataBase/msg.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/DataBase/msg.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/DataBase/output_pc.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/DataBase/output_pc.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/components/bubble_message.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/components/bubble_message.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/ui_pc/Icon.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/Icon.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/ui_pc/contact/contactInfo.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/contact/contactInfo.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/ui_pc/contact/contactUi.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/contact/contactUi.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/ui_pc/contact/contactUi.ui" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/contact/contactUi.ui" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/ui_pc/contact/contact_window.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/contact/contact_window.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/app/ui_pc/mainview.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/mainview.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -125,27 +132,6 @@
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="contact_info_ui" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="WeChatMsg" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/app/components" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/app/components/contact_info_ui.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="decrypt_window" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="WeChatMsg" />
<option name="INTERPRETER_OPTIONS" value="" />
@ -209,6 +195,27 @@
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="msg" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
<module name="WeChatMsg" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/app/DataBase" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/app/DataBase/msg.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="pc_decrypt" type="PythonConfigurationType" factoryName="Python" nameIsGenerated="true">
<module name="WeChatMsg" />
<option name="INTERPRETER_OPTIONS" value="" />
@ -233,10 +240,10 @@
<recent_temporary>
<list>
<item itemvalue="Python.decrypt_window" />
<item itemvalue="Python.msg" />
<item itemvalue="Python.main" />
<item itemvalue="Python.misc" />
<item itemvalue="Python.CAvatar" />
<item itemvalue="Python.contact_info_ui" />
</list>
</recent_temporary>
</component>

View File

@ -3,9 +3,43 @@ import sqlite3
DB = None
cursor = None
misc_path = "./app/Database/Msg/MSG0.db"
msg_path = "./app/Database/Msg/MSG0.db"
# misc_path = './Msg/Misc.db'
if os.path.exists(misc_path):
DB = sqlite3.connect(misc_path, check_same_thread=False)
if os.path.exists(msg_path):
DB = sqlite3.connect(msg_path, check_same_thread=False)
# '''创建游标'''
cursor = DB.cursor()
def init_database():
global DB
global cursor
if not DB:
if os.path.exists(msg_path):
DB = sqlite3.connect(msg_path, check_same_thread=False)
# '''创建游标'''
cursor = DB.cursor()
def get_messages(username_):
sql = '''
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime
from MSG
where StrTalker=?
order by CreateTime
'''
cursor.execute(sql, [username_])
result_ = cursor.fetchall()
return result_
if __name__ == '__main__':
from pprint import pprint
msg_path = './Msg/MSG3.db'
init_database()
username = 'wxid_0o18ef858vnu22'
result = get_messages(username)
pprint(result)
pprint(len(result))

View File

@ -1,8 +1,10 @@
import os
import numpy as np
import pandas as pd
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtCore import pyqtSignal, QThread
from . import msg
from ..log import log
class Output(QThread):
@ -17,32 +19,34 @@ class Output(QThread):
DOCX = 1
HTML = 2
def __init__(self, ta_u, parent=None, type_=DOCX):
def __init__(self, contact, parent=None, type_=DOCX):
super().__init__(parent)
self.sec = 2 # 默认1000秒
self.ta_username = ta_u
self.contact = contact
self.ta_username = contact.wxid
self.msg_id = 0
self.output_type = type_
self.total_num = 0
self.num = 0
@log
def to_csv(self, conRemark, path):
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}"
filename = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}/{conRemark}.csv"
last_timestamp = 1601968667000
columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"]
df = pd.DataFrame()
df["用户名"] = np.array(list(map(lambda x: x[7], messages)))
df["消息内容"] = np.array(list(map(lambda x: x[8], messages)))
df["发送时间"] = np.array(list(map(lambda x: time_format(x[6]), messages)))
df["发送状态"] = np.array(list(map(lambda x: x[3], messages)))
df["消息类型"] = np.array(list(map(lambda x: x[2], messages)))
df["isSend"] = np.array(list(map(lambda x: x[4], messages)))
df["msgId"] = np.array(list(map(lambda x: x[0], messages)))
df.to_csv(filename)
# df.to_csv('data.csv')
print(df)
self.progressSignal.emit(self.num)
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
if not os.path.exists(origin_docx_path):
os.mkdir(origin_docx_path)
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.csv"
# columns = ["用户名", "消息内容", "发送时间", "发送状态", "消息类型", "isSend", "msgId"]
columns = ['localId', 'TalkerId', 'Type', 'SubType',
'IsSender', 'CreateTime', 'Status', 'StrContent',
'StrTime']
messages = msg.get_messages(self.contact.wxid)
# print()
df = pd.DataFrame(
data=messages,
columns=columns,
)
df.to_csv(filename, encoding='utf-8')
self.okSignal.emit('ok')
def run(self):
if self.output_type == self.DOCX:

View File

@ -1,9 +1,8 @@
import sys
from Lib import QtNinePatch2
from PyQt5.QtCore import Qt, QRectF
from PyQt5.QtGui import QImage, QPainter, QColor, QFont, QPixmap
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy
from Lib import QtNinePatch2
from PyQt5.QtWidgets import QLabel, QWidget, QHBoxLayout, QVBoxLayout, QSizePolicy
class Label(QLabel):
@ -86,12 +85,3 @@ class MainWindow(QWidget):
layout.addWidget(bubble_mesage1)
# layout.setStretch(0, 1)
self.setLayout(layout)
app = QApplication(sys.argv)
# w = Label()
w = MainWindow()
w.resize(400, 200)
w.show()
sys.exit(app.exec_())

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700143141609" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4021" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M955.069071 864.311021 740.015134 649.258107c-3.752464-3.751441-8.841366-5.860475-14.149255-5.860475-5.306866 0-10.395768 2.108011-14.149255 5.860475l-16.692171 16.692171-38.34226-38.34226c53.03796-59.810201 85.298711-138.442072 85.298711-224.478588 0-186.774871-151.952784-338.727655-338.727655-338.727655S64.527642 216.35456 64.527642 403.12943c0 186.775894 151.952784 338.728678 338.727655 338.728678 86.36909 0 165.276231-32.510438 225.170343-85.913718l38.303374 38.303374-17.34504 17.34504c-7.812943 7.813966-7.812943 20.48352 0 28.297486l215.051891 215.052914c3.753487 3.751441 8.841366 5.860475 14.149255 5.860475 5.306866 0 10.395768-2.108011 14.149255-5.860475l62.334697-62.334697C962.883037 884.794541 962.883037 872.124987 955.069071 864.311021zM104.546078 403.12943c0-164.709319 133.9999-298.709219 298.709219-298.709219s298.709219 133.9999 298.709219 298.709219S567.964616 701.839673 403.255297 701.839673 104.546078 567.838749 104.546078 403.12943zM878.585119 912.496463 691.829691 725.741036l34.036187-34.036187 186.755428 186.755428L878.585119 912.496463z" fill="#272636" p-id="4022"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -16,3 +16,4 @@ class Icon:
Annual_Report_Icon = QIcon('./app/data/icons/annual_report.svg')
Analysis_Icon = QIcon('./app/data/icons/analysis.svg')
Emotion_Icon = QIcon('./app/data/icons/emotion.svg')
Search_Icon = QIcon('./app/data/icons/search.svg')

View File

@ -2,7 +2,7 @@ from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from app import person
from app.DataBase.output import Output
from app.DataBase.output_pc import Output
from app.Ui.Icon import Icon
from .contactInfoUi import Ui_Form
from .userinfo import userinfo
@ -105,13 +105,13 @@ class ContactInfo(QWidget, Ui_Form):
return
self.outputThread = Output(self.Me, self.contact.wxid)
elif self.sender() == self.toCSVAct:
QMessageBox.warning(self,
"别急别急",
"马上就实现该功能"
)
print('开始导出csv')
return
self.outputThread = Output(self.Me, self.contact.wxid, type_=Output.CSV)
# QMessageBox.warning(self,
# "别急别急",
# "马上就实现该功能"
# )
# print('开始导出csv')
# return
self.outputThread = Output(self.contact, type_=Output.CSV)
print('导出csv')
elif self.sender() == self.toHtmlAct:
print('功能暂未实现')

View File

@ -16,27 +16,47 @@ class Ui_Form(object):
Form.setObjectName("Form")
Form.resize(840, 752)
Form.setStyleSheet("background: rgb(240, 240, 240);")
self.horizontalLayout = QtWidgets.QHBoxLayout(Form)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(Form)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setSpacing(0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(Form)
self.label.setText("")
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(Form)
self.lineEdit.setMinimumSize(QtCore.QSize(250, 30))
self.lineEdit.setMaximumSize(QtCore.QSize(250, 16777215))
self.lineEdit.setMinimumSize(QtCore.QSize(200, 30))
self.lineEdit.setMaximumSize(QtCore.QSize(200, 16777215))
self.lineEdit.setStyleSheet("background:transparent;\n"
"border-width:0;\n"
"border-style:outset;\n"
"background-color:rgb(226,226,226);")
self.lineEdit.setCursorMoveStyle(QtCore.Qt.VisualMoveStyle)
self.lineEdit.setObjectName("lineEdit")
self.verticalLayout.addWidget(self.lineEdit)
self.horizontalLayout.addWidget(self.lineEdit)
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setText("")
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.verticalLayout.addLayout(self.horizontalLayout)
self.verticalLayout_2.addLayout(self.verticalLayout)
self.listWidget = QtWidgets.QListWidget(Form)
self.listWidget.setMinimumSize(QtCore.QSize(250, 0))
self.listWidget.setMaximumSize(QtCore.QSize(250, 16777215))
self.listWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.listWidget.setObjectName("listWidget")
self.verticalLayout.addWidget(self.listWidget)
self.horizontalLayout.addLayout(self.verticalLayout)
self.verticalLayout_2.addWidget(self.listWidget)
self.verticalLayout_2.setStretch(1, 1)
self.horizontalLayout_2.addLayout(self.verticalLayout_2)
self.stackedWidget = QtWidgets.QStackedWidget(Form)
self.stackedWidget.setObjectName("stackedWidget")
self.horizontalLayout.addWidget(self.stackedWidget)
self.horizontalLayout.setStretch(1, 1)
self.horizontalLayout_2.addWidget(self.stackedWidget)
self.horizontalLayout_2.setStretch(1, 1)
self.retranslateUi(Form)
self.stackedWidget.setCurrentIndex(-1)

View File

@ -16,36 +16,59 @@
<property name="styleSheet">
<string notr="true">background: rgb(240, 240, 240);</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="minimumSize">
<size>
<width>250</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>250</width>
<height>16777215</height>
</size>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="minimumSize">
<size>
<width>200</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">background:transparent;
border-width:0;
border-style:outset;
background-color:rgb(226,226,226);
</string>
</property>
<property name="cursorMoveStyle">
<enum>Qt::VisualMoveStyle</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="listWidget">

View File

@ -1,11 +1,12 @@
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QMessageBox
from PyQt5.QtWidgets import QWidget, QMessageBox, QAction, QLineEdit
from app.DataBase import micro_msg, misc
from app.components import ContactQListWidgetItem
from app.person import ContactPC
from .contactInfo import ContactInfo
from .contactUi import Ui_Form
from ..Icon import Icon
# 美化样式表
Stylesheet = """
@ -55,6 +56,9 @@ class ContactWindow(QWidget, Ui_Form):
self.show_contacts()
def init_ui(self):
search_action = QAction(self.lineEdit)
search_action.setIcon(Icon.Search_Icon)
self.lineEdit.addAction(search_action, QLineEdit.LeadingPosition)
self.listWidget.clear()
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
self.listWidget.setCurrentRow(0)