mirror of
https://github.com/wtc86939209/WeChatMsg110.git
synced 2026-05-18 10:10:40 +08:00
支持自定义选择导出聊天记录的日期
This commit is contained in:
@@ -13,7 +13,7 @@ class CSVExporter(ExporterBase):
|
||||
columns = ['localId', 'TalkerId', 'Type', 'SubType',
|
||||
'IsSender', 'CreateTime', 'Status', 'StrContent',
|
||||
'StrTime', 'Remark', 'NickName', 'Sender']
|
||||
messages = msg_db.get_messages(self.contact.wxid)
|
||||
messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range)
|
||||
# 写入CSV文件
|
||||
with open(filename, mode='w', newline='', encoding='utf-8-sig') as file:
|
||||
writer = csv.writer(file)
|
||||
|
||||
@@ -288,7 +288,7 @@ class DocxExporter(ExporterBase):
|
||||
doc = docx.Document()
|
||||
doc.styles['Normal'].font.name = u'Cambria'
|
||||
doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
|
||||
messages = msg_db.get_messages(self.contact.wxid)
|
||||
messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range)
|
||||
Me().save_avatar(os.path.join(f"{origin_docx_path}/avatar/{Me().wxid}.png"))
|
||||
if self.contact.is_chatroom:
|
||||
for message in messages:
|
||||
|
||||
@@ -275,7 +275,7 @@ class HtmlExporter(ExporterBase):
|
||||
)
|
||||
|
||||
def export(self):
|
||||
messages = msg_db.get_messages(self.contact.wxid)
|
||||
messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range)
|
||||
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.html"
|
||||
file_path = './app/resources/data/template.html'
|
||||
if not os.path.exists(file_path):
|
||||
|
||||
@@ -113,7 +113,7 @@ class TxtExporter(ExporterBase):
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
os.makedirs(origin_docx_path, exist_ok=True)
|
||||
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.txt"
|
||||
messages = msg_db.get_messages(self.contact.wxid)
|
||||
messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range)
|
||||
total_steps = len(messages)
|
||||
with open(filename, mode='w', newline='', encoding='utf-8') as f:
|
||||
for index, message in enumerate(messages):
|
||||
|
||||
+10
-4
@@ -139,7 +139,7 @@ class Msg:
|
||||
new_messages.append(new_message)
|
||||
return new_messages
|
||||
|
||||
def get_messages(self, username_):
|
||||
def get_messages(self, username_, time_range=None):
|
||||
"""
|
||||
return list
|
||||
a[0]: localId,
|
||||
@@ -157,10 +157,13 @@ class Msg:
|
||||
"""
|
||||
if not self.open_flag:
|
||||
return None
|
||||
sql = '''
|
||||
if time_range:
|
||||
start_time, end_time = time_range
|
||||
sql = f'''
|
||||
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra,CompressContent
|
||||
from MSG
|
||||
where StrTalker=?
|
||||
{'AND CreateTime>' + str(start_time) + ' AND CreateTime<' + str(end_time) if time_range else ''}
|
||||
order by CreateTime
|
||||
'''
|
||||
try:
|
||||
@@ -230,14 +233,17 @@ class Msg:
|
||||
# result.sort(key=lambda x: x[5])
|
||||
return parser_chatroom_message(result) if username_.__contains__('@chatroom') else result
|
||||
|
||||
def get_messages_by_type(self, username_, type_, year_='all'):
|
||||
def get_messages_by_type(self, username_, type_, year_='all',time_range=None):
|
||||
if not self.open_flag:
|
||||
return None
|
||||
if time_range:
|
||||
start_time, end_time = time_range
|
||||
if year_ == 'all':
|
||||
sql = '''
|
||||
sql = f'''
|
||||
select localId,TalkerId,Type,SubType,IsSender,CreateTime,Status,StrContent,strftime('%Y-%m-%d %H:%M:%S',CreateTime,'unixepoch','localtime') as StrTime,MsgSvrID,BytesExtra,CompressContent
|
||||
from MSG
|
||||
where StrTalker=? and Type=?
|
||||
{'AND CreateTime>' + str(start_time) + ' AND CreateTime<' + str(end_time) if time_range else ''}
|
||||
order by CreateTime
|
||||
'''
|
||||
try:
|
||||
|
||||
+3
-19
@@ -3,29 +3,12 @@ import html
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
|
||||
import filecmp
|
||||
from re import findall
|
||||
|
||||
import docx
|
||||
from PyQt5.QtCore import pyqtSignal, QThread
|
||||
from PyQt5.QtWidgets import QFileDialog
|
||||
from docx import shared
|
||||
from docx.enum.table import WD_ALIGN_VERTICAL
|
||||
from docx.enum.text import WD_COLOR_INDEX, WD_PARAGRAPH_ALIGNMENT
|
||||
from docx.oxml.ns import qn
|
||||
|
||||
from .package_msg import PackageMsg
|
||||
from ..DataBase import media_msg_db, hard_link_db, micro_msg_db, msg_db
|
||||
from ..log import logger
|
||||
from ..person import Me, Contact
|
||||
from ..util import path
|
||||
from ..util.compress_content import parser_reply, music_share, share_card
|
||||
from ..util.emoji import get_emoji_url
|
||||
from ..util.file import get_file
|
||||
from ..util.music import get_music_path
|
||||
from ..util.image import get_image_path, get_image, get_image_abs_path
|
||||
|
||||
os.makedirs('./data/聊天记录', exist_ok=True)
|
||||
|
||||
@@ -107,7 +90,7 @@ class ExporterBase(QThread):
|
||||
CONTACT_CSV = 4
|
||||
TXT = 5
|
||||
|
||||
def __init__(self, contact, type_=DOCX, message_types={}, parent=None):
|
||||
def __init__(self, contact, type_=DOCX, message_types={},time_range=None, parent=None):
|
||||
super().__init__(parent)
|
||||
self.message_types = message_types # 导出的消息类型
|
||||
self.contact: Contact = contact # 联系人
|
||||
@@ -115,6 +98,7 @@ class ExporterBase(QThread):
|
||||
self.total_num = 1 # 总的消息数量
|
||||
self.num = 0 # 当前处理的消息数量
|
||||
self.last_timestamp = 0
|
||||
self.time_range = time_range
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
makedirs(origin_docx_path)
|
||||
def run(self):
|
||||
|
||||
+20
-15
@@ -39,11 +39,12 @@ class Output(QThread):
|
||||
TXT = 5
|
||||
Batch = 10086
|
||||
|
||||
def __init__(self, contact, type_=DOCX, message_types={}, sub_type=[], parent=None):
|
||||
def __init__(self, contact, type_=DOCX, message_types={}, sub_type=[], time_range=None,parent=None):
|
||||
super().__init__(parent)
|
||||
self.children = []
|
||||
self.last_timestamp = 0
|
||||
self.sub_type = sub_type
|
||||
self.time_range = time_range
|
||||
self.message_types = message_types
|
||||
self.sec = 2 # 默认1000秒
|
||||
self.contact = contact
|
||||
@@ -161,7 +162,7 @@ class Output(QThread):
|
||||
self.okSignal.emit(1)
|
||||
|
||||
def to_docx(self, contact, message_types, is_batch=False):
|
||||
Child = DocxExporter(contact, type_=self.DOCX, message_types=message_types)
|
||||
Child = DocxExporter(contact, type_=self.DOCX, message_types=message_types,time_range=self.time_range)
|
||||
self.children.append(Child)
|
||||
Child.progressSignal.connect(self.progress)
|
||||
if not is_batch:
|
||||
@@ -170,7 +171,7 @@ class Output(QThread):
|
||||
Child.start()
|
||||
|
||||
def to_txt(self, contact, message_types, is_batch=False):
|
||||
Child = TxtExporter(contact, type_=self.TXT, message_types=message_types)
|
||||
Child = TxtExporter(contact, type_=self.TXT, message_types=message_types,time_range=self.time_range)
|
||||
self.children.append(Child)
|
||||
Child.progressSignal.connect(self.progress)
|
||||
if not is_batch:
|
||||
@@ -179,7 +180,7 @@ class Output(QThread):
|
||||
Child.start()
|
||||
|
||||
def to_html(self, contact, message_types, is_batch=False):
|
||||
Child = HtmlExporter(contact, type_=self.output_type, message_types=message_types)
|
||||
Child = HtmlExporter(contact, type_=self.output_type, message_types=message_types,time_range=self.time_range)
|
||||
self.children.append(Child)
|
||||
Child.progressSignal.connect(self.progress)
|
||||
if not is_batch:
|
||||
@@ -190,7 +191,7 @@ class Output(QThread):
|
||||
if message_types.get(34):
|
||||
# 语音消息单独的线程
|
||||
self.total_num += 1
|
||||
output_media = OutputMedia(contact)
|
||||
output_media = OutputMedia(contact,time_range=self.time_range)
|
||||
self.children.append(output_media)
|
||||
output_media.okSingal.connect(self.count_finish_num)
|
||||
output_media.progressSignal.connect(self.progressSignal)
|
||||
@@ -198,7 +199,7 @@ class Output(QThread):
|
||||
if message_types.get(47):
|
||||
# emoji消息单独的线程
|
||||
self.total_num += 1
|
||||
output_emoji = OutputEmoji(contact)
|
||||
output_emoji = OutputEmoji(contact,time_range=self.time_range)
|
||||
self.children.append(output_emoji)
|
||||
output_emoji.okSingal.connect(self.count_finish_num)
|
||||
output_emoji.progressSignal.connect(self.progressSignal)
|
||||
@@ -206,14 +207,14 @@ class Output(QThread):
|
||||
if message_types.get(3):
|
||||
# 图片消息单独的线程
|
||||
self.total_num += 1
|
||||
output_image = OutputImage(contact)
|
||||
output_image = OutputImage(contact,time_range=self.time_range)
|
||||
self.children.append(output_image)
|
||||
output_image.okSingal.connect(self.count_finish_num)
|
||||
output_image.progressSignal.connect(self.progressSignal)
|
||||
output_image.start()
|
||||
|
||||
def to_csv(self, contact, message_types, is_batch=False):
|
||||
Child = CSVExporter(contact, type_=self.CSV, message_types=message_types)
|
||||
Child = CSVExporter(contact, type_=self.CSV, message_types=message_types,time_range=self.time_range)
|
||||
self.children.append(Child)
|
||||
Child.progressSignal.connect(self.progress)
|
||||
if not is_batch:
|
||||
@@ -263,13 +264,14 @@ class OutputMedia(QThread):
|
||||
okSingal = pyqtSignal(int)
|
||||
progressSignal = pyqtSignal(int)
|
||||
|
||||
def __init__(self, contact):
|
||||
def __init__(self, contact,time_range=None):
|
||||
super().__init__()
|
||||
self.contact = contact
|
||||
self.time_range = time_range
|
||||
|
||||
def run(self):
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 34)
|
||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 34,time_range=self.time_range)
|
||||
for message in messages:
|
||||
is_send = message[4]
|
||||
msgSvrId = message[9]
|
||||
@@ -289,13 +291,14 @@ class OutputEmoji(QThread):
|
||||
okSingal = pyqtSignal(int)
|
||||
progressSignal = pyqtSignal(int)
|
||||
|
||||
def __init__(self, contact):
|
||||
def __init__(self, contact,time_range=None):
|
||||
super().__init__()
|
||||
self.contact = contact
|
||||
self.time_range = time_range
|
||||
|
||||
def run(self):
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 47)
|
||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 47,time_range=self.time_range)
|
||||
for message in messages:
|
||||
str_content = message[7]
|
||||
try:
|
||||
@@ -315,10 +318,11 @@ class OutputImage(QThread):
|
||||
okSingal = pyqtSignal(int)
|
||||
progressSignal = pyqtSignal(int)
|
||||
|
||||
def __init__(self, contact):
|
||||
def __init__(self, contact,time_range):
|
||||
super().__init__()
|
||||
self.contact = contact
|
||||
self.child_thread_num = 2
|
||||
self.time_range =time_range
|
||||
self.child_threads = [0] * (self.child_thread_num + 1)
|
||||
self.num = 0
|
||||
|
||||
@@ -331,7 +335,7 @@ class OutputImage(QThread):
|
||||
|
||||
def run(self):
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 3)
|
||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 3,time_range=self.time_range)
|
||||
for message in messages:
|
||||
str_content = message[7]
|
||||
BytesExtra = message[10]
|
||||
@@ -359,10 +363,11 @@ class OutputImageChild(QThread):
|
||||
okSingal = pyqtSignal(int)
|
||||
progressSignal = pyqtSignal(int)
|
||||
|
||||
def __init__(self, contact, messages):
|
||||
def __init__(self, contact, messages,time_range):
|
||||
super().__init__()
|
||||
self.contact = contact
|
||||
self.messages = messages
|
||||
self.time_range = time_range
|
||||
|
||||
def run(self):
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
|
||||
Reference in New Issue
Block a user