shivvamm commited on
Commit
1d91262
1 Parent(s): 2a6bbc8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +207 -0
app.py ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import re
3
+ import smtplib
4
+ from email.mime.text import MIMEText
5
+ from email.mime.multipart import MIMEMultipart
6
+ import streamlit as st
7
+ import os
8
+ from datetime import datetime
9
+
10
+ # Function to validate email using regular expression
11
+ def is_valid_email(email):
12
+ pattern = r'^[a-zA-Z0-9._%+-]+@[a-zAZ0-9.-]+\.[a-zA-Z]{2,}$'
13
+ return re.match(pattern, email) is not None
14
+
15
+ # Function to validate email via SMTP server
16
+ def check_smtp_validity(email, smtp_server='smtp.gmail.com', smtp_port=587, sender_email='[email protected]', sender_password='your_email_password'):
17
+ try:
18
+ server = smtplib.SMTP(smtp_server, smtp_port)
19
+ server.starttls()
20
+ server.login(sender_email, sender_password)
21
+
22
+ msg = MIMEMultipart()
23
+ msg['From'] = sender_email
24
+ msg['To'] = email
25
+ msg['Subject'] = 'Congratulations! You’ve won a prize!'
26
+
27
+ body = 'Click this link to claim your prize: http://example.com'
28
+ msg.attach(MIMEText(body, 'plain'))
29
+
30
+ server.sendmail(sender_email, email, msg.as_string())
31
+ server.quit()
32
+
33
+ return 'valid'
34
+
35
+ except smtplib.SMTPRecipientsRefused:
36
+ return 'invalid'
37
+ except Exception as e:
38
+ return 'invalid'
39
+
40
+ # Function to read different types of files
41
+ def read_file(file):
42
+ if file.name.endswith('.xls') or file.name.endswith('.xlsx'):
43
+ return pd.read_excel(file)
44
+ elif file.name.endswith('.csv'):
45
+ return pd.read_csv(file)
46
+ elif file.name.endswith('.ods'):
47
+ return pd.read_excel(file, engine="odf")
48
+ else:
49
+ st.error("Unsupported file format. Please upload a valid Excel (.xls, .xlsx), CSV, or ODS file.")
50
+ return None
51
+
52
+ # Function to validate emails and save results to a new file
53
+ def verify_emails(input_df, output_file, sender_email, sender_password, batch_start, batch_size=500):
54
+ try:
55
+ # Process only a batch of 500 emails per day
56
+ batch_df = input_df.iloc[batch_start:batch_start + batch_size]
57
+
58
+ # Validate the emails in the batch
59
+ batch_df['status'] = batch_df['emails'].apply(lambda email: check_smtp_validity(email, sender_email=sender_email, sender_password=sender_password))
60
+
61
+ # Save the result to output file
62
+ if output_file.endswith('.csv'):
63
+ batch_df.to_csv(output_file, index=False)
64
+ elif output_file.endswith('.ods'):
65
+ batch_df.to_excel(output_file, index=False, engine='odf')
66
+ else:
67
+ batch_df.to_excel(output_file, index=False)
68
+
69
+ return batch_df, batch_start + len(batch_df)
70
+
71
+ except Exception as e:
72
+ st.error(f"Error: {e}")
73
+ return None, batch_start
74
+
75
+ # Function to send email with results as attachment
76
+ def send_email_result(output_file, recipient_email, sender_email, sender_password):
77
+ try:
78
+ # Create the email message
79
+ msg = MIMEMultipart()
80
+ msg['From'] = sender_email
81
+ msg['To'] = recipient_email
82
+ msg['Subject'] = 'Email Validation Results'
83
+
84
+ body = 'Please find the attached email validation results.'
85
+ msg.attach(MIMEText(body, 'plain'))
86
+
87
+ # Attach the output file (Excel with validation results)
88
+ with open(output_file, 'rb') as attachment:
89
+ part = MIMEText(attachment.read(), 'base64', 'utf-8')
90
+ part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(output_file))
91
+ msg.attach(part)
92
+
93
+ # Send the email
94
+ with smtplib.SMTP('smtp.gmail.com', 587) as server:
95
+ server.starttls()
96
+ server.login(sender_email, sender_password)
97
+ server.sendmail(sender_email, recipient_email, msg.as_string())
98
+
99
+ st.success(f"Results successfully sent to {recipient_email}")
100
+
101
+ except Exception as e:
102
+ st.error(f"Error sending email: {e}")
103
+
104
+ # Function to load settings (sender email, app password, recipient email)
105
+ def load_settings():
106
+ if os.path.exists("settings.txt"):
107
+ with open("settings.txt", "r") as f:
108
+ settings = f.read().splitlines()
109
+ return settings
110
+ return None
111
+
112
+ # Function to save settings (sender email, app password, recipient email)
113
+ def save_settings(sender_email, sender_password, recipient_email):
114
+ with open("settings.txt", "w") as f:
115
+ f.write(f"{sender_email}\n{sender_password}\n{recipient_email}")
116
+
117
+ # Function to load progress (last processed email index)
118
+ def load_progress():
119
+ if os.path.exists("progress.txt"):
120
+ with open("progress.txt", "r") as f:
121
+ return int(f.read().strip())
122
+ return 0
123
+
124
+ # Function to save progress (last processed email index)
125
+ def save_progress(progress):
126
+ with open("progress.txt", "w") as f:
127
+ f.write(str(progress))
128
+
129
+ # Streamlit App
130
+ def main():
131
+ st.title("Email Validation App")
132
+
133
+ # Display instructions to create a Gmail App Password
134
+ st.markdown("""
135
+ **To send emails using your Gmail account, you need to generate an App Password:**
136
+
137
+ 1. Go to [Google App Passwords](https://myaccount.google.com/apppasswords).
138
+ 2. Sign in to your Google account if prompted.
139
+ 3. Under "Select App," choose **Other (Custom name)** from the dropdown list.
140
+ 4. Enter a name for the app (e.g., "Email Validation App") and click **Generate**.
141
+ 5. Copy the generated password and paste it into the "App Password" field in this app.
142
+ 6. Use this App Password instead of your regular Gmail password when sending emails.
143
+ """)
144
+
145
+ # Load settings if they exist
146
+ settings = load_settings()
147
+
148
+ # Step 1: Upload the file (Excel, CSV, or ODS) only if settings are already saved
149
+ if settings:
150
+ st.info("Settings already saved. You can upload your email file to continue processing.")
151
+ else:
152
+ st.warning("No settings found. Please provide your Gmail credentials and recipient email first.")
153
+
154
+ uploaded_file = st.file_uploader("Upload your file with emails (Excel, CSV, or ODS)", type=["xls", "xlsx", "csv", "ods"])
155
+
156
+ # Load the file and process emails only if it's uploaded
157
+ if uploaded_file:
158
+ input_df = read_file(uploaded_file)
159
+
160
+ if input_df is None:
161
+ return
162
+
163
+ # Ensure the file contains an 'emails' column
164
+ if 'emails' not in input_df.columns:
165
+ st.error("Error: 'emails' column not found in the uploaded file.")
166
+ return
167
+
168
+ # Step 2: Input Gmail credentials if not already saved
169
+ if not settings:
170
+ sender_email = st.text_input("Enter temporary Gmail ID", type="default")
171
+ sender_password = st.text_input("Enter Gmail App Password", type="password")
172
+ recipient_email = st.text_input("Enter recipient email for results", type="default")
173
+
174
+ if sender_email and sender_password and recipient_email:
175
+ if st.button("Save Settings"):
176
+ save_settings(sender_email, sender_password, recipient_email)
177
+ st.success("Settings saved. You can now upload your email file and continue processing.")
178
+ st.experimental_rerun() # Rerun the app to load the new settings and show the process button
179
+ else:
180
+ # Use saved settings
181
+ sender_email, sender_password, recipient_email = settings
182
+
183
+ # Process emails in batches of 500
184
+ batch_start = load_progress()
185
+ output_file = f"output_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
186
+
187
+ if uploaded_file.name.endswith('.csv'):
188
+ output_file += '.csv'
189
+ elif uploaded_file.name.endswith('.ods'):
190
+ output_file += '.ods'
191
+ else:
192
+ output_file += '.xlsx'
193
+
194
+ # After saving settings, now show the "Process Next Batch" button
195
+ if st.button("Process Next Batch"):
196
+ batch_df, new_progress = verify_emails(input_df, output_file, sender_email, sender_password, batch_start)
197
+ if batch_df is not None:
198
+ save_progress(new_progress)
199
+ send_email_result(output_file, recipient_email, sender_email, sender_password)
200
+ st.success(f"Processed and sent results for batch {batch_start // 500 + 1}. Progress saved.")
201
+ else:
202
+ st.error("Error processing the batch.")
203
+
204
+ if __name__ == "__main__":
205
+ if not os.path.exists("uploaded_files"):
206
+ os.makedirs("uploaded_files")
207
+ main()