Skip to content

Commit e910c3d

Browse files
authored
Create Email-Validation-Tool.py
1 parent 7861c0f commit e910c3d

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
import sys
2+
import os
3+
import re
4+
import threading
5+
import time
6+
import tkinter as tk
7+
from tkinter import ttk, messagebox
8+
import sv_ttk
9+
from tkinter import filedialog
10+
import dns.resolver # For domain MX record checks
11+
12+
# =========================
13+
# Helpers
14+
# =========================
15+
def resource_path(file_name):
16+
base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
17+
return os.path.join(base_path, file_name)
18+
19+
def set_status(msg):
20+
status_var.set(msg)
21+
root.update_idletasks()
22+
23+
# =========================
24+
# App Setup
25+
# =========================
26+
root = tk.Tk()
27+
root.title("Email Validation Tool")
28+
root.geometry("720x680")
29+
sv_ttk.set_theme("light")
30+
31+
# =========================
32+
# Globals
33+
# =========================
34+
dark_mode_var = tk.BooleanVar(value=False)
35+
email_var = tk.StringVar()
36+
validation_result_var = tk.StringVar(value="Result: —")
37+
email_history = []
38+
39+
# =========================
40+
# Theme Toggle
41+
# =========================
42+
def toggle_theme():
43+
bg = "#2E2E2E" if dark_mode_var.get() else "#FFFFFF"
44+
fg = "white" if dark_mode_var.get() else "black"
45+
root.configure(bg=bg)
46+
for w in ["TFrame", "TLabel", "TLabelframe", "TLabelframe.Label", "TCheckbutton"]:
47+
style.configure(w, background=bg, foreground=fg)
48+
email_entry.configure(background=bg, foreground=fg)
49+
50+
# =========================
51+
# Email Validation Logic
52+
# =========================
53+
def is_valid_email_format(email):
54+
# Basic regex email validation
55+
regex = r"^[\w\.-]+@[\w\.-]+\.\w+$"
56+
return re.match(regex, email) is not None
57+
58+
def has_mx_record(domain):
59+
# Check if domain has MX records
60+
try:
61+
records = dns.resolver.resolve(domain, 'MX')
62+
return bool(records)
63+
except Exception:
64+
return False
65+
66+
def validate_email():
67+
email = email_var.get().strip()
68+
if not email:
69+
messagebox.showwarning("Error", "Please enter an email address.")
70+
return
71+
72+
set_status("Validating email...")
73+
threading.Thread(target=_validate_email_thread, args=(email,), daemon=True).start()
74+
75+
def _validate_email_thread(email):
76+
# Check format
77+
if not is_valid_email_format(email):
78+
validation_result_var.set("Result: ❌ Invalid format")
79+
set_status("Validation complete")
80+
return
81+
82+
# Check MX record
83+
domain = email.split("@")[1]
84+
if has_mx_record(domain):
85+
validation_result_var.set("Result: ✅ Valid email")
86+
else:
87+
validation_result_var.set("Result: ⚠ Domain may not receive emails")
88+
89+
add_to_history(email)
90+
set_status("Validation complete")
91+
92+
# =========================
93+
# Email History
94+
# =========================
95+
def add_to_history(email):
96+
email_history.append(email)
97+
history_list.insert(tk.END, f"{len(email_history)}{email}")
98+
99+
def export_history_txt():
100+
if not email_history:
101+
messagebox.showinfo("Empty History", "No emails to export.")
102+
return
103+
104+
file_path = filedialog.asksaveasfilename(
105+
defaultextension=".txt",
106+
filetypes=[("Text Files", "*.txt")],
107+
title="Export Email History"
108+
)
109+
110+
if not file_path:
111+
return
112+
113+
try:
114+
with open(file_path, "w", encoding="utf-8") as f:
115+
f.write("Email Validation History\n")
116+
f.write("=" * 30 + "\n\n")
117+
for i, email in enumerate(email_history, 1):
118+
f.write(f"{i}. {email}\n")
119+
set_status("Email history exported")
120+
messagebox.showinfo("Export Successful", "Email history saved successfully.")
121+
except Exception as e:
122+
messagebox.showerror("Export Failed", str(e))
123+
124+
# =========================
125+
# Styles
126+
# =========================
127+
style = ttk.Style()
128+
style.theme_use("clam")
129+
style.configure("Action.TButton", font=("Segoe UI", 11, "bold"), padding=8)
130+
131+
# =========================
132+
# Status Bar
133+
# =========================
134+
status_var = tk.StringVar(value="Ready")
135+
ttk.Label(root, textvariable=status_var, anchor="w").pack(side=tk.BOTTOM, fill="x")
136+
137+
# =========================
138+
# UI Layout
139+
# =========================
140+
main = ttk.Frame(root, padding=20)
141+
main.pack(expand=True, fill="both")
142+
143+
ttk.Label(main, text="Email Validation Tool",
144+
font=("Segoe UI", 22, "bold")).pack()
145+
146+
email_entry = ttk.Entry(
147+
main, textvariable=email_var,
148+
font=("Segoe UI", 14), justify="center"
149+
)
150+
email_entry.pack(fill="x", pady=8)
151+
152+
ttk.Label(main, textvariable=validation_result_var,
153+
font=("Segoe UI", 12, "bold")).pack(pady=4)
154+
155+
# =========================
156+
# Controls
157+
# =========================
158+
controls = ttk.Frame(main)
159+
controls.pack(pady=8)
160+
161+
ttk.Button(controls, text="✅ Validate",
162+
command=validate_email,
163+
style="Action.TButton").pack(side="left", padx=4)
164+
165+
ttk.Button(controls, text="📤 Export History",
166+
command=export_history_txt,
167+
style="Action.TButton").pack(side="left", padx=4)
168+
169+
# =========================
170+
# History Vault
171+
# =========================
172+
vault = ttk.LabelFrame(main, text="Email History Vault", padding=10)
173+
vault.pack(fill="both", expand=True, pady=10)
174+
175+
history_list = tk.Listbox(vault, font=("Segoe UI", 10), height=10)
176+
history_list.pack(fill="both", expand=True)
177+
178+
# =========================
179+
# Options
180+
# =========================
181+
ttk.Checkbutton(main, text="Dark Mode",
182+
variable=dark_mode_var,
183+
command=toggle_theme).pack(pady=6)
184+
185+
# =========================
186+
# Run App
187+
# =========================
188+
root.mainloop()

0 commit comments

Comments
 (0)