diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py index e4410ee..d6d616b 100644 --- a/app/DataBase/msg.py +++ b/app/DataBase/msg.py @@ -126,10 +126,18 @@ class Msg: # result.sort(key=lambda x: x[5]) return result - def get_messages_by_type(self, username_, type_): + def get_messages_by_type(self, username_, type_, is_Annual_report_=False, year_='2023'): if not self.open_flag: return None - sql = ''' + if is_Annual_report_: + sql = ''' + select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra + from MSG + where StrTalker=? and Type=? and strftime('%Y',CreateTime,'unixepoch','localtime') = ? + order by CreateTime + ''' + else: + sql = ''' select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra from MSG where StrTalker=? and Type=? @@ -137,7 +145,10 @@ class Msg: ''' try: lock.acquire(True) - self.cursor.execute(sql, [username_, type_]) + if is_Annual_report_: + self.cursor.execute(sql, [username_, type_, year_]) + else: + self.cursor.execute(sql, [username_, type_]) result = self.cursor.fetchall() finally: lock.release() @@ -186,37 +197,59 @@ class Msg: )) return res - def get_messages_by_days(self, username_, year_='2023'): - sql = ''' - SELECT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') as days,count(MsgSvrID) - from MSG - where StrTalker = ? and strftime('%Y',CreateTime,'unixepoch','localtime') = ? - group by days - ''' - result = None - if not self.open_flag: - return None - try: - lock.acquire(True) - self.cursor.execute(sql, [username_, year_]) - result = self.cursor.fetchall() - finally: - lock.release() - return result - - def get_messages_by_month(self, username_, year_='2023'): - sql = ''' - SELECT strftime('%Y-%m',CreateTime,'unixepoch','localtime') as days,count(MsgSvrID) + 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 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 MSG + where StrTalker = ? + group by days + ''' result = None if not self.open_flag: return None try: lock.acquire(True) - self.cursor.execute(sql, [username_, year_]) + if is_Annual_report_: + self.cursor.execute(sql, [username_, year_]) + else: + 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 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 MSG + where StrTalker = ? + 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_]) result = self.cursor.fetchall() except sqlite3.DatabaseError: logger.error(f'{traceback.format_exc()}\n数据库损坏请删除msg文件夹重试') @@ -225,11 +258,19 @@ class Msg: # result.sort(key=lambda x: x[5]) return result - def get_messages_by_hour(self, username_, year_='2023'): - sql = ''' + def get_messages_by_hour(self, username_, is_Annual_report_=False, year_='2023'): + if is_Annual_report_: + sql = ''' + SELECT strftime('%H:00',CreateTime,'unixepoch','localtime') as hours,count(MsgSvrID) + from MSG + where StrTalker = ? and strftime('%Y',CreateTime,'unixepoch','localtime') = ? + group by hours + ''' + else: + sql = ''' SELECT strftime('%H:00',CreateTime,'unixepoch','localtime') as hours,count(MsgSvrID) from MSG - where StrTalker = ? and strftime('%Y',CreateTime,'unixepoch','localtime') = ? + where StrTalker = ? group by hours ''' result = None @@ -237,7 +278,10 @@ class Msg: return None try: lock.acquire(True) - self.cursor.execute(sql, [username_, year_]) + if is_Annual_report_: + self.cursor.execute(sql, [username_, year_]) + else: + self.cursor.execute(sql, [username_]) result = self.cursor.fetchall() except sqlite3.DatabaseError: logger.error(f'{traceback.format_exc()}\n数据库损坏请删除msg文件夹重试') diff --git a/app/analysis/analysis.py b/app/analysis/analysis.py index 7ef407a..2f2c8fa 100644 --- a/app/analysis/analysis.py +++ b/app/analysis/analysis.py @@ -7,7 +7,7 @@ sys.path.append('.') from app.DataBase import msg_db, MsgType from pyecharts import options as opts -from pyecharts.charts import WordCloud, Calendar, Bar +from pyecharts.charts import WordCloud, Calendar, Bar, Line from app.resources import resource_rc import tkinter as tk @@ -92,9 +92,9 @@ class StopwordsWindow(tk.Tk): except Exception as e: messagebox.showerror("Error", f"An error occurred: {str(e)}") -def wordcloud(wxid): +def wordcloud(wxid, is_Annual_report=False, year='2023'): import jieba - txt_messages = msg_db.get_messages_by_type(wxid, MsgType.TEXT) + txt_messages = msg_db.get_messages_by_type(wxid, MsgType.TEXT, is_Annual_report, year) if not txt_messages: return { 'chart_data': None, @@ -157,23 +157,31 @@ def wordcloud(wxid): } -def calendar_chart(wxid, year): - calendar_data = msg_db.get_messages_by_days(wxid, year) +def calendar_chart(wxid, is_Annual_report=False, year='2023'): + calendar_data = msg_db.get_messages_by_days(wxid, is_Annual_report, year) if not calendar_data: return False 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的聊天情况' c = ( Calendar(init_opts=opts.InitOpts(width=f"{charts_width}px", height=f"{charts_height}px")) .add( "", calendar_data, - calendar_opts=opts.CalendarOpts(range_=year) + calendar_opts=opts.CalendarOpts(range_=calendar_days) ) .set_global_opts( - title_opts=opts.TitleOpts(title="2023年聊天情况"), + title_opts=opts.TitleOpts(title=calendar_title), visualmap_opts=opts.VisualMapOpts( max_=max_, min_=min_, @@ -191,11 +199,11 @@ def calendar_chart(wxid, year): } -def month_count(wxid, year): +def month_count(wxid, is_Annual_report=False, year='2023'): """ 每月聊天条数 """ - msg_data = msg_db.get_messages_by_month(wxid, year) + msg_data = msg_db.get_messages_by_month(wxid, is_Annual_report, year) y_data = list(map(lambda x: x[1], msg_data)) x_axis = list(map(lambda x: x[0], msg_data)) m = ( @@ -226,11 +234,11 @@ def month_count(wxid, year): } -def hour_count(wxid, year): +def hour_count(wxid, is_Annual_report=False, year='2023'): """ 小时计数聊天条数 """ - msg_data = msg_db.get_messages_by_hour(wxid, year) + msg_data = msg_db.get_messages_by_hour(wxid, is_Annual_report, year) print(msg_data) y_data = list(map(lambda x: x[1], msg_data)) x_axis = list(map(lambda x: x[0], msg_data)) @@ -274,10 +282,13 @@ class Analysis: if __name__ == '__main__': msg_db.init_database(path='../DataBase/Msg/MSG.db') # w = wordcloud('wxid_0o18ef858vnu22') - c = calendar_chart('wxid_27hqbq7vx5hf22', '2023') + 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', '2023') + # print('c:::', c) + m = month_count('wxid_27hqbq7vx5hf22', False, '2023') m['chart_data'].render("./data/聊天统计/month_num.html") - h = hour_count('wxid_27hqbq7vx5hf22', '2023') + h = hour_count('wxid_27hqbq7vx5hf22') h['chart_data'].render("./data/聊天统计/hour_count.html") diff --git a/app/ui_pc/chat/chat_info.py b/app/ui_pc/chat/chat_info.py index 2421151..5735824 100644 --- a/app/ui_pc/chat/chat_info.py +++ b/app/ui_pc/chat/chat_info.py @@ -88,6 +88,7 @@ class ChatInfo(QWidget): is_send = message[4] avatar = MePC().avatar if is_send else self.contact.avatar timestamp = message[5] + BytesExtra = message[10] if type_ == 1: if self.is_5_min(timestamp): time_message = Notice(self.last_str_time) @@ -106,7 +107,7 @@ class ChatInfo(QWidget): time_message = Notice(self.last_str_time) self.last_str_time = str_time self.chat_window.add_message_item(time_message, 0) - image_path = hard_link_db.get_image(content=str_content, thumb=False) + image_path = hard_link_db.get_image(content=str_content,bytesExtra=BytesExtra, thumb=False) image_path = get_abs_path(image_path) bubble_message = BubbleMessage( image_path, diff --git a/readme.md b/readme.md index 7dabb86..45d4b36 100644 --- a/readme.md +++ b/readme.md @@ -316,11 +316,29 @@ python main.py 如果您是一名开发者,有新的想法或建议,欢迎[fork](https://github.com/LC044/WeChatMsg/forks) 该项目并发起[PR](https://github.com/LC044/WeChatMsg/pulls),我将把您的名字写入贡献者名单中 -另外本人硬件配置: +# 贡献者 -* 在校大学生一枚,时间有限、精力有限、能力有限 -* 24寸1080p屏幕一个(缩放率100%,不是500%) -* CPU:AMD 6800H -* 内存:64G(那些说性能差爆内存的有没有从自身找原因,这么多年了,有没有努力,内存容量涨没涨) -* 操作系统:Win11(就俩字“好看”) -* 所以任何超出硬件支持之外的需求在我硬件没变之前都不会适配 \ No newline at end of file + + + + +# 支持 + +感谢您对这个项目的兴趣和支持!如果您发现这个项目对您有帮助,并且您愿意提供赞助以维持项目的发展和改进,我将非常感激。 + +## 赞助方式 + +您可以通过以下方式提供赞助: + +- [爱发电](https://afdian.net/a/lc044) +- [博客主页](https://blog.lc044.love/about) + +## 赞助者名单 + +感谢以下赞助者的慷慨支持: + +如果您提供赞助并希望出现在赞助者名单中,请在提交赞助时提供您的 GitHub 用户名或其他相关信息。 + +## 感谢 + +再次感谢您的支持,这对项目的持续发展至关重要! \ No newline at end of file