适配微信4.0.3正式版,修复图片解析失败的问题
This commit is contained in:
@@ -194,7 +194,7 @@ class Msg(DataBaseBase):
|
|||||||
@param username_:
|
@param username_:
|
||||||
@return:
|
@return:
|
||||||
"""
|
"""
|
||||||
sql = f'''SELECT DISTINCT strftime('%Y-%m-%d',create_time,'unixepoch','localtime') AS date
|
sql = f'''SELECT DISTINCT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') AS date
|
||||||
from MSG
|
from MSG
|
||||||
where StrTalker=?
|
where StrTalker=?
|
||||||
ORDER BY date desc;
|
ORDER BY date desc;
|
||||||
|
|||||||
@@ -195,7 +195,30 @@ class OpenIMMsgDB(DataBaseBase):
|
|||||||
|
|
||||||
def get_messages_by_type(self, username: str, type_: MessageType,
|
def get_messages_by_type(self, username: str, type_: MessageType,
|
||||||
time_range: Tuple[int | float | str | date, int | float | str | date] = None, ):
|
time_range: Tuple[int | float | str | date, int | float | str | date] = None, ):
|
||||||
return self.get_messages_by_type(self.DB.cursor, username, type_, time_range)
|
return self._get_messages_by_type(self.DB.cursor, username, type_, time_range)
|
||||||
|
|
||||||
|
def _get_messages_calendar(self, cursor, username):
|
||||||
|
"""
|
||||||
|
获取某个人的聊天日历列表
|
||||||
|
@param username_:
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
sql = f'''SELECT DISTINCT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') AS date
|
||||||
|
from PublicMsg
|
||||||
|
where StrTalker=?
|
||||||
|
ORDER BY date desc;
|
||||||
|
'''
|
||||||
|
cursor.execute(sql, [username])
|
||||||
|
result = cursor.fetchall()
|
||||||
|
return (data[0] for data in result)
|
||||||
|
|
||||||
|
def get_messages_calendar(self, username):
|
||||||
|
res = []
|
||||||
|
r1 = self._get_messages_calendar(self.DB.cursor(), username)
|
||||||
|
if r1:
|
||||||
|
res.extend(r1)
|
||||||
|
res.sort()
|
||||||
|
return res
|
||||||
|
|
||||||
def merge(self, db_path):
|
def merge(self, db_path):
|
||||||
if not (os.path.exists(db_path) or os.path.isfile(db_path)):
|
if not (os.path.exists(db_path) or os.path.isfile(db_path)):
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class PublicMsg(DataBaseBase):
|
|||||||
|
|
||||||
def get_messages_by_type(self, username: str, type_: MessageType,
|
def get_messages_by_type(self, username: str, type_: MessageType,
|
||||||
time_range: Tuple[int | float | str | date, int | float | str | date] = None, ):
|
time_range: Tuple[int | float | str | date, int | float | str | date] = None, ):
|
||||||
return self.get_messages_by_type(self.DB.cursor, username, type_, time_range)
|
return self._get_messages_by_type(self.DB.cursor, username, type_, time_range)
|
||||||
|
|
||||||
def get_sport_score_by_name(self, username,
|
def get_sport_score_by_name(self, username,
|
||||||
time_range: Tuple[int | float | str | date, int | float | str | date] = None, ):
|
time_range: Tuple[int | float | str | date, int | float | str | date] = None, ):
|
||||||
@@ -110,7 +110,7 @@ class PublicMsg(DataBaseBase):
|
|||||||
@param username_:
|
@param username_:
|
||||||
@return:
|
@return:
|
||||||
"""
|
"""
|
||||||
sql = f'''SELECT DISTINCT strftime('%Y-%m-%d',create_time,'unixepoch','localtime') AS date
|
sql = f'''SELECT DISTINCT strftime('%Y-%m-%d',CreateTime,'unixepoch','localtime') AS date
|
||||||
from PublicMsg
|
from PublicMsg
|
||||||
where StrTalker=?
|
where StrTalker=?
|
||||||
ORDER BY date desc;
|
ORDER BY date desc;
|
||||||
|
|||||||
@@ -51,5 +51,6 @@ class EmotionDB(DataBaseBase):
|
|||||||
print(f"数据库操作错误: {traceback.format_exc()}")
|
print(f"数据库操作错误: {traceback.format_exc()}")
|
||||||
self.DB.rollback()
|
self.DB.rollback()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -182,6 +182,10 @@ class HardLinkDB(DataBaseBase):
|
|||||||
if os.path.exists(os.path.join(Me().wx_dir, path1)):
|
if os.path.exists(os.path.join(Me().wx_dir, path1)):
|
||||||
return path1
|
return path1
|
||||||
else:
|
else:
|
||||||
|
data_image = f'{message.file_name}_h.dat' if message.file_name else f'{local_id}_{create_time}_h.dat'
|
||||||
|
path1 = os.path.join(image_root_path, dir1, dir2, dir0, data_image)
|
||||||
|
if os.path.exists(os.path.join(Me().wx_dir, path1)):
|
||||||
|
return path1
|
||||||
data_image = f'{message.file_name}.dat' if message.file_name else f'{local_id}_{create_time}.dat'
|
data_image = f'{message.file_name}.dat' if message.file_name else f'{local_id}_{create_time}.dat'
|
||||||
path1 = os.path.join(image_root_path, dir1, dir2, dir0, data_image)
|
path1 = os.path.join(image_root_path, dir1, dir2, dir0, data_image)
|
||||||
return path1
|
return path1
|
||||||
|
|||||||
@@ -121,15 +121,22 @@ def decode_dat(xor_key: int, file_path, out_path, dst_name='') -> str | bytes:
|
|||||||
|
|
||||||
|
|
||||||
def get_decode_code_v4(wx_dir):
|
def get_decode_code_v4(wx_dir):
|
||||||
|
"""
|
||||||
|
从微信文件夹里找到异或密钥,原理详见:https://blog.lc044.love/post/16
|
||||||
|
:param wx_dir:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
cache_dir = os.path.join(wx_dir, 'cache')
|
cache_dir = os.path.join(wx_dir, 'cache')
|
||||||
if not os.path.isdir(wx_dir) or not os.path.exists(cache_dir):
|
if not os.path.isdir(wx_dir) or not os.path.exists(cache_dir):
|
||||||
raise ValueError(f'微信路径输入错误,请检查:{wx_dir}')
|
raise ValueError(f'微信路径输入错误,请检查:{wx_dir}')
|
||||||
|
|
||||||
|
def find_xor_key(dir0):
|
||||||
ok_flag = False
|
ok_flag = False
|
||||||
for root, dirs, files in os.walk(cache_dir):
|
for root, dirs, files in os.walk(dir0):
|
||||||
if ok_flag:
|
if ok_flag:
|
||||||
break
|
break
|
||||||
for file in files:
|
for file in files:
|
||||||
if file.endswith(".dat"):
|
if file.endswith("_t.dat"):
|
||||||
# 构造源文件和目标文件的完整路径
|
# 构造源文件和目标文件的完整路径
|
||||||
src_file_path = os.path.join(root, file)
|
src_file_path = os.path.join(root, file)
|
||||||
with open(src_file_path, 'rb') as f:
|
with open(src_file_path, 'rb') as f:
|
||||||
@@ -146,6 +153,18 @@ def get_decode_code_v4(wx_dir):
|
|||||||
return xor_key[0]
|
return xor_key[0]
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
xor_key_ = find_xor_key(cache_dir)
|
||||||
|
if xor_key_ != -1:
|
||||||
|
return xor_key_
|
||||||
|
else:
|
||||||
|
dirs = ['temp', 'msg']
|
||||||
|
for dir_name in dirs:
|
||||||
|
cache_dir = os.path.join(wx_dir, dir_name)
|
||||||
|
xor_key_ = find_xor_key(cache_dir)
|
||||||
|
if xor_key_ != -1:
|
||||||
|
return xor_key_
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def get_image_type(data: bytes) -> str:
|
def get_image_type(data: bytes) -> str:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ class Me:
|
|||||||
self.small_head_img_url = ''
|
self.small_head_img_url = ''
|
||||||
self.nickname = self.name
|
self.nickname = self.name
|
||||||
self.remark = self.nickname
|
self.remark = self.nickname
|
||||||
self.xor_key = -1
|
self.xor_key = 0
|
||||||
|
|
||||||
def to_json(self) -> dict:
|
def to_json(self) -> dict:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
@Description :
|
@Description :
|
||||||
"""
|
"""
|
||||||
import base64
|
import base64
|
||||||
|
import re
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import xmltodict
|
import xmltodict
|
||||||
@@ -26,9 +27,23 @@ def parser_emoji(xml_content):
|
|||||||
'height': 0,
|
'height': 0,
|
||||||
'desc': ''
|
'desc': ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def extract_msg(text):
|
||||||
|
# 使用正则表达式匹配第一个 <msg> 标签及其内容
|
||||||
|
pattern = r'(<msg>.*?</msg>)'
|
||||||
|
match = re.search(pattern, text)
|
||||||
|
return f'<msg>{match.group(0)}</msg>' if match else ''
|
||||||
|
|
||||||
xml_content = xml_content.strip().replace('&', '&')
|
xml_content = xml_content.strip().replace('&', '&')
|
||||||
try:
|
try:
|
||||||
xml_dict = xmltodict.parse(xml_content)
|
xml_dict = xmltodict.parse(xml_content)
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
xml_content = extract_msg(xml_content)
|
||||||
|
xml_dict = xmltodict.parse(xml_content)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
emoji_dic = xml_dict.get('msg', {}).get('emoji', {})
|
emoji_dic = xml_dict.get('msg', {}).get('emoji', {})
|
||||||
if '@androidmd5' in emoji_dic:
|
if '@androidmd5' in emoji_dic:
|
||||||
md5 = emoji_dic.get('@androidmd5', '')
|
md5 = emoji_dic.get('@androidmd5', '')
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from wxManager.log import logger
|
|||||||
def get_image_type(header):
|
def get_image_type(header):
|
||||||
# 根据文件头判断图片类型
|
# 根据文件头判断图片类型
|
||||||
if header.startswith(b'\xFF\xD8'):
|
if header.startswith(b'\xFF\xD8'):
|
||||||
return 'jepg'
|
return 'jpeg'
|
||||||
elif header.startswith(b'\x89PNG'):
|
elif header.startswith(b'\x89PNG'):
|
||||||
return 'png'
|
return 'png'
|
||||||
elif header[:6] in (b'GIF87a', b'GIF89a'):
|
elif header[:6] in (b'GIF87a', b'GIF89a'):
|
||||||
|
|||||||
Reference in New Issue
Block a user