From 959b0929c978dd25ab6417a9785a2600d36808fe Mon Sep 17 00:00:00 2001 From: John Hyla Date: Wed, 14 Jan 2026 09:39:48 -0800 Subject: [PATCH 1/3] Fix MIME guessing --- scripts/ilapfuncs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/ilapfuncs.py b/scripts/ilapfuncs.py index 896a64eb..70cfc7da 100644 --- a/scripts/ilapfuncs.py +++ b/scripts/ilapfuncs.py @@ -328,7 +328,9 @@ def check_in_media(file_path, name="", converted_file_path=False, force_type=Non file_info = Context.get_seeker().file_infos.get(extraction_path) if file_info: media_id = hashlib.sha1(f"{file_info.source_path}".encode()).hexdigest() - return _check_in_media(media_id, file_path, False, name, converted_file_path=converted_file_path, + with open(extraction_path, "rb") as f: + file_data = f.read() + return _check_in_media(media_id, file_path, False, name, media_data=file_data, converted_file_path=converted_file_path, force_type=force_type, force_extension=force_extension, force_creation_date=force_creation_date, force_modification_date=force_modification_date) return None From ef126d8b1035f3b563de8675821a0801b3040a0b Mon Sep 17 00:00:00 2001 From: John Hyla Date: Wed, 14 Jan 2026 17:18:25 -0800 Subject: [PATCH 2/3] Fixed json skips and attachments --- scripts/artifacts/discordChats.py | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/scripts/artifacts/discordChats.py b/scripts/artifacts/discordChats.py index 3eec8462..b50487d2 100644 --- a/scripts/artifacts/discordChats.py +++ b/scripts/artifacts/discordChats.py @@ -8,7 +8,7 @@ "requirements": "none", "category": "Discord", "notes": "", - "paths": ('*/activation_record.plist', '*/com.hammerandchisel.discord/fsCachedData/*', '*/Library/Caches/com.hackemist.SDImageCache/default/*', '*/Library/Caches/kv-storage/@account*/a*'), + "paths": ('*/activation_record.plist', '*/com.hammerandchisel.discord/fsCachedData/*', '*/Library/Caches/kv-storage/@account*/a*', '*/Library/Caches/com.hackemist.SDImageCache/default/*'), "output_types": "standard", # or ["html", "tsv", "timeline", "lava"] "artifact_icon": "message-circle" } @@ -21,7 +21,7 @@ import os import re -from scripts.ilapfuncs import artifact_processor, logfunc, media_to_html, get_resolution_for_model_id, get_file_path, get_sqlite_db_records +from scripts.ilapfuncs import artifact_processor, logfunc, media_to_html, get_resolution_for_model_id, get_file_path, get_sqlite_db_records, check_in_media @artifact_processor def discordChats(context): @@ -116,16 +116,18 @@ def process_json(jsonfinal): #Check if a file by this name was found if any(proxy_url_md5 in string for string in files_found): #If Yes, generate thumbnail - attachmentsArray.append(media_to_html(proxy_url_md5, files_found, report_folder)) + #attachmentsArray.append(media_to_html(proxy_url_md5, files_found, report_folder)) + attachment_file = check_in_media(proxy_url_md5) + attachmentsArray.append([attachment_file, proxy_url_md5]) else: #If no, show the URL, but also show the filename we think should exist in case it can be located elsewhere - attachmentsArray.append(a.get('proxy_url') + f' ({proxy_url_md5})') + attachmentsArray.append([None, a.get('proxy_url') + f' ({proxy_url_md5})']) else: #Resolution was not found, just show the URL - attachmentsArray.append(a.get('proxy_url')) + attachmentsArray.append([None, a.get('proxy_url')]) #Combine all attachments - attachments = "
".join(attachmentsArray) + #attachments = "
".join(attachmentsArray) else: attachments = '' @@ -171,7 +173,14 @@ def process_json(jsonfinal): if timestamp == '': pass else: - data_list.append((timestamp, editedtimestamp, username, botuser, content, attachments, userid, channelid, emdeddedauthor, authorurl, authoriconurl, embededurl, embededdescript, footertext, footericonurl, pathedtail)) + if len(attachmentsArray) > 0: + for attach in attachmentsArray: + data_list.append((timestamp, editedtimestamp, username, botuser, content, attach[0], attach[1], userid, channelid, emdeddedauthor, authorurl, authoriconurl, embededurl, embededdescript, footertext, footericonurl, pathedtail)) + else: + data_list.append( + (timestamp, editedtimestamp, username, botuser, content, None, None, userid, channelid, + emdeddedauthor, authorurl, authoriconurl, embededurl, embededdescript, footertext, footericonurl, + pathedtail)) #First find modelID and screen resolution resolution = None @@ -210,13 +219,13 @@ def process_json(jsonfinal): source_path = get_file_path(files_found, "a") try: - if not file_found.endswith('activation_record.plist') and os.path.isfile(file_found) and file_found != source_path: + if not file_found.endswith('activation_record.plist') and os.path.isfile(file_found) and file_found != source_path and 'com.hackemist.SDImageCache' not in file_found: with open(file_found, "r", encoding="utf-8") as f_in: for jsondata in f_in: jsonfinal = json.loads(jsondata) if isinstance(jsonfinal, list): - jsonfinal = jsonfinal[0] - process_json(jsonfinal) + for json_record in jsonfinal: + process_json(json_record) elif source_path: query = '''select data from messages0''' @@ -233,7 +242,7 @@ def process_json(jsonfinal): except ValueError as e: logfunc(f"Error parsing JSON from {file_found}: {str(e)}") - data_headers = (('Timestamp', 'datetime'), ('Edited Timestamp', 'datetime'), 'Username', 'Bot?', 'Content', 'Attachments', + data_headers = (('Timestamp', 'datetime'), ('Edited Timestamp', 'datetime'), 'Username', 'Bot?', 'Content', ('Attachment', 'media'), 'Attachment Link', 'User ID', 'Channel ID', 'Embedded Author', 'Author URL', 'Author Icon URL', 'Embedded URL', 'Embedded Script', 'Footer Text', 'Footer Icon URL', 'Source File') return data_headers, data_list, 'See source file(s) below:' \ No newline at end of file From 6926b1ff542bf213b27bb604019c160b114fec99 Mon Sep 17 00:00:00 2001 From: John Hyla Date: Fri, 16 Jan 2026 15:52:02 -0800 Subject: [PATCH 3/3] cleanup --- scripts/artifacts/discordChats.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/scripts/artifacts/discordChats.py b/scripts/artifacts/discordChats.py index b50487d2..270600a1 100644 --- a/scripts/artifacts/discordChats.py +++ b/scripts/artifacts/discordChats.py @@ -21,13 +21,12 @@ import os import re -from scripts.ilapfuncs import artifact_processor, logfunc, media_to_html, get_resolution_for_model_id, get_file_path, get_sqlite_db_records, check_in_media +from scripts.ilapfuncs import artifact_processor, logfunc, get_resolution_for_model_id, get_file_path, get_sqlite_db_records, check_in_media @artifact_processor def discordChats(context): files_found = context.get_files_found() - report_folder = context.get_report_folder() - + def reduceSize(width: int, height: int, max_width: int, max_height: int) -> (int, int): if width > height: if width > max_width: @@ -125,11 +124,6 @@ def process_json(jsonfinal): else: #Resolution was not found, just show the URL attachmentsArray.append([None, a.get('proxy_url')]) - - #Combine all attachments - #attachments = "
".join(attachmentsArray) - else: - attachments = '' if 'embeds' in jsonfinal: if len(jsonfinal['embeds']) > 0: