main.py (Entry Point)
│
└─> BulkEmailSender (Main Window)
│
├─> ConfigManager (Configuration)
│ └─> config/smtp_config.json
│
├─> EmailSender (Business Logic)
│ ├─> SMTP Connection
│ ├─> Email Composition
│ ├─> Recipient Parsing
│ └─> Image/QR Embedding
│
├─> AppStyles (UI Styling)
│
└─> UI Components
├─> SMTPTab (Configure SMTP)
├─> RecipientsTab (Manage Recipients)
├─> ComposeTab (Compose Email)
├─> SendTab (Send Campaign)
└─> ConnectionDialog (Connect Popup)
📁 Email_sender/
│
├── 📁 app/ Main application package
│ ├── __init__.py Package initialization
│ ├── config.py ConfigManager class
│ ├── email_sender.py EmailSender business logic
│ ├── html_parser.py HTML parsing utilities
│ │
│ └── 📁 ui/ User interface components
│ ├── __init__.py UI package init
│ ├── main_window.py Main application window
│ ├── tab_base.py Base class for tabs
│ ├── styles.py Centralized styling
│ ├── smtp_tab.py SMTP configuration tab
│ ├── recipients_tab.py Recipients management tab
│ ├── compose_tab.py Email composition tab
│ ├── send_tab.py Campaign sending tab
│ └── connection_dialog.py Connection popup dialog
│
├── 📁 config/ Configuration storage
│ └── smtp_config.json SMTP credentials (auto-created)
│
├── 📁 data/ Data files
│ ├── data.csv Sample recipient data
│ └── qrcodes/ QR code images (user-created)
│
├── 📁 templates/ Email HTML templates (optional)
│
├── main.py 🎯 New entry point (run this!)
├── sender.py 📜 Original monolithic version
├── README.md 📖 Complete documentation
├── QUICKSTART.md ⚡ Quick start guide
├── requirement.txt 📦 Dependencies info
└── .gitignore 🔒 Git ignore rules
- Loads/saves SMTP configuration from JSON
- Provides get/update/save methods
- Used by: All tabs, EmailSender
- Handles SMTP connection and authentication
- Sends emails with HTML, images, QR codes
- Parses recipient CSV data
- Used by: SendTab, ConnectionDialog, SMTPTab
- Converts HTML to plain text for preview
- Used by: ComposeTab
- Defines color scheme and theme
- Configures TTK styles
- Used by: All UI components
- Base class for all tabs
- Provides consistent header styling
- Inherited by: SMTPTab, RecipientsTab, ComposeTab, SendTab
- Creates main application window
- Manages top toolbar with connection status
- Creates all tabs
- Handles auto-connect on startup
- SMTPTab: Configure SMTP settings, save/test connection
- RecipientsTab: Import/manage recipients from CSV/TXT
- ComposeTab: Compose email with HTML, images, live preview
- SendTab: Send campaign with progress tracking
- Popup for SMTP authentication
- Tests connection and saves credentials
- Updates main window connection status
User Action (SendTab)
│
├─> Get Subject (ComposeTab)
├─> Get Body (ComposeTab)
├─> Get Image (ComposeTab)
└─> Get Recipients (RecipientsTab)
↓
Parse Recipients (EmailSender)
├─> Detect CSV format (header/no header)
├─> Extract email, name, link, qrcode
└─> Return list of recipients
↓
For Each Recipient:
├─> Replace placeholders ({{name}}, {{link}})
├─> Embed image with CID reference
├─> Attach QR code if present
├─> Send via SMTP
├─> Update progress bar
├─> Log status
└─> Delay before next email
↓
Campaign Complete
Application Start
│
└─> ConfigManager loads config/smtp_config.json
↓
If credentials exist:
├─> Create EmailSender
├─> Test connection
└─> Update UI (connected/not connected)
↓
User clicks "Connect SMTP"
├─> Show ConnectionDialog
├─> Enter credentials
├─> Test connection
├─> Save to config/smtp_config.json
└─> Update main window status
- Business Logic:
app/*.py(no UI code) - UI Components:
app/ui/*.py(minimal business logic) - Configuration:
config/(persistent storage)
- All tabs inherit from
TabBasefor consistent structure - Provides reusable
create_header()method
- Each component has single responsibility
- Easy to maintain and extend
- Clear dependencies between modules
- Model: ConfigManager, EmailSender (data and logic)
- View: All UI tabs (presentation)
- Controller: Main window coordinates interactions
- Create
app/ui/new_tab.py - Inherit from
TabBase - Implement
create_widgets() - Import in
main_window.py - Add to notebook
- Extend
EmailSenderclass - Add method for new feature
- Update
ComposeTaborSendTabto use it
- Edit
AppStylesinapp/ui/styles.py - Update color constants
- All tabs automatically use new colors
- Add field to
SMTPTab - Save via
ConfigManager - Use in
EmailSenderor other component
- Email sending: Done in background thread (SendTab)
- Preview updates: Debounced with 500ms delay
- SMTP connection: Reused across campaign (not per-email)
- Large CSV files: Parsed line-by-line (memory efficient)
- SMTP passwords stored in plain text in
config/smtp_config.json - Recommended: Use app-specific passwords (e.g., Gmail App Passwords)
.gitignoreexcludes config files from version control- DO NOT commit
smtp_config.jsonto public repositories
This architecture provides a clean, maintainable, and extensible foundation for the Email Campaign Manager.