支持单个联系人选择导出日期

This commit is contained in:
shuaikangzhou 2024-01-10 20:03:04 +08:00
parent 88770e0d3c
commit e7de20d50e
14 changed files with 413 additions and 111 deletions

View File

@ -344,6 +344,28 @@ class Msg:
contacts.sort(key=lambda cur_contact: cur_contact[-1], reverse=True) contacts.sort(key=lambda cur_contact: cur_contact[-1], reverse=True)
return contacts return contacts
def get_messages_calendar(self, username_):
sql = '''
SELECT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') as days
from (
SELECT MsgSvrID, CreateTime
FROM MSG
WHERE StrTalker = ?
ORDER BY CreateTime
)
group by days
'''
if not self.open_flag:
print('数据库未就绪')
return None
try:
lock.acquire(True)
self.cursor.execute(sql, [username_])
result = self.cursor.fetchall()
finally:
lock.release()
return [date[0] for date in result]
def get_messages_by_days(self, username_, is_Annual_report_=False, year_='2023'): def get_messages_by_days(self, username_, is_Annual_report_=False, year_='2023'):
if is_Annual_report_: if is_Annual_report_:
sql = ''' sql = '''
@ -694,39 +716,11 @@ class Msg:
if __name__ == '__main__': if __name__ == '__main__':
db_path = "./app/database/Msg/MSG.db" db_path = "./Msg/MSG.db"
msg = Msg() msg = Msg()
msg.init_database() msg.init_database()
wxid = 'wxid_0o18ef858vnu22' wxid = 'wxid_0o18ef858vnu22'
wxid = '24521163022@chatroom' wxid = '24521163022@chatroom'
wxid = 'wxid_vtz9jk9ulzjt22' # si wxid = 'wxid_vtz9jk9ulzjt22' # si
print() print()
from app.util import compress_content print(msg.get_messages_calendar(wxid))
import xml.etree.ElementTree as ET
msgs = msg.get_messages(wxid)
for msg in msgs:
if msg[2] == 49 and msg[3] == 5:
xml = compress_content.decompress_CompressContent(msg[11])
root = ET.XML(xml)
appmsg = root.find('appmsg')
title = appmsg.find('title').text
des = appmsg.find('des').text
url = appmsg.find('url').text
appinfo = root.find('appinfo')
show_display_name = appmsg.find('sourcedisplayname')
if show_display_name is not None:
show_display_name = show_display_name.text
else:
show_display_name = appinfo.find('appname').text
print(title, des, url, show_display_name)
msg_bytes = MessageBytesExtra()
msg_bytes.ParseFromString(msg[10])
for tmp in msg_bytes.message2:
if tmp.field1 == 3:
thumb = tmp.field2
print(thumb)
if tmp.field2 == 4:
app_logo = tmp.field2
print('logo', app_logo)

View File

@ -1,8 +1,12 @@
import time import time
from PyQt5 import QtWidgets from datetime import datetime, timedelta
from PyQt5.QtCore import QTimer, QThread, pyqtSignal from PyQt5.QtCore import QTimer, QThread, pyqtSignal, Qt
from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout, \
QToolButton
from app.ui.Icon import Icon
class CalendarDialog(QDialog): class CalendarDialog(QDialog):
@ -18,12 +22,37 @@ class CalendarDialog(QDialog):
self.setWindowTitle('选择日期') self.setWindowTitle('选择日期')
self.calendar = QCalendarWidget(self) self.calendar = QCalendarWidget(self)
self.calendar.clicked.connect(self.onDateChanged) self.calendar.clicked.connect(self.onDateChanged)
prev_btn = self.calendar.findChild(QToolButton, "qt_calendar_prevmonth")
prev_btn.setIcon(Icon.Arrow_left_Icon)
next_btn = self.calendar.findChild(QToolButton, "qt_calendar_nextmonth")
next_btn.setIcon(Icon.Arrow_right_Icon)
self.date_range = date_range
if date_range: if date_range:
self.calendar.setDateRange(*date_range) self.calendar.setDateRange(*date_range)
# 从第一天开始,依次添加日期到列表,直到该月的最后一天
current_date = date_range[1]
while (current_date + timedelta(days=1)).month == date_range[1].month:
current_date += timedelta(days=1)
range_format = self.calendar.dateTextFormat(current_date)
range_format.setForeground(Qt.gray)
self.calendar.setDateTextFormat(current_date, range_format)
# 从第一天开始,依次添加日期到列表,直到该月的最后一天
current_date = date_range[0]
while (current_date - timedelta(days=1)).month == date_range[0].month:
current_date -= timedelta(days=1)
range_format = self.calendar.dateTextFormat(current_date)
range_format.setForeground(Qt.gray)
self.calendar.setDateTextFormat(current_date, range_format)
layout = QVBoxLayout(self) layout = QVBoxLayout(self)
layout.addWidget(self.calendar) layout.addWidget(self.calendar)
self.setLayout(layout) self.setLayout(layout)
def set_start_date(self):
if self.date_range:
self.calendar.setCurrentPage(self.date_range[0].year, self.date_range[0].month)
def set_end_date(self):
if self.date_range:
self.calendar.setCurrentPage(self.date_range[1].year, self.date_range[1].month)
def onDateChanged(self): def onDateChanged(self):
# 获取选择的日期 # 获取选择的日期
selected_date = self.calendar.selectedDate() selected_date = self.calendar.selectedDate()
@ -37,11 +66,11 @@ class CalendarDialog(QDialog):
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
from datetime import datetime from datetime import datetime, timedelta
app = QApplication(sys.argv) app = QApplication(sys.argv)
# 设置日期范围 # 设置日期范围
start_date = datetime(2023, 12, 11) start_date = datetime(2024, 1, 5)
end_date = datetime(2024, 1, 9) end_date = datetime(2024, 1, 9)
date_range = (start_date.date(), end_date.date()) date_range = (start_date.date(), end_date.date())
ex = CalendarDialog(date_range=date_range) ex = CalendarDialog(date_range=date_range)

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1704887643791" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6156" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M803.342997 87.013896a47.908827 47.908827 0 0 0 0-70.993102A61.421574 61.421574 0 0 0 723.904429 13.256823l-3.173448 2.763971L241.23323 470.949915l-2.405678 1.842647c-1.637909 1.228431-3.173448 2.559232-4.606618 3.941218-20.013196 18.938319-20.985704 48.113566-2.86634 68.075577l2.815155 2.917525 484.820954 459.945216c22.521244 21.343997 60.090773 21.343997 82.612016 0 20.013196-18.938319 20.985704-48.113566 2.86634-68.075577l-2.86634-2.968709-446.893132-423.911227L803.342997 87.013896z" fill="#303133" p-id="6157"></path></svg>

After

Width:  |  Height:  |  Size: 863 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1704887684029" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7130" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M240.871694 97.117314a56.39844 56.39844 0 0 1 0-80.461775 58.110393 58.110393 0 0 1 81.469746 0l460.787257 455.107414a56.39844 56.39844 0 0 1 0 80.445775L322.34144 1007.332141a58.110393 58.110393 0 0 1-81.469746 0 56.39844 56.39844 0 0 1 0-80.461775L660.956076 511.98584 240.871694 97.117314z" fill="#111111" p-id="7131"></path></svg>

After

Width:  |  Height:  |  Size: 665 B

View File

@ -41,5 +41,7 @@
<file>icons/woman.svg</file> <file>icons/woman.svg</file>
<file>icons/select.svg</file> <file>icons/select.svg</file>
<file>icons/unselect.svg</file> <file>icons/unselect.svg</file>
<file>icons/arrow-left.svg</file>
<file>icons/arrow-right.svg</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -16768,6 +16768,62 @@ qt_resource_data = b"\
\x22\x20\x66\x69\x6c\x6c\x3d\x22\x23\x46\x46\x37\x42\x31\x35\x22\ \x22\x20\x66\x69\x6c\x6c\x3d\x22\x23\x46\x46\x37\x42\x31\x35\x22\
\x20\x70\x2d\x69\x64\x3d\x22\x32\x36\x30\x33\x33\x22\x3e\x3c\x2f\ \x20\x70\x2d\x69\x64\x3d\x22\x32\x36\x30\x33\x33\x22\x3e\x3c\x2f\
\x70\x61\x74\x68\x3e\x3c\x2f\x73\x76\x67\x3e\ \x70\x61\x74\x68\x3e\x3c\x2f\x73\x76\x67\x3e\
\x00\x00\x03\x5f\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\x6e\
\x6f\x22\x3f\x3e\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x73\x76\
\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\x57\x33\x43\
\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\x2f\x2f\x45\
\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\x73\x2f\x53\
\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\x67\x31\x31\
\x2e\x64\x74\x64\x22\x3e\x3c\x73\x76\x67\x20\x74\x3d\x22\x31\x37\
\x30\x34\x38\x38\x37\x36\x34\x33\x37\x39\x31\x22\x20\x63\x6c\x61\
\x73\x73\x3d\x22\x69\x63\x6f\x6e\x22\x20\x76\x69\x65\x77\x42\x6f\
\x78\x3d\x22\x30\x20\x30\x20\x31\x30\x32\x34\x20\x31\x30\x32\x34\
\x22\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\
\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
\x67\x22\x20\x70\x2d\x69\x64\x3d\x22\x36\x31\x35\x36\x22\x20\x78\
\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\
\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\
\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x77\x69\x64\x74\x68\x3d\
\x22\x31\x36\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x36\x22\
\x3e\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x38\x30\x33\x2e\x33\
\x34\x32\x39\x39\x37\x20\x38\x37\x2e\x30\x31\x33\x38\x39\x36\x61\
\x34\x37\x2e\x39\x30\x38\x38\x32\x37\x20\x34\x37\x2e\x39\x30\x38\
\x38\x32\x37\x20\x30\x20\x30\x20\x30\x20\x30\x2d\x37\x30\x2e\x39\
\x39\x33\x31\x30\x32\x41\x36\x31\x2e\x34\x32\x31\x35\x37\x34\x20\
\x36\x31\x2e\x34\x32\x31\x35\x37\x34\x20\x30\x20\x30\x20\x30\x20\
\x37\x32\x33\x2e\x39\x30\x34\x34\x32\x39\x20\x31\x33\x2e\x32\x35\
\x36\x38\x32\x33\x6c\x2d\x33\x2e\x31\x37\x33\x34\x34\x38\x20\x32\
\x2e\x37\x36\x33\x39\x37\x31\x4c\x32\x34\x31\x2e\x32\x33\x33\x32\
\x33\x20\x34\x37\x30\x2e\x39\x34\x39\x39\x31\x35\x6c\x2d\x32\x2e\
\x34\x30\x35\x36\x37\x38\x20\x31\x2e\x38\x34\x32\x36\x34\x37\x63\
\x2d\x31\x2e\x36\x33\x37\x39\x30\x39\x20\x31\x2e\x32\x32\x38\x34\
\x33\x31\x2d\x33\x2e\x31\x37\x33\x34\x34\x38\x20\x32\x2e\x35\x35\
\x39\x32\x33\x32\x2d\x34\x2e\x36\x30\x36\x36\x31\x38\x20\x33\x2e\
\x39\x34\x31\x32\x31\x38\x2d\x32\x30\x2e\x30\x31\x33\x31\x39\x36\
\x20\x31\x38\x2e\x39\x33\x38\x33\x31\x39\x2d\x32\x30\x2e\x39\x38\
\x35\x37\x30\x34\x20\x34\x38\x2e\x31\x31\x33\x35\x36\x36\x2d\x32\
\x2e\x38\x36\x36\x33\x34\x20\x36\x38\x2e\x30\x37\x35\x35\x37\x37\
\x6c\x32\x2e\x38\x31\x35\x31\x35\x35\x20\x32\x2e\x39\x31\x37\x35\
\x32\x35\x20\x34\x38\x34\x2e\x38\x32\x30\x39\x35\x34\x20\x34\x35\
\x39\x2e\x39\x34\x35\x32\x31\x36\x63\x32\x32\x2e\x35\x32\x31\x32\
\x34\x34\x20\x32\x31\x2e\x33\x34\x33\x39\x39\x37\x20\x36\x30\x2e\
\x30\x39\x30\x37\x37\x33\x20\x32\x31\x2e\x33\x34\x33\x39\x39\x37\
\x20\x38\x32\x2e\x36\x31\x32\x30\x31\x36\x20\x30\x20\x32\x30\x2e\
\x30\x31\x33\x31\x39\x36\x2d\x31\x38\x2e\x39\x33\x38\x33\x31\x39\
\x20\x32\x30\x2e\x39\x38\x35\x37\x30\x34\x2d\x34\x38\x2e\x31\x31\
\x33\x35\x36\x36\x20\x32\x2e\x38\x36\x36\x33\x34\x2d\x36\x38\x2e\
\x30\x37\x35\x35\x37\x37\x6c\x2d\x32\x2e\x38\x36\x36\x33\x34\x2d\
\x32\x2e\x39\x36\x38\x37\x30\x39\x2d\x34\x34\x36\x2e\x38\x39\x33\
\x31\x33\x32\x2d\x34\x32\x33\x2e\x39\x31\x31\x32\x32\x37\x4c\x38\
\x30\x33\x2e\x33\x34\x32\x39\x39\x37\x20\x38\x37\x2e\x30\x31\x33\
\x38\x39\x36\x7a\x22\x20\x66\x69\x6c\x6c\x3d\x22\x23\x33\x30\x33\
\x31\x33\x33\x22\x20\x70\x2d\x69\x64\x3d\x22\x36\x31\x35\x37\x22\
\x3e\x3c\x2f\x70\x61\x74\x68\x3e\x3c\x2f\x73\x76\x67\x3e\
\x00\x00\x09\xf9\ \x00\x00\x09\xf9\
\x3c\ \x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\ \x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
@ -19560,6 +19616,50 @@ qt_resource_data = b"\
\x91\x45\x16\x59\x64\x91\x45\x16\xff\xa5\x50\xea\xff\x03\xa2\x62\ \x91\x45\x16\x59\x64\x91\x45\x16\xff\xa5\x50\xea\xff\x03\xa2\x62\
\xb7\x9c\xc4\xc5\xc1\xc0\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\ \xb7\x9c\xc4\xc5\xc1\xc0\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\
\x60\x82\ \x60\x82\
\x00\x00\x02\x99\
\x3c\
\x3f\x78\x6d\x6c\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\
\x30\x22\x20\x73\x74\x61\x6e\x64\x61\x6c\x6f\x6e\x65\x3d\x22\x6e\
\x6f\x22\x3f\x3e\x3c\x21\x44\x4f\x43\x54\x59\x50\x45\x20\x73\x76\
\x67\x20\x50\x55\x42\x4c\x49\x43\x20\x22\x2d\x2f\x2f\x57\x33\x43\
\x2f\x2f\x44\x54\x44\x20\x53\x56\x47\x20\x31\x2e\x31\x2f\x2f\x45\
\x4e\x22\x20\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x77\
\x33\x2e\x6f\x72\x67\x2f\x47\x72\x61\x70\x68\x69\x63\x73\x2f\x53\
\x56\x47\x2f\x31\x2e\x31\x2f\x44\x54\x44\x2f\x73\x76\x67\x31\x31\
\x2e\x64\x74\x64\x22\x3e\x3c\x73\x76\x67\x20\x74\x3d\x22\x31\x37\
\x30\x34\x38\x38\x37\x36\x38\x34\x30\x32\x39\x22\x20\x63\x6c\x61\
\x73\x73\x3d\x22\x69\x63\x6f\x6e\x22\x20\x76\x69\x65\x77\x42\x6f\
\x78\x3d\x22\x30\x20\x30\x20\x31\x30\x32\x34\x20\x31\x30\x32\x34\
\x22\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x22\x31\x2e\x31\x22\x20\
\x78\x6d\x6c\x6e\x73\x3d\x22\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\
\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x32\x30\x30\x30\x2f\x73\x76\
\x67\x22\x20\x70\x2d\x69\x64\x3d\x22\x37\x31\x33\x30\x22\x20\x78\
\x6d\x6c\x6e\x73\x3a\x78\x6c\x69\x6e\x6b\x3d\x22\x68\x74\x74\x70\
\x3a\x2f\x2f\x77\x77\x77\x2e\x77\x33\x2e\x6f\x72\x67\x2f\x31\x39\
\x39\x39\x2f\x78\x6c\x69\x6e\x6b\x22\x20\x77\x69\x64\x74\x68\x3d\
\x22\x31\x36\x22\x20\x68\x65\x69\x67\x68\x74\x3d\x22\x31\x36\x22\
\x3e\x3c\x70\x61\x74\x68\x20\x64\x3d\x22\x4d\x32\x34\x30\x2e\x38\
\x37\x31\x36\x39\x34\x20\x39\x37\x2e\x31\x31\x37\x33\x31\x34\x61\
\x35\x36\x2e\x33\x39\x38\x34\x34\x20\x35\x36\x2e\x33\x39\x38\x34\
\x34\x20\x30\x20\x30\x20\x31\x20\x30\x2d\x38\x30\x2e\x34\x36\x31\
\x37\x37\x35\x20\x35\x38\x2e\x31\x31\x30\x33\x39\x33\x20\x35\x38\
\x2e\x31\x31\x30\x33\x39\x33\x20\x30\x20\x30\x20\x31\x20\x38\x31\
\x2e\x34\x36\x39\x37\x34\x36\x20\x30\x6c\x34\x36\x30\x2e\x37\x38\
\x37\x32\x35\x37\x20\x34\x35\x35\x2e\x31\x30\x37\x34\x31\x34\x61\
\x35\x36\x2e\x33\x39\x38\x34\x34\x20\x35\x36\x2e\x33\x39\x38\x34\
\x34\x20\x30\x20\x30\x20\x31\x20\x30\x20\x38\x30\x2e\x34\x34\x35\
\x37\x37\x35\x4c\x33\x32\x32\x2e\x33\x34\x31\x34\x34\x20\x31\x30\
\x30\x37\x2e\x33\x33\x32\x31\x34\x31\x61\x35\x38\x2e\x31\x31\x30\
\x33\x39\x33\x20\x35\x38\x2e\x31\x31\x30\x33\x39\x33\x20\x30\x20\
\x30\x20\x31\x2d\x38\x31\x2e\x34\x36\x39\x37\x34\x36\x20\x30\x20\
\x35\x36\x2e\x33\x39\x38\x34\x34\x20\x35\x36\x2e\x33\x39\x38\x34\
\x34\x20\x30\x20\x30\x20\x31\x20\x30\x2d\x38\x30\x2e\x34\x36\x31\
\x37\x37\x35\x4c\x36\x36\x30\x2e\x39\x35\x36\x30\x37\x36\x20\x35\
\x31\x31\x2e\x39\x38\x35\x38\x34\x20\x32\x34\x30\x2e\x38\x37\x31\
\x36\x39\x34\x20\x39\x37\x2e\x31\x31\x37\x33\x31\x34\x7a\x22\x20\
\x66\x69\x6c\x6c\x3d\x22\x23\x31\x31\x31\x31\x31\x31\x22\x20\x70\
\x2d\x69\x64\x3d\x22\x37\x31\x33\x31\x22\x3e\x3c\x2f\x70\x61\x74\
\x68\x3e\x3c\x2f\x73\x76\x67\x3e\
\x00\x00\x05\x66\ \x00\x00\x05\x66\
\x89\ \x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@ -20457,6 +20557,10 @@ qt_resource_name = b"\
\x08\x97\xaf\x87\ \x08\x97\xaf\x87\
\x00\x73\ \x00\x73\
\x00\x74\x00\x61\x00\x72\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\ \x00\x74\x00\x61\x00\x72\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x0e\
\x08\xfa\x38\xa7\
\x00\x61\
\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x07\ \x00\x07\
\x0a\xa9\x5a\x07\ \x0a\xa9\x5a\x07\
\x00\x63\ \x00\x63\
@ -20493,6 +20597,10 @@ qt_resource_name = b"\
\x0f\x0e\xef\x47\ \x0f\x0e\xef\x47\
\x00\x77\ \x00\x77\
\x00\x65\x00\x69\x00\x78\x00\x69\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x65\x00\x69\x00\x78\x00\x69\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
\x00\x0f\
\x0f\x22\x69\x47\
\x00\x61\
\x00\x72\x00\x72\x00\x6f\x00\x77\x00\x2d\x00\x72\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x73\x00\x76\x00\x67\
\x00\x05\ \x00\x05\
\x00\x33\x57\x47\ \x00\x33\x57\x47\
\x00\x30\ \x00\x30\
@ -20530,7 +20638,7 @@ qt_resource_name = b"\
qt_resource_struct_v1 = b"\ qt_resource_struct_v1 = b"\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x22\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x24\x00\x00\x00\x03\
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x13\x52\ \x00\x00\x00\x34\x00\x00\x00\x00\x00\x01\x00\x00\x13\x52\
\x00\x00\x00\x50\x00\x01\x00\x00\x00\x01\x00\x00\x19\x78\ \x00\x00\x00\x50\x00\x01\x00\x00\x00\x01\x00\x00\x19\x78\
@ -20557,22 +20665,24 @@ qt_resource_struct_v1 = b"\
\x00\x00\x02\x76\x00\x00\x00\x00\x00\x01\x00\x04\x0c\x41\ \x00\x00\x02\x76\x00\x00\x00\x00\x00\x01\x00\x04\x0c\x41\
\x00\x00\x02\x90\x00\x00\x00\x00\x00\x01\x00\x04\x11\xe2\ \x00\x00\x02\x90\x00\x00\x00\x00\x00\x01\x00\x04\x11\xe2\
\x00\x00\x02\xa8\x00\x00\x00\x00\x00\x01\x00\x04\x14\x12\ \x00\x00\x02\xa8\x00\x00\x00\x00\x00\x01\x00\x04\x14\x12\
\x00\x00\x02\xbc\x00\x00\x00\x00\x00\x01\x00\x04\x1e\x0f\ \x00\x00\x02\xca\x00\x00\x00\x00\x00\x01\x00\x04\x17\x75\
\x00\x00\x02\xd6\x00\x02\x00\x00\x00\x08\x00\x00\x00\x25\ \x00\x00\x02\xde\x00\x00\x00\x00\x00\x01\x00\x04\x21\x72\
\x00\x00\x02\xea\x00\x00\x00\x00\x00\x01\x00\x04\x26\x4a\ \x00\x00\x02\xf8\x00\x02\x00\x00\x00\x08\x00\x00\x00\x27\
\x00\x00\x03\x00\x00\x00\x00\x00\x00\x01\x00\x04\x2e\x00\ \x00\x00\x03\x0c\x00\x00\x00\x00\x00\x01\x00\x04\x29\xad\
\x00\x00\x03\x1a\x00\x00\x00\x00\x00\x01\x00\x04\x31\x18\ \x00\x00\x03\x22\x00\x00\x00\x00\x00\x01\x00\x04\x31\x63\
\x00\x00\x03\x2e\x00\x00\x00\x00\x00\x01\x00\x04\x34\x91\ \x00\x00\x03\x3c\x00\x00\x00\x00\x00\x01\x00\x04\x34\x7b\
\x00\x00\x03\x44\x00\x00\x00\x00\x00\x01\x00\x04\x3d\x9c\ \x00\x00\x03\x50\x00\x00\x00\x00\x00\x01\x00\x04\x37\xf4\
\x00\x00\x03\x5a\x00\x00\x00\x00\x00\x01\x00\x04\x44\xe1\ \x00\x00\x03\x66\x00\x00\x00\x00\x00\x01\x00\x04\x40\xff\
\x00\x00\x03\x74\x00\x00\x00\x00\x00\x01\x00\x04\xc1\x58\ \x00\x00\x03\x7c\x00\x00\x00\x00\x00\x01\x00\x04\x48\x44\
\x00\x00\x03\x84\x00\x00\x00\x00\x00\x01\x00\x04\xc6\xc2\ \x00\x00\x03\x96\x00\x00\x00\x00\x00\x01\x00\x04\xc4\xbb\
\x00\x00\x03\x94\x00\x00\x00\x00\x00\x01\x00\x04\xcc\x40\ \x00\x00\x03\xba\x00\x00\x00\x00\x00\x01\x00\x04\xc7\x58\
\x00\x00\x03\xa4\x00\x00\x00\x00\x00\x01\x00\x04\xd2\x63\ \x00\x00\x03\xca\x00\x00\x00\x00\x00\x01\x00\x04\xcc\xc2\
\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x04\xd8\x6c\ \x00\x00\x03\xda\x00\x00\x00\x00\x00\x01\x00\x04\xd2\x40\
\x00\x00\x03\xc4\x00\x00\x00\x00\x00\x01\x00\x04\xde\x8f\ \x00\x00\x03\xea\x00\x00\x00\x00\x00\x01\x00\x04\xd8\x63\
\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x04\xe4\xd0\ \x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x04\xde\x6c\
\x00\x00\x03\xe4\x00\x00\x00\x00\x00\x01\x00\x04\xeb\x23\ \x00\x00\x04\x0a\x00\x00\x00\x00\x00\x01\x00\x04\xe4\x8f\
\x00\x00\x04\x1a\x00\x00\x00\x00\x00\x01\x00\x04\xea\xd0\
\x00\x00\x04\x2a\x00\x00\x00\x00\x00\x01\x00\x04\xf1\x23\
" "
qt_resource_struct_v2 = b"\ qt_resource_struct_v2 = b"\
@ -20580,7 +20690,7 @@ qt_resource_struct_v2 = b"\
\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x22\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x02\x00\x00\x00\x24\x00\x00\x00\x03\
\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ \x00\x00\x00\x10\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
\x00\x00\x01\x8c\x68\xa4\x46\x85\ \x00\x00\x01\x8c\x68\xa4\x46\x85\
@ -20633,38 +20743,42 @@ qt_resource_struct_v2 = b"\
\x00\x00\x02\x90\x00\x00\x00\x00\x00\x01\x00\x04\x11\xe2\ \x00\x00\x02\x90\x00\x00\x00\x00\x00\x01\x00\x04\x11\xe2\
\x00\x00\x01\x8c\x68\xa6\x6b\x89\ \x00\x00\x01\x8c\x68\xa6\x6b\x89\
\x00\x00\x02\xa8\x00\x00\x00\x00\x00\x01\x00\x04\x14\x12\ \x00\x00\x02\xa8\x00\x00\x00\x00\x00\x01\x00\x04\x14\x12\
\x00\x00\x01\x8c\xf3\x38\xf8\x1c\
\x00\x00\x02\xca\x00\x00\x00\x00\x00\x01\x00\x04\x17\x75\
\x00\x00\x01\x8c\x16\x33\xc3\xa4\ \x00\x00\x01\x8c\x16\x33\xc3\xa4\
\x00\x00\x02\xbc\x00\x00\x00\x00\x00\x01\x00\x04\x1e\x0f\ \x00\x00\x02\xde\x00\x00\x00\x00\x00\x01\x00\x04\x21\x72\
\x00\x00\x01\x8c\x68\xa5\xb8\xe6\ \x00\x00\x01\x8c\x68\xa5\xb8\xe6\
\x00\x00\x02\xd6\x00\x02\x00\x00\x00\x08\x00\x00\x00\x25\ \x00\x00\x02\xf8\x00\x02\x00\x00\x00\x08\x00\x00\x00\x27\
\x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x02\xea\x00\x00\x00\x00\x00\x01\x00\x04\x26\x4a\ \x00\x00\x03\x0c\x00\x00\x00\x00\x00\x01\x00\x04\x29\xad\
\x00\x00\x01\x8c\x16\x33\xc3\xa5\ \x00\x00\x01\x8c\x16\x33\xc3\xa5\
\x00\x00\x03\x00\x00\x00\x00\x00\x00\x01\x00\x04\x2e\x00\ \x00\x00\x03\x22\x00\x00\x00\x00\x00\x01\x00\x04\x31\x63\
\x00\x00\x01\x8c\xee\x70\x7d\x1b\ \x00\x00\x01\x8c\xee\x70\x7d\x1b\
\x00\x00\x03\x1a\x00\x00\x00\x00\x00\x01\x00\x04\x31\x18\ \x00\x00\x03\x3c\x00\x00\x00\x00\x00\x01\x00\x04\x34\x7b\
\x00\x00\x01\x8c\x68\x2b\xa2\xb9\ \x00\x00\x01\x8c\x68\x2b\xa2\xb9\
\x00\x00\x03\x2e\x00\x00\x00\x00\x00\x01\x00\x04\x34\x91\ \x00\x00\x03\x50\x00\x00\x00\x00\x00\x01\x00\x04\x37\xf4\
\x00\x00\x01\x8c\x68\xa8\x53\x77\ \x00\x00\x01\x8c\x68\xa8\x53\x77\
\x00\x00\x03\x44\x00\x00\x00\x00\x00\x01\x00\x04\x3d\x9c\ \x00\x00\x03\x66\x00\x00\x00\x00\x00\x01\x00\x04\x40\xff\
\x00\x00\x01\x8c\x68\x9c\x76\x1a\ \x00\x00\x01\x8c\x68\x9c\x76\x1a\
\x00\x00\x03\x5a\x00\x00\x00\x00\x00\x01\x00\x04\x44\xe1\ \x00\x00\x03\x7c\x00\x00\x00\x00\x00\x01\x00\x04\x48\x44\
\x00\x00\x01\x8c\x9b\xb4\x01\x0f\ \x00\x00\x01\x8c\x9b\xb4\x01\x0f\
\x00\x00\x03\x74\x00\x00\x00\x00\x00\x01\x00\x04\xc1\x58\ \x00\x00\x03\x96\x00\x00\x00\x00\x00\x01\x00\x04\xc4\xbb\
\x00\x00\x01\x8c\xf3\x39\x91\xdd\
\x00\x00\x03\xba\x00\x00\x00\x00\x00\x01\x00\x04\xc7\x58\
\x00\x00\x01\x8b\x0b\x05\xf6\x30\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\
\x00\x00\x03\x84\x00\x00\x00\x00\x00\x01\x00\x04\xc6\xc2\ \x00\x00\x03\xca\x00\x00\x00\x00\x00\x01\x00\x04\xcc\xc2\
\x00\x00\x01\x8b\x0b\x05\xf6\x30\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\
\x00\x00\x03\x94\x00\x00\x00\x00\x00\x01\x00\x04\xcc\x40\ \x00\x00\x03\xda\x00\x00\x00\x00\x00\x01\x00\x04\xd2\x40\
\x00\x00\x01\x8b\x0b\x05\xf6\x30\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\
\x00\x00\x03\xa4\x00\x00\x00\x00\x00\x01\x00\x04\xd2\x63\ \x00\x00\x03\xea\x00\x00\x00\x00\x00\x01\x00\x04\xd8\x63\
\x00\x00\x01\x8b\x0b\x05\xf6\x30\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\
\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x04\xd8\x6c\ \x00\x00\x03\xfa\x00\x00\x00\x00\x00\x01\x00\x04\xde\x6c\
\x00\x00\x01\x8b\x0b\x05\xf6\x30\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\
\x00\x00\x03\xc4\x00\x00\x00\x00\x00\x01\x00\x04\xde\x8f\ \x00\x00\x04\x0a\x00\x00\x00\x00\x00\x01\x00\x04\xe4\x8f\
\x00\x00\x01\x8b\x0b\x05\xf6\x30\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\
\x00\x00\x03\xd4\x00\x00\x00\x00\x00\x01\x00\x04\xe4\xd0\ \x00\x00\x04\x1a\x00\x00\x00\x00\x00\x01\x00\x04\xea\xd0\
\x00\x00\x01\x8b\x0b\x05\xf6\x30\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\
\x00\x00\x03\xe4\x00\x00\x00\x00\x00\x01\x00\x04\xeb\x23\ \x00\x00\x04\x2a\x00\x00\x00\x00\x00\x01\x00\x04\xf1\x23\
\x00\x00\x01\x8b\x0b\x05\xf6\x30\ \x00\x00\x01\x8b\x0b\x05\xf6\x30\
" "

View File

@ -36,6 +36,8 @@ class Icon:
Woman_Icon_path = ':/icons/icons/woman.svg' Woman_Icon_path = ':/icons/icons/woman.svg'
Man_Icon = QIcon(':/icons/icons/man.svg') Man_Icon = QIcon(':/icons/icons/man.svg')
Woman_Icon = QIcon(':/icons/icons/woman.svg') Woman_Icon = QIcon(':/icons/icons/woman.svg')
Arrow_left_Icon = QIcon(':/icons/icons/arrow-left.svg')
Arrow_right_Icon = QIcon(':/icons/icons/arrow-right.svg')
# Man_Icon_pixmap = QPixmap(Man_Icon_path) # Man_Icon_pixmap = QPixmap(Man_Icon_path)
# Woman_Icon_pixmap = QPixmap(Woman_Icon_path) # Woman_Icon_pixmap = QPixmap(Woman_Icon_path)
# Logo_Icon = QIcon(':/icons/icons/logo.png') # Logo_Icon = QIcon(':/icons/icons/logo.png')

View File

@ -1,13 +1,12 @@
from PyQt5.QtCore import pyqtSignal, QUrl, QThread from PyQt5.QtCore import pyqtSignal, QUrl, QThread
from PyQt5.QtGui import QDesktopServices from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QWidget, QMenu, QAction, QToolButton, QMessageBox, QDialog from PyQt5.QtWidgets import QWidget, QMenu, QAction, QToolButton, QMessageBox
from app.DataBase.output_pc import Output
from app.ui.Icon import Icon from app.ui.Icon import Icon
from .contactInfoUi import Ui_Form from .contactInfoUi import Ui_Form
from .userinfo import userinfo from .userinfo import userinfo
from ...person import Contact, Me from ...person import Contact, Me
from .export_dialog import ExportDialog from app.ui.contact.export.export_dialog import ExportDialog
class ContactInfo(QWidget, Ui_Form): class ContactInfo(QWidget, Ui_Form):

View File

View File

@ -0,0 +1,91 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'exportUi.ui'
#
# Created by: PyQt5 UI code generator 5.15.10
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(553, 394)
self.verticalLayout_3 = QtWidgets.QVBoxLayout(Dialog)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label_3 = QtWidgets.QLabel(Dialog)
self.label_3.setObjectName("label_3")
self.horizontalLayout.addWidget(self.label_3)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.btn_select_all = QtWidgets.QPushButton(Dialog)
self.btn_select_all.setObjectName("btn_select_all")
self.horizontalLayout.addWidget(self.btn_select_all)
self.comboBox_time = QtWidgets.QComboBox(Dialog)
self.comboBox_time.setObjectName("comboBox_time")
self.comboBox_time.addItem("")
self.comboBox_time.addItem("")
self.comboBox_time.addItem("")
self.horizontalLayout.addWidget(self.comboBox_time)
self.comboBox_type = QtWidgets.QComboBox(Dialog)
self.comboBox_type.setObjectName("comboBox_type")
self.comboBox_type.addItem("")
self.comboBox_type.addItem("")
self.horizontalLayout.addWidget(self.comboBox_type)
self.verticalLayout_3.addLayout(self.horizontalLayout)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.label_2 = QtWidgets.QLabel(Dialog)
self.label_2.setObjectName("label_2")
self.verticalLayout_2.addWidget(self.label_2)
self.horizontalLayout_2.addLayout(self.verticalLayout_2)
self.horizontalLayout_2.setStretch(0, 1)
self.verticalLayout_3.addLayout(self.horizontalLayout_2)
self.progressBar = QtWidgets.QProgressBar(Dialog)
self.progressBar.setProperty("value", 24)
self.progressBar.setObjectName("progressBar")
self.verticalLayout_3.addWidget(self.progressBar)
self.label_process = QtWidgets.QLabel(Dialog)
self.label_process.setText("")
self.label_process.setObjectName("label_process")
self.verticalLayout_3.addWidget(self.label_process)
self.label_time = QtWidgets.QLabel(Dialog)
self.label_time.setText("")
self.label_time.setObjectName("label_time")
self.verticalLayout_3.addWidget(self.label_time)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem1)
self.btn_start = QtWidgets.QPushButton(Dialog)
self.btn_start.setObjectName("btn_start")
self.horizontalLayout_3.addWidget(self.btn_start)
self.btn_cancel = QtWidgets.QPushButton(Dialog)
self.btn_cancel.setObjectName("btn_cancel")
self.horizontalLayout_3.addWidget(self.btn_cancel)
self.verticalLayout_3.addLayout(self.horizontalLayout_3)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label_3.setText(_translate("Dialog", "导出过程中请不要退出"))
self.btn_select_all.setText(_translate("Dialog", "全选"))
self.comboBox_time.setItemText(0, _translate("Dialog", "全部时间"))
self.comboBox_time.setItemText(1, _translate("Dialog", "最近三个月"))
self.comboBox_time.setItemText(2, _translate("Dialog", "自定义时间"))
self.comboBox_type.setItemText(0, _translate("Dialog", "全部聊天记录"))
self.comboBox_type.setItemText(1, _translate("Dialog", "不含图片/视频/文件"))
self.label_2.setText(_translate("Dialog", "消息类型"))
self.btn_start.setText(_translate("Dialog", "开始"))
self.btn_cancel.setText(_translate("Dialog", "取消"))

View File

@ -1,9 +1,13 @@
import os
import time import time
from datetime import datetime, timedelta
from PyQt5.QtCore import QTimer from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLayout, QCheckBox, QHBoxLayout, \ from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLayout, QCheckBox, QHBoxLayout, \
QProgressBar, QLabel, QMessageBox, QComboBox QProgressBar, QLabel, QMessageBox, QComboBox
from app.DataBase import msg_db
from app.ui.menu.export_time_range import TimeRangeDialog
from .exportUi import Ui_Dialog
from app.DataBase.output_pc import Output from app.DataBase.output_pc import Output
types = { types = {
@ -27,10 +31,13 @@ QPushButton:hover {
""" """
class ExportDialog(QDialog): class ExportDialog(QDialog, Ui_Dialog):
def __init__(self, contact=None, title="选择导出的类型", file_type="csv", parent=None): def __init__(self, contact=None, title="选择导出的类型", file_type="csv", parent=None):
super(ExportDialog, self).__init__(parent) super(ExportDialog, self).__init__(parent)
self.select_all_flag = False
self.setupUi(self)
self.setStyleSheet(Stylesheet) self.setStyleSheet(Stylesheet)
self.contact = contact self.contact = contact
if file_type == 'html': if file_type == 'html':
self.export_type = Output.HTML self.export_type = Output.HTML
@ -52,49 +59,36 @@ class ExportDialog(QDialog):
else: else:
self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True} # 定义导出的数据类型,默认全部选择 self.export_choices = {"文本": True, "图片": True, "视频": True, "表情包": True} # 定义导出的数据类型,默认全部选择
self.setWindowTitle(title) self.setWindowTitle(title)
layout = QVBoxLayout(self)
self.resize(400, 300) self.resize(400, 300)
self.worker = None # 导出线程 self.worker = None # 导出线程
self.progress_bar = QProgressBar(self)
self.progress_label = QLabel(self)
self.time_label = QLabel(self)
for export_type, default_state in self.export_choices.items(): for export_type, default_state in self.export_choices.items():
checkbox = QCheckBox(export_type) checkbox = QCheckBox(export_type)
checkbox.setChecked(default_state) checkbox.setChecked(default_state)
layout.addWidget(checkbox) self.verticalLayout_2.addWidget(checkbox)
layout.addWidget(self.progress_bar)
layout.addWidget(self.progress_label)
layout.addWidget(self.time_label)
self.notice_label = QLabel(self)
self.notice_label.setText(
"注意:导出HTML时选择图片、视频、语音、文件、音乐与音频、表情包特别是表情包\n会导致大大影响导出速度,请合理选择导出的类型")
layout.addWidget(self.notice_label)
hlayout = QHBoxLayout(self)
self.export_button = QPushButton("导出")
self.export_button.clicked.connect(self.export_data)
hlayout.addWidget(self.export_button)
self.cancel_button = QPushButton("取消") self.btn_select_all.clicked.connect(self.select_all)
self.cancel_button.clicked.connect(self.reject) # 使用reject关闭对话框 self.btn_start.clicked.connect(self.export_data)
hlayout.addWidget(self.cancel_button) self.btn_cancel.clicked.connect(self.reject) # 使用reject关闭对话框
layout.addLayout(hlayout) self.comboBox_time.activated.connect(self.set_export_date)
self.setLayout(layout)
self.timer = QTimer(self) self.timer = QTimer(self)
self.time = 0 self.time = 0
self.total_msg_num = 99999 # 总的消息个数 self.total_msg_num = 99999 # 总的消息个数
self.num = 0 # 当前完成的消息个数 self.num = 0 # 当前完成的消息个数
self.timer.timeout.connect(self.update_elapsed_time) self.timer.timeout.connect(self.update_elapsed_time)
self.time_range = None
def export_data(self): def export_data(self):
self.export_button.setEnabled(False) self.btn_start.setEnabled(False)
self.cancel_button.setEnabled(False) self.btn_cancel.setEnabled(False)
# 在这里获取用户选择的导出数据类型 # 在这里获取用户选择的导出数据类型
selected_types = {types[export_type]: checkbox.isChecked() for export_type, checkbox in selected_types = {types[export_type]: checkbox.isChecked() for export_type, checkbox in
zip(self.export_choices.keys(), self.findChildren(QCheckBox))} zip(self.export_choices.keys(), self.findChildren(QCheckBox))}
# 在这里根据用户选择的数据类型执行导出操作 # 在这里根据用户选择的数据类型执行导出操作
print("选择的数据类型:", selected_types) print("选择的数据类型:", selected_types)
self.worker = Output(self.contact, type_=self.export_type, message_types=selected_types) self.worker = Output(self.contact, type_=self.export_type, message_types=selected_types,
time_range=self.time_range)
self.worker.progressSignal.connect(self.update_progress) self.worker.progressSignal.connect(self.update_progress)
self.worker.okSignal.connect(self.export_finished) self.worker.okSignal.connect(self.export_finished)
self.worker.rangeSignal.connect(self.set_total_msg_num) self.worker.rangeSignal.connect(self.set_total_msg_num)
@ -104,34 +98,92 @@ class ExportDialog(QDialog):
self.start_time = time.time() self.start_time = time.time()
# self.accept() # 使用accept关闭对话框 # self.accept() # 使用accept关闭对话框
def set_export_date(self):
date_range = self.comboBox_time.currentText()
if date_range == '全部时间':
pass
elif date_range == '最近三个月':
# 获取今天的日期和时间
today = datetime.now()
# 获取今天的日期
today_date = today.date()
# 获取今天的24:00:00的时间戳
today_midnight = datetime.combine(today_date, datetime.min.time()) + timedelta(days=1)
today_midnight_timestamp = int(today_midnight.timestamp())
# 获取三个月前的日期
three_months_ago = today - timedelta(days=90)
# 获取三个月前的00:00:00的时间戳
three_months_ago_date = three_months_ago.date()
three_months_ago_midnight = datetime.combine(three_months_ago_date, datetime.min.time())
three_months_ago_midnight_timestamp = int(three_months_ago_midnight.timestamp())
self.time_range = (three_months_ago_midnight_timestamp, today_midnight_timestamp)
elif date_range == '自定义时间':
date_range = None
chat_calendar = msg_db.get_messages_calendar(self.contact.wxid)
if chat_calendar:
start_time = datetime.strptime(chat_calendar[0], "%Y-%m-%d")
end_time = datetime.strptime(chat_calendar[-1], "%Y-%m-%d")
date_range = (start_time.date(),end_time.date())
self.time_range_view = TimeRangeDialog(date_range=date_range,parent=self)
self.time_range_view.date_range_signal.connect(self.set_time_range)
self.time_range_view.show()
self.comboBox_time.setCurrentIndex(0)
# QMessageBox.warning(self,
# "别急别急",
# "马上就实现该功能"
# )
def set_time_range(self, time_range):
self.time_range = time_range
self.comboBox_time.setCurrentIndex(2)
def set_total_msg_num(self, num): def set_total_msg_num(self, num):
self.total_msg_num = num self.total_msg_num = num
# b''+num +(1,1) # b''+num +(1,1)
def export_finished(self): def export_finished(self):
self.export_button.setEnabled(True) self.btn_start.setEnabled(True)
self.cancel_button.setEnabled(True) self.btn_cancel.setEnabled(True)
self.time = 0 self.time = 0
end_time = time.time() end_time = time.time()
print(f'总耗时:{end_time - self.start_time}s') print(f'总耗时:{end_time - self.start_time}s')
reply = QMessageBox(self) reply = QMessageBox(self)
reply.setIcon(QMessageBox.Information) reply.setIcon(QMessageBox.Information)
reply.setWindowTitle('OK') reply.setWindowTitle('OK')
reply.setText(f"导出聊天记录成功\n在./data/目录下(跟exe文件在一起)") reply.setText(f"导出聊天记录成功\n在./data/目录下(跟exe文件在一起)\n{os.getcwd()}\\data\\")
reply.addButton("确认", QMessageBox.AcceptRole) reply.addButton("确认", QMessageBox.AcceptRole)
reply.addButton("取消", QMessageBox.RejectRole) reply.addButton("取消", QMessageBox.RejectRole)
api = reply.exec_() api = reply.exec_()
self.accept() self.accept()
def select_all(self):
self.select_all_flag = not self.select_all_flag
print('全选', self.select_all_flag)
if self.select_all_flag:
for checkbox in self.findChildren(QCheckBox):
checkbox.setChecked(True)
self.btn_select_all.setText('全不选')
else:
for checkbox in self.findChildren(QCheckBox):
checkbox.setChecked(False)
self.btn_select_all.setText('全选')
def update_elapsed_time(self): def update_elapsed_time(self):
self.time += 1 self.time += 1
self.time_label.setText(f"耗时: {self.time}s") self.label_time.setText(f"耗时: {self.time}s")
def update_progress(self, progress_percentage): def update_progress(self, progress_percentage):
self.num += 1 self.num += 1
progress_percentage = int((self.num) / self.total_msg_num * 100) progress_percentage = int((self.num) / self.total_msg_num * 100)
self.progress_bar.setValue(progress_percentage) self.progressBar.setValue(progress_percentage)
self.progress_label.setText(f"导出进度: {progress_percentage}%") self.label_process.setText(f"导出进度: {progress_percentage}%")
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -4,12 +4,19 @@ from PyQt5.QtCore import QTimer, QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout, QLabel from PyQt5.QtWidgets import QApplication, QDialog, QCheckBox, QMessageBox, QCalendarWidget, QWidget, QVBoxLayout, QLabel
from app.components.calendar_dialog import CalendarDialog from app.components.calendar_dialog import CalendarDialog
try:
from .time_range import Ui_Dialog from .time_range import Ui_Dialog
except:
from time_range import Ui_Dialog
Stylesheet = ''' Stylesheet = '''
QToolButton{ QToolButton{
color:#000000; color:#000000;
} }
QCalendarWidget QAbstractItemView:disabled {
}
QCalendarWidget QAbstractItemView:enabled{
}
''' '''
@ -32,6 +39,8 @@ class TimeRangeDialog(QDialog, Ui_Dialog):
self.calendar = CalendarDialog(date_range=date_range, parent=self) self.calendar = CalendarDialog(date_range=date_range, parent=self)
self.calendar.selected_date_signal.connect(self.set_date) self.calendar.selected_date_signal.connect(self.set_date)
self.btn_ok.clicked.connect(self.ok) self.btn_ok.clicked.connect(self.ok)
self.btn_ok.setEnabled(False)
self.btn_ok_num = 0
self.btn_cancel.clicked.connect(lambda x: self.close()) self.btn_cancel.clicked.connect(lambda x: self.close())
self.start_time_flag = True self.start_time_flag = True
self.start_timestamp = 0 self.start_timestamp = 0
@ -43,11 +52,15 @@ class TimeRangeDialog(QDialog, Ui_Dialog):
date_object = datetime.fromtimestamp(timestamp) date_object = datetime.fromtimestamp(timestamp)
str_start = date_object.strftime("%Y-%m-%d") str_start = date_object.strftime("%Y-%m-%d")
self.toolButton_start_time.setText(str_start) self.toolButton_start_time.setText(str_start)
self.btn_ok_num += 1
else: else:
date_object = datetime.fromtimestamp(timestamp) date_object = datetime.fromtimestamp(timestamp)
str_start = date_object.strftime("%Y-%m-%d") str_start = date_object.strftime("%Y-%m-%d")
self.end_timestamp = timestamp + 86399 self.end_timestamp = timestamp + 86399
self.toolButton_end_time.setText(str_start) self.toolButton_end_time.setText(str_start)
self.btn_ok_num += 1
if self.btn_ok_num == 2:
self.btn_ok.setEnabled(True)
def ok(self): def ok(self):
date_range = (self.start_timestamp, self.end_timestamp) date_range = (self.start_timestamp, self.end_timestamp)
@ -56,10 +69,12 @@ class TimeRangeDialog(QDialog, Ui_Dialog):
def select_date_start(self): def select_date_start(self):
self.start_time_flag = True self.start_time_flag = True
self.calendar.set_start_date()
self.calendar.show() self.calendar.show()
def select_date_end(self): def select_date_end(self):
self.start_time_flag = False self.start_time_flag = False
self.calendar.set_end_date()
self.calendar.show() self.calendar.show()
@ -72,6 +87,6 @@ if __name__ == '__main__':
start_date = datetime(2023, 12, 11) start_date = datetime(2023, 12, 11)
end_date = datetime(2024, 1, 9) end_date = datetime(2024, 1, 9)
date_range = (start_date.date(), end_date.date()) date_range = (start_date.date(), end_date.date())
ex = CalendarDialog(date_range=date_range) ex = TimeRangeDialog(date_range=date_range)
ex.show() ex.show()
sys.exit(app.exec_()) sys.exit(app.exec_())

View File

@ -46,6 +46,8 @@ class Ui_Dialog(object):
self.toolButton_end_time.setObjectName("toolButton_end_time") self.toolButton_end_time.setObjectName("toolButton_end_time")
self.horizontalLayout.addWidget(self.toolButton_end_time) self.horizontalLayout.addWidget(self.toolButton_end_time)
self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout.addLayout(self.horizontalLayout)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem)
self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.btn_ok = QtWidgets.QPushButton(Dialog) self.btn_ok = QtWidgets.QPushButton(Dialog)

BIN
doc/images/contact_info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB