Untitled
unknown
plain_text
a year ago
10 kB
5
Indexable
import pandas as pd
import smtplib
import tkinter as tk
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from docx import Document
from tkinter import filedialog
from tkinter import messagebox
from tkinter import ttk
from dotenv import load_dotenv
# Function to read text from a Word document and convert custom HTML-like tags to real HTML tags
def extract_text_from_word(docx_file_path):
doc = Document(docx_file_path)
extracted_text = ""
for para in doc.paragraphs:
para_text = para.text
extracted_text += para_text + "\n"
return extracted_text
# Function to convert a DataFrame to styled HTML
def dataframe_to_styled_html(df, merge_first_row=False):
table_style = (
"border-collapse: collapse; width: 65%; font-family: Arial, sans-serif; "
"font-size: 14px; text-align: center;"
)
header_style = (
"background-color: #6A0DAD; color: white; padding: 10px; border: 1px solid black;"
)
cell_style = "padding: 10px; border: 1px solid black;"
row_alt_style = "background-color: #f2f2f2;"
html_table = f'<table style="{table_style}">'
# Merge first row if requested
if merge_first_row:
html_table += f'<tr><td colspan="{len(df.columns)}" style="{header_style}">{df.columns[0]}</td></tr>'
else:
# Add table headers
html_table += "<tr>"
for col in df.columns:
html_table += f'<th style="{header_style}">{col}</th>'
html_table += "</tr>"
# Add table rows
for i, row in df.iterrows():
row_style = row_alt_style if i % 2 == 1 else ""
html_table += f'<tr style="{row_style}">'
for cell in row:
if pd.isna(cell):
cell_content = ""
else:
if isinstance(cell, float):
cell_content = f"{cell:.2%}" if 0 <= cell <= 1 else cell
else:
cell_content = cell
html_table += f'<td style="{cell_style}">{cell_content}</td>'
html_table += "</tr>"
html_table += "</table>"
return html_table
# Function to send bulk emails with text and tables
def send_bulk_emails_with_text_and_tables(
sender_email,
sender_password,
smtp_server,
smtp_port,
email_list_file,
table1_file,
table2_file,
text_file,
log_text_widget,
log_file
):
log_serial_number = 1
with open(log_file, 'a') as log_file_obj:
# Read the email list from an Excel file
email_data = pd.read_excel(email_list_file)
if "Email" not in email_data.columns or "Salutations" not in email_data.columns or "CC" not in email_data.columns:
log_text_widget.insert(tk.END, "The email list file must contain columns: 'Email', 'Salutations', and 'CC'.\n")
return
email_details = email_data[["Email", "Salutations", "CC"]]
if text_file.endswith(".docx"):
email_text = extract_text_from_word(text_file)
else:
log_text_widget.insert(tk.END, "Unsupported file format. Use a .docx file for the text.\n")
return
table1_df = pd.read_excel(table1_file)
table2_df = pd.read_excel(table2_file)
table1_html = dataframe_to_styled_html(table1_df)
table2_html = dataframe_to_styled_html(table2_df, merge_first_row=True)
if "{{ TABLE_1 }}" in email_text:
email_text = email_text.replace("{{ TABLE_1 }}", table1_html)
else:
log_text_widget.insert(tk.END, "Placeholder {{ TABLE_1 }} not found in the text.\n")
if "{{ TABLE_2 }}" in email_text:
email_text = email_text.replace("{{ TABLE_2 }}", table2_html)
else:
log_text_widget.insert(tk.END, "Placeholder {{ TABLE_2 }} not found in the text.\n")
email_body_html = f"""
<html>
<body>
{email_text}
</body>
</html>
"""
try:
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(sender_email, sender_password)
for _, row in email_details.iterrows():
try:
recipients = row["Email"].split(",")
salutation = row["Salutations"]
cc_list = row["CC"].split(",") if pd.notna(row["CC"]) else []
personalized_text = email_body_html.replace("{{ Salutations }}", salutation)
msg = MIMEMultipart()
msg["From"] = sender_email
msg["To"] = ", ".join(recipients)
msg["Cc"] = ", ".join(cc_list)
msg["Subject"] = "Your Wealth Management Summary"
msg.attach(MIMEText(personalized_text, "html"))
all_recipients = recipients + cc_list
server.sendmail(sender_email, all_recipients, msg.as_string())
log_text_widget.insert(tk.END, f"{log_serial_number}. Email sent successfully to {', '.join(recipients)}, CC: {', '.join(cc_list)}\n")
log_text_widget.yview(tk.END)
log_file_obj.write(f"{log_serial_number}. Email sent successfully to {', '.join(recipients)}, CC: {', '.join(cc_list)}\n")
except Exception as e:
log_text_widget.insert(tk.END, f"{log_serial_number}. Failed to send email to {', '.join(recipients)}: {e}\n")
log_text_widget.yview(tk.END)
log_file_obj.write(f"{log_serial_number}. Failed to send email to {', '.join(recipients)}: {e}\n")
log_serial_number += 1
except Exception as e:
log_text_widget.insert(tk.END, f"Failed to connect to the SMTP server: {e}\n")
log_text_widget.yview(tk.END)
log_file_obj.write(f"Failed to connect to the SMTP server: {e}\n")
# Remaining code (UI setup) remains the same.
# Function to browse file
def browse_file(entry):
# Open file dialog to select a file and set the path to the entry
file_path = filedialog.askopenfilename(title="Select a file", filetypes=[("Excel files", "*.xlsx"), ("Text files", "*.txt"), ("PDF files", "*.pdf"), ("Word files", "*.docx")])
if file_path:
entry.delete(0, tk.END) # Clear existing content
entry.insert(0, file_path) # Insert selected file path
# Function to handle the send email button click
def send_email_ui():
sender_email = sender_email_entry.get()
sender_password = sender_password_entry.get()
email_list_file = email_list_entry.get()
table1_file = table1_entry.get()
table2_file = table2_entry.get()
text_file = text_file_entry.get()
smtp_server = "smtp.gmail.com"
smtp_port = 587
log_file = "email_log.txt" # Log file path
if not all([sender_email, sender_password, email_list_file, table1_file, table2_file, text_file]):
messagebox.showerror("Missing Information", "Please fill in all fields before sending.")
else:
# Call the send_bulk_emails_with_text_and_tables function with the inputs
send_bulk_emails_with_text_and_tables(
sender_email,
sender_password,
smtp_server,
smtp_port,
email_list_file,
table1_file,
table2_file,
text_file,
log_text_widget,
log_file
)
messagebox.showinfo("Task Complete", "All emails have been sent successfully!")
#env
load_dotenv()
sender_password = os.getenv("SENDER_PASSWORD", "")
sender_email = os.getenv("SENDER_EMAIL", "")
#print(os.getenv("SENDER_PASSWORD",""))
# Create the main window
root = tk.Tk()
root.title("Pygmalion Wealth") # Set the window title
# Sender Email
tk.Label(root, text="Sender Email:").grid(row=0, column=0, padx=10, pady=5)
sender_email_entry = tk.Entry(root, width=40)
sender_email_entry.insert(0, sender_email)
sender_email_entry.grid(row=0, column=1, padx=10, pady=5)
# Sender Password
tk.Label(root, text="Sender Password:").grid(row=1, column=0, padx=10, pady=5)
sender_password_entry = tk.Entry(root, width=40, show="*")
sender_password_entry.insert(0,sender_password)
sender_password_entry.grid(row=1, column=1, padx=10, pady=5)
# Email List File
tk.Label(root, text="Email List File:").grid(row=2, column=0, padx=10, pady=5)
email_list_entry = tk.Entry(root, width=40)
email_list_entry.grid(row=2, column=1, padx=10, pady=5)
tk.Button(root, text="Browse", command=lambda: browse_file(email_list_entry)).grid(row=2, column=2, padx=10, pady=5)
# Table 1 File
tk.Label(root, text="Table 1 File:").grid(row=3, column=0, padx=10, pady=5)
table1_entry = tk.Entry(root, width=40)
table1_entry.grid(row=3, column=1, padx=10, pady=5)
tk.Button(root, text="Browse", command=lambda: browse_file(table1_entry)).grid(row=3, column=2, padx=10, pady=5)
# Table 2 File
tk.Label(root, text="Table 2 File:").grid(row=4, column=0, padx=10, pady=5)
table2_entry = tk.Entry(root, width=40)
table2_entry.grid(row=4, column=1, padx=10, pady=5)
tk.Button(root, text="Browse", command=lambda: browse_file(table2_entry)).grid(row=4, column=2, padx=10, pady=5)
# Text File
tk.Label(root, text="Text File:").grid(row=5, column=0, padx=10, pady=5)
text_file_entry = tk.Entry(root, width=40)
text_file_entry.grid(row=5, column=1, padx=10, pady=5)
tk.Button(root, text="Browse", command=lambda: browse_file(text_file_entry)).grid(row=5, column=2, padx=10, pady=5)
# Log Text Widget (for display)
log_text_widget = tk.Text(root, height=10, width=80, wrap=tk.WORD, font=("Arial", 10))
log_text_widget.grid(row=6, column=0, columnspan=3, padx=10, pady=5)
# Send Email Button
send_button = tk.Button(root, text="Send Emails", command=send_email_ui)
send_button.grid(row=7, column=0, padx=10, pady=10)
#exit program button
exit_button = tk.Button(root, text="Exit", command=root.quit)
exit_button.grid(row=7, column=3, padx=10, pady=10)
# Start the Tkinter event loop
root.mainloop()Editor is loading...
Leave a Comment