Spaces:
Runtime error
Runtime error
File size: 7,092 Bytes
e0339c8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
import smtplib
import pandas as pd
import time
import openpyxl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.utils import formataddr
import streamlit as st
import os
import base64
# Set Streamlit app title and page configuration
st.set_page_config(page_title="Email Sender and Tracker", layout="wide")
# Email Sender Function
def send_email(server, sender_email, sender_password, receiver_email, subject, email_content):
message = MIMEMultipart()
message["From"] = formataddr(("AI Consultant", sender_email))
message["To"] = receiver_email
message["Subject"] = subject
email_content_formatted = email_content.replace("\n", "<br><br>")
html_content = f"""
<html>
<head>
<style>
body {{
font-family: Arial, sans-serif;
font-size: 14px;
line-height: 1.6;
margin: 0;
padding: 0;
}}
.email-container {{
max-width: 600px;
margin: 0 auto;
padding: 20px;
}}
.email-header {{
text-align: center;
margin-bottom: 20px;
}}
.email-header h2 {{
color: #333333;
font-size: 24px;
font-weight: 700;
line-height: 1.2;
margin: 0;
}}
.email-content {{
background-color: #f9f9f9;
padding: 20px;
text-align: justify;
}}
.email-content p {{
color: #555555;
font-size: 16px;
line-height: 1.6;
margin: 0 0 10px;
}}
.email-content hr {{
border: none;
border-top: 1px solid #dddddd;
margin: 20px 0;
}}
.logo {{
display: block;
margin: 0 auto;
width: 60px;
}}
</style>
</head>
<body>
<div class="email-container">
<div class="email-header">
<h2>{subject}</h2>
</div>
<div class="email-content">
{email_content_formatted}
<hr>
</div>
<img src="cid:logo_image" alt="Logo" class="logo">
</div>
</body>
</html>
"""
# Attach the logo image
logo_path = "AIConsultantBlackSmall.png"
with open(logo_path, "rb") as logo_file:
logo_image = MIMEImage(logo_file.read())
logo_image.add_header("Content-ID", "<logo_image>")
message.attach(logo_image)
message.attach(MIMEText(html_content, "html"))
email_message = message.as_string().encode("utf-8")
try:
server.sendmail(sender_email, receiver_email, email_message)
return True
except smtplib.SMTPException:
return False
# Main Function
def main():
st.title("Email Sender and Tracker")
# Sidebar Inputs
sender_email = st.sidebar.text_input("Your Email")
sender_password = st.sidebar.text_input("Your Email Password", type="password")
subject = st.sidebar.text_input("Subject")
email_content = st.sidebar.text_area("Email Content", height=400)
# Recipients File Selection
recipients_file_path = st.sidebar.file_uploader("Select Excel file with recipient emails", type=["xlsx", "xls"])
# Send Button
if st.sidebar.button("Send"):
if not sender_email or not sender_password or not subject or not email_content:
st.warning("Incomplete Information. Please fill in all the required fields.")
elif not recipients_file_path:
st.warning("Missing Recipients File. Please select an Excel file with recipient emails.")
else:
st.info("Sending emails...")
df = pd.read_excel(recipients_file_path)
receiver_emails = df.iloc[:, 0].tolist()
successful_emails = []
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
try:
server.login(sender_email, sender_password)
except smtplib.SMTPAuthenticationError:
st.error("Authentication Failed. Username and password not accepted.")
return
progress_bar = st.progress(0)
progress_text = st.empty()
for i, receiver_email in enumerate(receiver_emails[:1000], 1): # Send at most 200 emails from the list
if send_email(server, sender_email, sender_password, receiver_email, subject, email_content):
successful_emails.append(receiver_email)
time.sleep(0.1) # Delay between sending emails
progress_bar.progress(i / 1000)
progress_text.text(f"Sending email {i}")
st.success("Emails sent successfully!")
# Save Successful Emails
if successful_emails:
try:
workbook = openpyxl.Workbook()
worksheet = workbook.active
for email in successful_emails:
worksheet.append([email])
# Specify the custom file name
custom_file_name = "successful_emails.xlsx"
excel_file_path = custom_file_name
workbook.save(excel_file_path)
workbook.close()
# Get the absolute file path
absolute_file_path = os.path.abspath(excel_file_path)
# Rename the file
new_file_name = "successful_emails.xlsx"
os.rename(absolute_file_path, new_file_name)
st.info(f"Successful emails saved to Excel file: {new_file_name}")
# Add button to save or download the Excel file
download_button_str = create_download_button(new_file_name, new_file_name)
st.markdown(download_button_str, unsafe_allow_html=True)
except Exception as e:
st.error(f"Error saving successful emails: {str(e)}")
else:
st.warning("No successful emails to save.")
# Helper function to create download button HTML string
def create_download_button(file_path, file_name):
button_str = f'<a href="data:application/octet-stream;base64,{get_base64_encoded(file_path)}" download="{file_name}" class="stButton">Download Successful Emails</a>'
return button_str
# Helper function to encode the file to base64
def get_base64_encoded(file_path):
with open(file_path, "rb") as file:
encoded = base64.b64encode(file.read()).decode()
return encoded
# Run the Streamlit app
if __name__ == "__main__":
main()
|