diff --git a/app/DataBase/exporter_docx.py b/app/DataBase/exporter_docx.py index bd81d1f..48ebfdb 100644 --- a/app/DataBase/exporter_docx.py +++ b/app/DataBase/exporter_docx.py @@ -25,6 +25,7 @@ encoded_chars = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f\x10\x11\x # 创建一个字典,将要删除的字符映射为 None char_mapping = {char: None for char in encoded_chars} + def filter_control_characters(input_string): """ 过滤掉不可打印字符 @@ -39,6 +40,84 @@ def filter_control_characters(input_string): class DocxExporter(ExporterBase): + def merge_docx(self, n): + self.process_num += 1 + conRemark = self.contact.remark + origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}" + filename = f"{origin_docx_path}/{conRemark}_{n}.docx" + # print(all_file_path) + doc = docx.Document(filename) + if self.merged_doc_index == [-1, -1]: + self.document.append(doc) + self.merged_doc_index = [n, n] + else: + if n == self.merged_doc_index[0] - 1: + self.document.insert(0, doc) + self.merged_doc_index[0] -= 1 + elif n == self.merged_doc_index[1] + 1: + self.document.append(doc) + self.merged_doc_index[1] += 1 + else: + self.docs.append([doc, n]) + self.docs_set.add(n) + new_docx = [] + new_set = set() + # print(self.docs) + while new_set!=self.docs_set: + self.docs.sort(key=lambda x: x[1]) + for doc_, index in self.docs: + if index == self.merged_doc_index[0] - 1: + self.document.insert(0, doc_) + self.merged_doc_index[0] -= 1 + elif index == self.merged_doc_index[1] + 1: + self.document.append(doc_) + self.merged_doc_index[1] += 1 + else: + new_docx.append([doc_, index]) + new_set.add(index) + self.docs = new_docx + self.docs_set = new_set + os.remove(filename) + if self.process_num == self.child_thread_num: + # self.document.append(self.document) + file = os.path.join(origin_docx_path, f'{conRemark}.docx') + try: + self.document.save(file) + except PermissionError: + file = file[:-5] + f'{time.time()}' + '.docx' + self.document.save(file) + self.okSignal.emit(1) + + def export(self): + self.child_threads = [] + messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range) + # 计算每个子列表的长度 + num = 1 + # num = len(messages) // 500 +1 + sublist_length = len(messages) // num + + # 使用列表切片将列表分成n个子列表 + divided_list = [messages[i:i + sublist_length] for i in range(0, len(messages), sublist_length)] + self.child_thread_num = len(divided_list) + self.process_num = 0 + doc = docx.Document() + doc.styles["Normal"].font.name = "Cambria" + doc.styles["Normal"]._element.rPr.rFonts.set(qn("w:eastAsia"), "宋体") + self.document = Composer(doc) + self.merged_doc_index = [-1, -1] + self.docs = [] + self.docs_set = set() + # self.document.append(self.document) + for i in range(self.child_thread_num): + child_thread = DocxExporterChildThread(self.contact, type_=self.DOCX, message_types=self.message_types, + time_range=self.time_range, messages=divided_list[i], index=i) + self.child_threads.append(child_thread) + child_thread.okSignal.connect(self.merge_docx) + child_thread.progressSignal.connect(self.progressSignal) + child_thread.start() + + +class DocxExporterChildThread(ExporterBase): def text(self, doc, message): type_ = message[2] str_content = message[7] @@ -313,15 +392,15 @@ class DocxExporter(ExporterBase): def export(self): print(f"【开始导出 DOCX {self.contact.remark}】") origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}" - messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range) + messages = self.messages Me().save_avatar(os.path.join(f"{origin_docx_path}/avatar/{Me().wxid}.png")) if self.contact.is_chatroom: for message in messages: if message[4]: # is_send continue try: - chatroom_avatar_path = f"{origin_docx_path}/avatar/{message[13].wxid}.png" - message[13].save_avatar(chatroom_avatar_path) + chatroom_avatar_path = f"{origin_docx_path}/avatar/{message[12].wxid}.png" + message[12].save_avatar(chatroom_avatar_path) except: print(message) pass @@ -329,6 +408,8 @@ class DocxExporter(ExporterBase): self.contact.save_avatar(os.path.join(f"{origin_docx_path}/avatar/{self.contact.wxid}.png")) self.rangeSignal.emit(len(messages)) + index = 0 + def newdoc(): nonlocal n, doc doc = docx.Document() @@ -347,8 +428,8 @@ class DocxExporter(ExporterBase): for index, message in enumerate(messages): if index % 200 == 0 and index: # doc = document.add_paragraph() - filename = os.path.join(origin_docx_path, f"{self.contact.remark}{n}.docx") - doc.save(filename) + # filename = os.path.join(origin_docx_path, f"{self.contact.remark}{n}.docx") + # doc.save(filename) newdoc() type_ = message[2] @@ -391,6 +472,7 @@ class DocxExporter(ExporterBase): for index, dx in enumerate(docs[::-1]): print(f"【合并 DOCX {self.contact.remark}】{index + 1}/{len(docs)}") doc.insert(0, dx) + filename = os.path.join(origin_docx_path, f"{self.contact.remark}_{self.index}.docx") try: # document.save(filename) doc.save(filename) @@ -399,4 +481,4 @@ class DocxExporter(ExporterBase): # document.save(filename) doc.save(filename) print(f"【完成导出 DOCX {self.contact.remark}】") - self.okSignal.emit(1) + self.okSignal.emit(self.index) diff --git a/app/DataBase/exporter_html.py b/app/DataBase/exporter_html.py index bd8cb98..2d799f7 100644 --- a/app/DataBase/exporter_html.py +++ b/app/DataBase/exporter_html.py @@ -11,26 +11,19 @@ from app.DataBase.output import ExporterBase, escape_js_and_html from app.log import logger from app.person import Me from app.util import path -from app.util.compress_content import ( - parser_reply, - share_card, - music_share, - file, - transfer_decompress, - call_decompress, -) +from app.util.compress_content import parser_reply, share_card, music_share, file, transfer_decompress, call_decompress from app.util.emoji import get_emoji_url from app.util.image import get_image_path, get_image from app.util.music import get_music_path icon_files = { - "./icon/word.png": ["doc", "docx"], - "./icon/excel.png": ["xls", "xlsx"], - "./icon/csv.png": ["csv"], - "./icon/txt.png": ["txt"], - "./icon/zip.png": ["zip", "7z", "rar"], - "./icon/ppt.png": ["ppt", "pptx"], - "./icon/pdf.png": ["pdf"], + './icon/word.png': ['doc', 'docx'], + './icon/excel.png': ['xls', 'xlsx'], + './icon/csv.png': ['csv'], + './icon/txt.png': ['txt'], + './icon/zip.png': ['zip', '7z', 'rar'], + './icon/ppt.png': ['ppt', 'pptx'], + './icon/pdf.png': ['pdf'], } @@ -47,7 +40,7 @@ class HtmlExporter(ExporterBase): avatar = self.get_avatar_path(is_send, message) str_content = escape_js_and_html(str_content) doc.write( - f"""{{ type:{1}, text: '{str_content}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:{1}, text: '{str_content}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) def image(self, doc, message): @@ -64,17 +57,13 @@ class HtmlExporter(ExporterBase): str_content = escape_js_and_html(str_content) image_path = hard_link_db.get_image(str_content, BytesExtra, thumb=False) if not os.path.exists(os.path.join(Me().wx_dir, image_path)): - image_thumb_path = hard_link_db.get_image( - str_content, BytesExtra, thumb=True - ) + image_thumb_path = hard_link_db.get_image(str_content, BytesExtra, thumb=True) if not os.path.exists(os.path.join(Me().wx_dir, image_thumb_path)): return image_path = image_thumb_path - image_path = get_image_path( - image_path, base_path=f"/data/聊天记录/{self.contact.remark}/image" - ) + image_path = get_image_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image') doc.write( - f"""{{ type:{type_}, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:{type_}, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) def audio(self, doc, message): @@ -88,9 +77,7 @@ class HtmlExporter(ExporterBase): avatar = self.get_avatar_path(is_send, message) display_name = self.get_display_name(is_send, message) try: - audio_path = media_msg_db.get_audio_path( - msgSvrId, output_path=origin_docx_path + "/voice" - ) + audio_path = media_msg_db.get_audio_path(msgSvrId, output_path=origin_docx_path + "/voice") audio_path = "./voice/" + os.path.basename(audio_path) except: logger.error(traceback.format_exc()) @@ -99,7 +86,7 @@ class HtmlExporter(ExporterBase): if voice_to_text and voice_to_text != "": voice_to_text = escape_js_and_html(voice_to_text) doc.write( - f"""{{ type:34, text:'{audio_path}',is_send:{is_send},avatar_path:'{avatar}',voice_to_text:'{voice_to_text}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:34, text:'{audio_path}',is_send:{is_send},avatar_path:'{avatar}',voice_to_text:'{voice_to_text}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) def emoji(self, doc, message): @@ -112,7 +99,7 @@ class HtmlExporter(ExporterBase): display_name = self.get_display_name(is_send, message) emoji_path = get_emoji_url(str_content, thumb=True) doc.write( - f"""{{ type:{3}, text: '{emoji_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:{3}, text: '{emoji_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) def file(self, doc, message): @@ -125,27 +112,22 @@ class HtmlExporter(ExporterBase): is_chatroom = 1 if self.contact.is_chatroom else 0 avatar = self.get_avatar_path(is_send, message) display_name = self.get_display_name(is_send, message) - file_info = file( - bytesExtra, compress_content, output_path=origin_docx_path + "/file" - ) - if file_info.get("is_error") == False: + file_info = file(bytesExtra, compress_content, output_path=origin_docx_path + '/file') + if file_info.get('is_error') == False: icon_path = None for icon, extensions in icon_files.items(): - if file_info.get("file_ext") in extensions: + if file_info.get('file_ext') in extensions: icon_path = icon break # 如果没有与文件后缀匹配的图标,则使用默认图标 if icon_path is None: - default_icon = "./icon/file.png" + default_icon = './icon/file.png' icon_path = default_icon - file_path = file_info.get("file_path") + file_path = file_info.get('file_path') if file_path != "": - file_path = "./file/" + file_info.get("file_name") + file_path = './file/' + file_info.get('file_name') doc.write( - f"""{{ type:49, text: '{file_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp} - ,is_chatroom:{is_chatroom},displayname:'{display_name}',icon_path: '{icon_path}' - ,sub_type:6,file_name: '{file_info.get('file_name')}',file_size: '{file_info.get('file_len')}' - ,app_name: '{file_info.get('app_name')}'}},""" + f'''{{ type:49, text: '{file_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}',icon_path: '{icon_path}',sub_type:6,file_name: '{file_info.get('file_name')}',file_size: '{file_info.get('file_len')}',app_name: '{file_info.get('app_name')}'}},''' ) def refermsg(self, doc, message): @@ -158,20 +140,20 @@ class HtmlExporter(ExporterBase): str_time = message[8] is_send = message[4] content = parser_reply(message[11]) - refer_msg = content.get("refer") + refer_msg = content.get('refer') timestamp = message[5] is_chatroom = 1 if self.contact.is_chatroom else 0 avatar = self.get_avatar_path(is_send, message) display_name = self.get_display_name(is_send, message) - contentText = escape_js_and_html(content.get("title")) + contentText = escape_js_and_html(content.get('title')) if refer_msg: referText = f"{escape_js_and_html(refer_msg.get('displayname'))}:{escape_js_and_html(refer_msg.get('content'))}" doc.write( - f"""{{ type:49, text: '{contentText}',is_send:{is_send},sub_type:{content.get('type')},refer_text: '{referText}',avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:49, text: '{contentText}',is_send:{is_send},sub_type:{content.get('type')},refer_text: '{referText}',avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) else: doc.write( - f"""{{ type:49, text: '{contentText}',is_send:{is_send},sub_type:{content.get('type')},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:49, text: '{contentText}',is_send:{is_send},sub_type:{content.get('type')},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) def system_msg(self, doc, message): @@ -181,15 +163,14 @@ class HtmlExporter(ExporterBase): timestamp = message[5] is_chatroom = 1 if self.contact.is_chatroom else 0 - str_content = str_content.replace("重新编辑]]>', "" - ) - res = findall("()", str_content) + str_content = str_content.replace('重新编辑]]>', "") + res = findall('()', str_content) for xmlstr, b in res: str_content = str_content.replace(xmlstr, "") str_content = escape_js_and_html(str_content) doc.write( - f"""{{ type:0, text: '{str_content}',is_send:{is_send},avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:''}},""" + f'''{{ type:0, text: '{str_content}',is_send:{is_send},avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:''}},''' ) def video(self, doc, message): @@ -206,32 +187,30 @@ class HtmlExporter(ExporterBase): video_path = hard_link_db.get_video(str_content, BytesExtra, thumb=False) image_path = hard_link_db.get_video(str_content, BytesExtra, thumb=True) if video_path is None and image_path is not None: - image_path = path.get_relative_path( - image_path, base_path=f"/data/聊天记录/{self.contact.remark}/image" - ) + image_path = path.get_relative_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image') try: # todo 网络图片问题 print(origin_docx_path + image_path[1:]) os.utime(origin_docx_path + image_path[1:], (timestamp, timestamp)) doc.write( - f"""{{ type:3, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:3, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) except: doc.write( - f"""{{ type:1, text: '视频丢失',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:1, text: '视频丢失',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) return if video_path is None and image_path is None: return - video_path = f"{Me().wx_dir}/{video_path}" + video_path = f'{Me().wx_dir}/{video_path}' if os.path.exists(video_path): - new_path = origin_docx_path + "/video/" + os.path.basename(video_path) + new_path = origin_docx_path + '/video/' + os.path.basename(video_path) if not os.path.exists(new_path): - shutil.copy(video_path, os.path.join(origin_docx_path, "video")) + shutil.copy(video_path, os.path.join(origin_docx_path, 'video')) os.utime(new_path, (timestamp, timestamp)) - video_path = f"./video/{os.path.basename(video_path)}" + video_path = f'./video/{os.path.basename(video_path)}' doc.write( - f"""{{ type:{type_}, text: '{video_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},""" + f'''{{ type:{type_}, text: '{video_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}'}},''' ) def music_share(self, doc, message): @@ -239,24 +218,20 @@ class HtmlExporter(ExporterBase): is_send = message[4] timestamp = message[5] content = music_share(message[11]) - music_path = "" - if content.get("is_error") == False: - if content.get("audio_url") != "": - music_path = get_music_path( - content.get("audio_url"), - content.get("title"), - output_path=origin_docx_path + "/music", - ) - if music_path != "": - music_path = f"./music/{os.path.basename(music_path)}" - music_path = music_path.replace("\\", "/") + music_path = '' + if content.get('is_error') == False: + if content.get('audio_url') != '': + music_path = get_music_path(content.get('audio_url'), content.get('title'), + output_path=origin_docx_path + '/music') + if music_path != '': + music_path = f'./music/{os.path.basename(music_path)}' + music_path = music_path.replace('\\', '/') is_chatroom = 1 if self.contact.is_chatroom else 0 avatar = self.get_avatar_path(is_send, message) display_name = self.get_display_name(is_send, message) + music_path = escape_js_and_html(music_path) doc.write( - f"""{{ type:49, text:'{music_path}',is_send:{is_send},avatar_path:'{avatar}',link_url:'{content.get('link_url')}', - timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}',sub_type:3,title:'{content.get('title')}', - artist:'{content.get('artist')}', website_name:'{content.get('website_name')}'}},""" + f'''{{ type:49, text:'{music_path}',is_send:{is_send},avatar_path:'{avatar}',link_url:'{content.get('link_url')}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}',sub_type:3,title:'{content.get('title')}',artist:'{content.get('artist')}', website_name:'{content.get('website_name')}'}},''' ) def share_card(self, doc, message): @@ -269,36 +244,24 @@ class HtmlExporter(ExporterBase): is_chatroom = 1 if self.contact.is_chatroom else 0 avatar = self.get_avatar_path(is_send, message) display_name = self.get_display_name(is_send, message) - thumbnail = "" - if card_data.get("thumbnail"): - thumbnail = os.path.join(Me().wx_dir, card_data.get("thumbnail")) + thumbnail = '' + if card_data.get('thumbnail'): + thumbnail = os.path.join(Me().wx_dir, card_data.get('thumbnail')) if os.path.exists(thumbnail): - shutil.copy( - thumbnail, - os.path.join( - origin_docx_path, "image", os.path.basename(thumbnail) - ), - ) - thumbnail = "./image/" + os.path.basename(thumbnail) + shutil.copy(thumbnail, os.path.join(origin_docx_path, 'image', os.path.basename(thumbnail))) + thumbnail = './image/' + os.path.basename(thumbnail) else: - thumbnail = "" - app_logo = "" - if card_data.get("app_logo"): - app_logo = os.path.join(Me().wx_dir, card_data.get("app_logo")) + thumbnail = '' + app_logo = '' + if card_data.get('app_logo'): + app_logo = os.path.join(Me().wx_dir, card_data.get('app_logo')) if os.path.exists(app_logo): - shutil.copy( - app_logo, - os.path.join(origin_docx_path, "image", os.path.basename(app_logo)), - ) - app_logo = "./image/" + os.path.basename(app_logo) + shutil.copy(app_logo, os.path.join(origin_docx_path, 'image', os.path.basename(app_logo))) + app_logo = './image/' + os.path.basename(app_logo) else: - app_logo = card_data.get("app_logo") + app_logo = card_data.get('app_logo') doc.write( - f"""{{ type:49,sub_type:5, text:'',is_send:{is_send},avatar_path:'{avatar}',url:'{card_data.get('url')}', - timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}',title:'{card_data.get('title')}', - description:'{card_data.get('description')}',thumbnail:'{thumbnail}',app_logo:'{app_logo}', - app_name:'{card_data.get('app_name')}' - }},\n""" + f'''{{ type:49,sub_type:5, text:'',is_send:{is_send},avatar_path:'{avatar}',url:'{card_data.get('url')}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}',title:'{card_data.get('title')}',description:'{card_data.get('description')}',thumbnail:'{thumbnail}',app_logo:'{app_logo}',app_name:'{card_data.get('app_name')}'}},\n''' ) def transfer(self, doc, message): @@ -315,15 +278,7 @@ class HtmlExporter(ExporterBase): 3: "已收款", 4: "已退还", } - doc.write( - f"""{{ type:49, sub_type:2000, - text:'{text_info_map[transfer_detail["paysubtype"]]}', - is_send:{is_send},avatar_path:'{avatar}', - timestamp:{timestamp},is_chatroom:{is_chatroom}, - displayname:'{display_name}',paysubtype:{transfer_detail["paysubtype"]}, - pay_memo:'{transfer_detail["pay_memo"]}',feedesc:'{transfer_detail["feedesc"]}', - }},\n""" - ) + doc.write(f"""{{ type:49, sub_type:2000,text:'{text_info_map[transfer_detail["paysubtype"]]}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}',paysubtype:{transfer_detail["paysubtype"]},pay_memo:'{transfer_detail["pay_memo"]}',feedesc:'{transfer_detail["feedesc"]}',}},\n""") def call(self, doc, message): is_send = message[4] @@ -337,13 +292,7 @@ class HtmlExporter(ExporterBase): is_chatroom = 1 if self.contact.is_chatroom else 0 avatar = self.get_avatar_path(is_send, message) display_name = self.get_display_name(is_send, message) - doc.write( - f"""{{ type:50, text:'{call_detail["display_content"]}', - call_type:{call_detail["call_type"]},avatar_path:'{avatar}', - timestamp:{timestamp},is_chatroom:{is_chatroom}, - displayname:'{display_name}', - }},\n""" - ) + doc.write(f"""{{ type:50, text:'{call_detail["display_content"]}',call_type:{call_detail["call_type"]},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{display_name}',}},\n""") def export(self): print(f"【开始导出 HTML {self.contact.remark}】") diff --git a/app/DataBase/output.py b/app/DataBase/output.py index 86104c7..359ee4a 100644 --- a/app/DataBase/output.py +++ b/app/DataBase/output.py @@ -90,19 +90,23 @@ class ExporterBase(QThread): CONTACT_CSV = 4 TXT = 5 - def __init__(self, contact, type_=DOCX, message_types={},time_range=None, parent=None): + def __init__(self, contact, type_=DOCX, message_types={}, time_range=None, messages=None,index=0, parent=None): super().__init__(parent) self.message_types = message_types # 导出的消息类型 self.contact: Contact = contact # 联系人 self.output_type = type_ # 导出文件类型 self.total_num = 1 # 总的消息数量 self.num = 0 # 当前处理的消息数量 + self.index = index # self.last_timestamp = 0 self.time_range = time_range + self.messages = messages origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}" makedirs(origin_docx_path) + def run(self): self.export() + def export(self): raise NotImplementedError("export method must be implemented in subclasses") @@ -166,4 +170,4 @@ class ExporterBase(QThread): return def share_card(self, doc, message): - return \ No newline at end of file + return diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py index d7dcfed..6905b45 100644 --- a/app/DataBase/output_pc.py +++ b/app/DataBase/output_pc.py @@ -3,7 +3,7 @@ import os import traceback from typing import List -from PyQt5.QtCore import pyqtSignal, QThread +from PyQt5.QtCore import pyqtSignal, QThread, QObject from PyQt5.QtWidgets import QFileDialog from app.DataBase.exporter_csv import CSVExporter @@ -20,7 +20,7 @@ from ..util.image import get_image os.makedirs('./data/聊天记录', exist_ok=True) -class Output(QThread): +class Output(QObject): """ 发送信息线程 """ @@ -222,7 +222,7 @@ class Output(QThread): Child.okSignal.connect(self.okSignal if not is_batch else self.batch_finish_one) Child.start() - def run(self): + def start(self): if self.output_type == self.DOCX: self.to_docx(self.contact, self.message_types) elif self.output_type == self.CSV_ALL: