From 2b49ac2e41439beff25d2d017920806c3e8d5b0c Mon Sep 17 00:00:00 2001 From: KnugiHK <24708955+KnugiHK@users.noreply.github.com> Date: Mon, 12 Feb 2024 18:00:26 +0800 Subject: [PATCH] Add date filter for iOS #82 --- Whatsapp_Chat_Exporter/__main__.py | 26 ++++++++++++++++++++---- Whatsapp_Chat_Exporter/extract_iphone.py | 26 +++++++++++++++--------- 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/Whatsapp_Chat_Exporter/__main__.py b/Whatsapp_Chat_Exporter/__main__.py index 9efe721..4c0b0ec 100644 --- a/Whatsapp_Chat_Exporter/__main__.py +++ b/Whatsapp_Chat_Exporter/__main__.py @@ -10,7 +10,7 @@ import glob from Whatsapp_Chat_Exporter import extract_exported, extract_iphone from Whatsapp_Chat_Exporter import extract, extract_iphone_media from Whatsapp_Chat_Exporter.data_model import ChatStore -from Whatsapp_Chat_Exporter.utility import Crypt, DbType, check_update, import_from_json +from Whatsapp_Chat_Exporter.utility import APPLE_TIME, Crypt, DbType, check_update, import_from_json from argparse import ArgumentParser, SUPPRESS from datetime import datetime from sys import exit @@ -250,13 +250,31 @@ def main(): start, end = args.filter_date.split(" - ") start = int(datetime.strptime(start, args.filter_date_format).timestamp()) end = int(datetime.strptime(end, args.filter_date_format).timestamp()) - args.filter_date = f"BETWEEN {start}000 AND {end}000" + if start < 1009843200 or end < 1009843200: + print("WhatsApp was developed in 2009...") + exit(1) + if start > end: + print("The start date cannot be a moment after the end date.") + exit(1) + if args.android: + args.filter_date = f"BETWEEN {start}000 AND {end}000" + elif args.iphone: + args.filter_date = f"BETWEEN {start - APPLE_TIME} AND {end - APPLE_TIME}" else: _timestamp = int(datetime.strptime(args.filter_date[2:], args.filter_date_format).timestamp()) + if _timestamp < 1009843200: + print("WhatsApp was developed in 2009...") + exit(1) if args.filter_date[:2] == "> ": - args.filter_date = f">= {_timestamp}000" + if args.android: + args.filter_date = f">= {_timestamp}000" + elif args.iphone: + args.filter_date = f">= {_timestamp - APPLE_TIME}" elif args.filter_date[:2] == "< ": - args.filter_date = f"<= {_timestamp}000" + if args.android: + args.filter_date = f"<= {_timestamp}000" + elif args.iphone: + args.filter_date = f"<= {_timestamp - APPLE_TIME}" else: print("Unsupported date format. See https://wts.knugi.dev/filter.html") exit(1) diff --git a/Whatsapp_Chat_Exporter/extract_iphone.py b/Whatsapp_Chat_Exporter/extract_iphone.py index 97cb2ca..d8f739f 100644 --- a/Whatsapp_Chat_Exporter/extract_iphone.py +++ b/Whatsapp_Chat_Exporter/extract_iphone.py @@ -24,7 +24,7 @@ def contacts(db, data): content = c.fetchone() -def messages(db, data, media_folder, timezone_offset): +def messages(db, data, media_folder, timezone_offset, range): c = db.cursor() # Get contacts c.execute("""SELECT count() FROM ZWACHATSESSION""") @@ -65,11 +65,10 @@ def messages(db, data, media_folder, timezone_offset): content = c.fetchone() # Get message history - c.execute("""SELECT count() FROM ZWAMESSAGE""") + c.execute(f"""SELECT count() FROM ZWAMESSAGE {f'WHERE ZMESSAGEDATE {range}' if range is not None else ''}""") total_row_number = c.fetchone()[0] print(f"Processing messages...(0/{total_row_number})", end="\r") - - c.execute("""SELECT ZCONTACTJID, + c.execute(f"""SELECT ZCONTACTJID, ZWAMESSAGE.Z_PK, ZISFROMME, ZMESSAGEDATE, @@ -86,6 +85,7 @@ def messages(db, data, media_folder, timezone_offset): ON ZWAMESSAGE.Z_PK = ZWAMEDIAITEM.ZMESSAGE INNER JOIN ZWACHATSESSION ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK + {f'WHERE ZMESSAGEDATE {range}' if range is not None else ''} ORDER BY ZMESSAGEDATE ASC;""") i = 0 content = c.fetchone() @@ -188,14 +188,18 @@ def messages(db, data, media_folder, timezone_offset): f"Processing messages...({total_row_number}/{total_row_number})", end="\r") -def media(db, data, media_folder): +def media(db, data, media_folder, range): c = db.cursor() # Get media - c.execute("""SELECT count() FROM ZWAMEDIAITEM""") + c.execute(f"""SELECT count() + FROM ZWAMEDIAITEM + INNER JOIN ZWAMESSAGE + ON ZWAMEDIAITEM.ZMESSAGE = ZWAMESSAGE.Z_PK + {f'WHERE ZMESSAGEDATE {range}' if range is not None else ''}""") total_row_number = c.fetchone()[0] print(f"\nProcessing media...(0/{total_row_number})", end="\r") i = 0 - c.execute("""SELECT ZCONTACTJID, + c.execute(f"""SELECT ZCONTACTJID, ZMESSAGE, ZMEDIALOCALPATH, ZMEDIAURL, @@ -208,6 +212,7 @@ def media(db, data, media_folder): INNER JOIN ZWACHATSESSION ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK WHERE ZMEDIALOCALPATH IS NOT NULL + {f'AND ZWAMESSAGE.ZMESSAGEDATE {range}' if range is not None else ''} ORDER BY ZCONTACTJID ASC""") content = c.fetchone() mime = MimeTypes() @@ -251,9 +256,9 @@ def media(db, data, media_folder): f"Processing media...({total_row_number}/{total_row_number})", end="\r") -def vcard(db, data, media_folder): +def vcard(db, data, media_folder, range): c = db.cursor() - c.execute("""SELECT DISTINCT ZWAVCARDMENTION.ZMEDIAITEM, + c.execute(f"""SELECT DISTINCT ZWAVCARDMENTION.ZMEDIAITEM, ZWAMEDIAITEM.ZMESSAGE, ZCONTACTJID, ZVCARDNAME, @@ -264,7 +269,8 @@ def vcard(db, data, media_folder): INNER JOIN ZWAMESSAGE ON ZWAMEDIAITEM.ZMESSAGE = ZWAMESSAGE.Z_PK INNER JOIN ZWACHATSESSION - ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK;""") + ON ZWAMESSAGE.ZCHATSESSION = ZWACHATSESSION.Z_PK + {f'WHERE ZWAMESSAGE.ZMESSAGEDATE {range}' if range is not None else ''};""") contents = c.fetchall() total_row_number = len(contents) print(f"\nProcessing vCards...(0/{total_row_number})", end="\r")