diff --git a/TEST.py b/TEST.py index cd02973..43c5642 100644 --- a/TEST.py +++ b/TEST.py @@ -1,25 +1,40 @@ -import os -import openai +import json -print("欢迎使用ChatGPT智能问答,请在Q:后面输入你的问题,输入quit退出!") -openai.api_key = '''eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UaEVOVUpHTkVNMVFURTRNMEZCTWpkQ05UZzVNRFUxUlRVd1FVSkRNRU13UmtGRVFrRXpSZyJ9.eyJodHRwczovL2FwaS5vcGVuYWkuY29tL3Byb2ZpbGUiOnsiZW1haWwiOiI4NjM5MDk2OTRAcXEuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImdlb2lwX2NvdW50cnkiOiJVUyJ9LCJodHRwczovL2FwaS5vcGVuYWkuY29tL2F1dGgiOnsidXNlcl9pZCI6InVzZXItdmdiMG1IeU5MQUNHRG1qRndrekVMNVM3In0sImlzcyI6Imh0dHBzOi8vYXV0aDAub3BlbmFpLmNvbS8iLCJzdWIiOiJhdXRoMHw2M2RjYmNiZWRiNzFkNmVhMzA5YmEzYzciLCJhdWQiOlsiaHR0cHM6Ly9hcGkub3BlbmFpLmNvbS92MSIsImh0dHBzOi8vb3BlbmFpLm9wZW5haS5hdXRoMGFwcC5jb20vdXNlcmluZm8iXSwiaWF0IjoxNjc1NDEyNTg2LCJleHAiOjE2NzYwMTczODYsImF6cCI6IlRkSkljYmUxNldvVEh0Tjk1bnl5d2g1RTR5T282SXRHIiwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBlbWFpbCBtb2RlbC5yZWFkIG1vZGVsLnJlcXVlc3Qgb3JnYW5pemF0aW9uLnJlYWQgb2ZmbGluZV9hY2Nlc3MifQ.dlTy6oc0eIDIJg0AqlFdarXWh7h-n7C6id3Kv5-uOrASoYB3qtfhPMuj15yV0VOOmFyj_L7v3MCpPEnsJp08NJo1Jn32jKtCkKD-sy8DpT5rafj_B6TKNvEBsqdXgDENg0ly9KiAjS-HDlCmQoBEqg-kc2VaqlpPIfk-164WI2SCTgQb50GNKWu0jwG-lx8BHnY8gUqC7sGVx4Hg9sLHccyAL93kMu4NS-S9CsqNefYAolLbqQLPBOG9MFaTD1jvyZpuqwm3eiv7HwgHempVWAfCK9sfGBblExHRT5zi0oSGwwBGmi2EnBHjEX185RRqtuH_uKRwp47m0TcHulJsfQ''' +from pyecharts import options as opts +from pyecharts.charts import Graph -start_sequence = "\nA:" -restart_sequence = "\nQ: " -while True: - prompt = input(restart_sequence) - if prompt == 'quit': - break - else: - try: - response = openai.Completion.create( - model="text-davinci-003", # 这里我们使用的是davinci-003的模型,准确度更高。 - prompt=prompt, - temperature=1, - max_tokens=2000, # 这里限制的是回答的长度,你可以可以限制字数,如:写一个300字作文等。 - frequency_penalty=0, - presence_penalty=0 - ) - print(start_sequence, response["choices"][0]["text"].strip()) - except Exception as exc: # 捕获异常后打印出来 - print(exc) +with open(r'data/npmdepgraph.min10.json', 'r') as f: + data = json.load(f) + +nodes = [ + { + 'x': node['x'], + 'y': node['y'], + 'name': node['label'], + 'symbolSize': node['size'], + 'itemStyle': {'color': node['color']} + } + for node in data['nodes'] +] + +edges = [ + { + 'source': edge['sourceID'], + 'target': edge['targetID'] + } + for edge in data['edges'] +] + +G = Graph(init_opts=opts.InitOpts(width='900', height='900')) +G.add( + series_name='', + nodes=nodes, + links=edges, + layout='none', + is_roam=True, + is_focusnode=True, + label_opts=opts.LabelOpts(is_show=True), + linestyle_opts=opts.LineStyleOpts(width=0.5, curve=0.3, opacity=0.7) +) +G.set_global_opts(title_opts=opts.TitleOpts(title='NPM Dependencies')) +G.render('npm_dependencies.html') diff --git a/app/DataBase/data.py b/app/DataBase/data.py index 1dcf093..e21eb3a 100644 --- a/app/DataBase/data.py +++ b/app/DataBase/data.py @@ -11,6 +11,7 @@ import hashlib import os import sqlite3 import time + import requests DB = None @@ -66,6 +67,7 @@ def mkdir(path): return True +mkdir(os.path.abspath('.') + '/app/DataBase') mkdir(os.path.abspath('.') + '/app/data/emoji') if os.path.exists('./app/DataBase/Msg.db'): DB = sqlite3.connect("./app/DataBase/Msg.db", check_same_thread=False) @@ -96,7 +98,7 @@ def decrypt(db, key): if os.path.exists('./app/DataBase/Msg.db'): print('/app/DataBase/Msg.db 已经存在') return True - cmd = '/sqlcipher-3.0.1/bin/sqlcipher-shell32.exe' + cmd = './sqlcipher-3.0.1/bin/sqlcipher-shell32.exe' print(os.path.abspath('.')) param = f""" PRAGMA key = '{key}'; @@ -105,9 +107,10 @@ def decrypt(db, key): SELECT sqlcipher_export('Msg'); DETACH DATABASE Msg; """ - with open('./app/DataBase/config.txt', 'w') as f: + + with open('./app/data/config.txt', 'w') as f: f.write(param) - p = os.system(f"{os.path.abspath('.')}{cmd} {db} < ./app/DataBase/config.txt") + p = os.system(f"{os.path.abspath('.')}{cmd} {db} < ./app/data/config.txt") global DB global cursor DB = sqlite3.connect("./app/DataBase/Msg.db", check_same_thread=False) @@ -155,10 +158,12 @@ def get_conRemark(username): sql = 'select conRemark,nickname from rcontact where username=?' cursor.execute(sql, [username]) result = cursor.fetchone() - if result[0]: - return result[0] - else: - return result[1] + if result: + if result[0]: + return result[0] + else: + return result[1] + return False def get_nickname(username): @@ -260,9 +265,14 @@ def get_emoji(imgPath): def download_emoji(imgPath, url): - resp = requests.get(url) - with open(imgPath, 'wb') as f: - f.write(resp.content) + if not url: + return False + try: + resp = requests.get(url) + with open(imgPath, 'wb') as f: + f.write(resp.content) + except: + return False return imgPath @@ -308,6 +318,15 @@ def recv_nums(username): return cursor.fetchone()[0] +def get_imgPath(imgPath): + sql = ''' + select bigImgPath from ImgInfo2 + where thumbImgPath = ?; + ''' + cursor.execute(sql, [imgPath]) + return cursor.fetchone()[0] + + def get_text(username): sql = ''' select content from message @@ -330,7 +349,7 @@ def msg_type_num(username): def get_msg_start_time(username): sql = ''' - select createTime from message + select strftime('%Y-%m-%d %H:%M:%S',createTime/1000,'unixepoch','localtime') from message where talker = ? order by msgId limit 1 @@ -341,7 +360,7 @@ def get_msg_start_time(username): def get_msg_end_time(username): sql = ''' - select createTime from message + select strftime('%Y-%m-%d %H:%M:%S',createTime/1000,'unixepoch','localtime') from message where talker = ? order by msgId desc limit 1 @@ -365,6 +384,18 @@ def get_msg_by_days(username, year='2022'): return result +def get_msg_by_day(username): + sql = ''' + SELECT strftime('%Y-%m-%d',createTime/1000,'unixepoch','localtime') as days,count(msgId) + from message + where talker = ? + group by days + ''' + cursor.execute(sql, [username]) + result = cursor.fetchall() + return result + + def get_msg_by_month(username, year='2022'): sql = ''' SELECT strftime('%Y-%m',createTime/1000,'unixepoch','localtime') as days,count(msgId) @@ -377,6 +408,252 @@ def get_msg_by_month(username, year='2022'): return result +def get_msg_by_hour(username): + sql = ''' + SELECT strftime('%H:00',createTime/1000,'unixepoch','localtime') as days,count(msgId) + from message + where talker = ? + group by days + ''' + cursor.execute(sql, [username]) + result = cursor.fetchall() + return result + + +def get_sport(): + sql = ''' + SELECT createTime,content,strftime('%Y-%m-%d',createTime/1000,'unixepoch','localtime') as months + from message + where talker = 'gh_43f2581f6fd6' + ''' + cursor.execute(sql) + result = cursor.fetchall() + return result + + +def get_myInfo(): + sql = ''' + select value from userinfo + where id = 4 + ''' + cursor.execute(sql) + name = cursor.fetchone()[0] + sql = ''' + select value from userinfo + where id = 5 + ''' + cursor.execute(sql) + email = cursor.fetchone()[0] + sql = ''' + select value from userinfo + where id = 6 + ''' + cursor.execute(sql) + tel = cursor.fetchone()[0] + sql = ''' + select value from userinfo + where id = 9 + ''' + cursor.execute(sql) + QQ = cursor.fetchone()[0] + sql = ''' + select value from userinfo + where id = 42 + ''' + cursor.execute(sql) + wxid = cursor.fetchone()[0] + sql = ''' + select value from userinfo + where id = 12291 + ''' + cursor.execute(sql) + signature = cursor.fetchone()[0] + sql = ''' + select value from userinfo + where id = 12292 + ''' + cursor.execute(sql) + city = cursor.fetchone()[0] + sql = ''' + select value from userinfo + where id = 12293 + ''' + cursor.execute(sql) + province = cursor.fetchone()[0] + return { + 'name': name, + 'username': wxid, + 'city': city, + 'province': province, + 'email': email, + 'QQ': QQ, + 'signature': signature, + 'tel': tel, + } + + +from pyecharts import options as opts +from pyecharts.charts import Bar, Line, Timeline, Grid +import pandas as pd +import xmltodict + + +def sport(username): + sports = get_sport() + ranks = [] + steps = [] + date = [] + for sport in sports: + try: + timestamp, content, t = sport + rank_data = xmltodict.parse(content) + sub_data = rank_data['msg']['appmsg']['hardwareinfo']['messagenodeinfo'] + # print(sub_data) + my_rank = sub_data['rankinfo']['rank']['rankdisplay'] + my_steps = int(sub_data['rankinfo']['score']['scoredisplay']) + # print(f'rank: {my_rank},steps: {my_steps}') + rank_view = rank_data['msg']['appmsg']['hardwareinfo']['rankview']['rankinfolist']['rankinfo'] + for userinfo in rank_view: + username0 = userinfo['username'] + if username0 == username: + rank_ta = int(userinfo['rank']['rankdisplay']) + steps_ta = int(userinfo['score']['scoredisplay']) + ranks.append(rank_ta) + steps.append(steps_ta) + date.append(t) + except: + continue + df = pd.DataFrame({'ranks': ranks, 'score': steps, 'date': date}, index=date) + months = pd.date_range(date[0], date[-1], freq='M') + tl = Timeline(init_opts=opts.InitOpts(width="440px", height="245px")) + tl.add_schema(is_auto_play=True) + for i in range(len(months) - 1): + da = df[(months[i + 1].strftime("%Y-%m-%d") >= df['date']) & (df['date'] > months[i].strftime("%Y-%m-%d"))] + bar = ( + Bar(init_opts=opts.InitOpts(width="400px", height="235px")) + .add_xaxis(list(da['date'])) + .add_yaxis( + "步数", + list(da['score']), + yaxis_index=1, + color="#d14a61", + ) + .extend_axis( + yaxis=opts.AxisOpts( + name="步数", + type_="value", + # grid_index=0, + # min_=0, + # max_=250, + position="right", + axisline_opts=opts.AxisLineOpts( + linestyle_opts=opts.LineStyleOpts(color="#d14a61") + ), + # axislabel_opts=opts.LabelOpts(formatter="{value} ml"), + ) + ) + .extend_axis( + yaxis=opts.AxisOpts( + type_="value", + name="排名", + # min_=0, + # max_=25, + position="left", + is_inverse=True, + # interval=True, + # grid_index=1, + axisline_opts=opts.AxisLineOpts( + linestyle_opts=opts.LineStyleOpts(color="#675bba") + ), + # axislabel_opts=opts.LabelOpts(formatter="{value} °C"), + splitline_opts=opts.SplitLineOpts( + is_show=True, linestyle_opts=opts.LineStyleOpts(opacity=1) + ), + ) + ) + .set_global_opts( + title_opts=opts.TitleOpts(title="{}月运动步数".format(months[i + 1].strftime("%Y-%m"))), + # legend_opts=opts.LegendOpts(is_show=False), + yaxis_opts=opts.AxisOpts(is_inverse=True) + ) + .set_series_opts( + label_opts=opts.LabelOpts( + is_show=False + ) + ) + ) + # init_opts = opts.InitOpts(width="400px", height="235px") + line = ( + Line(init_opts=opts.InitOpts(width="400px", height="235px")) + .add_xaxis(list(da['date'])) + .add_yaxis( + "排名", + list(da['ranks']), + yaxis_index=0, + color="#675bba", + # label_opts=opts.LabelOpts(is_show=False), + + ) + .set_global_opts( + yaxis_opts=opts.AxisOpts(is_inverse=True) + ) + ) + bar.overlap(line) + grid = Grid() + grid.add(bar, opts.GridOpts(pos_left="5%", pos_right="20%"), is_control_axis_index=True) + grid.render("grid_multi_yaxis.html") + quit() + # tl.add(bar, "{}".format(months[i].strftime("%Y-%m"))) + # tl.render("./sports.html") + + return { + username: { + 'ranks': ranks, + 'score': steps, + 'date': date, + } + } + + +def radar_hour(username): + msg_data = get_msg_by_hour(username) + x_axis = list(map(lambda x: x[0], msg_data)) + y_data = list(map(lambda x: x[1], msg_data)) + print(x_axis) + print(y_data) + max_ = max(y_data) + c = ( + Line() + .add_xaxis(xaxis_data=x_axis) + .add_yaxis( + series_name="聊天频率", + y_axis=y_data, + markpoint_opts=opts.MarkPointOpts( + data=[ + opts.MarkPointItem(type_="max", name="最大值"), + opts.MarkPointItem(type_="min", name="最小值"), + ] + ), + markline_opts=opts.MarkLineOpts( + data=[opts.MarkLineItem(type_="average", name="平均值")] + ), + ) + .render("temperature_change_line_chart.html") + ) + + +def chat_start_endTime(username): + start_time = get_msg_start_time(username) + end_time = get_msg_end_time(username) + year = start_time[:4] + month = start_time[5:7] + day = start_time[8:10] + hour = start_time[11:13] + minute = start_time[14:16] + second = start_time[17:] + print(year, month, day, hour, minute, second) + + if __name__ == '__main__': # rconversation = get_rconversation() # for i in rconversation: @@ -385,14 +662,23 @@ if __name__ == '__main__': # for contact in contacts: # print(contact) # [(177325,)] (73546,) (103770,) - print(search_send_message(1, 1)) - print(send_nums('wxid_vqave8lcp49r22')) - print(recv_nums('wxid_vqave8lcp49r22')) - # for t in get_text('wxid_vqave8lcp49r22'): - # print(t) - print(msg_type_num('wxid_vqave8lcp49r22')) - st = get_msg_start_time('wxid_vqave8lcp49r22') - print(st, timestamp2str(st)) - st = get_msg_end_time('wxid_vqave8lcp49r22') - print(st, timestamp2str(st)) - print(get_msg_by_month('wxid_8piw6sb4hvfm22', year='2022')) + # print(search_send_message(1, 1)) + # print(send_nums('wxid_vqave8lcp49r22')) + # print(recv_nums('wxid_vqave8lcp49r22')) + # # for t in get_text('wxid_vqave8lcp49r22'): + # # print(t) + # print(msg_type_num('wxid_vqave8lcp49r22')) + # st = get_msg_start_time('wxid_vqave8lcp49r22') + # print(st, timestamp2str(st)) + # st = get_msg_end_time('wxid_vqave8lcp49r22') + # print(st, timestamp2str(st)) + # print(get_msg_by_month('wxid_8piw6sb4hvfm22', year='2022')) + # print(len(get_sport())) + # result = sport('wxid_8piw6sb4hvfm22') + # print(get_imgPath('THUMBNAIL_DIRPATH://th_92f32326df645b3e1aecef9b6266a3b8')) + # result = get_msg_by_hour('wxid_8piw6sb4hvfm22') + # print(result) + # radar_hour('wxid_8piw6sb4hvfm22') + # print(result) + print(get_msg_start_time('wxid_8piw6sb4hvfm22'), get_msg_end_time('wxid_8piw6sb4hvfm22')) + chat_start_endTime('wxid_8piw6sb4hvfm22') diff --git a/app/DataBase/output.py b/app/DataBase/output.py index 882f7c4..dbead37 100644 --- a/app/DataBase/output.py +++ b/app/DataBase/output.py @@ -1,13 +1,15 @@ import os import re import time + import docx import xmltodict +from PyQt5.QtCore import * from docx import shared from docx.enum.table import WD_ALIGN_VERTICAL from docx.enum.text import WD_COLOR_INDEX, WD_PARAGRAPH_ALIGNMENT from docxcompose.composer import Composer -from PyQt5.QtCore import * + from . import data @@ -79,7 +81,7 @@ class Output(QThread): if self.i == self.total_num: QThread.sleep(1) conRemark = data.get_conRemark(self.ta_username) - self.progressSignal.emit(self.total_num-1) + self.progressSignal.emit(self.total_num - 1) self.merge_docx(conRemark, self.n) print('ok') self.progressSignal.emit(self.total_num) @@ -103,7 +105,7 @@ class Output(QThread): p = l len_data = messages[q:p] # self.to_docx(len_data, i, conRemark) - self.Child[i] = ChildThread(self.Me, self.ta_username, len_data, conRemark,i) + self.Child[i] = ChildThread(self.Me, self.ta_username, len_data, conRemark, i) self.Child[i].progressSignal.connect(self.progress) self.Child[i].start() @@ -116,7 +118,7 @@ class ChildThread(QThread): rangeSignal = pyqtSignal(int) i = 1 - def __init__(self, Me, ta_u, message, conRemark,num, parent=None): + def __init__(self, Me, ta_u, message, conRemark, num, parent=None): super().__init__(parent) self.Me = Me self.sec = 2 # 默认1000秒 @@ -301,16 +303,20 @@ class ChildThread(QThread): :param status: :return: ''' - pat_data = xmltodict.parse(content) - pat_data = pat_data['msg']['appmsg']['patMsg']['records']['record'] - fromUser = pat_data['fromUser'] - pattedUser = pat_data['pattedUser'] - template = pat_data['template'] - template = ''.join(template.split('${pattedusername@textstatusicon}')) - template = ''.join(template.split('${fromusername@textstatusicon}')) - template = template.replace(f'${{{fromUser}}}', data.get_conRemark(fromUser)) - template = template.replace(f'${{{pattedUser}}}', data.get_conRemark(pattedUser)) - print(template) + try: + pat_data = xmltodict.parse(content) + pat_data = pat_data['msg']['appmsg']['patMsg']['records']['record'] + fromUser = pat_data['fromUser'] + pattedUser = pat_data['pattedUser'] + template = pat_data['template'] + template = ''.join(template.split('${pattedusername@textstatusicon}')) + template = ''.join(template.split('${fromusername@textstatusicon}')) + template = template.replace(f'${{{fromUser}}}', data.get_conRemark(fromUser)) + template = template.replace(f'${{{pattedUser}}}', data.get_conRemark(pattedUser)) + print(template) + except Exception as e: + print(e) + template = '糟糕!出错了。' p = doc.add_paragraph() run = p.add_run(template) p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER diff --git a/app/Ui/chat/chat.py b/app/Ui/chat/chat.py index 7312ce8..3ee31d3 100644 --- a/app/Ui/chat/chat.py +++ b/app/Ui/chat/chat.py @@ -12,9 +12,10 @@ import time import xmltodict from PIL import Image -from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * +from PyQt5.QtWidgets import * + from .chatUi import * from ...DataBase import data from ...ImageBox.ui import MainDemo @@ -225,16 +226,21 @@ class ChatController(QWidget, Ui_Dialog): # self.message.moveCursor(self.message.textCursor().End) def pat_a_pat(self, content): - pat_data = xmltodict.parse(content) - pat_data = pat_data['msg']['appmsg']['patMsg']['records']['record'] - fromUser = pat_data['fromUser'] - pattedUser = pat_data['pattedUser'] - template = pat_data['template'] - template = ''.join(template.split('${pattedusername@textstatusicon}')) - template = ''.join(template.split('${fromusername@textstatusicon}')) - template = template.replace(f'${{{fromUser}}}', data.get_conRemark(fromUser)) - template = template.replace(f'${{{pattedUser}}}', data.get_conRemark(pattedUser)) - print(template) + try: + pat_data = xmltodict.parse(content) + pat_data = pat_data['msg']['appmsg']['patMsg']['records']['record'] + fromUser = pat_data['fromUser'] + pattedUser = pat_data['pattedUser'] + template = pat_data['template'] + template = ''.join(template.split('${pattedusername@textstatusicon}')) + template = ''.join(template.split('${fromusername@textstatusicon}')) + template = template.replace(f'${{{fromUser}}}', data.get_conRemark(fromUser)) + template = template.replace(f'${{{pattedUser}}}', data.get_conRemark(pattedUser)) + print(template) + except Exception as e: + print(e) + template = '糟糕!出错了。' + html = ''' @@ -258,6 +264,8 @@ class ChatController(QWidget, Ui_Dialog): def show_emoji(self, isSend, imagePath, content): imgPath = data.get_emoji(imagePath) + if not imgPath: + return False image = Image.open(imgPath) imagePixmap = image.size # 宽高像素 # 设置最大宽度 @@ -281,12 +289,13 @@ class ChatController(QWidget, Ui_Dialog): def show_img(self, isSend, imgPath, content): 'THUMBNAIL_DIRPATH://th_29cd0f0ca87652943be9ede365aabeaa' - imgPath = imgPath.split('th_')[1] - imgPath = f'./app/data/image2/{imgPath[0:2]}/{imgPath[2:4]}/th_{imgPath}' + # imgPath = imgPath.split('th_')[1] + imgPath = data.get_imgPath(imgPath) + imgPath = f'./app/data/image2/{imgPath[0:2]}/{imgPath[2:4]}/{imgPath}' html = ''' - ''' % (imgPath, imgPath) diff --git a/app/Ui/contact/analysis/analysis.py b/app/Ui/contact/analysis/analysis.py index 3909d18..ea9d3da 100644 --- a/app/Ui/contact/analysis/analysis.py +++ b/app/Ui/contact/analysis/analysis.py @@ -1,9 +1,10 @@ import sys -from PyQt5.QtWebEngineWidgets import QWebEngineView -from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * +from PyQt5.QtWebEngineWidgets import QWebEngineView +from PyQt5.QtWidgets import * + from . import charts @@ -14,7 +15,8 @@ class AnalysisController(QWidget): self.setWindowTitle('数据分析') self.setWindowIcon(QIcon('./app/data/icon.png')) # self.setWindowFlag(Qt.FramelessWindowHint) - self.setStyleSheet('''QWidget{background-color:rgb(255, 255, 255);}''') + # self.setStyleSheet('''QWidget{background-color:rgb(255, 255, 255);}''') + # self.setBackground() self.resize(400, 300) self.center() self.setAttribute(Qt.WA_AttributeCount) @@ -40,16 +42,14 @@ class AnalysisController(QWidget): def m_movie(self): movie = QMovie("./app/data/bg.gif") - self.label.setMovie(movie) - movie.start() def initUI(self): self.label.setVisible(False) main_box = QHBoxLayout(self) self.browser1 = QWebEngineView() - self.browser1.load(QUrl('http://www.baidu.com')) + self.browser1.load(QUrl('file:///data/聊天统计/title.html')) # self.browser1 = QFrame(self) # self.browser1.setFrameShape(QFrame.StyledPanel) # self.layoutWidget = QtWidgets.QWidget(self.browser1) @@ -67,13 +67,13 @@ class AnalysisController(QWidget): self.browser2 = QWebEngineView() self.browser2.load(QUrl('file:///data/聊天统计/wordcloud.html')) self.browser3 = QWebEngineView() - self.browser3.load(QUrl('http://www.baidu.com')) + self.browser3.load(QUrl('file:///data/聊天统计/time.html')) self.browser4 = QWebEngineView() self.browser4.load(QUrl('http://www.baidu.com')) self.browser5 = QWebEngineView() - self.browser5.load(QUrl('http://www.baidu.com')) + self.browser5.load(QUrl('file:///data/聊天统计/chat_session.html')) self.browser6 = QWebEngineView() - self.browser6.load(QUrl('http://www.baidu.com')) + self.browser6.load(QUrl('file:///data/聊天统计/sports.html')) self.browser7 = QWebEngineView() self.browser7.load(QUrl('file:///data/聊天统计/month_num.html')) self.browser8 = QWebEngineView() @@ -95,7 +95,7 @@ class AnalysisController(QWidget): splitter1.addWidget(self.browser1) splitter1.addWidget(splitter2) - splitter1.setSizes([1, 5]) + splitter1.setSizes([1, 8]) splitter2.addWidget(splitter6) splitter2.addWidget(splitter3) @@ -107,10 +107,10 @@ class AnalysisController(QWidget): splitter4.addWidget(splitter5) splitter4.addWidget(self.browser2) - splitter4.setSizes([1, 3]) + splitter4.setSizes([1, 5]) splitter5.addWidget(self.browser3) - splitter5.addWidget(self.browser4) + # splitter5.addWidget(self.browser4) splitter6.addWidget(self.browser5) splitter6.addWidget(splitter7) @@ -144,16 +144,20 @@ class LoadData(QThread): """ okSignal = pyqtSignal(int) - def __init__(self,ta_u, parent=None): + def __init__(self, ta_u, parent=None): super().__init__(parent) self.ta_username = ta_u def run(self): + charts.chat_start_endTime(self.ta_username) + charts.title(self.ta_username) charts.send_recv_rate(self.ta_username) charts.message_word_cloud(self.ta_username) charts.msg_type_rate(self.ta_username) charts.calendar_chart(self.ta_username) charts.month_num(self.ta_username) + charts.sport(self.ta_username) + charts.chat_session(self.ta_username) self.okSignal.emit(10) diff --git a/app/Ui/contact/analysis/charts.py b/app/Ui/contact/analysis/charts.py index 3740761..48ca2cf 100644 --- a/app/Ui/contact/analysis/charts.py +++ b/app/Ui/contact/analysis/charts.py @@ -1,9 +1,15 @@ import os + import jieba +import pandas as pd +import xmltodict from pyecharts import options as opts -from pyecharts.charts import Pie, WordCloud, Calendar, Bar +from pyecharts.charts import Pie, WordCloud, Calendar, Bar, Line, Timeline, Grid + from ....DataBase import data +# from app.DataBase import data + data.mkdir(os.path.abspath('.') + '/data/聊天统计') Type = { @@ -34,7 +40,7 @@ def send_recv_rate(username): total_num = send_num + recv_num print(send_num, recv_num) c = ( - Pie(init_opts=opts.InitOpts(width="460px", height="240px")) + Pie(init_opts=opts.InitOpts(width="463px", height="243px")) .add( "", [ @@ -43,7 +49,7 @@ def send_recv_rate(username): center=["40%", "50%"], ) .set_global_opts( - title_opts=opts.TitleOpts(title=f"信息发送接收",subtitle=f"总计:{total_num}条消息", pos_bottom="0%"), + title_opts=opts.TitleOpts(title=f"信息发送接收", subtitle=f"总计:{total_num}条消息", pos_bottom="0%"), legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical"), ) .set_series_opts( @@ -104,7 +110,7 @@ def message_word_cloud(username): text_data = text_data[:100] # print(text_data) ( - WordCloud(init_opts=opts.InitOpts(width="900px", height="550px")) + WordCloud(init_opts=opts.InitOpts(width="900px", height="700px")) .add(series_name="聊天文字", data_pair=text_data, word_size_range=[20, 100]) .set_global_opts( title_opts=opts.TitleOpts( @@ -112,17 +118,18 @@ def message_word_cloud(username): title_textstyle_opts=opts.TextStyleOpts(font_size=23) ), tooltip_opts=opts.TooltipOpts(is_show=True), + legend_opts=opts.LegendOpts(is_show=False) ) .render("./data/聊天统计/wordcloud.html") ) def calendar_chart(username): - msg_data = data.get_msg_by_days(username) + msg_data = data.get_msg_by_days(username, year='2022') min_ = min(map(lambda x: x[1], msg_data)) max_ = max(map(lambda x: x[1], msg_data)) c = ( - Calendar(init_opts=opts.InitOpts(width="460px", height="255px")) + Calendar(init_opts=opts.InitOpts(width="460px", height="270px")) .add( "", msg_data, @@ -139,6 +146,7 @@ def calendar_chart(username): pos_bottom="0px", pos_left="0px", ), + legend_opts=opts.LegendOpts(is_show=False) ) .render("./data/聊天统计/calendar.html") ) @@ -152,10 +160,9 @@ def month_num(username): y_data = list(map(lambda x: x[1], msg_data)) x_axis = list(map(lambda x: x[0], msg_data)) c = ( - Bar(init_opts=opts.InitOpts(width="440px", height="245px")) + Bar(init_opts=opts.InitOpts(width="440px", height="265px")) .add_xaxis(x_axis) .add_yaxis("消息数量", y_data) - # .add_yaxis("商家B", Faker.values()) .set_global_opts( title_opts=opts.TitleOpts(title="逐月聊天统计", subtitle=None), datazoom_opts=opts.DataZoomOpts(), @@ -165,5 +172,339 @@ def month_num(username): ) +def chat_session(username): + msg_data = data.get_msg_by_hour(username) + x_axis = list(map(lambda x: x[0], msg_data)) + y_data = list(map(lambda x: x[1], msg_data)) + # print(x_axis) + # print(y_data) + # max_ = max(y_data) + c = ( + Line(init_opts=opts.InitOpts(width="460px", height="270px")) + .add_xaxis(xaxis_data=x_axis) + .add_yaxis( + series_name="聊天频率", + y_axis=y_data, + markpoint_opts=opts.MarkPointOpts( + data=[ + opts.MarkPointItem(type_="max", name="最大值"), + opts.MarkPointItem(type_="min", name="最小值", value=int(10)), + ] + ), + markline_opts=opts.MarkLineOpts( + data=[opts.MarkLineItem(type_="average", name="平均值")] + ), + ) + .set_global_opts( + title_opts=opts.TitleOpts(title="聊天时段", subtitle=None), + # datazoom_opts=opts.DataZoomOpts(), + # toolbox_opts=opts.ToolboxOpts(), + ) + .set_series_opts( + label_opts=opts.LabelOpts( + is_show=False + ) + ) + .render("./data/聊天统计/chat_session.html") + ) + + +def sport(username): + sports = data.get_sport() + ranks = [] + steps = [] + date = [] + for sport in sports: + try: + timestamp, content, t = sport + rank_data = xmltodict.parse(content) + sub_data = rank_data['msg']['appmsg']['hardwareinfo']['messagenodeinfo'] + # print(sub_data) + my_rank = sub_data['rankinfo']['rank']['rankdisplay'] + my_steps = int(sub_data['rankinfo']['score']['scoredisplay']) + # print(f'rank: {my_rank},steps: {my_steps}') + rank_view = rank_data['msg']['appmsg']['hardwareinfo']['rankview']['rankinfolist']['rankinfo'] + for userinfo in rank_view: + username0 = userinfo['username'] + if username0 == username: + rank_ta = int(userinfo['rank']['rankdisplay']) + steps_ta = int(userinfo['score']['scoredisplay']) + ranks.append(rank_ta) + steps.append(steps_ta) + date.append(t) + except: + continue + df = pd.DataFrame({'ranks': ranks, 'score': steps, 'date': date}, index=date) + months = pd.date_range(date[0], date[-1], freq='M') + tl = Timeline(init_opts=opts.InitOpts(width="440px", height="265px")) + tl.add_schema(is_auto_play=True) + for i in range(len(months) - 1): + da = df[(months[i + 1].strftime("%Y-%m-%d") >= df['date']) & (df['date'] > months[i].strftime("%Y-%m-%d"))] + bar = ( + Bar(init_opts=opts.InitOpts(width="440px", height="265px")) + .add_xaxis(list(da['date'])) + .add_yaxis( + "步数", + list(da['score']), + yaxis_index=1, + color="#d14a61", + ) + .extend_axis( + yaxis=opts.AxisOpts( + name="步数", + type_="value", + # grid_index=0, + # min_=0, + # max_=250, + position="right", + axisline_opts=opts.AxisLineOpts( + linestyle_opts=opts.LineStyleOpts(color="#d14a61") + ), + # axislabel_opts=opts.LabelOpts(formatter="{value} ml"), + ) + ) + .extend_axis( + yaxis=opts.AxisOpts( + type_="value", + name="排名", + # min_=0, + # max_=25, + position="left", + is_inverse=True, + is_show=False, + # interval=True, + # grid_index=1, + axisline_opts=opts.AxisLineOpts( + linestyle_opts=opts.LineStyleOpts(color="#675bba") + ), + # axislabel_opts=opts.LabelOpts(formatter="{value} °C"), + splitline_opts=opts.SplitLineOpts( + is_show=True, linestyle_opts=opts.LineStyleOpts(opacity=1) + ), + ) + ) + .set_global_opts( + title_opts=opts.TitleOpts(title="{}月".format(months[i + 1].strftime("%Y-%m"))), + # legend_opts=opts.LegendOpts(is_show=False), + yaxis_opts=opts.AxisOpts(is_inverse=True) + ) + .set_series_opts( + label_opts=opts.LabelOpts( + is_show=False + ) + ) + ) + # init_opts = opts.InitOpts(width="400px", height="235px") + line = ( + Line(init_opts=opts.InitOpts(width="440px", height="265px")) + .add_xaxis(list(da['date'])) + .add_yaxis( + "排名", + list(da['ranks']), + yaxis_index=0, + color="#675bba", + # label_opts=opts.LabelOpts(is_show=False), + + ) + .set_global_opts( + yaxis_opts=opts.AxisOpts(is_inverse=True) + ) + .set_series_opts( + label_opts=opts.LabelOpts( + is_show=False + ) + ) + ) + bar.overlap(line) + grid = Grid() + grid.add(bar, opts.GridOpts(pos_left="7%", pos_right="11%"), is_control_axis_index=True) + # grid.render("grid_multi_yaxis.html") + tl.add(grid, "{}".format(months[i].strftime("%Y-%m"))) + tl.render("./data/聊天统计/sports.html") + return { + username: { + 'ranks': ranks, + 'score': steps, + 'date': date, + } + } + + +def chat_start_endTime(username): + start_time = data.get_msg_start_time(username) + end_time = data.get_msg_end_time(username) + year = start_time[:4] + month = start_time[5:7] + day = start_time[8:10] + hour = start_time[11:13] + minute = start_time[14:16] + second = start_time[17:] + html = ''' + + + + 聊天时间 + + + + +
+

+ 一次聊天发生 + %s-%s %s:%s:%s +

+
+
+ 距今已有 + 626 天 + 6 时 + 26 分 + 26 秒 +
+
+
+ + + + + ''' % (year, month + '-' + day, hour, minute, second, start_time) + print(year, month, day, hour, minute, second) + with open('./data/聊天统计/time.html', 'w', encoding='utf-8') as f: + f.write(html) + + +def title(username): + conRemark = data.get_conRemark(username) + avatar = data.get_avator(username) + html = ''' + + + + 聊天时间 + + + + +
+
- - + + +
+ + + + +
+ + + + +
+ Avatar +
+
+ + + + +
+ %s +
+
+
+ + + + +
+ + + + ''' % (avatar, conRemark) + print('头像地址', avatar) + with open('./data/聊天统计/title.html', 'w', encoding='utf-8') as f: + f.write(html) + + if __name__ == '__main__': - send_recv_rate('wxid_wt2vsktnu4z022') + # send_recv_rate('wxid_wt2vsktnu4z022') + sport('wxid_wt2vsktnu4z022') diff --git a/app/Ui/decrypt/decrypt.py b/app/Ui/decrypt/decrypt.py index d6c12a0..d6a791e 100644 --- a/app/Ui/decrypt/decrypt.py +++ b/app/Ui/decrypt/decrypt.py @@ -10,13 +10,14 @@ import hashlib import os import time +import xml.etree.ElementTree as ET +from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * -from PyQt5.QtCore import * + from . import decryptUi from ...DataBase import data -import xml.etree.ElementTree as ET class DecryptControl(QWidget, decryptUi.Ui_Dialog): @@ -103,7 +104,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog): print("enter clicked") # 中间可以添加处理逻辑 self.DecryptSignal.emit('ok') - self.close() + # self.close() def progressBar_view(self, value): """ @@ -120,7 +121,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog): def btnExitClicked(self): print("Exit clicked") - self.close() + # self.close() class DecryptThread(QThread): diff --git a/app/Ui/mainview.py b/app/Ui/mainview.py index 5cb2672..951d761 100644 --- a/app/Ui/mainview.py +++ b/app/Ui/mainview.py @@ -8,13 +8,14 @@ @comment : 主窗口 """ -from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * -from .mainviewUi import * +from PyQt5.QtWidgets import * + from app.DataBase import data from .chat import chat from .contact import contact +from .mainviewUi import * class MainWinController(QMainWindow, Ui_Dialog): @@ -31,9 +32,11 @@ class MainWinController(QMainWindow, Ui_Dialog): self.chatView.setVisible(False) self.contactView = contact.ContactController(self.Me, parent=self.frame_main) self.contactView.setVisible(False) + # self.myinfoView = userinfo.MyinfoController(self.Me, parent=self.frame_main) + # self.myinfoView.setVisible(False) self.btn_chat.clicked.connect(self.chat_view) # 聊天按钮 self.btn_contact.clicked.connect(self.contact_view) - self.btn_myinfo.clicked.connect(self.myInfo) + # self.btn_myinfo.clicked.connect(self.myInfo) self.btn_about.clicked.connect(self.about) self.now_btn = self.btn_chat self.btn_about.setContextMenuPolicy(Qt.CustomContextMenu) @@ -105,6 +108,7 @@ class MainWinController(QMainWindow, Ui_Dialog): self.last_btn.setStyleSheet("QPushButton {background-color: rgb(240,240,240);}" "QPushButton:hover{background-color: rgb(209,209,209);}\n") self.last_btn = self.now_btn + self.setviewVisible(self.myinfoView) def about(self): """ diff --git a/app/Ui/mainviewUi.py b/app/Ui/mainviewUi.py index 1a24102..17a84be 100644 --- a/app/Ui/mainviewUi.py +++ b/app/Ui/mainviewUi.py @@ -47,18 +47,6 @@ class Ui_Dialog(object): "QPushButton:hover{background-color: rgb(209,209,209);}") self.btn_contact.setObjectName("btn_contact") self.verticalLayout_2.addWidget(self.btn_contact) - self.btn_addC = QtWidgets.QPushButton(self.verticalLayoutWidget) - self.btn_addC.setMinimumSize(QtCore.QSize(0, 80)) - self.btn_addC.setStyleSheet("QPushButton {background-color: rgb(240,240,240);}\n" -"QPushButton:hover{background-color: rgb(209,209,209);}") - self.btn_addC.setObjectName("btn_addC") - self.verticalLayout_2.addWidget(self.btn_addC) - self.btn_add_group = QtWidgets.QPushButton(self.verticalLayoutWidget) - self.btn_add_group.setMinimumSize(QtCore.QSize(0, 80)) - self.btn_add_group.setStyleSheet("QPushButton {background-color: rgb(240,240,240);}\n" -"QPushButton:hover{background-color: rgb(209,209,209);}") - self.btn_add_group.setObjectName("btn_add_group") - self.verticalLayout_2.addWidget(self.btn_add_group) self.btn_myinfo = QtWidgets.QPushButton(self.verticalLayoutWidget) self.btn_myinfo.setMinimumSize(QtCore.QSize(100, 80)) self.btn_myinfo.setStyleSheet("QPushButton {background-color: rgb(240,240,240);}\n" @@ -73,7 +61,6 @@ class Ui_Dialog(object): self.verticalLayout_2.addWidget(self.btn_about) self.verticalLayout_2.setStretch(0, 1) self.verticalLayout_2.setStretch(2, 1) - self.verticalLayout_2.setStretch(4, 1) self.myavatar = QtWidgets.QLabel(self.frame_info) self.myavatar.setGeometry(QtCore.QRect(30, 50, 100, 100)) self.myavatar.setObjectName("myavatar") @@ -92,8 +79,6 @@ class Ui_Dialog(object): Dialog.setWindowTitle(_translate("Dialog", "Dialog")) self.btn_chat.setText(_translate("Dialog", "聊天")) self.btn_contact.setText(_translate("Dialog", "联系人")) - self.btn_addC.setText(_translate("Dialog", "添加联系人")) - self.btn_add_group.setText(_translate("Dialog", "群聊")) self.btn_myinfo.setText(_translate("Dialog", "我的")) self.btn_about.setText(_translate("Dialog", "关于")) self.myavatar.setText(_translate("Dialog", "avatar")) diff --git a/app/Ui/mainviewUi.ui b/app/Ui/mainviewUi.ui index 90406dd..64f4302 100644 --- a/app/Ui/mainviewUi.ui +++ b/app/Ui/mainviewUi.ui @@ -1,216 +1,186 @@ - Dialog - - - - 0 - 0 - 1280 - 720 - - - - ArrowCursor - - - Dialog - - - false - - - - - 160 - 0 - 1120 - 720 - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - 0 - 0 - 161 - 721 - - - - background-color:rgb(240,240,240) - - - QFrame::StyledPanel - - - QFrame::Sunken - - - - - 20 - 190 - 111 - 501 - - - - - 0 - - - - - - 0 - 80 - - - - QPushButton {background-color: rgb(240,240,240);} -QPushButton:hover{background-color: rgb(209,209,209);} - - - 聊天 - - - - - - - - 0 - 80 - - - - QPushButton {background-color: rgb(240,240,240);} -QPushButton:hover{background-color: rgb(209,209,209);} - - - 联系人 - - - - - - - - 0 - 80 - - - - QPushButton {background-color: rgb(240,240,240);} -QPushButton:hover{background-color: rgb(209,209,209);} - - - 添加联系人 - - - - - - - - 0 - 80 - - - - QPushButton {background-color: rgb(240,240,240);} -QPushButton:hover{background-color: rgb(209,209,209);} - - - 群聊 - - - - - - - - 100 - 80 - - - - QPushButton {background-color: rgb(240,240,240);} -QPushButton:hover{background-color: rgb(209,209,209);} - - - 我的 - - - - - - - - 100 - 80 - - - - QPushButton {background-color: rgb(240,240,240);} -QPushButton:hover{background-color: rgb(209,209,209);} - - - 关于 - - - - - - - - - 30 - 50 - 100 - 100 - - - - avatar - - - - - - 0 - 0 - 71 - 28 - - - - 退出登录 - - - - - - 80 - 0 - 71 - 28 - - - - 注销账户 - - - - - - + Dialog + + + + 0 + 0 + 1280 + 720 + + + + ArrowCursor + + + Dialog + + + false + + + + + 160 + 0 + 1120 + 720 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + 0 + 0 + 161 + 721 + + + + background-color:rgb(240,240,240) + + + QFrame::StyledPanel + + + QFrame::Sunken + + + + + 20 + 190 + 111 + 501 + + + + + 0 + + + + + + 0 + 80 + + + + QPushButton {background-color: rgb(240,240,240);} + QPushButton:hover{background-color: rgb(209,209,209);} + + + + 聊天 + + + + + + + + 0 + 80 + + + + QPushButton {background-color: rgb(240,240,240);} + QPushButton:hover{background-color: rgb(209,209,209);} + + + + 联系人 + + + + + + + + 100 + 80 + + + + QPushButton {background-color: rgb(240,240,240);} + QPushButton:hover{background-color: rgb(209,209,209);} + + + + 我的 + + + + + + + + 100 + 80 + + + + QPushButton {background-color: rgb(240,240,240);} + QPushButton:hover{background-color: rgb(209,209,209);} + + + + 关于 + + + + + + + + + 30 + 50 + 100 + 100 + + + + avatar + + + + + + 0 + 0 + 71 + 28 + + + + 退出登录 + + + + + + 80 + 0 + 71 + 28 + + + + 注销账户 + + + + + + diff --git a/app/data/icon.png b/app/data/icon.png index 8e6590f..4920ebd 100644 Binary files a/app/data/icon.png and b/app/data/icon.png differ diff --git a/main.py b/main.py index 53aa065..5614723 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,7 @@ -from PyQt5.QtWidgets import * -from PyQt5.QtCore import * -from PyQt5.QtGui import * import sys + +from PyQt5.QtWidgets import * + from app.Ui import * @@ -23,9 +23,10 @@ class ViewController: 注册界面 :return: """ - self.viewDecrypt = register.registerControl() # 需要将viewlogin设为成员变量 - self.viewDecrypt.DecryptSignal.connect(self.loadDecryptView) - self.viewDecrypt.show() + pass + # self.viewDecrypt = register.registerControl() # 需要将viewlogin设为成员变量 + # self.viewDecrypt.DecryptSignal.connect(self.loadDecryptView) + # self.viewDecrypt.show() def loadMainWinView(self, username): """ @@ -46,6 +47,6 @@ class ViewController: if __name__ == '__main__': app = QApplication(sys.argv) view = ViewController() - # view.loadDecryptView() # 进入登录界面,如果viewlogin不是成员变量,则离开作用域后失效。 - view.loadMainWinView('102') + view.loadDecryptView() # 进入登录界面,如果viewlogin不是成员变量,则离开作用域后失效。 + # view.loadMainWinView('102') sys.exit(app.exec_()) diff --git a/test.html b/test.html index 72ff00f..9ed6e65 100644 --- a/test.html +++ b/test.html @@ -3,8 +3,7 @@ Title - - - -
- - - - - - - - > - - - - - - - -
- %s 13245: - - - - - ADC
- %s 13245: -
+ + + + + + + + + + + +
+ + + + + + + + + > + + + + + + + +
+ + + + + + + + + ADC
+ %s 13245: +
- - Document + + Document - - - - - - - - - - - - - - - - - - - - - - - - - - -
我是标题
英雄性别职业
亚索中单
卡莎ADC
寒冰
+ + + + + + + + + + + + + + + + + + + + + + + + + +
我是标题
英雄性别职业
亚索中单
卡莎ADC
寒冰
diff --git a/wechat.html b/wechat.html index 6d22c10..15d1ce8 100644 --- a/wechat.html +++ b/wechat.html @@ -1,168 +1,55 @@ - - - - - - - - -title + + 聊天时间 + + + + -
-
-
- 我要抢楼 - -
- -
-
- -
- - 欢迎来抢楼!欢迎来抢楼!欢迎来抢楼!欢迎来抢楼!欢迎来抢楼!欢迎来抢楼!欢迎来抢楼! -
-
-
-
- 我要抢楼我要抢楼我要抢楼。 - -
- -
-
- -
- - 欢迎来抢楼!欢迎来抢楼!欢迎来抢楼!欢迎来抢楼!欢迎来抢楼!欢迎来抢楼! -
-
-
+ +
+ 你好 +
+
+ +
+ \ No newline at end of file