From 4815b319670e40b0be328aa2e6a48ee41432ac14 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Fri, 15 Dec 2023 14:48:54 +0800
Subject: [PATCH 01/15] =?UTF-8?q?=E7=BB=99=E9=9F=B3=E9=A2=91=E7=9A=84?=
=?UTF-8?q?=E5=85=83=E6=95=B0=E6=8D=AE=E5=8A=A0=E4=B8=8A=E5=88=9B=E4=BD=9C?=
=?UTF-8?q?=E8=80=85=E4=BF=A1=E6=81=AF=EF=BC=8C=E4=BE=BF=E4=BA=8E=E6=9C=AC?=
=?UTF-8?q?=E5=9C=B0=E5=BD=92=E7=B1=BB=E6=9F=A5=E6=89=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 15 +++++++++++++++
requirements.txt | 3 ++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 92e4938..7e9fb3d 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -4,6 +4,7 @@ import os
from re import findall
from PyQt5.QtCore import pyqtSignal, QThread
from PyQt5.QtWidgets import QFileDialog
+from eyed3 import load
from . import msg_db, micro_msg_db
from .package_msg import PackageMsg
@@ -136,6 +137,18 @@ class Output(QThread):
self.requestInterruption()
+def modify_audio_metadata(audiofile, new_artist): # 修改音频元数据中的“创作者”标签
+ audiofile = load(audiofile)
+
+ # 检查文件是否有标签
+ if audiofile.tag is None:
+ audiofile.initTag()
+
+ # 修改艺术家名称
+ audiofile.tag.artist = new_artist
+ audiofile.tag.save()
+
+
class ChildThread(QThread):
"""
子线程,用于导出部分聊天记录
@@ -235,12 +248,14 @@ class ChildThread(QThread):
str_time = message[8]
is_send = message[4]
avatar = 'myhead.png' if is_send else 'tahead.png'
+ creatorName = MePC().name if is_send else self.contact.remark
timestamp = message[5]
msgSvrId = message[9]
if self.output_type == Output.HTML:
try:
audio_path = media_msg_db.get_audio(msgSvrId, output_path=origin_docx_path + "/voice")
audio_path = audio_path.replace('/', '\\')
+ modify_audio_metadata(audio_path, creatorName)
os.utime(audio_path, (timestamp, timestamp))
audio_path = audio_path.replace('\\', '/')
voice_to_text = media_msg_db.get_audio_text(str_content)
diff --git a/requirements.txt b/requirements.txt
index 713b142..dc07800 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -16,4 +16,5 @@ google==3.0.0
protobuf==4.25.1
soupsieve==2.5
lz4==4.3.2
-pilk==0.2.4
\ No newline at end of file
+pilk==0.2.4
+eyed3==0.9.7
\ No newline at end of file
From b1f42aa0bb30ac06dddf67bd665e45bff6a13042 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sat, 16 Dec 2023 12:29:51 +0800
Subject: [PATCH 02/15] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E8=A7=A3=E5=86=B3?=
=?UTF-8?q?=E5=8A=A0=E5=AF=86=E8=A1=A8=E6=83=85=E5=8C=85=E7=9A=84=E8=A7=A3?=
=?UTF-8?q?=E6=9E=90=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 8 ++-
app/util/emoji.py | 108 +++++++++++++++++++++++++++++++++-----
2 files changed, 101 insertions(+), 15 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 7e9fb3d..ae4193e 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -284,7 +284,11 @@ class ChildThread(QThread):
timestamp = message[5]
if self.output_type == Output.HTML:
emoji_path = get_emoji(str_content, thumb=True, output_path=origin_docx_path + '/emoji')
- emoji_path = './emoji/' + os.path.basename(emoji_path)
+ if emoji_path == "":
+ shutil.copy(f"{os.path.abspath('.')}/app/resources/icons/404.png", origin_docx_path + '/emoji/404.png')
+ emoji_path = "./emoji/404.png"
+ else:
+ emoji_path = './emoji/' + os.path.basename(emoji_path)
if self.is_5_min(timestamp):
doc.write(
f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
@@ -463,7 +467,7 @@ class ChildThread(QThread):
self.emoji(f, message)
elif type_ == 10000 and self.message_types.get(type_):
self.system_msg(f, message)
- elif type_ == 49 and sub_type == 57:
+ elif type_ == 49 and sub_type == 57 and self.message_types.get(1):
self.refermsg(f,message)
f.write(html_end)
f.close()
diff --git a/app/util/emoji.py b/app/util/emoji.py
index d2a4d7f..f6b707a 100644
--- a/app/util/emoji.py
+++ b/app/util/emoji.py
@@ -11,7 +11,8 @@ emoji.py
import os
import traceback
import xml.etree.ElementTree as ET
-
+import sqlite3
+import threading
import requests
from app.log import log, logger
@@ -43,7 +44,10 @@ def get_image_format(header):
def parser_xml(xml_string):
assert type(xml_string) == str
# Parse the XML string
- root = ET.fromstring(xml_string)
+ try:
+ root = ET.fromstring(xml_string)
+ except:
+ root = ET.fromstring(xml_string.replace("&", "&"))
emoji = root.find('./emoji')
# Accessing attributes of the 'emoji' element
fromusername = emoji.get('fromusername')
@@ -61,10 +65,67 @@ def parser_xml(xml_string):
'height': height,
'cdnurl': cdnurl,
'thumburl': thumburl if thumburl else cdnurl,
- 'md5': md5 if md5 else androidmd5,
+ 'md5': (md5 if md5 else androidmd5).lower(),
}
-@log
+def singleton(cls):
+ _instance = {}
+
+ def inner():
+ if cls not in _instance:
+ _instance[cls] = cls()
+ return _instance[cls]
+
+ return inner
+
+lock = threading.Lock()
+db_path = "./app/Database/Msg/Emotion.db"
+
+@singleton
+class Emotion:
+ def __init__(self):
+ self.DB = None
+ self.cursor: sqlite3.Cursor = None
+ self.open_flag = False
+ self.init_database()
+
+ def init_database(self):
+ if not self.open_flag:
+ if os.path.exists(db_path):
+ self.DB = sqlite3.connect(db_path, check_same_thread=False)
+ # '''创建游标'''
+ self.cursor = self.DB.cursor()
+ self.open_flag = True
+ if lock.locked():
+ lock.release()
+
+ def get_emoji_url(self, md5: str):
+ sql = '''
+ select CDNUrl
+ from CustomEmotion
+ where md5 = ?
+ '''
+ try:
+ lock.acquire(True)
+ self.cursor.execute(sql, [md5])
+ return self.cursor.fetchone()[0]
+ except:
+ md5 = md5.upper()
+ sql = """
+ select Data
+ from EmotionItem
+ where md5 = ?
+ """
+ self.cursor.execute(sql, [md5])
+ try:
+ return self.cursor.fetchone()[0]
+ except:
+ return ""
+ finally:
+ lock.release()
+
+emoji_db = Emotion()
+
def download(url, output_dir, name, thumb=False):
if not url:
return ':/icons/icons/404.png'
@@ -92,23 +153,44 @@ def get_emoji(xml_string, thumb=True, output_path=root_path) -> str:
prefix = 'th_' if thumb else ''
file_path = os.path.join(output_path, prefix + md5 + f)
if os.path.exists(file_path):
- print('表情包已存在')
+ # print('表情包已存在', file_path)
return file_path
url = emoji_info['thumburl'] if thumb else emoji_info['cdnurl']
- print("下载表情包ing:", url)
- emoji_path = download(url, output_path, md5, thumb)
- return emoji_path
+ if not url or url == "":
+ url = emoji_db.get_emoji_url(md5)
+ if type(url) == str and url != "":
+ print("下载表情包ing:", url)
+ emoji_path = download(url, output_path, md5, thumb)
+ return emoji_path
+ elif type(url) == bytes:
+ image_format = get_image_format(url[:8])
+ if image_format:
+ if thumb:
+ output_path = os.path.join(output_path, 'th_' + md5 + '.' + image_format)
+ else:
+ output_path = os.path.join(output_path, md5 + '.' + image_format)
+ else:
+ output_path = os.path.join(output_path, md5)
+ with open(output_path, 'wb') as f:
+ f.write(url)
+ print("表情包数据库加载", output_path)
+ return output_path
+ else:
+ print("!!!未知表情包数据,信息:", xml_string, emoji_info, url)
+ return ""
except:
logger.error(traceback.format_exc())
return ""
if __name__ == '__main__':
- xml_string = ' '
- res1 = parser_xml(xml_string)
- print(res1, res1['md5'])
+ db_path = r"..\DataBase\Msg\Emotion.db"
+ xml_string = ''
+ print(get_emoji(xml_string, thumb=False, output_path="."))
+ # ET.fromstring()
+ # print(res1, res1['md5'])
# download(res1['cdnurl'], "./data/emoji/", res1['md5'])
# download(res1['thumburl'], "./data/emoji/", res1['md5'], True)
- print(get_emoji(xml_string, True))
- print(get_emoji(xml_string, False))
+ # print(get_emoji(xml_string, True))
+ # print(get_emoji(xml_string, False))
# http://vweixinf.tc.qq.com/110/20403/stodownload?m=3a4d439aba02dce4834b2c54e9f15597&filekey=3043020101042f302d02016e0402534804203361346434333961626130326463653438333462326335346539663135353937020213f0040d00000004627466730000000131&hy=SH&storeid=323032313037323030373236313130303039653236646365316535316534383236386234306230303030303036653033303034666233&ef=3&bizid=1022
From 777756ae5a6a3aedd91669b6db9d3497b761b986 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sat, 16 Dec 2023 12:58:29 +0800
Subject: [PATCH 03/15] =?UTF-8?q?=E5=BF=98=E8=AE=B0=E5=AF=B9=E8=AF=AD?=
=?UTF-8?q?=E9=9F=B3=E8=BD=AC=E7=9A=84=E6=96=87=E5=AD=97escape=E4=BA=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index ae4193e..508191c 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -258,7 +258,7 @@ class ChildThread(QThread):
modify_audio_metadata(audio_path, creatorName)
os.utime(audio_path, (timestamp, timestamp))
audio_path = audio_path.replace('\\', '/')
- voice_to_text = media_msg_db.get_audio_text(str_content)
+ voice_to_text = escape_js_and_html(media_msg_db.get_audio_text(str_content))
except:
return
if self.is_5_min(timestamp):
From 2d0cbff14acae2fc23100d8d428e769347e9139b Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 10:56:27 +0800
Subject: [PATCH 04/15] =?UTF-8?q?Revert=20"=E5=9F=BA=E6=9C=AC=E8=A7=A3?=
=?UTF-8?q?=E5=86=B3=E5=8A=A0=E5=AF=86=E8=A1=A8=E6=83=85=E5=8C=85=E7=9A=84?=
=?UTF-8?q?=E8=A7=A3=E6=9E=90=E9=97=AE=E9=A2=98"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit b1f42aa0bb30ac06dddf67bd665e45bff6a13042.
---
app/DataBase/output_pc.py | 8 +--
app/util/emoji.py | 108 +++++---------------------------------
2 files changed, 15 insertions(+), 101 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 11600f7..492c5fb 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -284,11 +284,7 @@ class ChildThread(QThread):
timestamp = message[5]
if self.output_type == Output.HTML:
emoji_path = get_emoji(str_content, thumb=True, output_path=origin_docx_path + '/emoji')
- if emoji_path == "":
- shutil.copy(f"{os.path.abspath('.')}/app/resources/icons/404.png", origin_docx_path + '/emoji/404.png')
- emoji_path = "./emoji/404.png"
- else:
- emoji_path = './emoji/' + os.path.basename(emoji_path)
+ emoji_path = './emoji/' + os.path.basename(emoji_path)
if self.is_5_min(timestamp):
doc.write(
f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
@@ -473,7 +469,7 @@ class ChildThread(QThread):
self.emoji(f, message)
elif type_ == 10000 and self.message_types.get(type_):
self.system_msg(f, message)
- elif type_ == 49 and sub_type == 57 and self.message_types.get(1):
+ elif type_ == 49 and sub_type == 57:
self.refermsg(f,message)
f.write(html_end)
f.close()
diff --git a/app/util/emoji.py b/app/util/emoji.py
index f6b707a..d2a4d7f 100644
--- a/app/util/emoji.py
+++ b/app/util/emoji.py
@@ -11,8 +11,7 @@ emoji.py
import os
import traceback
import xml.etree.ElementTree as ET
-import sqlite3
-import threading
+
import requests
from app.log import log, logger
@@ -44,10 +43,7 @@ def get_image_format(header):
def parser_xml(xml_string):
assert type(xml_string) == str
# Parse the XML string
- try:
- root = ET.fromstring(xml_string)
- except:
- root = ET.fromstring(xml_string.replace("&", "&"))
+ root = ET.fromstring(xml_string)
emoji = root.find('./emoji')
# Accessing attributes of the 'emoji' element
fromusername = emoji.get('fromusername')
@@ -65,67 +61,10 @@ def parser_xml(xml_string):
'height': height,
'cdnurl': cdnurl,
'thumburl': thumburl if thumburl else cdnurl,
- 'md5': (md5 if md5 else androidmd5).lower(),
+ 'md5': md5 if md5 else androidmd5,
}
-def singleton(cls):
- _instance = {}
-
- def inner():
- if cls not in _instance:
- _instance[cls] = cls()
- return _instance[cls]
-
- return inner
-
-lock = threading.Lock()
-db_path = "./app/Database/Msg/Emotion.db"
-
-@singleton
-class Emotion:
- def __init__(self):
- self.DB = None
- self.cursor: sqlite3.Cursor = None
- self.open_flag = False
- self.init_database()
-
- def init_database(self):
- if not self.open_flag:
- if os.path.exists(db_path):
- self.DB = sqlite3.connect(db_path, check_same_thread=False)
- # '''创建游标'''
- self.cursor = self.DB.cursor()
- self.open_flag = True
- if lock.locked():
- lock.release()
-
- def get_emoji_url(self, md5: str):
- sql = '''
- select CDNUrl
- from CustomEmotion
- where md5 = ?
- '''
- try:
- lock.acquire(True)
- self.cursor.execute(sql, [md5])
- return self.cursor.fetchone()[0]
- except:
- md5 = md5.upper()
- sql = """
- select Data
- from EmotionItem
- where md5 = ?
- """
- self.cursor.execute(sql, [md5])
- try:
- return self.cursor.fetchone()[0]
- except:
- return ""
- finally:
- lock.release()
-
-emoji_db = Emotion()
-
+@log
def download(url, output_dir, name, thumb=False):
if not url:
return ':/icons/icons/404.png'
@@ -153,44 +92,23 @@ def get_emoji(xml_string, thumb=True, output_path=root_path) -> str:
prefix = 'th_' if thumb else ''
file_path = os.path.join(output_path, prefix + md5 + f)
if os.path.exists(file_path):
- # print('表情包已存在', file_path)
+ print('表情包已存在')
return file_path
url = emoji_info['thumburl'] if thumb else emoji_info['cdnurl']
- if not url or url == "":
- url = emoji_db.get_emoji_url(md5)
- if type(url) == str and url != "":
- print("下载表情包ing:", url)
- emoji_path = download(url, output_path, md5, thumb)
- return emoji_path
- elif type(url) == bytes:
- image_format = get_image_format(url[:8])
- if image_format:
- if thumb:
- output_path = os.path.join(output_path, 'th_' + md5 + '.' + image_format)
- else:
- output_path = os.path.join(output_path, md5 + '.' + image_format)
- else:
- output_path = os.path.join(output_path, md5)
- with open(output_path, 'wb') as f:
- f.write(url)
- print("表情包数据库加载", output_path)
- return output_path
- else:
- print("!!!未知表情包数据,信息:", xml_string, emoji_info, url)
- return ""
+ print("下载表情包ing:", url)
+ emoji_path = download(url, output_path, md5, thumb)
+ return emoji_path
except:
logger.error(traceback.format_exc())
return ""
if __name__ == '__main__':
- db_path = r"..\DataBase\Msg\Emotion.db"
- xml_string = ''
- print(get_emoji(xml_string, thumb=False, output_path="."))
- # ET.fromstring()
- # print(res1, res1['md5'])
+ xml_string = ' '
+ res1 = parser_xml(xml_string)
+ print(res1, res1['md5'])
# download(res1['cdnurl'], "./data/emoji/", res1['md5'])
# download(res1['thumburl'], "./data/emoji/", res1['md5'], True)
- # print(get_emoji(xml_string, True))
- # print(get_emoji(xml_string, False))
+ print(get_emoji(xml_string, True))
+ print(get_emoji(xml_string, False))
# http://vweixinf.tc.qq.com/110/20403/stodownload?m=3a4d439aba02dce4834b2c54e9f15597&filekey=3043020101042f302d02016e0402534804203361346434333961626130326463653438333462326335346539663135353937020213f0040d00000004627466730000000131&hy=SH&storeid=323032313037323030373236313130303039653236646365316535316534383236386234306230303030303036653033303034666233&ef=3&bizid=1022
From ef7bea7f9c22a916fbe7aa4eb9cfc6483b8952ef Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 18:33:06 +0800
Subject: [PATCH 05/15] =?UTF-8?q?html=E7=BE=A4=E8=81=8A=E5=AF=BC=E5=87=BA?=
=?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=B4=E5=83=8F=E5=92=8C=E6=98=B5=E7=A7=B0?=
=?UTF-8?q?=EF=BC=9B=E4=BF=AE=E5=A4=8D=E4=BA=86=E4=B8=80=E4=BA=9B=E5=85=B6?=
=?UTF-8?q?=E4=BB=96=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/msg.py | 15 ++
app/DataBase/output_pc.py | 349 ++++++++++++++++++++++++++----------
app/DataBase/package_msg.py | 64 ++++++-
app/util/emoji.py | 91 +++++++++-
main.py | 1 +
5 files changed, 424 insertions(+), 96 deletions(-)
diff --git a/app/DataBase/msg.py b/app/DataBase/msg.py
index 037c5eb..b0ff151 100644
--- a/app/DataBase/msg.py
+++ b/app/DataBase/msg.py
@@ -57,6 +57,21 @@ class Msg:
lock.release()
def get_messages(self, username_):
+ '''
+ return list
+ a[0]: localId,
+ a[1]: talkerId, (和strtalker对应的,不是群聊信息发送人)
+ a[2]: type,
+ a[3]: subType,
+ a[4]: is_sender,
+ a[5]: timestamp,
+ a[6]: status, (没啥用)
+ a[7]: str_content,
+ a[8]: str_time, (格式化的时间)
+ a[9]: msgSvrId,
+ a[10]: BytesExtra,
+ a[11]: CompressContent,
+ '''
if not self.open_flag:
return None
sql = '''
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 60569c7..329d5ab 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -27,6 +27,7 @@ def makedirs(path):
os.makedirs(os.path.join(path, 'video'), exist_ok=True)
os.makedirs(os.path.join(path, 'voice'), exist_ok=True)
os.makedirs(os.path.join(path, 'file'), exist_ok=True)
+ os.makedirs(os.path.join(path, 'avatar'), exist_ok=True)
def escape_js_and_html(input_str):
@@ -181,20 +182,32 @@ class ChildThread(QThread):
str_content = message[7]
str_time = message[8]
is_send = message[4]
- avatar = 'myhead.png' if is_send else 'tahead.png'
timestamp = message[5]
+ is_chatroom = 1 if self.contact.is_chatroom else 0
+ if is_chatroom:
+ avatar = f"./avatar/{message[12].wxid}.png"
+ else:
+ avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ if is_chatroom:
+ if is_send:
+ displayname = MePC().name
+ else:
+ displayname = message[12].remark
+ else:
+ displayname = MePC().name if is_send else self.contact.remark
+ displayname = escape_js_and_html(displayname)
if self.output_type == Output.HTML:
str_content = escape_js_and_html(str_content)
if self.is_5_min(timestamp):
doc.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
emojiText = findall(r"(\[.+?\])", str_content)
for emoji_text in emojiText:
if emoji_text in emoji:
str_content = str_content.replace(emoji_text, emoji[emoji_text])
doc.write(
- f'''{{ type:{1}, text: '{str_content}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ f'''{{ type:{1}, text: '{str_content}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
elif self.output_type == Output.TXT:
name = '你' if is_send else self.contact.remark
@@ -208,9 +221,21 @@ class ChildThread(QThread):
str_content = message[7]
str_time = message[8]
is_send = message[4]
- avatar = 'myhead.png' if is_send else 'tahead.png'
- timestamp = message[5]
BytesExtra = message[10]
+ timestamp = message[5]
+ is_chatroom = 1 if self.contact.is_chatroom else 0
+ if is_chatroom:
+ avatar = f"./avatar/{message[12].wxid}.png"
+ else:
+ avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ if is_chatroom:
+ if is_send:
+ displayname = MePC().name
+ else:
+ displayname = message[12].remark
+ else:
+ displayname = MePC().name if is_send else self.contact.remark
+ displayname = escape_js_and_html(displayname)
if self.output_type == Output.HTML:
str_content = escape_js_and_html(str_content)
image_path = hard_link_db.get_image(str_content, BytesExtra, thumb=False)
@@ -231,10 +256,10 @@ class ChildThread(QThread):
# print(f"tohtml:---{image_path}")
if self.is_5_min(timestamp):
doc.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
doc.write(
- f'''{{ type:{type_}, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ f'''{{ type:{type_}, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
elif self.output_type == Output.TXT:
name = '你' if is_send else self.contact.remark
@@ -247,15 +272,26 @@ class ChildThread(QThread):
str_content = message[7]
str_time = message[8]
is_send = message[4]
- avatar = 'myhead.png' if is_send else 'tahead.png'
- creatorName = MePC().name if is_send else self.contact.remark
- timestamp = message[5]
msgSvrId = message[9]
+ timestamp = message[5]
+ is_chatroom = 1 if self.contact.is_chatroom else 0
+ if is_chatroom:
+ avatar = f"./avatar/{message[12].wxid}.png"
+ else:
+ avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ if is_chatroom:
+ if is_send:
+ displayname = MePC().name
+ else:
+ displayname = message[12].remark
+ else:
+ displayname = MePC().name if is_send else self.contact.remark
+ displayname = escape_js_and_html(displayname)
if self.output_type == Output.HTML:
try:
audio_path = media_msg_db.get_audio(msgSvrId, output_path=origin_docx_path + "/voice")
audio_path = audio_path.replace('/', '\\')
- modify_audio_metadata(audio_path, creatorName)
+ modify_audio_metadata(audio_path, displayname)
os.utime(audio_path, (timestamp, timestamp))
audio_path = audio_path.replace('\\', '/')
voice_to_text = escape_js_and_html(media_msg_db.get_audio_text(str_content))
@@ -263,10 +299,10 @@ class ChildThread(QThread):
return
if self.is_5_min(timestamp):
doc.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
doc.write(
- f'''{{ type:34, text:'{audio_path}',is_send:{is_send},avatar_path:'{avatar}',voice_to_text:'{voice_to_text}'}},'''
+ 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:'{displayname}'}},'''
)
if self.output_type == Output.TXT:
name = '你' if is_send else self.contact.remark
@@ -279,17 +315,33 @@ class ChildThread(QThread):
str_content = message[7]
str_time = message[8]
is_send = message[4]
- avatar = 'myhead.png' if is_send else 'tahead.png'
timestamp = message[5]
+ is_chatroom = 1 if self.contact.is_chatroom else 0
+ if is_chatroom:
+ avatar = f"./avatar/{message[12].wxid}.png"
+ else:
+ avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ if is_chatroom:
+ if is_send:
+ displayname = MePC().name
+ else:
+ displayname = message[12].remark
+ else:
+ displayname = MePC().name if is_send else self.contact.remark
+ displayname = escape_js_and_html(displayname)
if self.output_type == Output.HTML:
emoji_path = get_emoji(str_content, thumb=True, output_path=origin_docx_path + '/emoji')
- emoji_path = './emoji/' + os.path.basename(emoji_path)
+ if emoji_path == "":
+ shutil.copy(f"{os.path.abspath('.')}/app/resources/icons/404.png", origin_docx_path + '/emoji/404.png')
+ emoji_path = "./emoji/404.png"
+ else:
+ emoji_path = './emoji/' + os.path.basename(emoji_path)
if self.is_5_min(timestamp):
doc.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
doc.write(
- f'''{{ type:{3}, text: '{emoji_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ f'''{{ type:{3}, text: '{emoji_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
elif self.output_type == Output.TXT:
name = '你' if is_send else self.contact.remark
@@ -317,6 +369,20 @@ class ChildThread(QThread):
avatar = 'myhead.png' if is_send else 'tahead.png'
content = parser_reply(message[11])
refer_msg = content.get('refer')
+ timestamp = message[5]
+ is_chatroom = 1 if self.contact.is_chatroom else 0
+ if is_chatroom:
+ avatar = f"./avatar/{message[12].wxid}.png"
+ else:
+ avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ if is_chatroom:
+ if is_send:
+ displayname = MePC().name
+ else:
+ displayname = message[12].remark
+ else:
+ displayname = MePC().name if is_send else self.contact.remark
+ displayname = escape_js_and_html(displayname)
if self.output_type == Output.HTML:
contentText = content.get('title')
emojiText = findall(r"(\[.+?\])", contentText)
@@ -330,11 +396,11 @@ class ChildThread(QThread):
if emoji_text in emoji:
referText = referText.replace(emoji_text, emoji[emoji_text])
doc.write(
- f'''{{ type:49, text: '{contentText}',is_send:{is_send},sub_type:{content.get('type')},refer_text: '{referText}',avatar_path:'{avatar}'}},'''
+ 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:'{displayname}'}},'''
)
else:
doc.write(
- f'''{{ type:49, text: '{contentText}',is_send:{is_send},sub_type:{content.get('type')},avatar_path:'{avatar}'}},'''
+ f'''{{ type:49, text: '{contentText}',is_send:{is_send},sub_type:{content.get('type')},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
elif self.output_type == Output.TXT:
name = '你' if is_send else self.contact.remark
@@ -351,10 +417,12 @@ class ChildThread(QThread):
str_content = message[7]
is_send = message[4]
str_time = message[8]
+ timestamp = message[5]
+ is_chatroom = 1 if self.contact.is_chatroom else 0
str_content = escape_js_and_html(str_content.lstrip('').rstrip(''))
if self.output_type == Output.HTML:
doc.write(
- f'''{{ type:0, text: '{str_content}',is_send:{is_send},avatar_path:''}},'''
+ f'''{{ type:0, text: '{str_content}',is_send:{is_send},avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:''}},'''
)
elif self.output_type == Output.TXT:
name = '你' if is_send else self.contact.remark
@@ -369,8 +437,20 @@ class ChildThread(QThread):
str_time = message[8]
is_send = message[4]
BytesExtra = message[10]
- avatar = 'myhead.png' if is_send else 'tahead.png'
timestamp = message[5]
+ is_chatroom = 1 if self.contact.is_chatroom else 0
+ if is_chatroom:
+ avatar = f"./avatar/{message[12].wxid}.png"
+ else:
+ avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ if is_chatroom:
+ if is_send:
+ displayname = MePC().name
+ else:
+ displayname = message[12].remark
+ else:
+ displayname = MePC().name if is_send else self.contact.remark
+ displayname = escape_js_and_html(displayname)
if self.output_type == Output.HTML:
video_path = hard_link_db.get_video(str_content, BytesExtra, thumb=False)
image_path = hard_link_db.get_video(str_content, BytesExtra, thumb=True)
@@ -385,14 +465,14 @@ class ChildThread(QThread):
# print(f"tohtml:---{image_path}")
if self.is_5_min(timestamp):
doc.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
doc.write(
- f'''{{ type:3, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ f'''{{ type:3, text: '{image_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
except:
doc.write(
- f'''{{ type:1, text: '视频丢失',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ f'''{{ type:1, text: '视频丢失',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
return
if video_path is None and image_path is None:
@@ -407,10 +487,10 @@ class ChildThread(QThread):
video_path = video_path.replace('\\', '/')
if self.is_5_min(timestamp):
doc.write(
- f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
+ f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:'',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
doc.write(
- f'''{{ type:{type_}, text: '{video_path}',is_send:{is_send},avatar_path:'{avatar}'}},'''
+ f'''{{ type:{type_}, text: '{video_path}',is_send:{is_send},avatar_path:'{avatar}',timestamp:{timestamp},is_chatroom:{is_chatroom},displayname:'{displayname}'}},'''
)
elif self.output_type == Output.TXT:
name = '你' if is_send else self.contact.remark
@@ -443,12 +523,27 @@ class ChildThread(QThread):
def to_html_(self):
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
makedirs(origin_docx_path)
- messages = msg_db.get_messages(self.contact.wxid)
+ if self.contact.is_chatroom:
+ packagemsg = PackageMsg()
+ messages = packagemsg.get_package_message_by_wxid(self.contact.wxid)
+ else:
+ messages = msg_db.get_messages(self.contact.wxid)
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.html"
f = open(filename, 'w', encoding='utf-8')
- f.write(html_head)
- MePC().avatar.save(os.path.join(origin_docx_path, 'myhead.png'))
- self.contact.avatar.save(os.path.join(origin_docx_path, 'tahead.png'))
+ f.write(html_head.replace("
Chat Records", f"{self.contact.remark}"))
+ MePC().avatar.save(os.path.join(f"{origin_docx_path}/avatar/{MePC().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[12].wxid}.png"
+ if not os.path.exists(chatroom_avatar_path):
+ message[12].avatar.save(chatroom_avatar_path)
+ except:
+ pass
+ else:
+ self.contact.avatar.save(os.path.join(f"{origin_docx_path}/avatar/{self.contact.wxid}.png"))
self.rangeSignal.emit(len(messages))
total_steps = len(messages)
for index, message in enumerate(messages):
@@ -467,7 +562,7 @@ class ChildThread(QThread):
self.emoji(f, message)
elif type_ == 10000 and self.message_types.get(type_):
self.system_msg(f, message)
- elif type_ == 49 and sub_type == 57:
+ elif type_ == 49 and sub_type == 57 and self.message_types.get(type_):
self.refermsg(f, message)
f.write(html_end)
f.close()
@@ -562,6 +657,7 @@ emoji = {
'[阴险]': '
',
'[亲亲]': '
',
'[可怜]': '
',
+ '[Whimper]': '
',
'[笑脸]': '
',
'[生病]': '
',
'[脸红]': '
',
@@ -691,7 +787,8 @@ body{
word-wrap:break-word;
word-break:normal;
}
-.chat-refer{
+.chat-refer {
+ margin-top: 5px;
max-width: 400px;
padding: 6px;
border-radius: 5px;
@@ -701,11 +798,11 @@ body{
word-wrap:break-word;
word-break:normal;
}
-.chat-refer-right{
- margin-right:55px;
+.chat-refer-right {
+ margin-right: 55px;
}
.chat-refer-left{
- margin-left:55px;
+ margin-left: 15px;
}
.item-left .bubble{
margin-left: 15px;
@@ -737,8 +834,8 @@ body{
border-bottom: 10px solid transparent;
right: -20px;
}
-.item{
- white-space: pre-line;
+.item {
+ white-space: pre-wrap;
margin-top: 15px;
display: flex;
width: 100%;
@@ -765,6 +862,20 @@ body{
user-select:none;
}
+.content-wrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: baseline;
+}
+
+.displayname {
+ margin-left: 13px;
+ margin-left: 13px;
+ font-size: 13px;
+ margin-bottom: 5px;
+ color: darkgray;
+}
+
.chat-image img{
margin-right: 18px;
margin-left: 18px;
@@ -960,84 +1071,142 @@ html_end = '''
const startIndex = (page - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
console.log(page);
+
+ // 生成各类标签的函数
+ function messageBubble(message, side) {
+ const messageBubbleTag = document.createElement('div');
+ messageBubbleTag.className = `bubble bubble-${side}`;
+ messageBubbleTag.innerHTML = message.text;
+ return messageBubbleTag;
+ }
+ function displayNameBox(message) {
+ const displayName = document.createElement('div');
+ displayName.className = "displayname";
+ displayName.innerHTML = message.displayname;
+ return displayName;
+ }
+ function avatarBox(message) {
+ const avatarTag = document.createElement('div');
+ avatarTag.className = "avatar";
+ avatarTag.innerHTML = `
`
+ return avatarTag;
+ }
+ function messageImgBox(message) {
+ const messageImgTag = document.createElement('div');
+ messageImgTag.className = `chat-image`;
+ messageImgTag.innerHTML = `
`;
+ return messageImgTag;
+ }
+ function messageVideoBox(message) {
+ const messageVideoTag = document.createElement('div');
+ messageVideoTag.className = `chat-video`;
+ messageVideoTag.innerHTML = ``;
+ return messageVideoTag;
+ }
+ function messageElementReferText(message, side) {
+ const messageElementRefer = document.createElement('div');
+ messageElementRefer.className = `chat-refer chat-refer-${side}`;
+ messageElementRefer.innerHTML = message.refer_text;
+ return messageElementRefer;
+ }
+ function messageVoiceToTextBubble(message, side) {
+ const messageVoiceToTextTag = document.createElement('div');
+ messageVoiceToTextTag.className = `bubble bubble-${side}`;
+ messageVoiceToTextTag.innerHTML = message.voice_to_text;
+ return messageVoiceToTextTag;
+ }
+ function messageAudioBox(message) {
+ const messageAudioTag = document.createElement('div');
+ messageAudioTag.className = `chat-audio`;
+ messageAudioTag.innerHTML = ``;
+ return messageAudioTag;
+ }
+
// 从数据列表中取出对应范围的元素并添加到容器中
for (let i = startIndex; i < endIndex && i < chatMessages.length; i++) {
const message = chatMessages[i];
- const messageElement = document.createElement('div');
- const messageElementRefer = document.createElement('div');
- const formattedText = message.text.replace(/\\n/g, "
");
- var formattedReferText = "";
+ const messageElement = document.createElement('div'); // 下面那俩的合体
+ const avatarTag = avatarBox(message); // 头像
+ const messageContent = document.createElement('div'); // 除了avatar之外的所有
+ const side = message.is_send ? "right" : "left";
if (message.type == 1) {
- if (message.is_send == 1) {
- messageElement.className = "item item-right";
- messageElement.innerHTML = `${formattedText}
`
- }
- else if (message.is_send == 0) {
- messageElement.className = "item item-left";
- messageElement.innerHTML = `${formattedText}
`
+ // displayname 和 bubble
+ messageContent.className = "content-wrapper";
+ if (message.is_chatroom && !message.is_send) {
+ messageContent.appendChild(displayNameBox(message));
}
+ messageContent.appendChild(messageBubble(message, side));
+
+ // 整合
+ messageElement.className = `item item-${side}`;
+ messageElement.appendChild(message.is_send ? messageContent : avatarTag);
+ messageElement.appendChild(message.is_send ? avatarTag : messageContent);
}
else if (message.type == 0) {
messageElement.className = "item item-center";
- messageElement.innerHTML = `${formattedText}`
+ messageElement.innerHTML = `${message.text}`
}
else if (message.type == 3) {
- if (message.is_send == 1) {
- messageElement.className = "item item-right";
- messageElement.innerHTML = ``
- }
- else if (message.is_send == 0) {
- messageElement.className = "item item-left";
- messageElement.innerHTML = ``
+ // displayname 和 img
+ messageContent.className = "content-wrapper";
+ if (message.is_chatroom && !message.is_send) {
+ messageContent.appendChild(displayNameBox(message));
}
+ messageContent.appendChild(messageImgBox(message));
+
+ // 整合
+ messageElement.className = `item item-${side}`;
+ messageElement.appendChild(message.is_send ? messageContent : avatarTag);
+ messageElement.appendChild(message.is_send ? avatarTag : messageContent);
}
else if (message.type == 43) {
- if (message.is_send == 1) {
- messageElement.className = "item item-right";
- messageElement.innerHTML = ``
- }
- else if (message.is_send == 0) {
- messageElement.className = "item item-left";
- messageElement.innerHTML = ``
+ // displayname 和 video
+ messageContent.className = "content-wrapper";
+ if (message.is_chatroom && !message.is_send) {
+ messageContent.appendChild(displayNameBox(message));
}
+ messageContent.appendChild(messageVideoBox(message));
+
+ // 整合
+ messageElement.className = `item item-${side}`;
+ messageElement.appendChild(message.is_send ? messageContent : avatarTag);
+ messageElement.appendChild(message.is_send ? avatarTag : messageContent);
}
else if (message.type == 49) {
- if (message.sub_type == 57){
+ if (message.sub_type == 57) {
+ // displayname 和 bubble 和 refer
+ messageContent.className = "content-wrapper";
+ if (message.is_chatroom && !message.is_send) {
+ messageContent.appendChild(displayNameBox(message));
+ }
+ messageContent.appendChild(messageBubble(message, side));
if (message.refer_text) {
- formattedReferText = message.refer_text.replace(/\\n/g, "
");
- }
- if (message.is_send == 1) {
- messageElement.className = "item item-right";
- messageElement.innerHTML = `${formattedText}
`
- if (message.refer_text) {
- messageElementRefer.className = "item item-right item-refer";
- messageElementRefer.innerHTML = `${formattedReferText}
`
- }
- }
- else if (message.is_send == 0) {
- messageElement.className = "item item-left";
- messageElement.innerHTML = `${formattedText}
`
- if (message.refer_text) {
- messageElementRefer.className = "item item-left item-refer";
- messageElementRefer.innerHTML = `${formattedReferText}
`
- }
+ messageContent.appendChild(messageElementReferText(message, side));
}
+
+ // 整合
+ messageElement.className = `item item-${side}`;
+ messageElement.appendChild(message.is_send ? messageContent : avatarTag);
+ messageElement.appendChild(message.is_send ? avatarTag : messageContent);
}
}
else if (message.type == 34) {
- if (message.is_send == 1) {
- messageElement.className = "item item-right";
- messageElement.innerHTML = `${message.voice_to_text == "" ? "" : `
${message.voice_to_text}
`}
`
+ // displayname 和 转的文字 和 audio
+ messageContent.className = "content-wrapper";
+ if (message.is_chatroom && !message.is_send) {
+ messageContent.appendChild(displayNameBox(message));
}
- else if (message.is_send == 0) {
- messageElement.className = "item item-left";
- messageElement.innerHTML = `${message.voice_to_text == "" ? "" : `
${message.voice_to_text}
`}
`
+ if (message.voice_to_text) {
+ messageContent.appendChild(messageVoiceToTextBubble(message, side));
}
+ messageContent.appendChild(messageAudioBox(message));
+
+ // 整合
+ messageElement.className = `item item-${side}`;
+ messageElement.appendChild(message.is_send ? messageContent : avatarTag);
+ messageElement.appendChild(message.is_send ? avatarTag : messageContent);
}
chatContainer.appendChild(messageElement);
- if (message.type == 49 && message.sub_type == 57 && message.refer_text) {
- chatContainer.appendChild(messageElementRefer);
- }
}
document.querySelector("#chat-container").scrollTop = 0;
updatePaginationInfo();
diff --git a/app/DataBase/package_msg.py b/app/DataBase/package_msg.py
index 59bfd9a..082c93b 100644
--- a/app/DataBase/package_msg.py
+++ b/app/DataBase/package_msg.py
@@ -1,8 +1,9 @@
import threading
-from app.DataBase import msg_db, micro_msg_db
+from app.DataBase import msg_db, micro_msg_db, misc_db
from app.util.protocbuf.msg_pb2 import MessageBytesExtra
from app.util.protocbuf.roomdata_pb2 import ChatRoomData
+from app.person import ContactPC, MePC
lock = threading.Lock()
@@ -76,6 +77,63 @@ class PackageMsg:
row_list.append(sender)
updated_messages.append(tuple(row_list))
return updated_messages
+
+ def get_package_message_by_wxid(self, chatroom_wxid):
+ '''
+ 获取一个群聊的聊天记录
+ return list
+ a[0]: localId,
+ a[1]: talkerId, (和strtalker对应的,不是群聊信息发送人)
+ a[2]: type,
+ a[3]: subType,
+ a[4]: is_sender,
+ a[5]: timestamp,
+ a[6]: status, (没啥用)
+ a[7]: str_content,
+ a[8]: str_time, (格式化的时间)
+ a[9]: msgSvrId,
+ a[10]: BytesExtra,
+ a[11]: CompressContent,
+ a[12]: msg_sender, (ContactPC类型,这个才是群聊里的信息发送人,不是群聊或者自己是发送者没有这个字段)
+ '''
+ updated_messages = [] # 用于存储修改后的消息列表
+
+ messages = msg_db.get_messages(chatroom_wxid)
+
+ for row in messages:
+ message = list(row)
+ if message[4] == 1: # 自己发送的就没必要解析了
+ message.append(MePC())
+ updated_messages.append(message)
+ continue
+ if message[10] is None: # BytesExtra是空的跳过
+ updated_messages.append(message)
+ continue
+ msgbytes = MessageBytesExtra()
+ msgbytes.ParseFromString(message[10])
+ wxid = ''
+ for tmp in msgbytes.message2:
+ if tmp.field1 != 1:
+ continue
+ wxid = tmp.field2
+ if wxid == "": # 系统消息里面 wxid 不存在
+ updated_messages.append(message)
+ continue
+ contact_info_list = micro_msg_db.get_contact_by_username(wxid)
+ contact_info = {
+ 'UserName': contact_info_list[0],
+ 'Alias': contact_info_list[1],
+ 'Type': contact_info_list[2],
+ 'Remark': contact_info_list[3],
+ 'NickName': contact_info_list[4],
+ 'smallHeadImgUrl': contact_info_list[7]
+ }
+ contact = ContactPC(contact_info)
+ contact.smallHeadImgBLOG = misc_db.get_avatar_buffer(contact.wxid)
+ contact.set_avatar(contact.smallHeadImgBLOG)
+ message.append(contact)
+ updated_messages.append(tuple(message))
+ return updated_messages
def get_chatroom_member_list(self, strtalker):
membermap = {}
@@ -101,3 +159,7 @@ class PackageMsg:
finally:
lock.release()
return membermap
+
+if __name__ == "__main__":
+ p = PackageMsg()
+ print(p.get_package_message_by_wxid("44326600419@chatroom"))
diff --git a/app/util/emoji.py b/app/util/emoji.py
index d2a4d7f..3ab73b7 100644
--- a/app/util/emoji.py
+++ b/app/util/emoji.py
@@ -11,6 +11,8 @@ emoji.py
import os
import traceback
import xml.etree.ElementTree as ET
+import sqlite3
+import threading
import requests
@@ -43,7 +45,10 @@ def get_image_format(header):
def parser_xml(xml_string):
assert type(xml_string) == str
# Parse the XML string
- root = ET.fromstring(xml_string)
+ try:
+ root = ET.fromstring(xml_string)
+ except:
+ root = ET.fromstring(xml_string.replace("&", "&"))
emoji = root.find('./emoji')
# Accessing attributes of the 'emoji' element
fromusername = emoji.get('fromusername')
@@ -61,9 +66,66 @@ def parser_xml(xml_string):
'height': height,
'cdnurl': cdnurl,
'thumburl': thumburl if thumburl else cdnurl,
- 'md5': md5 if md5 else androidmd5,
+ 'md5': (md5 if md5 else androidmd5).lower(),
}
+lock = threading.Lock()
+db_path = "./app/Database/Msg/Emotion.db"
+
+class Emotion:
+ def __init__(self):
+ self.DB = None
+ self.cursor: sqlite3.Cursor = None
+ self.open_flag = False
+ self.init_database()
+
+ def init_database(self):
+ if not self.open_flag:
+ if os.path.exists(db_path):
+ self.DB = sqlite3.connect(db_path, check_same_thread=False)
+ # '''创建游标'''
+ self.cursor = self.DB.cursor()
+ self.open_flag = True
+ if lock.locked():
+ lock.release()
+
+ def get_emoji_url(self, md5: str):
+ sql = '''
+ select CDNUrl
+ from CustomEmotion
+ where md5 = ?
+ '''
+ try:
+ lock.acquire(True)
+ self.cursor.execute(sql, [md5])
+ return self.cursor.fetchone()[0]
+ except:
+ md5 = md5.upper()
+ sql = """
+ select Data
+ from EmotionItem
+ where md5 = ?
+ """
+ self.cursor.execute(sql, [md5])
+ try:
+ return self.cursor.fetchone()[0]
+ except:
+ return ""
+ finally:
+ lock.release()
+
+ def close(self):
+ if self.open_flag:
+ try:
+ lock.acquire(True)
+ self.open_flag = False
+ self.DB.close()
+ finally:
+ lock.release()
+
+ def __del__(self):
+ self.close()
+
@log
def download(url, output_dir, name, thumb=False):
if not url:
@@ -95,9 +157,28 @@ def get_emoji(xml_string, thumb=True, output_path=root_path) -> str:
print('表情包已存在')
return file_path
url = emoji_info['thumburl'] if thumb else emoji_info['cdnurl']
- print("下载表情包ing:", url)
- emoji_path = download(url, output_path, md5, thumb)
- return emoji_path
+ if not url or url == "":
+ url = Emotion().get_emoji_url(md5)
+ if type(url) == str and url != "":
+ print("下载表情包ing:", url)
+ emoji_path = download(url, output_path, md5, thumb)
+ return emoji_path
+ elif type(url) == bytes:
+ image_format = get_image_format(url[:8])
+ if image_format:
+ if thumb:
+ output_path = os.path.join(output_path, 'th_' + md5 + '.' + image_format)
+ else:
+ output_path = os.path.join(output_path, md5 + '.' + image_format)
+ else:
+ output_path = os.path.join(output_path, md5)
+ with open(output_path, 'wb') as f:
+ f.write(url)
+ print("表情包数据库加载", output_path)
+ return output_path
+ else:
+ print("!!!未知表情包数据,信息:", xml_string, emoji_info, url)
+ return ""
except:
logger.error(traceback.format_exc())
return ""
diff --git a/main.py b/main.py
index cd73f0b..2dbc7f0 100644
--- a/main.py
+++ b/main.py
@@ -55,6 +55,7 @@ class ViewController(QWidget):
def close(self) -> bool:
close_db()
super().close()
+
if __name__ == '__main__':
app = QApplication(sys.argv)
font = QFont('微软雅黑', 12) # 使用 Times New Roman 字体,字体大小为 14
From 0e9f66c57f04afd708e39a37dbe227e540e27e63 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 18:43:37 +0800
Subject: [PATCH 06/15] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=A1=B5=E9=9D=A2?=
=?UTF-8?q?=E6=98=BE=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 2 +-
app/util/compress_content.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 329d5ab..5643ac5 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -790,7 +790,7 @@ body{
.chat-refer {
margin-top: 5px;
max-width: 400px;
- padding: 6px;
+ padding: 9px;
border-radius: 5px;
position: relative;
color: #000;
diff --git a/app/util/compress_content.py b/app/util/compress_content.py
index d0ddfe3..caf5424 100644
--- a/app/util/compress_content.py
+++ b/app/util/compress_content.py
@@ -48,7 +48,7 @@ def parser_reply(data: bytes):
'displayname': '用户名',
}
}
- try :
+ try:
root = ET.XML(xml_content)
appmsg = root.find('appmsg')
msg_type = int(appmsg.find('type').text)
From 9e6a4aadbabf0380c69d75fa1034605527af63b2 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 18:48:22 +0800
Subject: [PATCH 07/15] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BC=95=E7=94=A8?=
=?UTF-8?q?=E4=B8=8D=E8=83=BD=E6=98=BE=E7=A4=BA=E7=9A=84=E9=94=85?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 5643ac5..43e174a 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -562,7 +562,7 @@ class ChildThread(QThread):
self.emoji(f, message)
elif type_ == 10000 and self.message_types.get(type_):
self.system_msg(f, message)
- elif type_ == 49 and sub_type == 57 and self.message_types.get(type_):
+ elif type_ == 49 and sub_type == 57 and self.message_types.get(1):
self.refermsg(f, message)
f.write(html_end)
f.close()
From afe8dcd1d85a4386579c157cc32fe8ed8478f38a Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 18:54:59 +0800
Subject: [PATCH 08/15] =?UTF-8?q?=E8=B0=83=E6=95=B4=E5=BE=AE=E4=BF=A1?=
=?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=A1=A8=E6=83=85=E7=9A=84=E4=BD=8D=E7=BD=AE?=
=?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E7=95=8C=E9=9D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 43e174a..4945064 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -778,7 +778,9 @@ body{
.content:hover::-webkit-scrollbar-thumb{
background:rgba(0,0,0,0.1);
}
-.bubble{
+.bubble {
+ display: flex;
+ align-items: center;
max-width: 400px;
padding: 10px;
border-radius: 5px;
@@ -788,6 +790,8 @@ body{
word-break:normal;
}
.chat-refer {
+ display: flex;
+ align-items: center;
margin-top: 5px;
max-width: 400px;
padding: 9px;
@@ -1000,10 +1004,8 @@ input {
}
.emoji_img {
- width: 26px;
- height: 26px;
- position: relative;
- bottom: -6px;
+ width: 22px;
+ height: 22px;
}
From 48f268d0f5750bf5715da7eeae816a29f527e269 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 18:58:12 +0800
Subject: [PATCH 09/15] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E7=94=B1=E4=BA=8Exml?=
=?UTF-8?q?=E6=8D=A2=E4=B8=8D=E6=8D=A2=E8=A1=8C=E9=97=AE=E9=A2=98=E5=B8=A6?=
=?UTF-8?q?=E6=9D=A5=E7=9A=84=E5=85=88=E5=AF=BC=E5=9B=9E=E8=BD=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/util/compress_content.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/util/compress_content.py b/app/util/compress_content.py
index caf5424..0df8f27 100644
--- a/app/util/compress_content.py
+++ b/app/util/compress_content.py
@@ -61,7 +61,7 @@ def parser_reply(data: bytes):
'title': escape_js_and_html(title),
'refer': None if refermsg_type != 1 else {
'type': refermsg_type,
- 'content': escape_js_and_html(refermsg_content),
+ 'content': escape_js_and_html(refermsg_content.lstrip("\n")),
'displayname': escape_js_and_html(refermsg_displayname),
}
}
From e04ad64d3a35164fb94d50fa9fd8730482659404 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 18:59:03 +0800
Subject: [PATCH 10/15] =?UTF-8?q?Revert=20"=E8=B0=83=E6=95=B4=E5=BE=AE?=
=?UTF-8?q?=E4=BF=A1=E9=BB=98=E8=AE=A4=E8=A1=A8=E6=83=85=E7=9A=84=E4=BD=8D?=
=?UTF-8?q?=E7=BD=AE=EF=BC=8C=E4=BC=98=E5=8C=96=E7=95=8C=E9=9D=A2"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit afe8dcd1d85a4386579c157cc32fe8ed8478f38a.
---
app/DataBase/output_pc.py | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 4945064..43e174a 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -778,9 +778,7 @@ body{
.content:hover::-webkit-scrollbar-thumb{
background:rgba(0,0,0,0.1);
}
-.bubble {
- display: flex;
- align-items: center;
+.bubble{
max-width: 400px;
padding: 10px;
border-radius: 5px;
@@ -790,8 +788,6 @@ body{
word-break:normal;
}
.chat-refer {
- display: flex;
- align-items: center;
margin-top: 5px;
max-width: 400px;
padding: 9px;
@@ -1004,8 +1000,10 @@ input {
}
.emoji_img {
- width: 22px;
- height: 22px;
+ width: 26px;
+ height: 26px;
+ position: relative;
+ bottom: -6px;
}
From 6e977f59896a1840f59d8db0a0a64d4cc60c3426 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 19:12:46 +0800
Subject: [PATCH 11/15] =?UTF-8?q?=E6=8D=A2=E4=BA=86=E7=A7=8D=E6=AD=A3?=
=?UTF-8?q?=E5=B8=B8=E6=96=B9=E6=B3=95=E8=B0=83=E6=95=B4=E5=BE=AE=E4=BF=A1?=
=?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=A1=A8=E6=83=85=E7=9A=84=E4=BD=8D=E7=BD=AE?=
=?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E7=95=8C=E9=9D=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 43e174a..6387d03 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -1000,10 +1000,10 @@ input {
}
.emoji_img {
- width: 26px;
- height: 26px;
- position: relative;
- bottom: -6px;
+ width: 22px;
+ height: 22px;
+ vertical-align: middle;
+ margin-top: -4.4px;
}
From 45d406fcdc686732c051806da6d1f710368d8305 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 19:19:35 +0800
Subject: [PATCH 12/15] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=89=93=E5=BC=80?=
=?UTF-8?q?=E5=A4=A7=E5=9B=BE=E7=9A=84css=EF=BC=8C=E8=AE=A9=E5=AE=83?=
=?UTF-8?q?=E5=BE=85=E5=9C=A8=E5=B1=8F=E5=B9=95=E4=B8=AD=E9=97=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 6387d03..fdac261 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -756,8 +756,10 @@ body{
display: block;
max-width: 90%;
max-height: 90%;
- margin: auto;
- margin-top: 5%;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
}
.container{
height: 99%;
From aed1de2c4b8cd30dd62a84883864a5fec5403dc2 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 19:37:16 +0800
Subject: [PATCH 13/15] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E8=87=AA?=
=?UTF-8?q?=E5=B7=B1=E5=BC=95=E7=94=A8=E9=A1=B5=E9=9D=A2=E5=87=BA=E9=97=AE?=
=?UTF-8?q?=E9=A2=98=E7=9A=84bug=EF=BC=8C=E4=BF=AE=E5=A4=8D=E4=BA=86?=
=?UTF-8?q?=E5=8D=95=E4=BA=BA=E5=AF=BC=E5=87=BA=E6=97=B6=E5=A4=B4=E5=83=8F?=
=?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index fdac261..de349ac 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -187,7 +187,7 @@ class ChildThread(QThread):
if is_chatroom:
avatar = f"./avatar/{message[12].wxid}.png"
else:
- avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ avatar = f"./avatar/{MePC().wxid if is_send else self.contact.wxid}.png"
if is_chatroom:
if is_send:
displayname = MePC().name
@@ -227,7 +227,7 @@ class ChildThread(QThread):
if is_chatroom:
avatar = f"./avatar/{message[12].wxid}.png"
else:
- avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ avatar = f"./avatar/{MePC().wxid if is_send else self.contact.wxid}.png"
if is_chatroom:
if is_send:
displayname = MePC().name
@@ -278,7 +278,7 @@ class ChildThread(QThread):
if is_chatroom:
avatar = f"./avatar/{message[12].wxid}.png"
else:
- avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ avatar = f"./avatar/{MePC().wxid if is_send else self.contact.wxid}.png"
if is_chatroom:
if is_send:
displayname = MePC().name
@@ -320,7 +320,7 @@ class ChildThread(QThread):
if is_chatroom:
avatar = f"./avatar/{message[12].wxid}.png"
else:
- avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ avatar = f"./avatar/{MePC().wxid if is_send else self.contact.wxid}.png"
if is_chatroom:
if is_send:
displayname = MePC().name
@@ -374,7 +374,7 @@ class ChildThread(QThread):
if is_chatroom:
avatar = f"./avatar/{message[12].wxid}.png"
else:
- avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ avatar = f"./avatar/{MePC().wxid if is_send else self.contact.wxid}.png"
if is_chatroom:
if is_send:
displayname = MePC().name
@@ -442,7 +442,7 @@ class ChildThread(QThread):
if is_chatroom:
avatar = f"./avatar/{message[12].wxid}.png"
else:
- avatar = "./avatar/" + ('myhead.png' if is_send else 'tahead.png')
+ avatar = f"./avatar/{MePC().wxid if is_send else self.contact.wxid}.png"
if is_chatroom:
if is_send:
displayname = MePC().name
@@ -801,7 +801,7 @@ body{
word-break:normal;
}
.chat-refer-right {
- margin-right: 55px;
+ margin-right: 15px;
}
.chat-refer-left{
margin-left: 15px;
@@ -867,9 +867,16 @@ body{
.content-wrapper {
display: flex;
flex-direction: column;
+}
+
+.content-wrapper-left {
align-items: baseline;
}
+.content-wrapper-right {
+ align-items: flex-end;
+}
+
.displayname {
margin-left: 13px;
margin-left: 13px;
@@ -1133,7 +1140,7 @@ html_end = '''
const side = message.is_send ? "right" : "left";
if (message.type == 1) {
// displayname 和 bubble
- messageContent.className = "content-wrapper";
+ messageContent.className = `content-wrapper content-wrapper-${side}`;
if (message.is_chatroom && !message.is_send) {
messageContent.appendChild(displayNameBox(message));
}
@@ -1150,7 +1157,7 @@ html_end = '''
}
else if (message.type == 3) {
// displayname 和 img
- messageContent.className = "content-wrapper";
+ messageContent.className = `content-wrapper content-wrapper-${side}`;
if (message.is_chatroom && !message.is_send) {
messageContent.appendChild(displayNameBox(message));
}
@@ -1163,7 +1170,7 @@ html_end = '''
}
else if (message.type == 43) {
// displayname 和 video
- messageContent.className = "content-wrapper";
+ messageContent.className = `content-wrapper content-wrapper-${side}`;
if (message.is_chatroom && !message.is_send) {
messageContent.appendChild(displayNameBox(message));
}
@@ -1177,7 +1184,7 @@ html_end = '''
else if (message.type == 49) {
if (message.sub_type == 57) {
// displayname 和 bubble 和 refer
- messageContent.className = "content-wrapper";
+ messageContent.className = `content-wrapper content-wrapper-${side}`;
if (message.is_chatroom && !message.is_send) {
messageContent.appendChild(displayNameBox(message));
}
@@ -1194,7 +1201,7 @@ html_end = '''
}
else if (message.type == 34) {
// displayname 和 转的文字 和 audio
- messageContent.className = "content-wrapper";
+ messageContent.className = `content-wrapper content-wrapper-${side}`;
if (message.is_chatroom && !message.is_send) {
messageContent.appendChild(displayNameBox(message));
}
From bc6a479b4d700ca409a36acf1dd34f8f9bd53aa4 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 19:45:11 +0800
Subject: [PATCH 14/15] =?UTF-8?q?=E8=B0=83=E6=95=B4=E9=9F=B3=E9=A2=91?=
=?UTF-8?q?=E6=A0=87=E7=AD=BE=E7=9A=84=E4=BD=8D=E7=BD=AE=EF=BC=8C=E7=BE=8E?=
=?UTF-8?q?=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index de349ac..35a9037 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -902,10 +902,11 @@ body{
max-width: 350px;
}
.chat-audio{
- max-width: 300px;
+ max-width: 400px;
}
audio{
- right: 25px;
+ margin-left: 9px;
+ margin-right: 9px;
}
.input-area{
border-top:0.5px solid #e0e0e0;
From 9b2d1891d581d2124b6232c2ece05769fa5c0fb6 Mon Sep 17 00:00:00 2001
From: STDquantum <405720329@qq.com>
Date: Sun, 17 Dec 2023 20:19:29 +0800
Subject: [PATCH 15/15] =?UTF-8?q?=E8=A7=86=E9=A2=91=E5=92=8C=E9=9F=B3?=
=?UTF-8?q?=E9=A2=91=E6=92=AD=E6=94=BE=E4=B8=80=E4=B8=AA=EF=BC=8C=E5=85=B6?=
=?UTF-8?q?=E4=BB=96=E7=9A=84=E5=B0=B1=E6=9A=82=E5=81=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/DataBase/output_pc.py | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/app/DataBase/output_pc.py b/app/DataBase/output_pc.py
index 35a9037..0330610 100644
--- a/app/DataBase/output_pc.py
+++ b/app/DataBase/output_pc.py
@@ -1220,6 +1220,7 @@ html_end = '''
}
document.querySelector("#chat-container").scrollTop = 0;
updatePaginationInfo();
+ refreshMediaListener();
}
function prevPage() {
@@ -1256,6 +1257,39 @@ html_end = '''
// 初始化页面
renderPage(currentPage);
+
+ function refreshMediaListener() {
+ const audioTags = document.querySelectorAll('audio');
+ const videoTags = document.querySelectorAll('video');
+
+ audioTags.forEach(audio => {
+ audio.addEventListener('play', function () {
+ pauseOtherMedia(audio);
+ });
+ });
+ videoTags.forEach(video => {
+ video.addEventListener('play', function () {
+ pauseOtherMedia(video);
+ });
+ });
+
+ function pauseOtherMedia(currentMedia) {
+ const audioTags = document.querySelectorAll('audio');
+ const videoTags = document.querySelectorAll('video');
+ audioTags.forEach(media => {
+ if (media !== currentMedia && !media.paused) {
+ media.pause();
+ }
+ });
+ videoTags.forEach(media => {
+ if (media !== currentMedia && !media.paused) {
+ media.pause();
+ }
+ });
+ }
+ }
+
+ refreshMediaListener();