Implement chat filter with group msg sender for iOS #85

This commit is contained in:
KnugiHK
2024-09-15 10:55:43 +08:00
parent 75c429fe22
commit 04000c78e2
3 changed files with 54 additions and 37 deletions

View File

@@ -183,8 +183,8 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat):
ON messages.key_remote_jid = jid.raw_string ON messages.key_remote_jid = jid.raw_string
WHERE 1=1 WHERE 1=1
{f'AND timestamp {filter_date}' if filter_date is not None else ''} {f'AND timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "messages.remote_resource"], "jid")} {get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "messages.remote_resource"], "jid", "android")}
{get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "messages.remote_resource"], "jid")}""") {get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "messages.remote_resource"], "jid", "android")}""")
except sqlite3.OperationalError: except sqlite3.OperationalError:
c.execute(f"""SELECT count() c.execute(f"""SELECT count()
@@ -197,8 +197,8 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat):
ON jid_group._id = message.sender_jid_row_id ON jid_group._id = message.sender_jid_row_id
WHERE 1=1 WHERE 1=1
{f'AND timestamp {filter_date}' if filter_date is not None else ''} {f'AND timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["jid.raw_string", "jid_group.raw_string"], "jid")} {get_chat_condition(filter_chat[0], True, ["jid.raw_string", "jid_group.raw_string"], "jid", "android")}
{get_chat_condition(filter_chat[1], False, ["jid.raw_string", "jid_group.raw_string"], "jid")}""") {get_chat_condition(filter_chat[1], False, ["jid.raw_string", "jid_group.raw_string"], "jid", "android")}""")
total_row_number = c.fetchone()[0] total_row_number = c.fetchone()[0]
print(f"Processing messages...(0/{total_row_number})", end="\r") print(f"Processing messages...(0/{total_row_number})", end="\r")
@@ -254,8 +254,8 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat):
ON receipt_user.message_row_id = messages._id ON receipt_user.message_row_id = messages._id
WHERE messages.key_remote_jid <> '-1' WHERE messages.key_remote_jid <> '-1'
{f'AND messages.timestamp {filter_date}' if filter_date is not None else ''} {f'AND messages.timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "messages.remote_resource"], "jid_global")} {get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "messages.remote_resource"], "jid_global", "android")}
{get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "messages.remote_resource"], "jid_global")} {get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "messages.remote_resource"], "jid_global", "android")}
GROUP BY messages._id GROUP BY messages._id
ORDER BY messages.timestamp ASC;""" ORDER BY messages.timestamp ASC;"""
) )
@@ -322,8 +322,8 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat):
ON receipt_user.message_row_id = message._id ON receipt_user.message_row_id = message._id
WHERE key_remote_jid <> '-1' WHERE key_remote_jid <> '-1'
{f'AND message.timestamp {filter_date}' if filter_date is not None else ''} {f'AND message.timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["key_remote_jid", "jid_group.raw_string"], "jid_global")} {get_chat_condition(filter_chat[0], True, ["key_remote_jid", "jid_group.raw_string"], "jid_global", "android")}
{get_chat_condition(filter_chat[1], False, ["key_remote_jid", "jid_group.raw_string"], "jid_global")} {get_chat_condition(filter_chat[1], False, ["key_remote_jid", "jid_group.raw_string"], "jid_global", "android")}
GROUP BY message._id;""" GROUP BY message._id;"""
) )
except Exception as e: except Exception as e:
@@ -500,8 +500,8 @@ def media(db, data, media_folder, filter_date, filter_chat, separate_media=True)
ON messages.key_remote_jid = jid.raw_string ON messages.key_remote_jid = jid.raw_string
WHERE 1=1 WHERE 1=1
{f'AND messages.timestamp {filter_date}' if filter_date is not None else ''} {f'AND messages.timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "remote_resource"], "jid")} {get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "remote_resource"], "jid", "android")}
{get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "remote_resource"], "jid")}""") {get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "remote_resource"], "jid", "android")}""")
except sqlite3.OperationalError: except sqlite3.OperationalError:
c.execute(f"""SELECT count() c.execute(f"""SELECT count()
FROM message_media FROM message_media
@@ -515,8 +515,8 @@ def media(db, data, media_folder, filter_date, filter_chat, separate_media=True)
ON jid_group._id = message.sender_jid_row_id ON jid_group._id = message.sender_jid_row_id
WHERE 1=1 WHERE 1=1
{f'AND message.timestamp {filter_date}' if filter_date is not None else ''} {f'AND message.timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["jid.raw_string", "jid_group.raw_string"], "jid")} {get_chat_condition(filter_chat[0], True, ["jid.raw_string", "jid_group.raw_string"], "jid", "android")}
{get_chat_condition(filter_chat[1], False, ["jid.raw_string", "jid_group.raw_string"], "jid")}""") {get_chat_condition(filter_chat[1], False, ["jid.raw_string", "jid_group.raw_string"], "jid", "android")}""")
total_row_number = c.fetchone()[0] total_row_number = c.fetchone()[0]
print(f"\nProcessing media...(0/{total_row_number})", end="\r") print(f"\nProcessing media...(0/{total_row_number})", end="\r")
i = 0 i = 0
@@ -538,8 +538,8 @@ def media(db, data, media_folder, filter_date, filter_chat, separate_media=True)
ON messages.key_remote_jid = jid.raw_string ON messages.key_remote_jid = jid.raw_string
WHERE jid.type <> 7 WHERE jid.type <> 7
{f'AND messages.timestamp {filter_date}' if filter_date is not None else ''} {f'AND messages.timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "remote_resource"], "jid")} {get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "remote_resource"], "jid", "android")}
{get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "remote_resource"], "jid")} {get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "remote_resource"], "jid", "android")}
ORDER BY messages.key_remote_jid ASC""" ORDER BY messages.key_remote_jid ASC"""
) )
except sqlite3.OperationalError: except sqlite3.OperationalError:
@@ -564,8 +564,8 @@ def media(db, data, media_folder, filter_date, filter_chat, separate_media=True)
ON jid_group._id = message.sender_jid_row_id ON jid_group._id = message.sender_jid_row_id
WHERE jid.type <> 7 WHERE jid.type <> 7
{f'AND message.timestamp {filter_date}' if filter_date is not None else ''} {f'AND message.timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["key_remote_jid", "jid_group.raw_string"], "jid")} {get_chat_condition(filter_chat[0], True, ["key_remote_jid", "jid_group.raw_string"], "jid", "android")}
{get_chat_condition(filter_chat[1], False, ["key_remote_jid", "jid_group.raw_string"], "jid")} {get_chat_condition(filter_chat[1], False, ["key_remote_jid", "jid_group.raw_string"], "jid", "android")}
ORDER BY jid.raw_string ASC""" ORDER BY jid.raw_string ASC"""
) )
content = c.fetchone() content = c.fetchone()
@@ -627,8 +627,8 @@ def vcard(db, data, media_folder, filter_date, filter_chat):
ON messages.key_remote_jid = jid.raw_string ON messages.key_remote_jid = jid.raw_string
WHERE 1=1 WHERE 1=1
{f'AND messages.timestamp {filter_date}' if filter_date is not None else ''} {f'AND messages.timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "remote_resource"], "jid")} {get_chat_condition(filter_chat[0], True, ["messages.key_remote_jid", "remote_resource"], "jid", "android")}
{get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "remote_resource"], "jid")} {get_chat_condition(filter_chat[1], False, ["messages.key_remote_jid", "remote_resource"], "jid", "android")}
ORDER BY messages.key_remote_jid ASC;""" ORDER BY messages.key_remote_jid ASC;"""
) )
except sqlite3.OperationalError: except sqlite3.OperationalError:
@@ -647,8 +647,8 @@ def vcard(db, data, media_folder, filter_date, filter_chat):
ON jid_group._id = message.sender_jid_row_id ON jid_group._id = message.sender_jid_row_id
WHERE 1=1 WHERE 1=1
{f'AND message.timestamp {filter_date}' if filter_date is not None else ''} {f'AND message.timestamp {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["key_remote_jid", "jid_group.raw_string"], "jid")} {get_chat_condition(filter_chat[0], True, ["key_remote_jid", "jid_group.raw_string"], "jid", "android")}
{get_chat_condition(filter_chat[1], False, ["key_remote_jid", "jid_group.raw_string"], "jid")} {get_chat_condition(filter_chat[1], False, ["key_remote_jid", "jid_group.raw_string"], "jid", "android")}
ORDER BY message.chat_row_id ASC;""" ORDER BY message.chat_row_id ASC;"""
) )
@@ -684,8 +684,8 @@ def calls(db, data, timezone_offset, filter_chat):
LEFT JOIN chat LEFT JOIN chat
ON call_log.jid_row_id = chat.jid_row_id ON call_log.jid_row_id = chat.jid_row_id
WHERE 1=1 WHERE 1=1
{get_chat_condition(filter_chat[0], True, ["jid.raw_string"], "jid")} {get_chat_condition(filter_chat[0], True, ["jid.raw_string"])}
{get_chat_condition(filter_chat[1], False, ["jid.raw_string"], "jid")}""") {get_chat_condition(filter_chat[1], False, ["jid.raw_string"])}""")
total_row_number = c.fetchone()[0] total_row_number = c.fetchone()[0]
if total_row_number == 0: if total_row_number == 0:
return return
@@ -706,8 +706,8 @@ def calls(db, data, timezone_offset, filter_chat):
LEFT JOIN chat LEFT JOIN chat
ON call_log.jid_row_id = chat.jid_row_id ON call_log.jid_row_id = chat.jid_row_id
WHERE 1=1 WHERE 1=1
{get_chat_condition(filter_chat[0], True, ["jid.raw_string"], "jid")} {get_chat_condition(filter_chat[0], True, ["jid.raw_string"])}
{get_chat_condition(filter_chat[1], False, ["jid.raw_string"], "jid")}""" {get_chat_condition(filter_chat[1], False, ["jid.raw_string"])}"""
) )
chat = ChatStore(Device.ANDROID, "WhatsApp Calls") chat = ChatStore(Device.ANDROID, "WhatsApp Calls")
content = c.fetchone() content = c.fetchone()

View File

@@ -78,10 +78,12 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat):
FROM ZWAMESSAGE FROM ZWAMESSAGE
INNER JOIN ZWACHATSESSION INNER JOIN ZWACHATSESSION
ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK
LEFT JOIN ZWAGROUPMEMBER
ON ZWAMESSAGE.ZGROUPMEMBER = ZWAGROUPMEMBER.Z_PK
WHERE 1=1 WHERE 1=1
{f'AND ZMESSAGEDATE {filter_date}' if filter_date is not None else ''} {f'AND ZMESSAGEDATE {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["ZWACHATSESSION.ZCONTACTJID"])} {get_chat_condition(filter_chat[0], True, ["ZWACHATSESSION.ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")}
{get_chat_condition(filter_chat[1], False, ["ZWACHATSESSION.ZCONTACTJID"])}""") {get_chat_condition(filter_chat[1], False, ["ZWACHATSESSION.ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")}""")
total_row_number = c.fetchone()[0] total_row_number = c.fetchone()[0]
print(f"Processing messages...(0/{total_row_number})", end="\r") print(f"Processing messages...(0/{total_row_number})", end="\r")
c.execute(f"""SELECT ZCONTACTJID, c.execute(f"""SELECT ZCONTACTJID,
@@ -103,8 +105,8 @@ def messages(db, data, media_folder, timezone_offset, filter_date, filter_chat):
ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK
WHERE 1=1 WHERE 1=1
{f'AND ZMESSAGEDATE {filter_date}' if filter_date is not None else ''} {f'AND ZMESSAGEDATE {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["ZCONTACTJID"])} {get_chat_condition(filter_chat[0], True, ["ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")}
{get_chat_condition(filter_chat[1], False, ["ZCONTACTJID"])} {get_chat_condition(filter_chat[1], False, ["ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")}
ORDER BY ZMESSAGEDATE ASC;""") ORDER BY ZMESSAGEDATE ASC;""")
i = 0 i = 0
content = c.fetchone() content = c.fetchone()
@@ -216,10 +218,12 @@ def media(db, data, media_folder, filter_date, filter_chat, separate_media=False
ON ZWAMEDIAITEM.ZMESSAGE = ZWAMESSAGE.Z_PK ON ZWAMEDIAITEM.ZMESSAGE = ZWAMESSAGE.Z_PK
INNER JOIN ZWACHATSESSION INNER JOIN ZWACHATSESSION
ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK
LEFT JOIN ZWAGROUPMEMBER
ON ZWAMESSAGE.ZGROUPMEMBER = ZWAGROUPMEMBER.Z_PK
WHERE 1=1 WHERE 1=1
{f'AND ZMESSAGEDATE {filter_date}' if filter_date is not None else ''} {f'AND ZMESSAGEDATE {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["ZWACHATSESSION.ZCONTACTJID"])} {get_chat_condition(filter_chat[0], True, ["ZWACHATSESSION.ZCONTACTJID","ZMEMBERJID"], "ZGROUPINFO", "ios")}
{get_chat_condition(filter_chat[1], False, ["ZWACHATSESSION.ZCONTACTJID"])} {get_chat_condition(filter_chat[1], False, ["ZWACHATSESSION.ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")}
""") """)
total_row_number = c.fetchone()[0] total_row_number = c.fetchone()[0]
print(f"\nProcessing media...(0/{total_row_number})", end="\r") print(f"\nProcessing media...(0/{total_row_number})", end="\r")
@@ -236,10 +240,12 @@ def media(db, data, media_folder, filter_date, filter_chat, separate_media=False
ON ZWAMEDIAITEM.ZMESSAGE = ZWAMESSAGE.Z_PK ON ZWAMEDIAITEM.ZMESSAGE = ZWAMESSAGE.Z_PK
INNER JOIN ZWACHATSESSION INNER JOIN ZWACHATSESSION
ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK
LEFT JOIN ZWAGROUPMEMBER
ON ZWAMESSAGE.ZGROUPMEMBER = ZWAGROUPMEMBER.Z_PK
WHERE ZMEDIALOCALPATH IS NOT NULL WHERE ZMEDIALOCALPATH IS NOT NULL
{f'AND ZWAMESSAGE.ZMESSAGEDATE {filter_date}' if filter_date is not None else ''} {f'AND ZWAMESSAGE.ZMESSAGEDATE {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["ZCONTACTJID"])} {get_chat_condition(filter_chat[0], True, ["ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")}
{get_chat_condition(filter_chat[1], False, ["ZCONTACTJID"])} {get_chat_condition(filter_chat[1], False, ["ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")}
ORDER BY ZCONTACTJID ASC""") ORDER BY ZCONTACTJID ASC""")
content = c.fetchone() content = c.fetchone()
mime = MimeTypes() mime = MimeTypes()
@@ -298,10 +304,12 @@ def vcard(db, data, media_folder, filter_date, filter_chat):
ON ZWAMEDIAITEM.ZMESSAGE = ZWAMESSAGE.Z_PK ON ZWAMEDIAITEM.ZMESSAGE = ZWAMESSAGE.Z_PK
INNER JOIN ZWACHATSESSION INNER JOIN ZWACHATSESSION
ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK
LEFT JOIN ZWAGROUPMEMBER
ON ZWAMESSAGE.ZGROUPMEMBER = ZWAGROUPMEMBER.Z_PK
WHERE 1=1 WHERE 1=1
{f'AND ZWAMESSAGE.ZMESSAGEDATE {filter_date}' if filter_date is not None else ''} {f'AND ZWAMESSAGE.ZMESSAGEDATE {filter_date}' if filter_date is not None else ''}
{get_chat_condition(filter_chat[0], True, ["ZCONTACTJID"])} {get_chat_condition(filter_chat[0], True, ["ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")}
{get_chat_condition(filter_chat[1], False, ["ZCONTACTJID"])};""") {get_chat_condition(filter_chat[1], False, ["ZCONTACTJID", "ZMEMBERJID"], "ZGROUPINFO", "ios")};""")
contents = c.fetchall() contents = c.fetchall()
total_row_number = len(contents) total_row_number = len(contents)
print(f"\nProcessing vCards...(0/{total_row_number})", end="\r") print(f"\nProcessing vCards...(0/{total_row_number})", end="\r")

View File

@@ -218,18 +218,27 @@ def get_file_name(contact: str, chat: ChatStore):
return sanitize_filename(file_name), name return sanitize_filename(file_name), name
def get_chat_condition(filter, include, columns, jid=None): def get_chat_condition(filter, include, columns, jid=None, platform=None):
if filter is not None: if filter is not None:
conditions = [] conditions = []
if len(columns) < 2 and jid is not None:
raise ValueError("There must be at least two elements in argument columns if jid is not None")
if jid is not None:
if platform == "android":
is_group = f"{jid}.type == 1"
elif platform == "ios":
is_group = f"{jid} IS NOT NULL"
else:
raise ValueError("Only android and ios are supported for argument platform if jid is not None")
for index, chat in enumerate(filter): for index, chat in enumerate(filter):
if include: if include:
conditions.append(f"{' OR' if index > 0 else ''} {columns[0]} LIKE '%{chat}%'") conditions.append(f"{' OR' if index > 0 else ''} {columns[0]} LIKE '%{chat}%'")
if len(columns) > 1: if len(columns) > 1:
conditions.append(f" OR ({columns[1]} LIKE '%{chat}%' AND {jid}.type == 1)") conditions.append(f" OR ({columns[1]} LIKE '%{chat}%' AND {is_group})")
else: else:
conditions.append(f"{' AND' if index > 0 else ''} {columns[0]} NOT LIKE '%{chat}%'") conditions.append(f"{' AND' if index > 0 else ''} {columns[0]} NOT LIKE '%{chat}%'")
if len(columns) > 1: if len(columns) > 1:
conditions.append(f" AND ({columns[1]} NOT LIKE '%{chat}%' AND {jid}.type == 1)") conditions.append(f" AND ({columns[1]} NOT LIKE '%{chat}%' AND {is_group})")
return f"AND ({' '.join(conditions)})" return f"AND ({' '.join(conditions)})"
else: else:
return "" return ""