mirror of
https://github.com/LC044/WeChatMsg
synced 2025-02-23 03:22:17 +08:00
新增年度关键词
This commit is contained in:
parent
85cff9aaea
commit
163b2ef269
@ -3,6 +3,8 @@ from collections import Counter
|
|||||||
import sys
|
import sys
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
import jieba
|
||||||
|
|
||||||
from app.DataBase import msg_db, MsgType
|
from app.DataBase import msg_db, MsgType
|
||||||
from pyecharts import options as opts
|
from pyecharts import options as opts
|
||||||
from pyecharts.charts import WordCloud, Calendar, Bar, Line, Pie
|
from pyecharts.charts import WordCloud, Calendar, Bar, Line, Pie
|
||||||
@ -64,6 +66,46 @@ def wordcloud_(wxid, time_range=None):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_wordcloud(text):
|
||||||
|
total_msg_len = len(text)
|
||||||
|
# 使用jieba进行分词,并加入停用词
|
||||||
|
words = jieba.cut(text)
|
||||||
|
# 统计词频
|
||||||
|
word_count = Counter(words)
|
||||||
|
# 过滤停用词
|
||||||
|
stopwords_file = './app/data/stopwords.txt'
|
||||||
|
with open(stopwords_file, "r", encoding="utf-8") as stopword_file:
|
||||||
|
stopwords1 = set(stopword_file.read().splitlines())
|
||||||
|
# 构建 FFmpeg 可执行文件的路径
|
||||||
|
stopwords = set()
|
||||||
|
stopwords_file = './app/resources/data/stopwords.txt'
|
||||||
|
if not os.path.exists(stopwords_file):
|
||||||
|
resource_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
|
||||||
|
stopwords_file = os.path.join(resource_dir, 'app', 'resources', 'data', 'stopwords.txt')
|
||||||
|
with open(stopwords_file, "r", encoding="utf-8") as stopword_file:
|
||||||
|
stopwords = set(stopword_file.read().splitlines())
|
||||||
|
stopwords = stopwords.union(stopwords1)
|
||||||
|
|
||||||
|
filtered_word_count = {word: count for word, count in word_count.items() if len(word) > 1 and word not in stopwords}
|
||||||
|
# 转换为词云数据格式
|
||||||
|
data = [(word, count) for word, count in filtered_word_count.items()]
|
||||||
|
# text_data = data
|
||||||
|
data.sort(key=lambda x: x[1], reverse=True)
|
||||||
|
|
||||||
|
text_data = data[:100] if len(data) > 100 else data
|
||||||
|
# 创建词云图
|
||||||
|
keyword, max_num = text_data[0]
|
||||||
|
w = (
|
||||||
|
WordCloud()
|
||||||
|
.add(series_name="聊天文字", data_pair=text_data, word_size_range=[5, 40])
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
'chart_data_wordcloud': w.dump_options_with_quotes(),
|
||||||
|
'keyword': keyword,
|
||||||
|
'keyword_max_num': max_num,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def wordcloud_christmas(wxid, year='2023'):
|
def wordcloud_christmas(wxid, year='2023'):
|
||||||
import jieba
|
import jieba
|
||||||
txt_messages = msg_db.get_messages_by_type(wxid, MsgType.TEXT, year)
|
txt_messages = msg_db.get_messages_by_type(wxid, MsgType.TEXT, year)
|
||||||
@ -375,6 +417,8 @@ def my_message_counter(time_range, my_name=''):
|
|||||||
types_count = {}
|
types_count = {}
|
||||||
send_num = 0 # 发送消息的数量
|
send_num = 0 # 发送消息的数量
|
||||||
weekday_count = {}
|
weekday_count = {}
|
||||||
|
str_content = ''
|
||||||
|
total_text_num = 0
|
||||||
for message in msg_data:
|
for message in msg_data:
|
||||||
type_ = message[2]
|
type_ = message[2]
|
||||||
is_sender = message[4]
|
is_sender = message[4]
|
||||||
@ -393,6 +437,10 @@ def my_message_counter(time_range, my_name=''):
|
|||||||
weekday_count[weekday] += 1
|
weekday_count[weekday] += 1
|
||||||
else:
|
else:
|
||||||
weekday_count[weekday] = 1
|
weekday_count[weekday] = 1
|
||||||
|
if type_ == 1:
|
||||||
|
total_text_num += len(message[7])
|
||||||
|
if is_sender == 1:
|
||||||
|
str_content += message[7]
|
||||||
receive_num = len(msg_data) - send_num
|
receive_num = len(msg_data) - send_num
|
||||||
data = [[types_.get(key), value] for key, value in types_count.items() if key in types_]
|
data = [[types_.get(key), value] for key, value in types_count.items() if key in types_]
|
||||||
if not data:
|
if not data:
|
||||||
@ -428,9 +476,14 @@ def my_message_counter(time_range, my_name=''):
|
|||||||
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}\n{d}%", position='inside'))
|
.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}\n{d}%", position='inside'))
|
||||||
# .render("./data/聊天统计/pie_scroll_legend.html")
|
# .render("./data/聊天统计/pie_scroll_legend.html")
|
||||||
)
|
)
|
||||||
|
w = get_wordcloud(str_content)
|
||||||
return {
|
return {
|
||||||
'chart_data_sender': p2.dump_options_with_quotes(),
|
'chart_data_sender': p2.dump_options_with_quotes(),
|
||||||
'chart_data_types': p1.dump_options_with_quotes(),
|
'chart_data_types': p1.dump_options_with_quotes(),
|
||||||
|
'chart_data_wordcloud': w.get('chart_data_wordcloud'),
|
||||||
|
'keyword': w.get('keyword'),
|
||||||
|
'keyword_max_num': w.get('keyword_max_num'),
|
||||||
|
'total_text_num':total_text_num,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import traceback
|
|||||||
import requests
|
import requests
|
||||||
from PyQt5.QtCore import QThread, pyqtSignal, QSize, Qt
|
from PyQt5.QtCore import QThread, pyqtSignal, QSize, Qt
|
||||||
from PyQt5.QtGui import QPixmap
|
from PyQt5.QtGui import QPixmap
|
||||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QApplication, QTextBrowser
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QApplication, QTextBrowser, QMessageBox
|
||||||
|
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.ui.Icon import Icon
|
from app.ui.Icon import Icon
|
||||||
@ -61,10 +61,14 @@ class AIChat(QWidget, Ui_Form):
|
|||||||
self.init_ui()
|
self.init_ui()
|
||||||
self.show_chats()
|
self.show_chats()
|
||||||
self.pushButton.clicked.connect(self.send_msg)
|
self.pushButton.clicked.connect(self.send_msg)
|
||||||
|
self.toolButton.clicked.connect(self.tool)
|
||||||
|
|
||||||
def init_ui(self):
|
def init_ui(self):
|
||||||
self.textEdit.installEventFilter(self)
|
self.textEdit.installEventFilter(self)
|
||||||
|
|
||||||
|
def tool(self):
|
||||||
|
QMessageBox.information(self, "温馨提示", "暂未接入聊天数据,您可进行基础的AI对话,后续更新敬请期待")
|
||||||
|
|
||||||
def chat(self, text):
|
def chat(self, text):
|
||||||
self.now_message.append(text)
|
self.now_message.append(text)
|
||||||
self.scrollArea.verticalScrollBar().setValue(self.scrollArea.verticalScrollBar().maximum())
|
self.scrollArea.verticalScrollBar().setValue(self.scrollArea.verticalScrollBar().maximum())
|
||||||
|
@ -252,15 +252,48 @@ p {
|
|||||||
}
|
}
|
||||||
.chart{
|
.chart{
|
||||||
width: 800px;
|
width: 800px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
||||||
|
.chart-container{
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
#word_cloud{
|
||||||
|
width: 800px;
|
||||||
|
height: 800px;
|
||||||
|
}
|
||||||
|
@media screen and (max-width:480px){
|
||||||
|
.chart{
|
||||||
|
width: 300px;
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
.chart-container{
|
||||||
|
display:flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
#word_cloud{
|
||||||
|
width: 400px;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width:600px){
|
#keywords {
|
||||||
.chart{
|
font-size: 2.5em;
|
||||||
width: 400px;
|
color: #003366;
|
||||||
height: 220px;
|
animation: slideIn 1.5s ease-out;
|
||||||
|
transform: skew(-15deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50px) skew(-15deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0) skew(-15deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -270,18 +303,25 @@ p {
|
|||||||
<div class="section">
|
<div class="section">
|
||||||
<div id="cover">
|
<div id="cover">
|
||||||
<h1>年度聊天报告</h1>
|
<h1>年度聊天报告</h1>
|
||||||
<p>统计、分析、回顾,记录聊天时光</p>
|
<p>可掌控的才真正属于你</p>
|
||||||
<button id="enterButton" onclick="navigateToNextPage()">进入报告</button>
|
<button id="enterButton" onclick="navigateToNextPage()">进入报告</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section cover">
|
<div class="section cover">
|
||||||
<h1>2023年</h1>
|
<h1>2023年</h1>
|
||||||
<p>你一共给<span class="number">{{contact_num}}</span>个联系人<br>发送了<span class="number">{{send_msg_num}}</span>条消息<br>收到了<span class="number">{{receive_msg_num}}</span>条消息</p>
|
<p>你一共给<span class="number">{{contact_num}}</span>个联系人<br>发送了<span class="number">{{send_msg_num}}</span>条消息<br>收到了<span class="number">{{receive_msg_num}}</span>条消息<br>总计<span class="number">{{total_text_num}}</span>字</p>
|
||||||
<div id="sender-chart" class="chart" ></div>
|
<div class="chart-container">
|
||||||
<div id="types-chart" class="chart"></div>
|
<div id="types-chart" class="chart"></div>
|
||||||
|
<div id="sender-chart" class="chart" ></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section cover">
|
<div class="section cover">
|
||||||
<h1>我的年度好友</h1>
|
<h1>年度关键词</h1>
|
||||||
|
<div id="keywords">“{{keyword}}”<span class="number">{{keyword_max_num}}</span>次</div>
|
||||||
|
<div id="word_cloud"></div>
|
||||||
|
</div>
|
||||||
|
<div class="section cover">
|
||||||
|
<h1>年度聊天好友</h1>
|
||||||
<h2>聊天榜单</h2>
|
<h2>聊天榜单</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{% for contact,msg_num in contact_topN:%}
|
{% for contact,msg_num in contact_topN:%}
|
||||||
@ -360,6 +400,20 @@ p {
|
|||||||
document.getElementById('sender-chart'), 'white', {renderer: 'canvas'});
|
document.getElementById('sender-chart'), 'white', {renderer: 'canvas'});
|
||||||
var result = {{chart_data_sender|safe}};
|
var result = {{chart_data_sender|safe}};
|
||||||
chart_51ebd4312946429e9c32b2b55b96a4.setOption(result);
|
chart_51ebd4312946429e9c32b2b55b96a4.setOption(result);
|
||||||
|
var chart_51ebd4312946429e9c32b2b55b96 = echarts.init(
|
||||||
|
document.getElementById('word_cloud'), 'white', {renderer: 'canvas'});
|
||||||
|
var result = {{chart_data_wordcloud|safe}};
|
||||||
|
// 获取屏幕宽度
|
||||||
|
const screenWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
||||||
|
// 根据屏幕宽度设置字体范围
|
||||||
|
let fontSizeRange;
|
||||||
|
if (screenWidth < 768) { // 手机屏幕
|
||||||
|
fontSizeRange = [5, 40];
|
||||||
|
} else { // 电脑屏幕
|
||||||
|
fontSizeRange = [10, 100];
|
||||||
|
}
|
||||||
|
result.series[0].sizeRange = fontSizeRange;
|
||||||
|
chart_51ebd4312946429e9c32b2b55b96.setOption(result);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user