Spaces:
Sleeping
Sleeping
import pandas as pd | |
import re | |
import smtplib | |
from email.mime.text import MIMEText | |
from email.mime.multipart import MIMEMultipart | |
import streamlit as st | |
import os | |
from datetime import datetime | |
# Function to validate email using regular expression | |
def is_valid_email(email): | |
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zAZ0-9.-]+\.[a-zA-Z]{2,}$' | |
return re.match(pattern, email) is not None | |
# Function to validate email via SMTP server | |
def check_smtp_validity(email, smtp_server='smtp.gmail.com', smtp_port=587, sender_email='[email protected]', sender_password='your_email_password'): | |
try: | |
server = smtplib.SMTP(smtp_server, smtp_port) | |
server.starttls() | |
server.login(sender_email, sender_password) | |
msg = MIMEMultipart() | |
msg['From'] = sender_email | |
msg['To'] = email | |
msg['Subject'] = 'Congratulations! You’ve won a prize!' | |
body = 'Click this link to claim your prize: http://example.com' | |
msg.attach(MIMEText(body, 'plain')) | |
server.sendmail(sender_email, email, msg.as_string()) | |
server.quit() | |
return 'valid' | |
except smtplib.SMTPRecipientsRefused: | |
return 'invalid' | |
except Exception as e: | |
return 'invalid' | |
# Function to read different types of files | |
def read_file(file): | |
if file.name.endswith('.xls') or file.name.endswith('.xlsx'): | |
return pd.read_excel(file) | |
elif file.name.endswith('.csv'): | |
return pd.read_csv(file) | |
elif file.name.endswith('.ods'): | |
return pd.read_excel(file, engine="odf") | |
else: | |
st.error("Unsupported file format. Please upload a valid Excel (.xls, .xlsx), CSV, or ODS file.") | |
return None | |
# Function to validate emails and save results to a new file | |
def verify_emails(input_df, output_file, sender_email, sender_password, batch_start, batch_size=500): | |
try: | |
# Process only a batch of 500 emails per day | |
batch_df = input_df.iloc[batch_start:batch_start + batch_size] | |
# Validate the emails in the batch | |
batch_df['status'] = batch_df['emails'].apply(lambda email: check_smtp_validity(email, sender_email=sender_email, sender_password=sender_password)) | |
# Save the result to output file | |
if output_file.endswith('.csv'): | |
batch_df.to_csv(output_file, index=False) | |
elif output_file.endswith('.ods'): | |
batch_df.to_excel(output_file, index=False, engine='odf') | |
else: | |
batch_df.to_excel(output_file, index=False) | |
return batch_df, batch_start + len(batch_df) | |
except Exception as e: | |
st.error(f"Error: {e}") | |
return None, batch_start | |
# Function to send email with results as attachment | |
def send_email_result(output_file, recipient_email, sender_email, sender_password): | |
try: | |
# Create the email message | |
msg = MIMEMultipart() | |
msg['From'] = sender_email | |
msg['To'] = recipient_email | |
msg['Subject'] = 'Email Validation Results' | |
body = 'Please find the attached email validation results.' | |
msg.attach(MIMEText(body, 'plain')) | |
# Attach the output file (Excel with validation results) | |
with open(output_file, 'rb') as attachment: | |
part = MIMEText(attachment.read(), 'base64', 'utf-8') | |
part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(output_file)) | |
msg.attach(part) | |
# Send the email | |
with smtplib.SMTP('smtp.gmail.com', 587) as server: | |
server.starttls() | |
server.login(sender_email, sender_password) | |
server.sendmail(sender_email, recipient_email, msg.as_string()) | |
st.success(f"Results successfully sent to {recipient_email}") | |
except Exception as e: | |
st.error(f"Error sending email: {e}") | |
# Function to load settings (sender email, app password, recipient email) | |
def load_settings(): | |
if os.path.exists("settings.txt"): | |
with open("settings.txt", "r") as f: | |
settings = f.read().splitlines() | |
return settings | |
return None | |
# Function to save settings (sender email, app password, recipient email) | |
def save_settings(sender_email, sender_password, recipient_email): | |
with open("settings.txt", "w") as f: | |
f.write(f"{sender_email}\n{sender_password}\n{recipient_email}") | |
# Function to load progress (last processed email index) | |
def load_progress(): | |
if os.path.exists("progress.txt"): | |
with open("progress.txt", "r") as f: | |
return int(f.read().strip()) | |
return 0 | |
# Function to save progress (last processed email index) | |
def save_progress(progress): | |
with open("progress.txt", "w") as f: | |
f.write(str(progress)) | |
# Streamlit App | |
def main(): | |
st.title("Email Validation App") | |
# Display instructions to create a Gmail App Password | |
st.markdown(""" | |
**To send emails using your Gmail account, you need to generate an App Password:** | |
1. Go to [Google App Passwords](https://myaccount.google.com/apppasswords). | |
2. Sign in to your Google account if prompted. | |
3. Under "Select App," choose **Other (Custom name)** from the dropdown list. | |
4. Enter a name for the app (e.g., "Email Validation App") and click **Generate**. | |
5. Copy the generated password and paste it into the "App Password" field in this app. | |
6. Use this App Password instead of your regular Gmail password when sending emails. | |
""") | |
# Load settings if they exist | |
settings = load_settings() | |
# Step 1: Upload the file (Excel, CSV, or ODS) only if settings are already saved | |
if settings: | |
st.info("Settings already saved. You can upload your email file to continue processing.") | |
else: | |
st.warning("No settings found. Please provide your Gmail credentials and recipient email first.") | |
uploaded_file = st.file_uploader("Upload your file with emails (Excel, CSV, or ODS)", type=["xls", "xlsx", "csv", "ods"]) | |
# Load the file and process emails only if it's uploaded | |
if uploaded_file: | |
input_df = read_file(uploaded_file) | |
if input_df is None: | |
return | |
# Ensure the file contains an 'emails' column | |
if 'emails' not in input_df.columns: | |
st.error("Error: 'emails' column not found in the uploaded file.") | |
return | |
# Step 2: Input Gmail credentials if not already saved | |
if not settings: | |
sender_email = st.text_input("Enter temporary Gmail ID", type="default") | |
sender_password = st.text_input("Enter Gmail App Password", type="password") | |
recipient_email = st.text_input("Enter recipient email for results", type="default") | |
if sender_email and sender_password and recipient_email: | |
if st.button("Save Settings"): | |
save_settings(sender_email, sender_password, recipient_email) | |
st.success("Settings saved. You can now upload your email file and continue processing.") | |
st.experimental_rerun() # Rerun the app to load the new settings and show the process button | |
else: | |
# Use saved settings | |
sender_email, sender_password, recipient_email = settings | |
# Process emails in batches of 500 | |
batch_start = load_progress() | |
output_file = f"output_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}" | |
if uploaded_file.name.endswith('.csv'): | |
output_file += '.csv' | |
elif uploaded_file.name.endswith('.ods'): | |
output_file += '.ods' | |
else: | |
output_file += '.xlsx' | |
# After saving settings, now show the "Process Next Batch" button | |
if st.button("Process Next Batch"): | |
batch_df, new_progress = verify_emails(input_df, output_file, sender_email, sender_password, batch_start) | |
if batch_df is not None: | |
save_progress(new_progress) | |
send_email_result(output_file, recipient_email, sender_email, sender_password) | |
st.success(f"Processed and sent results for batch {batch_start // 500 + 1}. Progress saved.") | |
else: | |
st.error("Error processing the batch.") | |
if __name__ == "__main__": | |
if not os.path.exists("uploaded_files"): | |
os.makedirs("uploaded_files") | |
main() | |