Alpha108 commited on
Commit
b4525d3
Β·
verified Β·
1 Parent(s): 1d2d3bb

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +620 -0
app.py ADDED
@@ -0,0 +1,620 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AI Lead Generation & Outreach Agent
3
+ Optimized for Hugging Face Spaces Deployment
4
+ """
5
+
6
+ import os
7
+ import csv
8
+ import json
9
+ import time
10
+ import sqlite3
11
+ import re
12
+ from datetime import datetime
13
+ from typing import List, Dict, Optional
14
+ import streamlit as st
15
+ import pandas as pd
16
+ import requests
17
+ from bs4 import BeautifulSoup
18
+
19
+ # ======================== Configuration ========================
20
+ class Config:
21
+ # Hugging Face Configuration - Using environment variables for security
22
+ HF_API_TOKEN = os.getenv("HF_TOKEN", "") # Will be set in HF Spaces secrets
23
+
24
+ # Free models available on HF Inference API
25
+ MODELS = {
26
+ "Mistral-7B": "mistralai/Mistral-7B-Instruct-v0.1",
27
+ "Falcon-7B": "tiiuae/falcon-7b-instruct",
28
+ "GPT-2": "gpt2",
29
+ "FLAN-T5": "google/flan-t5-base"
30
+ }
31
+
32
+ # Database
33
+ DB_PATH = "leads.db"
34
+
35
+ # Rate limiting
36
+ SCRAPE_DELAY = 2
37
+ HF_API_DELAY = 1
38
+
39
+ # ======================== Database Setup ========================
40
+ @st.cache_resource
41
+ def init_database():
42
+ """Initialize database with connection pooling for Streamlit"""
43
+ conn = sqlite3.connect(Config.DB_PATH, check_same_thread=False)
44
+ cursor = conn.cursor()
45
+
46
+ # Create tables
47
+ cursor.execute('''
48
+ CREATE TABLE IF NOT EXISTS leads (
49
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
50
+ name TEXT,
51
+ title TEXT,
52
+ company TEXT,
53
+ email TEXT UNIQUE,
54
+ industry TEXT,
55
+ website TEXT,
56
+ scraped_date TIMESTAMP,
57
+ status TEXT DEFAULT 'new'
58
+ )
59
+ ''')
60
+
61
+ cursor.execute('''
62
+ CREATE TABLE IF NOT EXISTS generated_emails (
63
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
64
+ lead_id INTEGER,
65
+ subject TEXT,
66
+ body TEXT,
67
+ generated_date TIMESTAMP,
68
+ sent_status TEXT DEFAULT 'draft',
69
+ FOREIGN KEY (lead_id) REFERENCES leads (id)
70
+ )
71
+ ''')
72
+
73
+ conn.commit()
74
+ return conn
75
+
76
+ # ======================== Lead Generation ========================
77
+ class LeadGenerator:
78
+ """Generate sample leads for demonstration"""
79
+
80
+ @staticmethod
81
+ def generate_sample_leads(industry, count=5):
82
+ """Generate sample leads based on industry"""
83
+
84
+ # Sample data templates
85
+ companies = {
86
+ "Tech": ["TechCorp", "Digital Solutions", "CloudBase", "AI Innovations", "DataFlow Systems"],
87
+ "Marketing": ["Growth Agency", "Brand builders", "Digital Marketing Pro", "Creative Studios", "AdTech Solutions"],
88
+ "Finance": ["FinTech Plus", "Investment Partners", "Capital Growth", "Wealth Advisors", "Banking Solutions"],
89
+ "Healthcare": ["HealthTech", "MedCare Solutions", "Wellness Corp", "BioTech Innovations", "Healthcare Plus"],
90
+ "E-commerce": ["ShopFlow", "E-tail Masters", "Commerce Cloud", "Online Retail Pro", "Marketplace Leaders"]
91
+ }
92
+
93
+ first_names = ["John", "Sarah", "Michael", "Emma", "David", "Lisa", "Robert", "Jennifer", "James", "Maria"]
94
+ last_names = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Wilson", "Martinez"]
95
+ titles = ["CEO", "Marketing Director", "VP Sales", "CTO", "COO", "Head of Growth", "Director", "Founder"]
96
+
97
+ leads = []
98
+ company_list = companies.get(industry, companies["Tech"])
99
+
100
+ for i in range(min(count, len(company_list))):
101
+ first = first_names[i % len(first_names)]
102
+ last = last_names[i % len(last_names)]
103
+ company = company_list[i]
104
+
105
+ lead = {
106
+ 'name': f"{first} {last}",
107
+ 'title': titles[i % len(titles)],
108
+ 'company': company,
109
+ 'email': f"{first.lower()}.{last.lower()}@{company.lower().replace(' ', '')}.com",
110
+ 'industry': industry,
111
+ 'website': f"https://www.{company.lower().replace(' ', '')}.com",
112
+ 'scraped_date': datetime.now()
113
+ }
114
+ leads.append(lead)
115
+
116
+ return leads
117
+
118
+ class WebScraper:
119
+ """Simple web scraping utilities"""
120
+
121
+ @staticmethod
122
+ def extract_emails_from_text(text):
123
+ """Extract email addresses from text"""
124
+ email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
125
+ return list(set(re.findall(email_pattern, text)))
126
+
127
+ @staticmethod
128
+ def scrape_website_info(url):
129
+ """Basic website scraping - for demonstration"""
130
+ try:
131
+ headers = {
132
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
133
+ }
134
+ response = requests.get(url, headers=headers, timeout=5)
135
+ soup = BeautifulSoup(response.content, 'html.parser')
136
+
137
+ # Extract basic info
138
+ title = soup.find('title').text if soup.find('title') else "N/A"
139
+ description = ""
140
+ meta_desc = soup.find('meta', attrs={'name': 'description'})
141
+ if meta_desc:
142
+ description = meta_desc.get('content', '')
143
+
144
+ return {
145
+ 'title': title,
146
+ 'description': description,
147
+ 'success': True
148
+ }
149
+ except Exception as e:
150
+ return {'success': False, 'error': str(e)}
151
+
152
+ # ======================== AI Email Generation ========================
153
+ class EmailGenerator:
154
+ def __init__(self, api_token, model_name):
155
+ self.api_token = api_token
156
+ self.model_name = model_name
157
+ self.api_url = f"https://api-inference.huggingface.co/models/{model_name}"
158
+ self.headers = {"Authorization": f"Bearer {api_token}"}
159
+
160
+ def generate_email(self, lead_data, product_info, style="professional"):
161
+ """Generate personalized email using HF API"""
162
+
163
+ # Create prompt based on model type
164
+ if "gpt2" in self.model_name.lower():
165
+ prompt = self._create_simple_prompt(lead_data, product_info)
166
+ else:
167
+ prompt = self._create_detailed_prompt(lead_data, product_info, style)
168
+
169
+ # Prepare API request
170
+ payload = {
171
+ "inputs": prompt,
172
+ "parameters": {
173
+ "max_new_tokens": 250,
174
+ "temperature": 0.7,
175
+ "top_p": 0.95,
176
+ "do_sample": True
177
+ }
178
+ }
179
+
180
+ try:
181
+ response = requests.post(
182
+ self.api_url,
183
+ headers=self.headers,
184
+ json=payload,
185
+ timeout=30
186
+ )
187
+
188
+ if response.status_code == 200:
189
+ result = response.json()
190
+ if isinstance(result, list) and len(result) > 0:
191
+ generated_text = result[0].get('generated_text', '')
192
+ else:
193
+ generated_text = result.get('generated_text', '')
194
+
195
+ return self._parse_email_response(generated_text, lead_data, product_info)
196
+ else:
197
+ return self._create_fallback_email(lead_data, product_info)
198
+
199
+ except Exception as e:
200
+ st.error(f"API Error: {str(e)}")
201
+ return self._create_fallback_email(lead_data, product_info)
202
+
203
+ def _create_simple_prompt(self, lead_data, product_info):
204
+ """Simple prompt for GPT-2"""
205
+ return f"""Write a business email to {lead_data['name']} at {lead_data['company']} about {product_info}.
206
+
207
+ Subject: Helping {lead_data['company']} grow
208
+ Dear {lead_data['name']},"""
209
+
210
+ def _create_detailed_prompt(self, lead_data, product_info, style):
211
+ """Detailed prompt for instruction-following models"""
212
+ return f"""Generate a {style} cold outreach email with these details:
213
+
214
+ Recipient: {lead_data['name']}, {lead_data['title']} at {lead_data['company']}
215
+ Industry: {lead_data.get('industry', 'Business')}
216
+ Product/Service: {product_info}
217
+
218
+ Create a personalized email that:
219
+ 1. Has an attention-grabbing subject line
220
+ 2. Shows understanding of their industry
221
+ 3. Clearly states the value proposition
222
+ 4. Includes a specific call-to-action
223
+ 5. Keeps it under 150 words
224
+
225
+ Format:
226
+ Subject: [Create subject line]
227
+ Body: [Create email body]
228
+
229
+ Email:"""
230
+
231
+ def _parse_email_response(self, text, lead_data, product_info):
232
+ """Parse AI response to extract subject and body"""
233
+
234
+ # Try to find subject line
235
+ subject_match = re.search(r'Subject:?\s*(.+?)(?:\n|$)', text, re.IGNORECASE)
236
+ if subject_match:
237
+ subject = subject_match.group(1).strip()
238
+ # Remove subject from text to get body
239
+ body = text[subject_match.end():].strip()
240
+ else:
241
+ subject = f"Opportunity for {lead_data['company']}"
242
+ body = text.strip()
243
+
244
+ # Clean up body
245
+ body = re.sub(r'^(Body|Dear|Email):?\s*', '', body, flags=re.IGNORECASE).strip()
246
+
247
+ # Ensure we have content
248
+ if len(body) < 50:
249
+ return self._create_fallback_email(lead_data, product_info)
250
+
251
+ # Add greeting if missing
252
+ if not body.lower().startswith(('hi', 'hello', 'dear')):
253
+ body = f"Dear {lead_data['name']},\n\n{body}"
254
+
255
+ # Add signature if missing
256
+ if not any(word in body.lower() for word in ['regards', 'best', 'sincerely', 'thanks']):
257
+ body += "\n\nBest regards,\n[Your Name]"
258
+
259
+ return {
260
+ 'subject': subject[:100], # Limit subject length
261
+ 'body': body[:1000] # Limit body length
262
+ }
263
+
264
+ def _create_fallback_email(self, lead_data, product_info):
265
+ """Fallback template when AI generation fails"""
266
+ templates = [
267
+ {
268
+ 'subject': f"Quick question for {lead_data['company']}",
269
+ 'body': f"""Dear {lead_data['name']},
270
+
271
+ I hope this message finds you well. I noticed that {lead_data['company']} is a leader in the {lead_data.get('industry', 'industry')}, and I wanted to reach out with a brief introduction.
272
+
273
+ {product_info}
274
+
275
+ Companies similar to yours have seen significant improvements in efficiency and growth using our solution.
276
+
277
+ Would you be open to a brief 15-minute call next week to discuss how this could benefit {lead_data['company']}?
278
+
279
+ Best regards,
280
+ [Your Name]"""
281
+ },
282
+ {
283
+ 'subject': f"Helping {lead_data['company']} achieve better results",
284
+ 'body': f"""Hi {lead_data['name']},
285
+
286
+ As {lead_data['title']} at {lead_data['company']}, you're likely focused on driving growth and efficiency.
287
+
288
+ {product_info}
289
+
290
+ I'd love to show you how we've helped similar companies in the {lead_data.get('industry', 'industry')} achieve remarkable results.
291
+
292
+ Are you available for a quick call this week?
293
+
294
+ Best regards,
295
+ [Your Name]"""
296
+ }
297
+ ]
298
+
299
+ import random
300
+ return random.choice(templates)
301
+
302
+ # ======================== Streamlit App ========================
303
+ def main():
304
+ st.set_page_config(
305
+ page_title="AI Lead Gen Agent",
306
+ page_icon="πŸš€",
307
+ layout="wide"
308
+ )
309
+
310
+ # Custom CSS
311
+ st.markdown("""
312
+ <style>
313
+ .main { padding-top: 2rem; }
314
+ .stButton>button { width: 100%; }
315
+ .success-box { padding: 1rem; background-color: #d4edda; border-radius: 5px; margin: 1rem 0; }
316
+ </style>
317
+ """, unsafe_allow_html=True)
318
+
319
+ # Header
320
+ st.title("πŸš€ AI Lead Generation & Outreach Agent")
321
+ st.markdown("Generate leads and create personalized outreach emails using AI")
322
+ st.markdown("---")
323
+
324
+ # Initialize database
325
+ conn = init_database()
326
+
327
+ # Sidebar Configuration
328
+ with st.sidebar:
329
+ st.header("βš™οΈ Configuration")
330
+
331
+ # API Token
332
+ st.subheader("πŸ€– Hugging Face Setup")
333
+ api_token = st.text_input(
334
+ "HF API Token",
335
+ type="password",
336
+ value=Config.HF_API_TOKEN,
337
+ help="Get your free token at huggingface.co"
338
+ )
339
+
340
+ if not api_token:
341
+ st.warning("⚠️ Please enter your Hugging Face API token")
342
+ st.markdown("[Get your free token here](https://huggingface.co/settings/tokens)")
343
+
344
+ # Model Selection
345
+ selected_model = st.selectbox(
346
+ "AI Model",
347
+ options=list(Config.MODELS.keys()),
348
+ help="Choose the AI model for email generation"
349
+ )
350
+
351
+ # Product Description
352
+ st.subheader("πŸ“ Your Product/Service")
353
+ product_description = st.text_area(
354
+ "Description",
355
+ value="We provide AI-powered automation solutions that help businesses streamline their operations, reduce costs by 40%, and increase productivity.",
356
+ height=100
357
+ )
358
+
359
+ # Email Style
360
+ email_style = st.radio(
361
+ "Email Style",
362
+ ["Professional", "Casual", "Creative"],
363
+ help="Choose the tone for generated emails"
364
+ )
365
+
366
+ # Main Content Area
367
+ tab1, tab2, tab3, tab4 = st.tabs(["πŸ” Generate Leads", "βœ‰οΈ Create Emails", "πŸ“Š View Database", "πŸ“ˆ Analytics"])
368
+
369
+ # Tab 1: Generate Leads
370
+ with tab1:
371
+ st.header("Lead Generation")
372
+
373
+ col1, col2 = st.columns(2)
374
+
375
+ with col1:
376
+ st.subheader("🎯 Quick Lead Generation")
377
+ industry = st.selectbox(
378
+ "Select Industry",
379
+ ["Tech", "Marketing", "Finance", "Healthcare", "E-commerce"]
380
+ )
381
+
382
+ num_leads = st.slider("Number of Leads", 1, 10, 5)
383
+
384
+ if st.button("Generate Sample Leads", type="primary"):
385
+ with st.spinner("Generating leads..."):
386
+ # Generate sample leads
387
+ generator = LeadGenerator()
388
+ leads = generator.generate_sample_leads(industry, num_leads)
389
+
390
+ # Save to database
391
+ cursor = conn.cursor()
392
+ saved = 0
393
+
394
+ for lead in leads:
395
+ try:
396
+ cursor.execute('''
397
+ INSERT INTO leads (name, title, company, email, industry, website, scraped_date, status)
398
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
399
+ ''', (
400
+ lead['name'], lead['title'], lead['company'],
401
+ lead['email'], lead['industry'], lead['website'],
402
+ lead['scraped_date'], 'new'
403
+ ))
404
+ saved += 1
405
+ except sqlite3.IntegrityError:
406
+ pass # Skip duplicates
407
+
408
+ conn.commit()
409
+
410
+ st.success(f"βœ… Generated {saved} new leads!")
411
+
412
+ # Display generated leads
413
+ df = pd.DataFrame(leads)
414
+ st.dataframe(df[['name', 'title', 'company', 'email']])
415
+
416
+ with col2:
417
+ st.subheader("🌐 Website Scraper")
418
+ website_url = st.text_input("Website URL", "https://example.com")
419
+
420
+ if st.button("Scrape Website Info"):
421
+ if website_url:
422
+ with st.spinner("Scraping website..."):
423
+ scraper = WebScraper()
424
+ info = scraper.scrape_website_info(website_url)
425
+
426
+ if info['success']:
427
+ st.success("βœ… Website scraped successfully!")
428
+ st.write(f"**Title:** {info.get('title', 'N/A')}")
429
+ st.write(f"**Description:** {info.get('description', 'N/A')}")
430
+ else:
431
+ st.error(f"Failed to scrape: {info.get('error', 'Unknown error')}")
432
+
433
+ # Tab 2: Create Emails
434
+ with tab2:
435
+ st.header("Email Generation")
436
+
437
+ if not api_token:
438
+ st.warning("⚠️ Please configure your Hugging Face API token in the sidebar")
439
+ else:
440
+ # Fetch leads from database
441
+ cursor = conn.cursor()
442
+ cursor.execute("SELECT * FROM leads WHERE status = 'new' ORDER BY scraped_date DESC")
443
+ leads = cursor.fetchall()
444
+
445
+ if not leads:
446
+ st.info("No leads available. Generate some leads first!")
447
+ else:
448
+ # Lead selection
449
+ lead_options = [f"{lead[1]} - {lead[3]} ({lead[4]})" for lead in leads]
450
+ selected_index = st.selectbox("Select Lead", range(len(lead_options)), format_func=lambda x: lead_options[x])
451
+ selected_lead = leads[selected_index]
452
+
453
+ # Display lead info
454
+ col1, col2 = st.columns(2)
455
+ with col1:
456
+ st.write(f"**Name:** {selected_lead[1]}")
457
+ st.write(f"**Title:** {selected_lead[2]}")
458
+ with col2:
459
+ st.write(f"**Company:** {selected_lead[3]}")
460
+ st.write(f"**Email:** {selected_lead[4]}")
461
+
462
+ st.markdown("---")
463
+
464
+ # Generate email button
465
+ if st.button("πŸ€– Generate Personalized Email", type="primary"):
466
+ with st.spinner("Generating email with AI..."):
467
+ # Prepare lead data
468
+ lead_data = {
469
+ 'name': selected_lead[1],
470
+ 'title': selected_lead[2],
471
+ 'company': selected_lead[3],
472
+ 'email': selected_lead[4],
473
+ 'industry': selected_lead[5]
474
+ }
475
+
476
+ # Generate email
477
+ generator = EmailGenerator(
478
+ api_token,
479
+ Config.MODELS[selected_model]
480
+ )
481
+
482
+ email = generator.generate_email(
483
+ lead_data,
484
+ product_description,
485
+ email_style.lower()
486
+ )
487
+
488
+ # Display generated email
489
+ st.success("βœ… Email generated successfully!")
490
+
491
+ # Editable fields
492
+ subject = st.text_input("Subject Line", value=email['subject'])
493
+ body = st.text_area("Email Body", value=email['body'], height=300)
494
+
495
+ # Save to database
496
+ cursor.execute('''
497
+ INSERT INTO generated_emails (lead_id, subject, body, generated_date, sent_status)
498
+ VALUES (?, ?, ?, ?, ?)
499
+ ''', (selected_lead[0], subject, body, datetime.now(), 'draft'))
500
+ conn.commit()
501
+
502
+ # Action buttons
503
+ col1, col2, col3 = st.columns(3)
504
+ with col1:
505
+ if st.button("πŸ’Ύ Save Draft"):
506
+ st.success("Draft saved!")
507
+ with col2:
508
+ if st.button("πŸ”„ Regenerate"):
509
+ st.experimental_rerun()
510
+ with col3:
511
+ if st.button("πŸ“§ Copy to Clipboard"):
512
+ st.info("Email copied! (Feature requires JavaScript)")
513
+
514
+ # Tab 3: View Database
515
+ with tab3:
516
+ st.header("Lead Database")
517
+
518
+ # Fetch all leads
519
+ cursor = conn.cursor()
520
+ cursor.execute("SELECT * FROM leads ORDER BY scraped_date DESC")
521
+ all_leads = cursor.fetchall()
522
+
523
+ if all_leads:
524
+ # Convert to DataFrame
525
+ df = pd.DataFrame(all_leads, columns=['ID', 'Name', 'Title', 'Company', 'Email', 'Industry', 'Website', 'Date', 'Status'])
526
+
527
+ # Display metrics
528
+ col1, col2, col3 = st.columns(3)
529
+ with col1:
530
+ st.metric("Total Leads", len(all_leads))
531
+ with col2:
532
+ new_leads = len([l for l in all_leads if l[8] == 'new'])
533
+ st.metric("New Leads", new_leads)
534
+ with col3:
535
+ industries = len(set([l[5] for l in all_leads if l[5]]))
536
+ st.metric("Industries", industries)
537
+
538
+ # Display table
539
+ st.dataframe(df[['Name', 'Title', 'Company', 'Email', 'Industry', 'Status']])
540
+
541
+ # Export option
542
+ csv = df.to_csv(index=False)
543
+ st.download_button(
544
+ label="πŸ“₯ Download CSV",
545
+ data=csv,
546
+ file_name=f"leads_{datetime.now().strftime('%Y%m%d')}.csv",
547
+ mime="text/csv"
548
+ )
549
+
550
+ # Clear database option
551
+ if st.button("πŸ—‘οΈ Clear All Leads", type="secondary"):
552
+ cursor.execute("DELETE FROM leads")
553
+ cursor.execute("DELETE FROM generated_emails")
554
+ conn.commit()
555
+ st.experimental_rerun()
556
+ else:
557
+ st.info("No leads in database. Start by generating some leads!")
558
+
559
+ # Tab 4: Analytics
560
+ with tab4:
561
+ st.header("Campaign Analytics")
562
+
563
+ cursor = conn.cursor()
564
+
565
+ # Get statistics
566
+ cursor.execute("SELECT COUNT(*) FROM leads")
567
+ total_leads = cursor.fetchone()[0]
568
+
569
+ cursor.execute("SELECT COUNT(*) FROM generated_emails")
570
+ total_emails = cursor.fetchone()[0]
571
+
572
+ cursor.execute("SELECT industry, COUNT(*) FROM leads GROUP BY industry")
573
+ industry_data = cursor.fetchall()
574
+
575
+ # Display metrics
576
+ col1, col2, col3, col4 = st.columns(4)
577
+ with col1:
578
+ st.metric("Total Leads", total_leads)
579
+ with col2:
580
+ st.metric("Emails Generated", total_emails)
581
+ with col3:
582
+ avg_rate = (total_emails / total_leads * 100) if total_leads > 0 else 0
583
+ st.metric("Generation Rate", f"{avg_rate:.1f}%")
584
+ with col4:
585
+ st.metric("Industries", len(industry_data))
586
+
587
+ # Industry breakdown
588
+ if industry_data:
589
+ st.subheader("πŸ“Š Leads by Industry")
590
+ industry_df = pd.DataFrame(industry_data, columns=['Industry', 'Count'])
591
+ st.bar_chart(industry_df.set_index('Industry'))
592
+
593
+ # Recent activity
594
+ st.subheader("πŸ“ˆ Recent Activity")
595
+ cursor.execute("""
596
+ SELECT name, company, scraped_date
597
+ FROM leads
598
+ ORDER BY scraped_date DESC
599
+ LIMIT 10
600
+ """)
601
+ recent = cursor.fetchall()
602
+
603
+ if recent:
604
+ recent_df = pd.DataFrame(recent, columns=['Name', 'Company', 'Date'])
605
+ st.dataframe(recent_df)
606
+
607
+ # Footer
608
+ st.markdown("---")
609
+ st.markdown(
610
+ """
611
+ <div style='text-align: center; color: #666;'>
612
+ Built with ❀️ using Streamlit & Hugging Face |
613
+ <a href='https://huggingface.co/spaces' target='_blank'>Deploy your own</a>
614
+ </div>
615
+ """,
616
+ unsafe_allow_html=True
617
+ )
618
+
619
+ if __name__ == "__main__":
620
+ main()