mirror of
https://github.com/LC044/WeChatMsg
synced 2024-11-14 05:21:41 +08:00
Merge branch 'LC044:master' into master
This commit is contained in:
commit
5dfb122b49
@ -8,9 +8,10 @@ import filecmp
|
|||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, QThread
|
from PyQt5.QtCore import pyqtSignal, QThread
|
||||||
|
|
||||||
|
from ..config import output_dir
|
||||||
from ..person import Me, Contact
|
from ..person import Me, Contact
|
||||||
|
|
||||||
os.makedirs('./data/聊天记录', exist_ok=True)
|
os.makedirs(os.path.join(output_dir, '聊天记录'), exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
def set_global_font(doc, font_name):
|
def set_global_font(doc, font_name):
|
||||||
@ -103,8 +104,8 @@ class ExporterBase(QThread):
|
|||||||
self.last_timestamp = 0
|
self.last_timestamp = 0
|
||||||
self.time_range = time_range
|
self.time_range = time_range
|
||||||
self.messages = messages
|
self.messages = messages
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'),output_dir,'聊天记录',self.contact.remark)
|
||||||
makedirs(origin_docx_path)
|
makedirs(origin_path)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.export()
|
self.export()
|
||||||
|
@ -3,14 +3,15 @@ import os
|
|||||||
|
|
||||||
from app.DataBase import msg_db
|
from app.DataBase import msg_db
|
||||||
from app.DataBase.exporter import ExporterBase
|
from app.DataBase.exporter import ExporterBase
|
||||||
|
from app.config import output_dir
|
||||||
|
|
||||||
|
|
||||||
class CSVExporter(ExporterBase):
|
class CSVExporter(ExporterBase):
|
||||||
def to_csv(self):
|
def to_csv(self):
|
||||||
print(f"【开始导出 CSV {self.contact.remark}】")
|
print(f"【开始导出 CSV {self.contact.remark}】")
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'),output_dir,'聊天记录',self.contact.remark)
|
||||||
os.makedirs(origin_docx_path, exist_ok=True)
|
os.makedirs(origin_path, exist_ok=True)
|
||||||
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}_utf8.csv"
|
filename = os.path.join(origin_path,f"{self.contact.remark}_utf8.csv")
|
||||||
columns = ['localId', 'TalkerId', 'Type', 'SubType',
|
columns = ['localId', 'TalkerId', 'Type', 'SubType',
|
||||||
'IsSender', 'CreateTime', 'Status', 'StrContent',
|
'IsSender', 'CreateTime', 'Status', 'StrContent',
|
||||||
'StrTime', 'Remark', 'NickName', 'Sender']
|
'StrTime', 'Remark', 'NickName', 'Sender']
|
||||||
|
@ -13,6 +13,7 @@ from docxcompose.composer import Composer
|
|||||||
|
|
||||||
from app.DataBase import msg_db, hard_link_db
|
from app.DataBase import msg_db, hard_link_db
|
||||||
from app.DataBase.exporter import ExporterBase, escape_js_and_html
|
from app.DataBase.exporter import ExporterBase, escape_js_and_html
|
||||||
|
from app.config import output_dir
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.person import Me
|
from app.person import Me
|
||||||
from app.util.compress_content import parser_reply, share_card, music_share
|
from app.util.compress_content import parser_reply, share_card, music_share
|
||||||
@ -66,28 +67,23 @@ class DocxExporter(ExporterBase):
|
|||||||
p = content_cell.paragraphs[0]
|
p = content_cell.paragraphs[0]
|
||||||
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
|
p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT
|
||||||
doc.add_paragraph()
|
doc.add_paragraph()
|
||||||
|
|
||||||
def image(self, doc, message):
|
def image(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
|
||||||
type_ = message[2]
|
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
str_time = message[8]
|
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
BytesExtra = message[10]
|
BytesExtra = message[10]
|
||||||
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)
|
|
||||||
avatar = self.get_avatar_path(is_send, message, True)
|
avatar = self.get_avatar_path(is_send, message, True)
|
||||||
content = self.create_table(doc, is_send, avatar)
|
content = self.create_table(doc, is_send, avatar)
|
||||||
run = content.paragraphs[0].add_run()
|
run = content.paragraphs[0].add_run()
|
||||||
str_content = escape_js_and_html(str_content)
|
str_content = escape_js_and_html(str_content)
|
||||||
image_path = hard_link_db.get_image(str_content, BytesExtra, thumb=True)
|
image_path = hard_link_db.get_image(str_content, BytesExtra, thumb=True)
|
||||||
|
base_path = os.path.join(output_dir, '聊天记录', self.contact.remark, 'image')
|
||||||
if not os.path.exists(os.path.join(Me().wx_dir, image_path)):
|
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=False)
|
image_thumb_path = hard_link_db.get_image(str_content, BytesExtra, thumb=False)
|
||||||
if not os.path.exists(os.path.join(Me().wx_dir, image_thumb_path)):
|
if not os.path.exists(os.path.join(Me().wx_dir, image_thumb_path)):
|
||||||
return
|
return
|
||||||
image_path = image_thumb_path
|
image_path = image_thumb_path
|
||||||
image_path = get_image_abs_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
|
image_path = get_image_abs_path(image_path, base_path=base_path)
|
||||||
try:
|
try:
|
||||||
run.add_picture(image_path, height=shared.Inches(2))
|
run.add_picture(image_path, height=shared.Inches(2))
|
||||||
doc.add_paragraph()
|
doc.add_paragraph()
|
||||||
@ -95,7 +91,6 @@ class DocxExporter(ExporterBase):
|
|||||||
print("Error!image")
|
print("Error!image")
|
||||||
|
|
||||||
def audio(self, doc, message):
|
def audio(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
str_time = message[8]
|
str_time = message[8]
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
@ -131,7 +126,6 @@ class DocxExporter(ExporterBase):
|
|||||||
doc.add_paragraph()
|
doc.add_paragraph()
|
||||||
|
|
||||||
def file(self, doc, message):
|
def file(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
|
||||||
bytesExtra = message[10]
|
bytesExtra = message[10]
|
||||||
str_time = message[8]
|
str_time = message[8]
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
@ -196,7 +190,6 @@ class DocxExporter(ExporterBase):
|
|||||||
doc.add_paragraph(str_content).alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
doc.add_paragraph(str_content).alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
||||||
|
|
||||||
def video(self, doc, message):
|
def video(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
|
||||||
type_ = message[2]
|
type_ = message[2]
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
str_time = message[8]
|
str_time = message[8]
|
||||||
@ -247,14 +240,14 @@ class DocxExporter(ExporterBase):
|
|||||||
return content_cell
|
return content_cell
|
||||||
|
|
||||||
def music_share(self, doc, message):
|
def music_share(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
timestamp = message[5]
|
timestamp = message[5]
|
||||||
content = music_share(message[11])
|
content = music_share(message[11])
|
||||||
music_path = ''
|
music_path = ''
|
||||||
if content.get('audio_url') != '':
|
if content.get('audio_url') != '':
|
||||||
music_path = get_music_path(content.get('audio_url'), content.get('title'),
|
music_path = get_music_path(content.get('audio_url'), content.get('title'),
|
||||||
output_path=origin_docx_path + '/music')
|
output_path=origin_path + '/music')
|
||||||
if music_path != '':
|
if music_path != '':
|
||||||
music_path = f'./music/{os.path.basename(music_path)}'
|
music_path = f'./music/{os.path.basename(music_path)}'
|
||||||
music_path = music_path.replace('\\', '/')
|
music_path = music_path.replace('\\', '/')
|
||||||
@ -263,7 +256,7 @@ class DocxExporter(ExporterBase):
|
|||||||
display_name = self.get_display_name(is_send, message)
|
display_name = self.get_display_name(is_send, message)
|
||||||
|
|
||||||
def share_card(self, doc, message):
|
def share_card(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
timestamp = message[5]
|
timestamp = message[5]
|
||||||
bytesExtra = message[10]
|
bytesExtra = message[10]
|
||||||
@ -276,7 +269,7 @@ class DocxExporter(ExporterBase):
|
|||||||
if card_data.get('thumbnail'):
|
if card_data.get('thumbnail'):
|
||||||
thumbnail = os.path.join(Me().wx_dir, card_data.get('thumbnail'))
|
thumbnail = os.path.join(Me().wx_dir, card_data.get('thumbnail'))
|
||||||
if os.path.exists(thumbnail):
|
if os.path.exists(thumbnail):
|
||||||
shutil.copy(thumbnail, os.path.join(origin_docx_path, 'image', os.path.basename(thumbnail)))
|
shutil.copy(thumbnail, os.path.join(origin_path, 'image', os.path.basename(thumbnail)))
|
||||||
thumbnail = './image/' + os.path.basename(thumbnail)
|
thumbnail = './image/' + os.path.basename(thumbnail)
|
||||||
else:
|
else:
|
||||||
thumbnail = ''
|
thumbnail = ''
|
||||||
@ -284,22 +277,22 @@ class DocxExporter(ExporterBase):
|
|||||||
if card_data.get('app_logo'):
|
if card_data.get('app_logo'):
|
||||||
app_logo = os.path.join(Me().wx_dir, card_data.get('app_logo'))
|
app_logo = os.path.join(Me().wx_dir, card_data.get('app_logo'))
|
||||||
if os.path.exists(app_logo):
|
if os.path.exists(app_logo):
|
||||||
shutil.copy(app_logo, os.path.join(origin_docx_path, 'image', os.path.basename(app_logo)))
|
shutil.copy(app_logo, os.path.join(origin_path, 'image', os.path.basename(app_logo)))
|
||||||
app_logo = './image/' + os.path.basename(app_logo)
|
app_logo = './image/' + os.path.basename(app_logo)
|
||||||
else:
|
else:
|
||||||
app_logo = ''
|
app_logo = ''
|
||||||
|
|
||||||
def merge_docx(self, conRemark, n):
|
def merge_docx(self, conRemark, n):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录')
|
||||||
all_file_path = []
|
all_file_path = []
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
file_name = f"{conRemark}{i}.docx"
|
file_name = f"{conRemark}{i}.docx"
|
||||||
all_file_path.append(origin_docx_path + '/' + file_name)
|
all_file_path.append(origin_path + '/' + file_name)
|
||||||
filename = f"{conRemark}.docx"
|
filename = f"{conRemark}.docx"
|
||||||
# print(all_file_path)
|
# print(all_file_path)
|
||||||
doc = docx.Document()
|
doc = docx.Document()
|
||||||
doc.save(origin_docx_path + '/' + filename)
|
doc.save(origin_path + '/' + filename)
|
||||||
master = docx.Document(origin_docx_path + '/' + filename)
|
master = docx.Document(origin_path + '/' + filename)
|
||||||
middle_new_docx = Composer(master)
|
middle_new_docx = Composer(master)
|
||||||
num = 0
|
num = 0
|
||||||
for word in all_file_path:
|
for word in all_file_path:
|
||||||
@ -309,40 +302,41 @@ class DocxExporter(ExporterBase):
|
|||||||
middle_new_docx.append(word_document)
|
middle_new_docx.append(word_document)
|
||||||
num = num + 1
|
num = num + 1
|
||||||
os.remove(word)
|
os.remove(word)
|
||||||
middle_new_docx.save(origin_docx_path + '/' + filename)
|
middle_new_docx.save(origin_path + '/' + filename)
|
||||||
|
|
||||||
def export(self):
|
def export(self):
|
||||||
print(f"【开始导出 DOCX {self.contact.remark}】")
|
print(f"【开始导出 DOCX {self.contact.remark}】")
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
# messages = self.messages
|
|
||||||
messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range)
|
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"))
|
Me().save_avatar(os.path.join(origin_path, 'avatar', f'{Me().wxid}.png'))
|
||||||
if self.contact.is_chatroom:
|
if self.contact.is_chatroom:
|
||||||
for message in messages:
|
for message in messages:
|
||||||
if message[4]: # is_send
|
if message[4]: # is_send
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
chatroom_avatar_path = f"{origin_docx_path}/avatar/{message[13].wxid}.png"
|
chatroom_avatar_path =os.path.join(origin_path, 'avatar', f'{message[13].wxid}.png')
|
||||||
message[13].save_avatar(chatroom_avatar_path)
|
message[13].save_avatar(chatroom_avatar_path)
|
||||||
except:
|
except:
|
||||||
print(message)
|
print(message)
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self.contact.save_avatar(os.path.join(f"{origin_docx_path}/avatar/{self.contact.wxid}.png"))
|
self.contact.save_avatar(os.path.join(origin_path, 'avatar', f'{self.contact.wxid}.png'))
|
||||||
self.rangeSignal.emit(len(messages))
|
self.rangeSignal.emit(len(messages))
|
||||||
|
|
||||||
def newdoc():
|
def newdoc():
|
||||||
nonlocal n, doc
|
nonlocal n, doc
|
||||||
doc = docx.Document()
|
doc = docx.Document()
|
||||||
doc.styles["Normal"].font.name = "Cambria"
|
doc.styles["Normal"].font.name = "Cambria"
|
||||||
doc.styles["Normal"]._element.rPr.rFonts.set(qn("w:eastAsia"), "宋体")
|
doc.styles["Normal"]._element.rPr.rFonts.set(qn("w:eastAsia"), "宋体")
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
doc = None
|
doc = None
|
||||||
n = 0
|
n = 0
|
||||||
index = 0
|
index = 0
|
||||||
newdoc()
|
newdoc()
|
||||||
for index, message in enumerate(messages):
|
for index, message in enumerate(messages):
|
||||||
if index % 200 == 0 and index:
|
if index % 200 == 0 and index:
|
||||||
filename = os.path.join(origin_docx_path, f"{self.contact.remark}_{n}.docx")
|
filename = os.path.join(origin_path, f"{self.contact.remark}_{n}.docx")
|
||||||
doc.save(filename)
|
doc.save(filename)
|
||||||
self.okSignal.emit(n)
|
self.okSignal.emit(n)
|
||||||
newdoc()
|
newdoc()
|
||||||
@ -374,7 +368,7 @@ class DocxExporter(ExporterBase):
|
|||||||
print(f"【导出 DOCX {self.contact.remark}】{index}/{len(messages)}")
|
print(f"【导出 DOCX {self.contact.remark}】{index}/{len(messages)}")
|
||||||
if index % 25:
|
if index % 25:
|
||||||
print(f"【导出 DOCX {self.contact.remark}】{index + 1}/{len(messages)}")
|
print(f"【导出 DOCX {self.contact.remark}】{index + 1}/{len(messages)}")
|
||||||
filename = os.path.join(origin_docx_path, f"{self.contact.remark}_{n}.docx")
|
filename = os.path.join(origin_path, f"{self.contact.remark}_{n}.docx")
|
||||||
try:
|
try:
|
||||||
# document.save(filename)
|
# document.save(filename)
|
||||||
doc.save(filename)
|
doc.save(filename)
|
||||||
|
@ -8,6 +8,7 @@ from PyQt5.QtCore import pyqtSignal, QThread
|
|||||||
|
|
||||||
from app.DataBase import msg_db, hard_link_db, media_msg_db
|
from app.DataBase import msg_db, hard_link_db, media_msg_db
|
||||||
from app.DataBase.exporter import ExporterBase, escape_js_and_html
|
from app.DataBase.exporter import ExporterBase, escape_js_and_html
|
||||||
|
from app.config import output_dir
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.person import Me
|
from app.person import Me
|
||||||
from app.util import path
|
from app.util import path
|
||||||
@ -44,7 +45,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def image(self, doc, message):
|
def image(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
base_path = os.path.join(output_dir, '聊天记录', self.contact.remark, 'image')
|
||||||
type_ = message[2]
|
type_ = message[2]
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
str_time = message[8]
|
str_time = message[8]
|
||||||
@ -56,13 +57,13 @@ class HtmlExporter(ExporterBase):
|
|||||||
display_name = self.get_display_name(is_send, message)
|
display_name = self.get_display_name(is_send, message)
|
||||||
str_content = escape_js_and_html(str_content)
|
str_content = escape_js_and_html(str_content)
|
||||||
image_path = hard_link_db.get_image(str_content, BytesExtra, up_dir=Me().wx_dir, thumb=False)
|
image_path = hard_link_db.get_image(str_content, BytesExtra, up_dir=Me().wx_dir, thumb=False)
|
||||||
image_path = get_image_path(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
|
image_path = get_image_path(image_path, base_path=base_path)
|
||||||
doc.write(
|
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):
|
def audio(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
str_time = message[8]
|
str_time = message[8]
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
@ -72,7 +73,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
avatar = self.get_avatar_path(is_send, message)
|
avatar = self.get_avatar_path(is_send, message)
|
||||||
display_name = self.get_display_name(is_send, message)
|
display_name = self.get_display_name(is_send, message)
|
||||||
try:
|
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_path + "/voice")
|
||||||
audio_path = "./voice/" + os.path.basename(audio_path)
|
audio_path = "./voice/" + os.path.basename(audio_path)
|
||||||
except:
|
except:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
@ -98,7 +99,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def file(self, doc, message):
|
def file(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
bytesExtra = message[10]
|
bytesExtra = message[10]
|
||||||
compress_content = message[11]
|
compress_content = message[11]
|
||||||
str_time = message[8]
|
str_time = message[8]
|
||||||
@ -107,7 +108,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
is_chatroom = 1 if self.contact.is_chatroom else 0
|
is_chatroom = 1 if self.contact.is_chatroom else 0
|
||||||
avatar = self.get_avatar_path(is_send, message)
|
avatar = self.get_avatar_path(is_send, message)
|
||||||
display_name = self.get_display_name(is_send, message)
|
display_name = self.get_display_name(is_send, message)
|
||||||
file_info = file(bytesExtra, compress_content, output_path=origin_docx_path + '/file')
|
file_info = file(bytesExtra, compress_content, output_path=origin_path + '/file')
|
||||||
if file_info.get('is_error') == False:
|
if file_info.get('is_error') == False:
|
||||||
icon_path = None
|
icon_path = None
|
||||||
for icon, extensions in icon_files.items():
|
for icon, extensions in icon_files.items():
|
||||||
@ -169,7 +170,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def video(self, doc, message):
|
def video(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
type_ = message[2]
|
type_ = message[2]
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
str_time = message[8]
|
str_time = message[8]
|
||||||
@ -185,8 +186,8 @@ class HtmlExporter(ExporterBase):
|
|||||||
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:
|
try:
|
||||||
# todo 网络图片问题
|
# todo 网络图片问题
|
||||||
print(origin_docx_path + image_path[1:])
|
print(origin_path + image_path[1:])
|
||||||
os.utime(origin_docx_path + image_path[1:], (timestamp, timestamp))
|
os.utime(origin_path + image_path[1:], (timestamp, timestamp))
|
||||||
doc.write(
|
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}'}},'''
|
||||||
)
|
)
|
||||||
@ -200,9 +201,9 @@ class HtmlExporter(ExporterBase):
|
|||||||
video_path = f'{Me().wx_dir}/{video_path}'
|
video_path = f'{Me().wx_dir}/{video_path}'
|
||||||
video_path = video_path.replace('\\', '/')
|
video_path = video_path.replace('\\', '/')
|
||||||
if os.path.exists(video_path):
|
if os.path.exists(video_path):
|
||||||
new_path = origin_docx_path + '/video/' + os.path.basename(video_path)
|
new_path = origin_path + '/video/' + os.path.basename(video_path)
|
||||||
if not os.path.exists(new_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_path, 'video'))
|
||||||
os.utime(new_path, (timestamp, timestamp))
|
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(
|
doc.write(
|
||||||
@ -210,7 +211,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def music_share(self, doc, message):
|
def music_share(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
timestamp = message[5]
|
timestamp = message[5]
|
||||||
content = music_share(message[11])
|
content = music_share(message[11])
|
||||||
@ -218,7 +219,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
if content.get('is_error') == False:
|
if content.get('is_error') == False:
|
||||||
if content.get('audio_url') != '':
|
if content.get('audio_url') != '':
|
||||||
music_path = get_music_path(content.get('audio_url'), content.get('title'),
|
music_path = get_music_path(content.get('audio_url'), content.get('title'),
|
||||||
output_path=origin_docx_path + '/music')
|
output_path=origin_path + '/music')
|
||||||
if music_path != '':
|
if music_path != '':
|
||||||
music_path = f'./music/{os.path.basename(music_path)}'
|
music_path = f'./music/{os.path.basename(music_path)}'
|
||||||
music_path = music_path.replace('\\', '/')
|
music_path = music_path.replace('\\', '/')
|
||||||
@ -231,7 +232,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def share_card(self, doc, message):
|
def share_card(self, doc, message):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
timestamp = message[5]
|
timestamp = message[5]
|
||||||
bytesExtra = message[10]
|
bytesExtra = message[10]
|
||||||
@ -244,7 +245,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
if card_data.get('thumbnail'):
|
if card_data.get('thumbnail'):
|
||||||
thumbnail = os.path.join(Me().wx_dir, card_data.get('thumbnail'))
|
thumbnail = os.path.join(Me().wx_dir, card_data.get('thumbnail'))
|
||||||
if os.path.exists(thumbnail):
|
if os.path.exists(thumbnail):
|
||||||
shutil.copy(thumbnail, os.path.join(origin_docx_path, 'image', os.path.basename(thumbnail)))
|
shutil.copy(thumbnail, os.path.join(origin_path, 'image', os.path.basename(thumbnail)))
|
||||||
thumbnail = './image/' + os.path.basename(thumbnail)
|
thumbnail = './image/' + os.path.basename(thumbnail)
|
||||||
else:
|
else:
|
||||||
thumbnail = ''
|
thumbnail = ''
|
||||||
@ -252,7 +253,7 @@ class HtmlExporter(ExporterBase):
|
|||||||
if card_data.get('app_logo'):
|
if card_data.get('app_logo'):
|
||||||
app_logo = os.path.join(Me().wx_dir, card_data.get('app_logo'))
|
app_logo = os.path.join(Me().wx_dir, card_data.get('app_logo'))
|
||||||
if os.path.exists(app_logo):
|
if os.path.exists(app_logo):
|
||||||
shutil.copy(app_logo, os.path.join(origin_docx_path, 'image', os.path.basename(app_logo)))
|
shutil.copy(app_logo, os.path.join(origin_path, 'image', os.path.basename(app_logo)))
|
||||||
app_logo = './image/' + os.path.basename(app_logo)
|
app_logo = './image/' + os.path.basename(app_logo)
|
||||||
else:
|
else:
|
||||||
app_logo = card_data.get('app_logo')
|
app_logo = card_data.get('app_logo')
|
||||||
@ -296,7 +297,8 @@ class HtmlExporter(ExporterBase):
|
|||||||
def export(self):
|
def export(self):
|
||||||
print(f"【开始导出 HTML {self.contact.remark}】")
|
print(f"【开始导出 HTML {self.contact.remark}】")
|
||||||
messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range)
|
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"
|
filename = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark,
|
||||||
|
f'{self.contact.remark}.html')
|
||||||
file_path = './app/resources/data/template.html'
|
file_path = './app/resources/data/template.html'
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
resource_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
|
resource_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
|
||||||
@ -377,14 +379,14 @@ class OutputMedia(QThread):
|
|||||||
self.contact = contact
|
self.contact = contact
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', 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)
|
||||||
for message in messages:
|
for message in messages:
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
msgSvrId = message[9]
|
msgSvrId = message[9]
|
||||||
try:
|
try:
|
||||||
audio_path = media_msg_db.get_audio(
|
audio_path = media_msg_db.get_audio(
|
||||||
msgSvrId, output_path=origin_docx_path + "/voice"
|
msgSvrId, output_path=origin_path + "/voice"
|
||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
@ -406,13 +408,13 @@ class OutputEmoji(QThread):
|
|||||||
self.contact = contact
|
self.contact = contact
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', 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)
|
||||||
for message in messages:
|
for message in messages:
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
try:
|
try:
|
||||||
pass
|
pass
|
||||||
# emoji_path = get_emoji(str_content, thumb=True, output_path=origin_docx_path + '/emoji')
|
# emoji_path = get_emoji(str_content, thumb=True, output_path=origin_path + '/emoji')
|
||||||
except:
|
except:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
finally:
|
finally:
|
||||||
@ -443,8 +445,9 @@ class OutputImage(QThread):
|
|||||||
print("图片导出完成")
|
print("图片导出完成")
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', 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)
|
||||||
|
base_path = os.path.join(output_dir, '聊天记录', self.contact.remark, 'image')
|
||||||
for message in messages:
|
for message in messages:
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
BytesExtra = message[10]
|
BytesExtra = message[10]
|
||||||
@ -461,10 +464,10 @@ class OutputImage(QThread):
|
|||||||
continue
|
continue
|
||||||
image_path = image_thumb_path
|
image_path = image_thumb_path
|
||||||
image_path = get_image(
|
image_path = get_image(
|
||||||
image_path, base_path=f"/data/聊天记录/{self.contact.remark}/image"
|
image_path, base_path=base_path
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
os.utime(origin_docx_path + image_path[1:], (timestamp, timestamp))
|
os.utime(origin_path + image_path[1:], (timestamp, timestamp))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
@ -472,16 +475,6 @@ class OutputImage(QThread):
|
|||||||
finally:
|
finally:
|
||||||
self.progressSignal.emit(1)
|
self.progressSignal.emit(1)
|
||||||
self.okSingal.emit(47)
|
self.okSingal.emit(47)
|
||||||
# sublist_length = len(messages) // self.child_thread_num
|
|
||||||
# index = 0
|
|
||||||
# for i in range(0, len(messages), sublist_length):
|
|
||||||
# child_messages = messages[i:i + sublist_length]
|
|
||||||
# self.child_threads[index] = OutputImageChild(self.contact, child_messages)
|
|
||||||
# self.child_threads[index].okSingal.connect(self.count1)
|
|
||||||
# self.child_threads[index].progressSignal.connect(self.progressSignal)
|
|
||||||
# self.child_threads[index].start()
|
|
||||||
# print('开启一个新线程')
|
|
||||||
# index += 1
|
|
||||||
|
|
||||||
|
|
||||||
class OutputImageChild(QThread):
|
class OutputImageChild(QThread):
|
||||||
@ -494,7 +487,7 @@ class OutputImageChild(QThread):
|
|||||||
self.messages = messages
|
self.messages = messages
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
for message in self.messages:
|
for message in self.messages:
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
BytesExtra = message[10]
|
BytesExtra = message[10]
|
||||||
@ -514,7 +507,7 @@ class OutputImageChild(QThread):
|
|||||||
image_path, base_path=f"/data/聊天记录/{self.contact.remark}/image"
|
image_path, base_path=f"/data/聊天记录/{self.contact.remark}/image"
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
os.utime(origin_docx_path + image_path[1:], (timestamp, timestamp))
|
os.utime(origin_path + image_path[1:], (timestamp, timestamp))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
|
@ -2,6 +2,7 @@ import os
|
|||||||
|
|
||||||
from app.DataBase import msg_db
|
from app.DataBase import msg_db
|
||||||
from app.DataBase.exporter import ExporterBase
|
from app.DataBase.exporter import ExporterBase
|
||||||
|
from app.config import output_dir
|
||||||
from app.util.compress_content import parser_reply, share_card
|
from app.util.compress_content import parser_reply, share_card
|
||||||
|
|
||||||
|
|
||||||
@ -111,9 +112,9 @@ class TxtExporter(ExporterBase):
|
|||||||
def export(self):
|
def export(self):
|
||||||
# 实现导出为txt的逻辑
|
# 实现导出为txt的逻辑
|
||||||
print(f"【开始导出 TXT {self.contact.remark}】")
|
print(f"【开始导出 TXT {self.contact.remark}】")
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录', self.contact.remark)
|
||||||
os.makedirs(origin_docx_path, exist_ok=True)
|
os.makedirs(origin_path, exist_ok=True)
|
||||||
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.txt"
|
filename = os.path.join(origin_path, self.contact.remark+'.txt')
|
||||||
messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range)
|
messages = msg_db.get_messages(self.contact.wxid, time_range=self.time_range)
|
||||||
total_steps = len(messages)
|
total_steps = len(messages)
|
||||||
with open(filename, mode='w', newline='', encoding='utf-8') as f:
|
with open(filename, mode='w', newline='', encoding='utf-8') as f:
|
||||||
|
@ -15,13 +15,14 @@ from app.DataBase.exporter_docx import DocxExporter
|
|||||||
from app.DataBase.exporter_html import HtmlExporter
|
from app.DataBase.exporter_html import HtmlExporter
|
||||||
from app.DataBase.exporter_txt import TxtExporter
|
from app.DataBase.exporter_txt import TxtExporter
|
||||||
from app.DataBase.hard_link import decodeExtraBuf
|
from app.DataBase.hard_link import decodeExtraBuf
|
||||||
|
from app.config import output_dir
|
||||||
from .package_msg import PackageMsg
|
from .package_msg import PackageMsg
|
||||||
from ..DataBase import media_msg_db, hard_link_db, micro_msg_db, msg_db
|
from ..DataBase import media_msg_db, hard_link_db, micro_msg_db, msg_db
|
||||||
from ..log import logger
|
from ..log import logger
|
||||||
from ..person import Me
|
from ..person import Me
|
||||||
from ..util.image import get_image
|
from ..util.image import get_image
|
||||||
|
|
||||||
os.makedirs('./data/聊天记录', exist_ok=True)
|
os.makedirs(os.path.join(output_dir, '聊天记录'), exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
class Output(QThread):
|
class Output(QThread):
|
||||||
@ -79,8 +80,9 @@ class Output(QThread):
|
|||||||
导出全部聊天记录到CSV
|
导出全部聊天记录到CSV
|
||||||
@return:
|
@return:
|
||||||
"""
|
"""
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/"
|
|
||||||
os.makedirs(origin_docx_path, exist_ok=True)
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录')
|
||||||
|
os.makedirs(origin_path, exist_ok=True)
|
||||||
filename = QFileDialog.getSaveFileName(None, "save file", os.path.join(os.getcwd(), 'messages.csv'),
|
filename = QFileDialog.getSaveFileName(None, "save file", os.path.join(os.getcwd(), 'messages.csv'),
|
||||||
"csv files (*.csv);;all files(*.*)")
|
"csv files (*.csv);;all files(*.*)")
|
||||||
if not filename[0]:
|
if not filename[0]:
|
||||||
@ -167,11 +169,11 @@ class Output(QThread):
|
|||||||
|
|
||||||
def merge_docx(self, n):
|
def merge_docx(self, n):
|
||||||
conRemark = self.contact.remark
|
conRemark = self.contact.remark
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{conRemark}"
|
origin_path = os.path.join(os.path.abspath('.'), output_dir, '聊天记录',conRemark)
|
||||||
filename = f"{origin_docx_path}/{conRemark}_{n}.docx"
|
filename = f"{origin_path}/{conRemark}_{n}.docx"
|
||||||
if n == 10086:
|
if n == 10086:
|
||||||
# self.document.append(self.document)
|
# self.document.append(self.document)
|
||||||
file = os.path.join(origin_docx_path, f'{conRemark}.docx')
|
file = os.path.join(origin_path, f'{conRemark}.docx')
|
||||||
try:
|
try:
|
||||||
self.document.save(file)
|
self.document.save(file)
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
@ -184,7 +186,7 @@ class Output(QThread):
|
|||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
if n % 50 == 0:
|
if n % 50 == 0:
|
||||||
# self.document.append(self.document)
|
# self.document.append(self.document)
|
||||||
file = os.path.join(origin_docx_path, f'{conRemark}-{n//50}.docx')
|
file = os.path.join(origin_path, f'{conRemark}-{n // 50}.docx')
|
||||||
try:
|
try:
|
||||||
self.document.save(file)
|
self.document.save(file)
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
@ -308,13 +310,13 @@ class OutputMedia(QThread):
|
|||||||
self.time_range = time_range
|
self.time_range = time_range
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'),output_dir,'聊天记录',self.contact.remark)
|
||||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 34, time_range=self.time_range)
|
messages = msg_db.get_messages_by_type(self.contact.wxid, 34, time_range=self.time_range)
|
||||||
for message in messages:
|
for message in messages:
|
||||||
is_send = message[4]
|
is_send = message[4]
|
||||||
msgSvrId = message[9]
|
msgSvrId = message[9]
|
||||||
try:
|
try:
|
||||||
audio_path = media_msg_db.get_audio(msgSvrId, output_path=origin_docx_path + "/voice")
|
audio_path = media_msg_db.get_audio(msgSvrId, output_path=origin_path + "/voice")
|
||||||
except:
|
except:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
finally:
|
finally:
|
||||||
@ -335,13 +337,13 @@ class OutputEmoji(QThread):
|
|||||||
self.time_range = time_range
|
self.time_range = time_range
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'),output_dir,'聊天记录',self.contact.remark)
|
||||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 47, time_range=self.time_range)
|
messages = msg_db.get_messages_by_type(self.contact.wxid, 47, time_range=self.time_range)
|
||||||
for message in messages:
|
for message in messages:
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
try:
|
try:
|
||||||
pass
|
pass
|
||||||
# emoji_path = get_emoji(str_content, thumb=True, output_path=origin_docx_path + '/emoji')
|
# emoji_path = get_emoji(str_content, thumb=True, output_path=origin_path + '/emoji')
|
||||||
except:
|
except:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
finally:
|
finally:
|
||||||
@ -372,17 +374,18 @@ class OutputImage(QThread):
|
|||||||
print('图片导出完成')
|
print('图片导出完成')
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'),output_dir,'聊天记录',self.contact.remark)
|
||||||
messages = msg_db.get_messages_by_type(self.contact.wxid, 3, time_range=self.time_range)
|
messages = msg_db.get_messages_by_type(self.contact.wxid, 3, time_range=self.time_range)
|
||||||
|
base_path = os.path.join(output_dir,'聊天记录',self.contact.remark,'image')
|
||||||
for message in messages:
|
for message in messages:
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
BytesExtra = message[10]
|
BytesExtra = message[10]
|
||||||
timestamp = message[5]
|
timestamp = message[5]
|
||||||
try:
|
try:
|
||||||
image_path = hard_link_db.get_image(str_content, BytesExtra, up_dir=Me().wx_dir,thumb=False)
|
image_path = hard_link_db.get_image(str_content, BytesExtra, up_dir=Me().wx_dir, thumb=False)
|
||||||
image_path = get_image(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
|
image_path = get_image(image_path, base_path=base_path)
|
||||||
try:
|
try:
|
||||||
os.utime(origin_docx_path + image_path[1:], (timestamp, timestamp))
|
os.utime(origin_path + image_path[1:], (timestamp, timestamp))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
@ -403,7 +406,7 @@ class OutputImageChild(QThread):
|
|||||||
self.time_range = time_range
|
self.time_range = time_range
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
origin_path = os.path.join(os.path.abspath('.'),output_dir,'聊天记录',self.contact.remark)
|
||||||
for message in self.messages:
|
for message in self.messages:
|
||||||
str_content = message[7]
|
str_content = message[7]
|
||||||
BytesExtra = message[10]
|
BytesExtra = message[10]
|
||||||
@ -417,7 +420,7 @@ class OutputImageChild(QThread):
|
|||||||
image_path = image_thumb_path
|
image_path = image_thumb_path
|
||||||
image_path = get_image(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
|
image_path = get_image(image_path, base_path=f'/data/聊天记录/{self.contact.remark}/image')
|
||||||
try:
|
try:
|
||||||
os.utime(origin_docx_path + image_path[1:], (timestamp, timestamp))
|
os.utime(origin_path + image_path[1:], (timestamp, timestamp))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
|
@ -20,3 +20,9 @@ about = f'''
|
|||||||
License <a href='https://github.com/LC044/WeChatMsg/blob/master/LICENSE' target='_blank'>{license}</a><br>
|
License <a href='https://github.com/LC044/WeChatMsg/blob/master/LICENSE' target='_blank'>{license}</a><br>
|
||||||
Copyright {copyright}
|
Copyright {copyright}
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# 数据存放文件路径
|
||||||
|
|
||||||
|
info_file_path = './app/data/info.json' # 个人信息文件
|
||||||
|
db_dir = 'app/Database/Msg'
|
||||||
|
output_dir = './data/' # 输出文件夹
|
||||||
|
@ -9,6 +9,7 @@ from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog, QVBoxLa
|
|||||||
|
|
||||||
from app.DataBase import msg_db
|
from app.DataBase import msg_db
|
||||||
from app.components import ScrollBar
|
from app.components import ScrollBar
|
||||||
|
from app.config import output_dir
|
||||||
from app.ui.menu.export_time_range import TimeRangeDialog
|
from app.ui.menu.export_time_range import TimeRangeDialog
|
||||||
from .exportUi import Ui_Dialog
|
from .exportUi import Ui_Dialog
|
||||||
from app.DataBase.output import Output
|
from app.DataBase.output import Output
|
||||||
@ -169,7 +170,7 @@ class ExportDialog(QDialog, Ui_Dialog):
|
|||||||
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文件在一起)\n{os.getcwd()}\\data\\")
|
reply.setText(f"导出聊天记录成功\n在{output_dir}目录下(跟exe文件在一起)\n{os.path.normpath(os.path.join(os.getcwd(),output_dir))}")
|
||||||
reply.addButton("确认", QMessageBox.AcceptRole)
|
reply.addButton("确认", QMessageBox.AcceptRole)
|
||||||
reply.addButton("取消", QMessageBox.RejectRole)
|
reply.addButton("取消", QMessageBox.RejectRole)
|
||||||
api = reply.exec_()
|
api = reply.exec_()
|
||||||
|
@ -25,6 +25,7 @@ from app.ui.tool.tool_window import ToolWindow
|
|||||||
from .menu.export import ExportDialog
|
from .menu.export import ExportDialog
|
||||||
from ..DataBase.output import Output
|
from ..DataBase.output import Output
|
||||||
from ..components.QCursorGif import QCursorGif
|
from ..components.QCursorGif import QCursorGif
|
||||||
|
from ..config import info_file_path, db_dir
|
||||||
from ..log import logger
|
from ..log import logger
|
||||||
from ..person import Me
|
from ..person import Me
|
||||||
|
|
||||||
@ -298,8 +299,8 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow, QCursorGif):
|
|||||||
self.action_update.setIcon(Icon.Update_Icon)
|
self.action_update.setIcon(Icon.Update_Icon)
|
||||||
|
|
||||||
def load_data(self, flag=True):
|
def load_data(self, flag=True):
|
||||||
if os.path.exists('./app/data/info.json'):
|
if os.path.exists(info_file_path):
|
||||||
with open('./app/data/info.json', 'r', encoding='utf-8') as f:
|
with open(info_file_path, 'r', encoding='utf-8') as f:
|
||||||
dic = json.loads(f.read())
|
dic = json.loads(f.read())
|
||||||
wxid = dic.get('wxid')
|
wxid = dic.get('wxid')
|
||||||
if wxid:
|
if wxid:
|
||||||
@ -350,7 +351,7 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow, QCursorGif):
|
|||||||
close_db()
|
close_db()
|
||||||
import shutil
|
import shutil
|
||||||
try:
|
try:
|
||||||
shutil.rmtree('./app/Database/Msg')
|
shutil.rmtree(db_dir)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return
|
return
|
||||||
@ -366,7 +367,7 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow, QCursorGif):
|
|||||||
close_db()
|
close_db()
|
||||||
import shutil
|
import shutil
|
||||||
try:
|
try:
|
||||||
shutil.rmtree('./app/Database/Msg')
|
shutil.rmtree(db_dir)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
QMessageBox.critical(self, "数据库错误", "请重启电脑后重试")
|
QMessageBox.critical(self, "数据库错误", "请重启电脑后重试")
|
||||||
|
@ -12,6 +12,7 @@ from app.DataBase import micro_msg_db, misc_db
|
|||||||
from app.DataBase.output import Output
|
from app.DataBase.output import Output
|
||||||
from app.components import ScrollBar
|
from app.components import ScrollBar
|
||||||
from app.components.export_contact_item import ContactQListWidgetItem
|
from app.components.export_contact_item import ContactQListWidgetItem
|
||||||
|
from app.config import output_dir
|
||||||
from app.person import Contact
|
from app.person import Contact
|
||||||
from app.ui.menu.exportUi import Ui_Dialog
|
from app.ui.menu.exportUi import Ui_Dialog
|
||||||
from app.ui.menu.export_time_range import TimeRangeDialog
|
from app.ui.menu.export_time_range import TimeRangeDialog
|
||||||
@ -213,7 +214,7 @@ class ExportDialog(QDialog, Ui_Dialog):
|
|||||||
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文件在一起)\n{os.getcwd()}\\data\\")
|
reply.setText(f"导出聊天记录成功\n在{output_dir}目录下(跟exe文件在一起)\n{os.path.normpath(os.path.join(os.getcwd(),output_dir))}")
|
||||||
reply.addButton("确认", QMessageBox.AcceptRole)
|
reply.addButton("确认", QMessageBox.AcceptRole)
|
||||||
reply.addButton("取消", QMessageBox.RejectRole)
|
reply.addButton("取消", QMessageBox.RejectRole)
|
||||||
api = reply.exec_()
|
api = reply.exec_()
|
||||||
|
@ -11,6 +11,7 @@ from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog
|
|||||||
from app.DataBase import msg_db, misc_db, close_db
|
from app.DataBase import msg_db, misc_db, close_db
|
||||||
from app.DataBase.merge import merge_databases, merge_MediaMSG_databases
|
from app.DataBase.merge import merge_databases, merge_MediaMSG_databases
|
||||||
from app.components.QCursorGif import QCursorGif
|
from app.components.QCursorGif import QCursorGif
|
||||||
|
from app.config import info_file_path, db_dir
|
||||||
from app.decrypt import get_wx_info, decrypt
|
from app.decrypt import get_wx_info, decrypt
|
||||||
from app.log import logger
|
from app.log import logger
|
||||||
from app.util import path
|
from app.util import path
|
||||||
@ -185,7 +186,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
os.makedirs('./app/data', exist_ok=True)
|
os.makedirs('./app/data', exist_ok=True)
|
||||||
with open('./app/data/info.json', "w", encoding="utf-8") as f:
|
with open(info_file_path, "w", encoding="utf-8") as f:
|
||||||
json.dump(dic, f, ensure_ascii=False, indent=4)
|
json.dump(dic, f, ensure_ascii=False, indent=4)
|
||||||
except:
|
except:
|
||||||
with open('./info.json', 'w', encoding='utf-8') as f:
|
with open('./info.json', 'w', encoding='utf-8') as f:
|
||||||
@ -215,7 +216,7 @@ class DecryptThread(QThread):
|
|||||||
msg_db.close()
|
msg_db.close()
|
||||||
# micro_msg_db.close()
|
# micro_msg_db.close()
|
||||||
# hard_link_db.close()
|
# hard_link_db.close()
|
||||||
output_dir = 'app/DataBase/Msg'
|
output_dir = db_dir
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
tasks = []
|
tasks = []
|
||||||
if os.path.exists(self.db_path):
|
if os.path.exists(self.db_path):
|
||||||
@ -235,14 +236,14 @@ class DecryptThread(QThread):
|
|||||||
self.signal.emit(str(i))
|
self.signal.emit(str(i))
|
||||||
# print(self.db_path)
|
# print(self.db_path)
|
||||||
# 目标数据库文件
|
# 目标数据库文件
|
||||||
target_database = "app/DataBase/Msg/MSG.db"
|
target_database = os.path.join(db_dir, 'MSG.db')
|
||||||
# 源数据库文件列表
|
# 源数据库文件列表
|
||||||
source_databases = [f"app/DataBase/Msg/MSG{i}.db" for i in range(1, 50)]
|
source_databases = [os.path.join(db_dir, f"MSG{i}.db") for i in range(1, 50)]
|
||||||
import shutil
|
import shutil
|
||||||
if os.path.exists(target_database):
|
if os.path.exists(target_database):
|
||||||
os.remove(target_database)
|
os.remove(target_database)
|
||||||
try:
|
try:
|
||||||
shutil.copy2("app/DataBase/Msg/MSG0.db", target_database) # 使用一个数据库文件作为模板
|
shutil.copy2(os.path.join(db_dir, 'MSG0.db'), target_database) # 使用一个数据库文件作为模板
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
self.errorSignal.emit(True)
|
self.errorSignal.emit(True)
|
||||||
@ -254,13 +255,13 @@ class DecryptThread(QThread):
|
|||||||
QMessageBox.critical("错误", "数据库不存在\n请检查微信版本是否为最新")
|
QMessageBox.critical("错误", "数据库不存在\n请检查微信版本是否为最新")
|
||||||
|
|
||||||
# 音频数据库文件
|
# 音频数据库文件
|
||||||
target_database = "app/DataBase/Msg/MediaMSG.db"
|
target_database = os.path.join(db_dir,'MediaMSG.db')
|
||||||
# 源数据库文件列表
|
# 源数据库文件列表
|
||||||
if os.path.exists(target_database):
|
if os.path.exists(target_database):
|
||||||
os.remove(target_database)
|
os.remove(target_database)
|
||||||
source_databases = [f"app/DataBase/Msg/MediaMSG{i}.db" for i in range(1, 50)]
|
source_databases = [os.path.join(db_dir,f"MediaMSG{i}.db") for i in range(1, 50)]
|
||||||
try:
|
try:
|
||||||
shutil.copy2("app/DataBase/Msg/MediaMSG0.db", target_database) # 使用一个数据库文件作为模板
|
shutil.copy2(os.path.join(db_dir,'MediaMSG0.db'), target_database) # 使用一个数据库文件作为模板
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
self.errorSignal.emit(True)
|
self.errorSignal.emit(True)
|
||||||
@ -277,7 +278,7 @@ class DecryptThread(QThread):
|
|||||||
class MyThread(QThread):
|
class MyThread(QThread):
|
||||||
signal = pyqtSignal(list)
|
signal = pyqtSignal(list)
|
||||||
|
|
||||||
def __init__(self,version_list = None):
|
def __init__(self, version_list=None):
|
||||||
super(MyThread, self).__init__()
|
super(MyThread, self).__init__()
|
||||||
self.version_list = version_list
|
self.version_list = version_list
|
||||||
|
|
||||||
@ -328,7 +329,7 @@ class MyThread(QThread):
|
|||||||
result = get_wx_info.get_info(version_bias)
|
result = get_wx_info.get_info(version_bias)
|
||||||
else:
|
else:
|
||||||
logger.info(f"从云端获取内存基址失败:{version}")
|
logger.info(f"从云端获取内存基址失败:{version}")
|
||||||
result = [-2,version]
|
result = [-2, version]
|
||||||
except:
|
except:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
result = [-10086]
|
result = [-10086]
|
||||||
|
@ -102,7 +102,7 @@ def decode_dat_path(file_path, out_path) -> str:
|
|||||||
|
|
||||||
def get_image(path, base_path) -> str:
|
def get_image(path, base_path) -> str:
|
||||||
if path:
|
if path:
|
||||||
base_path = os.getcwd() + base_path
|
base_path = os.path.join(os.getcwd(),base_path)
|
||||||
output_path = decode_dat(os.path.join(Me().wx_dir, path), base_path)
|
output_path = decode_dat(os.path.join(Me().wx_dir, path), base_path)
|
||||||
relative_path = './image/' + os.path.basename(
|
relative_path = './image/' + os.path.basename(
|
||||||
output_path) if output_path else 'https://www.bing.com/images/search?view=detailV2&ccid=Zww6woP3&id=CCC91337C740656E800E51247E928ACD3052FECF&thid=OIP.Zww6woP3Em49TdSG_lnggAHaEK&mediaurl=https%3a%2f%2fmeekcitizen.files.wordpress.com%2f2018%2f09%2f404.jpg%3fw%3d656&exph=360&expw=640&q=404&simid=608040792714530493&FORM=IRPRST&ck=151E7337A86F1B9C5C5DB08B15B90809&selectedIndex=21&itb=0'
|
output_path) if output_path else 'https://www.bing.com/images/search?view=detailV2&ccid=Zww6woP3&id=CCC91337C740656E800E51247E928ACD3052FECF&thid=OIP.Zww6woP3Em49TdSG_lnggAHaEK&mediaurl=https%3a%2f%2fmeekcitizen.files.wordpress.com%2f2018%2f09%2f404.jpg%3fw%3d656&exph=360&expw=640&q=404&simid=608040792714530493&FORM=IRPRST&ck=151E7337A86F1B9C5C5DB08B15B90809&selectedIndex=21&itb=0'
|
||||||
@ -113,7 +113,7 @@ def get_image(path, base_path) -> str:
|
|||||||
|
|
||||||
def get_image_abs_path(path, base_path) -> str:
|
def get_image_abs_path(path, base_path) -> str:
|
||||||
if path:
|
if path:
|
||||||
base_path = os.getcwd() + base_path
|
base_path = os.path.join(os.getcwd(),base_path)
|
||||||
output_path = decode_dat(os.path.join(Me().wx_dir, path), base_path)
|
output_path = decode_dat(os.path.join(Me().wx_dir, path), base_path)
|
||||||
return output_path
|
return output_path
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user