diff --git a/Whatsapp_Chat_Exporter/__main__.py b/Whatsapp_Chat_Exporter/__main__.py index f360de1..7109e5e 100644 --- a/Whatsapp_Chat_Exporter/__main__.py +++ b/Whatsapp_Chat_Exporter/__main__.py @@ -293,6 +293,14 @@ def main(): default=None, help="Use with --enrich-from-vcards. When numbers in the vcf file does not have a country code, this will be used. 1 is for US, 66 for Thailand etc. Most likely use the number of your own country" ) + parser.add_argument( + "--txt", + dest="text_format", + nargs='?', + default=None, + type=str, + const="result", + help="Export chats in text format similar to what WhatsApp officially provided (default if present: result/)") args = parser.parse_args() @@ -305,8 +313,8 @@ def main(): parser.error("You must define only one device type.") if not args.android and not args.ios and not args.exported and not args.import_json: parser.error("You must define the device type.") - if args.no_html and not args.json: - parser.error("You must either specify a JSON output file or enable HTML output.") + if args.no_html and not args.json and not args.text_format: + parser.error("You must either specify a JSON output file, text file output directory or enable HTML output.") if args.import_json and (args.android or args.ios or args.exported or args.no_html): parser.error("You can only use --import with -j and without --no-html, -a, -i, -e.") elif args.import_json and not os.path.isfile(args.json): @@ -548,6 +556,10 @@ def main(): args.filter_empty ) + if args.text_format: + print("Writing text file...") + android_handler.create_txt(data, args.text_format) + if args.json and not args.import_json: if args.filter_empty: data = {k: v for k, v in data.items() if not chat_is_empty(v)} diff --git a/Whatsapp_Chat_Exporter/android_handler.py b/Whatsapp_Chat_Exporter/android_handler.py index dc62477..6a119a6 100644 --- a/Whatsapp_Chat_Exporter/android_handler.py +++ b/Whatsapp_Chat_Exporter/android_handler.py @@ -10,6 +10,7 @@ from mimetypes import MimeTypes from markupsafe import escape as htmle from hashlib import sha256 from base64 import b64decode, b64encode +from datetime import datetime from Whatsapp_Chat_Exporter.data_model import ChatStore, Message from Whatsapp_Chat_Exporter.utility import MAX_SIZE, ROW_SIZE, DbType, convert_time_unit, determine_metadata from Whatsapp_Chat_Exporter.utility import rendering, Crypt, Device, get_file_name, setup_template, JidType @@ -830,3 +831,38 @@ def create_html( print(f"Generating chats...({current}/{total_row_number})", end="\r") print(f"Generating chats...({total_row_number}/{total_row_number})", end="\r") + + +def create_txt(data, output): + os.makedirs(output, exist_ok=True) + for jik, chat in data.items(): + if chat.name is not None: + contact = chat.name.replace('/', '') + else: + contact = jik.replace('+', '') + output_file = os.path.join(output, f"{contact}.txt") + with open(output_file, "w", encoding="utf8") as f: + for message in chat.messages.values(): + date = datetime.fromtimestamp(message.timestamp).date() + if message.meta and message.mime != "media": + continue # Skip any metadata in text format + if message.from_me: + name = "You" + else: + name = message.sender if message.sender else contact + prefix = f"[{date} {message.time}] {name}: " + prefix_length = len(prefix) + if message.media and ("/" in message.mime or message.mime == "media"): + if message.data == "The media is missing": + message_text = "" + else: + message_text = f"" + else: + if message.data is None: + message_text = "" + else: + message_text = message.data.replace('
', f'\n{" " * prefix_length}') + if message.caption is not None: + message_text += "\n" + ' ' * len(prefix) + message.caption.replace('
', f'\n{" " * prefix_length}') + f.write(f"{prefix}{message_text}\n") +