基本解决加密表情包的解析问题

This commit is contained in:
STDquantum 2023-12-16 12:29:51 +08:00
parent 4815b31967
commit b1f42aa0bb
2 changed files with 101 additions and 15 deletions

View File

@ -284,7 +284,11 @@ class ChildThread(QThread):
timestamp = message[5] timestamp = message[5]
if self.output_type == Output.HTML: if self.output_type == Output.HTML:
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_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): if self.is_5_min(timestamp):
doc.write( doc.write(
f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},''' f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
@ -463,7 +467,7 @@ class ChildThread(QThread):
self.emoji(f, message) self.emoji(f, message)
elif type_ == 10000 and self.message_types.get(type_): elif type_ == 10000 and self.message_types.get(type_):
self.system_msg(f, message) 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) self.refermsg(f,message)
f.write(html_end) f.write(html_end)
f.close() f.close()

View File

@ -11,7 +11,8 @@ emoji.py
import os import os
import traceback import traceback
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import sqlite3
import threading
import requests import requests
from app.log import log, logger from app.log import log, logger
@ -43,7 +44,10 @@ def get_image_format(header):
def parser_xml(xml_string): def parser_xml(xml_string):
assert type(xml_string) == str assert type(xml_string) == str
# Parse the XML string # 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') emoji = root.find('./emoji')
# Accessing attributes of the 'emoji' element # Accessing attributes of the 'emoji' element
fromusername = emoji.get('fromusername') fromusername = emoji.get('fromusername')
@ -61,10 +65,67 @@ def parser_xml(xml_string):
'height': height, 'height': height,
'cdnurl': cdnurl, 'cdnurl': cdnurl,
'thumburl': thumburl if thumburl else 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): def download(url, output_dir, name, thumb=False):
if not url: if not url:
return ':/icons/icons/404.png' 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 '' prefix = 'th_' if thumb else ''
file_path = os.path.join(output_path, prefix + md5 + f) file_path = os.path.join(output_path, prefix + md5 + f)
if os.path.exists(file_path): if os.path.exists(file_path):
print('表情包已存在') # print('表情包已存在', file_path)
return file_path return file_path
url = emoji_info['thumburl'] if thumb else emoji_info['cdnurl'] url = emoji_info['thumburl'] if thumb else emoji_info['cdnurl']
print("下载表情包ing:", url) if not url or url == "":
emoji_path = download(url, output_path, md5, thumb) url = emoji_db.get_emoji_url(md5)
return emoji_path 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: except:
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
return "" return ""
if __name__ == '__main__': if __name__ == '__main__':
xml_string = '<msg><emoji fromusername = "wxid_0o18ef858vnu22" tousername = "wxid_27hqbq7vx5hf22" type="2" idbuffer="media:0_0" md5="71ce49ed3ce9e57e43e07f802983bf45" len = "352588" productid="com.tencent.xin.emoticon.person.stiker_1678703862259eb01f2ef4a313" androidmd5="71ce49ed3ce9e57e43e07f802983bf45" androidlen="352588" s60v3md5 = "71ce49ed3ce9e57e43e07f802983bf45" s60v3len="352588" s60v5md5 = "71ce49ed3ce9e57e43e07f802983bf45" s60v5len="352588" cdnurl = "http://wxapp.tc.qq.com/262/20304/stodownload?m=71ce49ed3ce9e57e43e07f802983bf45&amp;filekey=30350201010421301f020201060402535a041071ce49ed3ce9e57e43e07f802983bf45020305614c040d00000004627466730000000132&amp;hy=SZ&amp;storeid=263ffa00b000720d03274c5820000010600004f50535a1ca0c950b64287022&amp;bizid=1023" designerid = "" thumburl = "http://mmbiz.qpic.cn/mmemoticon/ajNVdqHZLLDSKTMRgM8agiadpFhKz9IJ3cD5Ra2sTROibOaShdt3D4z6PfE92WkjQY/0" encrypturl = "http://wxapp.tc.qq.com/262/20304/stodownload?m=cbaae1d847aac6389652b65562bacaa2&amp;filekey=30350201010421301f020201060402535a0410cbaae1d847aac6389652b65562bacaa20203056150040d00000004627466730000000132&amp;hy=SZ&amp;storeid=263ffa00b0008d8223274c5820000010600004f50535a17b82910b64764739&amp;bizid=1023" aeskey= "7051ab2a34442dec63434832463f45ce" externurl = "http://wxapp.tc.qq.com/262/20304/stodownload?m=960f68693454dfa64b9966ca5d70dbd3&amp;filekey=30340201010420301e020201060402535a0410960f68693454dfa64b9966ca5d70dbd3020221a0040d00000004627466730000000132&amp;hy=SZ&amp;storeid=26423dbe3000793a8720e40de0000010600004f50535a1d40c950b71be0a50&amp;bizid=1023" externmd5 = "41895664fc5a77878e2155fc96209a19" width= "240" height= "240" tpurl= "" tpauthkey= "" attachedtext= "" attachedtextcolor= "" lensid= "" emojiattr= "" linkid= "" desc= "ChEKB2RlZmF1bHQSBuWNlee6rw==" ></emoji> </msg>' db_path = r"..\DataBase\Msg\Emotion.db"
res1 = parser_xml(xml_string) xml_string = '<msg><emoji fromusername = "wxid_05rvkbftizq822" tousername = "wxid_lhbdvh3cnn4h22" type="2" androidmd5="882A3BC82838CBD4DD419F62A22EA244" androidlen="2469" aeskey="" encrypturl="" externurl="" externmd5=""></emoji></msg>'
print(res1, res1['md5']) print(get_emoji(xml_string, thumb=False, output_path="."))
# ET.fromstring()
# print(res1, res1['md5'])
# download(res1['cdnurl'], "./data/emoji/", res1['md5']) # download(res1['cdnurl'], "./data/emoji/", res1['md5'])
# download(res1['thumburl'], "./data/emoji/", res1['md5'], True) # download(res1['thumburl'], "./data/emoji/", res1['md5'], True)
print(get_emoji(xml_string, True)) # print(get_emoji(xml_string, True))
print(get_emoji(xml_string, False)) # 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 # http://vweixinf.tc.qq.com/110/20403/stodownload?m=3a4d439aba02dce4834b2c54e9f15597&filekey=3043020101042f302d02016e0402534804203361346434333961626130326463653438333462326335346539663135353937020213f0040d00000004627466730000000131&hy=SH&storeid=323032313037323030373236313130303039653236646365316535316534383236386234306230303030303036653033303034666233&ef=3&bizid=1022