import sqlite3 import json import sys import os import re import base64 def approve_and_move_email(email_id): # Connect to the source and destination databases review_db_path = os.path.join(os.environ.get('WORKSPACE_ROOT', '.'), 'Database/EmailsUnderReview/emailsUnderReview.db') outbox_db_path = os.path.join(os.environ.get('WORKSPACE_ROOT', '.'), 'Database/EmailsSent/email_to_be_sent.db') # The new database try: # Open connections conn_review = sqlite3.connect(review_db_path) conn_outbox = sqlite3.connect(outbox_db_path) cursor_review = conn_review.cursor() cursor_outbox = conn_outbox.cursor() # 1. Ensure the destination table exists in the new database # We use the exact same schema, but change the default status cursor_outbox.execute(''' CREATE TABLE IF NOT EXISTS ready_emails ( id INTEGER PRIMARY KEY, body_json TEXT, timestamp DATETIME, followup_date DATETIME, status TEXT DEFAULT 'ready to be sent', company_name TEXT, generated_subject TEXT, company_email TEXT, Unique_application_id TEXT ) ''') # 2. Fetch the email from the review database cursor_review.execute(""" SELECT id, body_json, timestamp, followup_date, status, company_name, generated_subject, company_email, Unique_application_id FROM tracking WHERE id = ? """, (email_id,)) row = cursor_review.fetchone() if not row: print(json.dumps({"ok": False, "error": f"Email ID {email_id} not found."})) return False # Unpack the row data (row_id, body_json, timestamp, followup_date, current_status, company_name, generated_subject, company_email, unique_app_id) = row # 3. Process attachments, links, and clean the body_json payload def process_email_attachments(row_id, body_str): output_dir = os.path.join(os.environ.get('WORKSPACE_ROOT', '.'), f'metadatatracking/{row_id}') os.makedirs(output_dir, exist_ok=True) try: data = json.loads(body_str) except Exception: data = {} html_content = data.get("body", {}).get("generated_content", body_str) if not isinstance(html_content, str): html_content = str(html_content) img_pattern = re.compile(r']+src="data:image/([^;]+);base64,([^"]+)"[^>]*>') images_saved = [] def replacer(match): ext = match.group(1) b64_data = match.group(2) idx = len(images_saved) filename = f"image_{idx}.{ext}" filepath = os.path.join(output_dir, filename) try: with open(filepath, "wb") as f: f.write(base64.b64decode(b64_data)) images_saved.append(filename) # Replace src payload entirely with local path full_tag = match.group(0) original_src = f'data:image/{ext};base64,{b64_data}' return full_tag.replace(original_src, f'file://{filepath}') except Exception as e: return match.group(0) modified_html = img_pattern.sub(replacer, html_content) link_pattern = re.compile(r']+href="([^"]+)"') links_found = link_pattern.findall(modified_html) if "body" in data and isinstance(data["body"], dict): data["body"]["generated_content"] = modified_html else: data = modified_html # fallback final_body_str = json.dumps(data) if isinstance(data, dict) else data with open(os.path.join(output_dir, 'email_data.json'), "w") as f: json.dump({ "cleaned_html_body": modified_html, "images_attached": images_saved, "links_found": links_found }, f, indent=4) return final_body_str cleaned_body_json = process_email_attachments(row_id, body_json) # 4. Change status to the new requirement new_status = 'ready to be sent' # 5. Insert the complete row into the new database cursor_outbox.execute(""" INSERT INTO ready_emails (id, body_json, timestamp, followup_date, status, company_name, generated_subject, company_email, Unique_application_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) """, (row_id, cleaned_body_json, timestamp, followup_date, new_status, company_name, generated_subject, company_email, unique_app_id)) # 6. Delete the entry from the original database cursor_review.execute("DELETE FROM tracking WHERE id = ?", (email_id,)) # 7. Commit transactions on BOTH databases conn_outbox.commit() conn_review.commit() print(json.dumps({"ok": True, "message": f"Success: Email {email_id} has been moved to the outbox."})) return True except sqlite3.Error as e: # If any database error occurs, roll back both databases so data isn't lost print(json.dumps({"ok": False, "error": f"Database error occurred: {e}"})) if 'conn_outbox' in locals(): conn_outbox.rollback() if 'conn_review' in locals(): conn_review.rollback() return False finally: # Always close connections to free up the DB locks if 'conn_outbox' in locals(): conn_outbox.close() if 'conn_review' in locals(): conn_review.close() if __name__ == '__main__': try: input_data = sys.stdin.read().strip() if input_data: payload = json.loads(input_data) email_id = payload.get('id') if email_id is not None: approve_and_move_email(int(email_id)) else: print(json.dumps({"ok": False, "error": "No 'id' provided in input"})) else: print(json.dumps({"ok": False, "error": "No input provided"})) except Exception as e: print(json.dumps({"ok": False, "error": str(e)}))