Skip to content

Commit

Permalink
新增年度报告功能
Browse files Browse the repository at this point in the history
  • Loading branch information
LC044 committed Dec 4, 2023
1 parent 1708a46 commit 1381f9b
Show file tree
Hide file tree
Showing 10 changed files with 7,867 additions and 6,434 deletions.
21 changes: 20 additions & 1 deletion app/DataBase/msg.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def get_message_by_num(self, username_, local_id):
from MSG
where StrTalker = ? and localId < ?
order by CreateTime desc
limit 10
limit 10
'''
result = None
if not self.open_flag:
Expand Down Expand Up @@ -170,6 +170,24 @@ def get_messages_by_keyword(self, username_, keyword, num=5):

return res

def get_first_time_of_message(self, username_):
if not self.open_flag:
return None
sql = '''
select StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime
from MSG
where StrTalker=?
order by CreateTime
limit 1
'''
try:
lock.acquire(True)
self.cursor.execute(sql, [username_])
result = self.cursor.fetchone()
finally:
lock.release()
return result

def close(self):
if self.open_flag:
try:
Expand All @@ -195,3 +213,4 @@ def __del__(self):
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'))
19 changes: 16 additions & 3 deletions app/analysis/analysis.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
from collections import Counter

from PyQt5.QtCore import QFile, QTextStream, QIODevice

from app.DataBase import msg_db, MsgType
from app.person_pc import ContactPC
import jieba
from pyecharts import options as opts
from pyecharts.charts import Pie, WordCloud, Calendar, Bar, Line, Timeline, Grid
from app.resources import resource_rc

var = resource_rc.qt_resource_name
charts_width = 800
charts_height = 450
wordcloud_width = 780
Expand All @@ -22,9 +26,18 @@ def wordcloud(wxid):
# 统计词频
word_count = Counter(words)
# 过滤停用词
stopwords_file = '../data/stopwords.txt'
with open(stopwords_file, "r", encoding="utf-8") as stopword_file:
stopwords = set(stopword_file.read().splitlines())
stopwords_file = './app/data/stopwords.txt'
try:
with open(stopwords_file, "r", encoding="utf-8") as stopword_file:
stopwords = set(stopword_file.read().splitlines())
except:
file = QFile(':/data/stopwords.txt')
if file.open(QIODevice.ReadOnly | QIODevice.Text):
stream = QTextStream(file)
stream.setCodec('utf-8')
content = stream.readAll()
file.close()
stopwords = set(content.splitlines())
filtered_word_count = {word: count for word, count in word_count.items() if len(word) > 1 and word not in stopwords}

# 转换为词云数据格式
Expand Down
18 changes: 18 additions & 0 deletions app/data/stopwords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@ wxid
裂开
苦涩
叹气
让我看看
奋斗
疑问
擦汗
抠鼻
鄙视
勾引
奸笑
嘿哈
捂脸
机智
加油
吃瓜
尴尬
乡村
炸弹
腹肌
Expand Down
6 changes: 0 additions & 6 deletions app/decrypt/get_wx_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,6 @@ def resource_path(relative_path):

@log
def get_info(VERSION_LIST):
# try:
# with open(VERSION_LIST_PATH, "r", encoding="utf-8") as f:
# VERSION_LIST = json.load(f)
# except:
# with open(resource_path(VERSION_LIST_PATH), "r", encoding="utf-8") as f:
# VERSION_LIST = json.load(f)
result = read_info(VERSION_LIST, True) # 读取微信信息
return result

Expand Down
13 changes: 13 additions & 0 deletions app/person_pc.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os.path
from typing import Dict

from PyQt5.QtCore import Qt
Expand Down Expand Up @@ -61,6 +62,18 @@ def set_avatar(self, img_bytes):
self.avatar.loadFromData(img_bytes, format='jfif')
self.avatar.scaled(60, 60, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)

def save_avatar(self, path=None):
if not self.avatar:
return
if path:
save_path = path
else:
os.makedirs('./data/avatar', exist_ok=True)
save_path = os.path.join(f'data/avatar/', self.wxid + '.png')
self.avatar_path = save_path
self.avatar.save(save_path)
print('保存头像', save_path)


if __name__ == '__main__':
p1 = MePC()
Expand Down
1 change: 1 addition & 0 deletions app/resources/resource.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@
</qresource>
<qresource prefix="/data">
<file>version_list.json</file>
<file>stopwords.txt</file>
</qresource>
</RCC>
14,135 changes: 7,734 additions & 6,401 deletions app/resources/resource_rc.py

Large diffs are not rendered by default.

39 changes: 29 additions & 10 deletions app/ui_pc/contact/contactInfo.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from PyQt5.QtCore import pyqtSignal, QUrl
from PyQt5.QtCore import pyqtSignal, QUrl, QThread
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QWidget, QMenu, QAction, QToolButton, QMessageBox

from app.DataBase.output_pc import Output
from app.ui_pc.Icon import Icon
from .contactInfoUi import Ui_Form
from .userinfo import userinfo
from ...person_pc import ContactPC


class ContactInfo(QWidget, Ui_Form):
Expand All @@ -15,7 +17,7 @@ class ContactInfo(QWidget, Ui_Form):
def __init__(self, contact, parent=None):
super(ContactInfo, self).__init__(parent)
self.setupUi(self)
self.contact = contact
self.contact:ContactPC = contact
self.view_userinfo = userinfo.UserinfoController(self.contact)
self.btn_back.clicked.connect(self.back)
self.init_ui()
Expand Down Expand Up @@ -66,14 +68,17 @@ def analysis(self):
self.view_analysis.start()

def annual_report(self):
QMessageBox.warning(
self,
"提示",
"敬请期待"
)
return
# self.report = report.ReportController(self.contact)
# self.report.show()
# QMessageBox.warning(
# self,
# "提示",
# "敬请期待"
# )
# return
self.contact.save_avatar()
self.report_thread = ReportThread(self.contact)
self.report_thread.okSignal.connect(lambda x: QDesktopServices.openUrl(QUrl("http://127.0.0.1:21314")))
self.report_thread.start()
QDesktopServices.openUrl(QUrl("http://127.0.0.1:21314"))

def emotionale_Analysis(self):
QMessageBox.warning(self,
Expand Down Expand Up @@ -136,3 +141,17 @@ def output_progress(self, value):
def set_progressBar_range(self, value):
self.view_userinfo.progressBar.setVisible(True)
self.view_userinfo.progressBar.setRange(0, value)


class ReportThread(QThread):
okSignal = pyqtSignal(bool)

def __init__(self, contact):
super().__init__()
self.contact = contact

def run(self):
from app.web_ui import web
web.contact = self.contact
web.run(port='21314')
self.okSignal.emit(True)
47 changes: 35 additions & 12 deletions app/web_ui/web.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import json
import os
import sys

from flask import Flask, render_template
from flask import Flask, render_template, send_file
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.globals import ThemeType

from app.DataBase import msg_db
from app.analysis import analysis
from app.person_pc import ContactPC, MePC

app = Flask(__name__)

wxid = ''
contact: ContactPC = None


@app.route("/")
def index():
Expand Down Expand Up @@ -37,24 +43,22 @@ def index0():
def home():
data = {
'sub_title': '二零二三年度报告',
'avatar_path': "static/my_resource/avatar.png",
'nickname': '司小远',
'first_time': '2023-09-18 20:39:08',
'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)


@app.route('/message_num')
@app.route('/wordcloud')
def one():
msg_db.init_database(path='../DataBase/Msg/MSG.db')
wxid = 'wxid_0o18ef858vnu22'
wxid = 'wxid_8piw6sb4hvfm22'
wxid = contact.wxid
# wxid = 'wxid_lltzaezg38so22'
world_cloud_data = analysis.wordcloud(wxid)
# 创建一个简单的柱状图
with open('message_num_test.html','w',encoding='utf-8') as f:
f.write(render_template('message_num.html', **world_cloud_data))
return render_template('message_num.html', **world_cloud_data)

with open('wordcloud.html', 'w', encoding='utf-8') as f:
f.write(render_template('wordcloud.html', **world_cloud_data))
return render_template('wordcloud.html', **world_cloud_data)


@app.route('/test')
Expand All @@ -68,5 +72,24 @@ def test():
return bar.dump_options_with_quotes()


def run(port=21314):
app.run(debug=True, host='0.0.0.0', port=port, use_reloader=False)


def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)


@app.route('/data/avatar/<filename>')
def get_image(filename):
try:
# 返回动态生成的图片
return send_file(os.path.join("../../data/avatar/", filename), mimetype='image/png')
except:
return send_file(os.path.join(f"{os.getcwd()}/data/avatar/", filename), mimetype='image/png')


if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0')
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ python main.py
# 🏆致谢

* PC微信解密工具:[https://github.com/xaoyaoo/PyWxDump](https://github.com/xaoyaoo/PyWxDump)
* PyQt组件库[https://github.com/PyQt5/CustomWidgets](https://github.com/PyQt5/CustomWidgets)
* PyQt组件库:[https://github.com/PyQt5/CustomWidgets](https://github.com/PyQt5/CustomWidgets)
* 我的得力助手:[ChatGPT](https://chat.openai.com/)

---
Expand Down

0 comments on commit 1381f9b

Please sign in to comment.