From 8f16ef5e6086beb72adfdacd85acab4c896c3096 Mon Sep 17 00:00:00 2001 From: shuaikangzhou <863909694@qq.com> Date: Sat, 27 Jan 2024 17:32:23 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E4=BF=A1=E6=81=AF=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=97=A5=E5=8E=86=E5=9B=BE=E5=92=8C=E9=80=90=E6=9C=88?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/DataBase/msg.py | 90 +++++++++++++------------------- app/analysis/analysis.py | 68 ++++++++++-------------- app/web_ui/templates/charts.html | 55 +++++++++++++++++-- app/web_ui/web.py | 77 ++++++++++++--------------- 4 files changed, 148 insertions(+), 142 deletions(-) diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index 8209680..21c0cc8 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -379,77 +379,57 @@ class Msg: lock.release() return [date[0] for date in result] - def get_messages_by_days(self, username_, is_Annual_report_=False, year_='2023'): - if is_Annual_report_: - sql = ''' - SELECT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') as days,count(MsgSvrID) - from ( - SELECT MsgSvrID, CreateTime - FROM MSG - WHERE StrTalker = ? AND strftime('%Y', CreateTime, 'unixepoch', 'localtime') = ? - ) - group by days - ''' - else: - sql = ''' - SELECT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') as days,count(MsgSvrID) - from ( - SELECT MsgSvrID, CreateTime - FROM MSG - WHERE StrTalker = ? - ) - group by days - ''' + def get_messages_by_days(self, username_, time_range=None): + result = None + if not self.open_flag: + return None + if time_range: + start_time, end_time = time_range + sql = f''' + SELECT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') as days,count(MsgSvrID) + from ( + SELECT MsgSvrID, CreateTime + FROM MSG + WHERE StrTalker = ? + {'AND CreateTime>' + str(start_time) + ' AND CreateTime<' + str(end_time) if time_range else ''} + ) + group by days + ''' result = None if not self.open_flag: return None try: lock.acquire(True) - if is_Annual_report_: - self.cursor.execute(sql, [username_, year_]) - else: - self.cursor.execute(sql, [username_]) + self.cursor.execute(sql, [username_]) result = self.cursor.fetchall() finally: lock.release() return result - def get_messages_by_month(self, username_, is_Annual_report_=False, year_='2023'): - if is_Annual_report_: - sql = ''' - SELECT strftime('%Y-%m',CreateTime,'unixepoch','localtime') as days,count(MsgSvrID) - from ( - SELECT MsgSvrID, CreateTime - FROM MSG - WHERE StrTalker = ? AND strftime('%Y', CreateTime, 'unixepoch', 'localtime') = ? - ) - group by days - ''' - else: - sql = ''' - SELECT strftime('%Y-%m',CreateTime,'unixepoch','localtime') as days,count(MsgSvrID) - from ( - SELECT MsgSvrID, CreateTime - FROM MSG - WHERE StrTalker = ? - ) - group by days - ''' + def get_messages_by_month(self, username_, time_range=None): result = None if not self.open_flag: return None + if time_range: + start_time, end_time = time_range + sql = f''' + SELECT strftime('%Y-%m',CreateTime,'unixepoch','localtime') as days,count(MsgSvrID) + from ( + SELECT MsgSvrID, CreateTime + FROM MSG + WHERE StrTalker = ? + {'AND CreateTime>' + str(start_time) + ' AND CreateTime<' + str(end_time) if time_range else ''} + ) + group by days + ''' try: lock.acquire(True) - if is_Annual_report_: - self.cursor.execute(sql, [username_, year_]) - else: - self.cursor.execute(sql, [username_]) + self.cursor.execute(sql, [username_]) result = self.cursor.fetchall() except sqlite3.DatabaseError: logger.error(f'{traceback.format_exc()}\n数据库损坏请删除msg文件夹重试') finally: lock.release() - # result.sort(key=lambda x: x[5]) return result def get_messages_by_hour(self, username_, year_='all'): @@ -572,12 +552,14 @@ class Msg: lock.release() return result - def get_messages_number(self, username_, year_="all") -> int: + def get_messages_number(self, username_, time_range=None) -> int: + if time_range: + start_time, end_time = time_range sql = f""" SELECT Count(MsgSvrID) from MSG where StrTalker = ? - {"and strftime('%Y', CreateTime, 'unixepoch', 'localtime') = ?" if year_ != "all" else ""} + {'AND CreateTime>' + str(start_time) + ' AND CreateTime<' + str(end_time) if time_range else ''} group by type, subtype order by Count(MsgSvrID) desc """ @@ -586,7 +568,7 @@ class Msg: return None try: lock.acquire(True) - self.cursor.execute(sql, [username_, year_] if year_ != "all" else [username_]) + self.cursor.execute(sql, [username_]) result = self.cursor.fetchone() except sqlite3.DatabaseError: logger.error(f'{traceback.format_exc()}\n数据库损坏请删除msg文件夹重试') diff --git a/app/analysis/analysis.py b/app/analysis/analysis.py index d39340f..28ad115 100644 --- a/app/analysis/analysis.py +++ b/app/analysis/analysis.py @@ -73,7 +73,7 @@ def wordcloud(wxid, is_Annual_report=False, year='2023', who='1'): } -def wordcloud_(wxid, is_Annual_report=False, time_range=None): +def wordcloud_(wxid, time_range=None): import jieba txt_messages = msg_db.get_messages_by_type(wxid, MsgType.TEXT, time_range=time_range) if not txt_messages: @@ -183,30 +183,15 @@ def wordcloud_christmas(wxid, year='2023'): } -def calendar_chart(wxid, is_Annual_report=False, year='2023'): - try: - calendar_data = msg_db.get_messages_by_days(wxid, is_Annual_report, year) - except: - return { - 'calendar_chart_data': None, - 'chat_days': 0, - } - if not calendar_data: - return { - 'calendar_chart_data': None, - 'chat_days': 0, - } +def calendar_chart(wxid, time_range=None): + calendar_data = msg_db.get_messages_by_days(wxid,time_range) min_ = min(map(lambda x: x[1], calendar_data)) max_ = max(map(lambda x: x[1], calendar_data)) start_date_ = calendar_data[0][0] end_date_ = calendar_data[-1][0] print(start_date_, '---->', end_date_) - if is_Annual_report: - calendar_days = year - calendar_title = f'{year}年聊天情况' - else: - calendar_days = (start_date_, end_date_) - calendar_title = '和Ta的聊天情况' + calendar_days = (start_date_, end_date_) + calendar_title = '和Ta的聊天情况' c = ( Calendar() .add( @@ -226,43 +211,50 @@ def calendar_chart(wxid, is_Annual_report=False, year='2023'): ) ) return { - 'calendar_chart_data': c.dump_options_with_quotes(), + 'chart_data': c.dump_options_with_quotes(), 'chat_days': len(calendar_data), + # 'chart':c, } -def month_count(wxid, is_Annual_report=False, year='2023'): +def month_count(wxid, time_range=None): """ 每月聊天条数 """ - msg_data = msg_db.get_messages_by_month(wxid, is_Annual_report, year) + msg_data = msg_db.get_messages_by_month(wxid, time_range) y_data = list(map(lambda x: x[1], msg_data)) x_axis = list(map(lambda x: x[0], msg_data)) m = ( - Bar(init_opts=opts.InitOpts(width=f"{charts_width}px", height=f"{charts_height}px")) + Bar(init_opts=opts.InitOpts()) .add_xaxis(x_axis) .add_yaxis("消息数量", y_data, - label_opts=opts.LabelOpts(is_show=False), - itemstyle_opts=opts.ItemStyleOpts(color="skyblue"), + label_opts=opts.LabelOpts(is_show=True), + itemstyle_opts=opts.ItemStyleOpts(color="#ffae80"), ) .set_global_opts( title_opts=opts.TitleOpts(title="逐月统计", subtitle=None), datazoom_opts=opts.DataZoomOpts(), toolbox_opts=opts.ToolboxOpts(), + yaxis_opts=opts.AxisOpts( + name="消息数", + type_="value", + axistick_opts=opts.AxisTickOpts(is_show=True), + splitline_opts=opts.SplitLineOpts(is_show=True), + ), visualmap_opts=opts.VisualMapOpts( min_=min(y_data), max_=max(y_data), dimension=1, # 根据第2个维度(y 轴)进行映射 is_piecewise=False, # 是否分段显示 - range_color=["#66ccff", "#003366"], # 设置颜色范围 + range_color=["#ffbe7a", "#fa7f6f"], # 设置颜色范围 type_="color", pos_right="0%", ), ) ) - return { - 'chart_data': m + 'chart_data': m.dump_options_with_quotes(), + # 'chart': m, } @@ -314,13 +306,11 @@ class Analysis: if __name__ == '__main__': msg_db.init_database(path='../DataBase/Msg/MSG.db') # w = wordcloud('wxid_0o18ef858vnu22') - w_data = wordcloud('wxid_27hqbq7vx5hf22', True, '2023') - # print(w_data) - # w['chart_data'].render("./data/聊天统计/wordcloud.html") - c = calendar_chart('wxid_27hqbq7vx5hf22', False, '2023') - c['chart_data'].render("./data/聊天统计/calendar.html") - # print('c:::', c) - m = month_count('wxid_27hqbq7vx5hf22', False, '2023') - m['chart_data'].render("./data/聊天统计/month_num.html") - h = hour_count('wxid_27hqbq7vx5hf22') - h['chart_data'].render("./data/聊天统计/hour_count.html") + # w_data = wordcloud('wxid_27hqbq7vx5hf22', True, '2023') + # # print(w_data) + # w_data['chart_data'].render("./data/聊天统计/wordcloud.html") + wxid = 'wxid_0o18ef858vnu22' + # data = month_count(wxid, time_range=None) + # data['chart'].render("./data/聊天统计/month_count.html") + data = calendar_chart(wxid, time_range=None) + data['chart'].render("./data/聊天统计/calendar_chart.html") diff --git a/app/web_ui/templates/charts.html b/app/web_ui/templates/charts.html index 979e45c..9090aa9 100644 --- a/app/web_ui/templates/charts.html +++ b/app/web_ui/templates/charts.html @@ -6,24 +6,59 @@ 微信年度聊天报告 +

{{my_nickname}}——{{ta_nickname}}

-
+
+

我们第一次聊天在

+

{{first_time}}

+

距今已有

+
+ + + + +
+
+
+
+ + diff --git a/app/web_ui/web.py b/app/web_ui/web.py index 1ef415d..735a0ac 100644 --- a/app/web_ui/web.py +++ b/app/web_ui/web.py @@ -28,6 +28,13 @@ def index(): @app.route("/christmas") def christmas(): + t = '2023-1-01 00:00:00' + s_t = time.strptime(t, "%Y-%m-%d %H:%M:%S") # 返回元祖 + start_time = int(time.mktime(s_t)) + t = '2023-12-31 23:59:59' + s_t = time.strptime(t, "%Y-%m-%d %H:%M:%S") # 返回元祖 + end_time = int(time.mktime(s_t)) + time_range = (start_time, end_time) # 渲染模板,并传递图表的 HTML 到模板中 try: first_message, first_time = msg_db.get_first_time_of_message(contact.wxid) @@ -63,7 +70,7 @@ def christmas(): 'chat_time': chat_time, 'chat_time_num': num, } - month_data = msg_db.get_messages_by_month(contact.wxid, True, year_='2023') + month_data = msg_db.get_messages_by_month(contact.wxid,time_range=time_range) if month_data: month_data.sort(key=lambda x: x[1]) @@ -74,16 +81,18 @@ def christmas(): else: max_month, max_num = '月份', 0 min_month, min_num = '月份', 0 + month_data = { 'year': '2023', - 'total_msg_num': msg_db.get_messages_number(contact.wxid, '2023'), + 'total_msg_num': msg_db.get_messages_number(contact.wxid,time_range=time_range), 'max_month': max_month, 'min_month': min_month, 'max_month_num': max_num, 'min_month_num': min_num, } - calendar_data = analysis.calendar_chart(contact.wxid, True, year='2023') - emoji_msgs = msg_db.get_messages_by_type(contact.wxid, 47, year_='2023') + + calendar_data = analysis.calendar_chart(contact.wxid, time_range) + emoji_msgs = msg_db.get_messages_by_type(contact.wxid, 47, time_range=time_range) url, num = get_most_emoji(emoji_msgs) emoji_data = { 'emoji_total_num': len(emoji_msgs), @@ -96,21 +105,6 @@ def christmas(): return html -@app.route('/home') -def home(): - try: - 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('/upload') def upload(): @@ -129,20 +123,6 @@ def upload(): response.headers.add('Content-Type', 'application/json') return response - -@app.route('/wordcloud//') -def one(who): - wxid = contact.wxid - # wxid = 'wxid_lltzaezg38so22' - # print('wxid:'+wxid) - world_cloud_data = analysis.wordcloud(wxid, who=who) # 获取与Ta的对话数据 - # print(world_cloud_data) - who = "你" if who == '1' else "TA" - 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, who=who) - - def set_text(text): html = ''' @@ -217,32 +197,41 @@ def generate_chart(): return bar.dump_options_with_quotes() -@app.route('/get_chart_options') +@app.route('/month_count') def get_chart_options(): - chart_options = generate_chart() - data = { - 'chart_data': chart_options - } + time_range = (0, time.time()) + data = analysis.month_count(contact.wxid, time_range=time_range) return jsonify(data) + @app.route('/wordcloud') def get_wordcloud(): - time_range = (0, time.time()) - print(time_range) + print(time_range,contact.wxid) + world_cloud_data = analysis.wordcloud_(contact.wxid, time_range=time_range) return jsonify(world_cloud_data) @app.route('/charts') def charts(): + # 渲染模板,并传递图表的 HTML 到模板中 + try: + first_message, first_time = msg_db.get_first_time_of_message(contact.wxid) + except TypeError: + first_time = '2023-01-01 00:00:00' data = { - 'my_nickname':Me().name, - 'ta_nickname':contact.remark, + 'my_nickname': Me().name, + 'ta_nickname': contact.remark, + 'first_time': first_time } - return render_template('charts.html',**data) - + return render_template('charts.html', **data) +@app.route('/calendar') +def get_calendar(): + time_range = (0, time.time()) + world_cloud_data = analysis.calendar_chart(contact.wxid, time_range=time_range) + return jsonify(world_cloud_data) if __name__ == "__main__": app.run(debug=True, host='0.0.0.0')