JayBene1 commited on
Commit
0d23196
Β·
verified Β·
1 Parent(s): d51fe17

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +415 -0
app.py ADDED
@@ -0,0 +1,415 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import re
4
+ import json
5
+ from urllib.parse import urlparse, urljoin
6
+ import time
7
+ import random
8
+
9
+ # Mock contacts database (same as your API)
10
+ CONTACTS_DB = [
11
+ {
12
+ "id": 1,
13
+ "first_name": "Sarah",
14
+ "last_name": "Chen",
15
+ "email": "sarah.chen@techflowsolutions.com",
16
+ "phone": "+1-555-0101",
17
+ "job_title": "CTO",
18
+ "company": "TechFlow Solutions",
19
+ "website": "https://techflowsolutions.com"
20
+ },
21
+ {
22
+ "id": 2,
23
+ "first_name": "Marcus",
24
+ "last_name": "Rodriguez",
25
+ "email": "m.rodriguez@techflowsolutions.com",
26
+ "phone": "+1-555-0102",
27
+ "job_title": "Senior Developer",
28
+ "company": "TechFlow Solutions",
29
+ "website": "https://techflowsolutions.com"
30
+ },
31
+ {
32
+ "id": 3,
33
+ "first_name": "Emma",
34
+ "last_name": "Thompson",
35
+ "email": "emma@greenleafconsult.com",
36
+ "phone": "+1-555-0201",
37
+ "job_title": "Managing Partner",
38
+ "company": "GreenLeaf Consulting",
39
+ "website": "https://greenleafconsult.com"
40
+ },
41
+ {
42
+ "id": 4,
43
+ "first_name": "David",
44
+ "last_name": "Park",
45
+ "email": "david.park@greenleafconsult.com",
46
+ "phone": "+1-555-0202",
47
+ "job_title": "Environmental Analyst",
48
+ "company": "GreenLeaf Consulting",
49
+ "website": "https://greenleafconsult.com"
50
+ },
51
+ {
52
+ "id": 5,
53
+ "first_name": "Jessica",
54
+ "last_name": "Williams",
55
+ "email": "jessica@blueskymarketing.net",
56
+ "phone": "+1-555-0301",
57
+ "job_title": "Creative Director",
58
+ "company": "BlueSky Marketing",
59
+ "website": "https://blueskymarketing.net"
60
+ },
61
+ {
62
+ "id": 6,
63
+ "first_name": "Ryan",
64
+ "last_name": "Mitchell",
65
+ "email": "ryan.mitchell@blueskymarketing.net",
66
+ "phone": "+1-555-0302",
67
+ "job_title": "Account Manager",
68
+ "company": "BlueSky Marketing",
69
+ "website": "https://blueskymarketing.net"
70
+ },
71
+ {
72
+ "id": 7,
73
+ "first_name": "Lisa",
74
+ "last_name": "Zhang",
75
+ "email": "l.zhang@quantumdynamics.org",
76
+ "phone": "+1-555-0401",
77
+ "job_title": "Research Director",
78
+ "company": "Quantum Dynamics Corp",
79
+ "website": "https://quantumdynamics.org"
80
+ },
81
+ {
82
+ "id": 8,
83
+ "first_name": "Ahmed",
84
+ "last_name": "Hassan",
85
+ "email": "ahmed.hassan@quantumdynamics.org",
86
+ "phone": "+1-555-0402",
87
+ "job_title": "Quantum Engineer",
88
+ "company": "Quantum Dynamics Corp",
89
+ "website": "https://quantumdynamics.org"
90
+ },
91
+ {
92
+ "id": 9,
93
+ "first_name": "Maria",
94
+ "last_name": "Gonzalez",
95
+ "email": "maria@stellarlogistics.biz",
96
+ "phone": "+1-555-0501",
97
+ "job_title": "Operations Manager",
98
+ "company": "Stellar Logistics",
99
+ "website": "https://stellarlogistics.biz"
100
+ },
101
+ {
102
+ "id": 10,
103
+ "first_name": "James",
104
+ "last_name": "O'Connor",
105
+ "email": "james.oconnor@stellarlogistics.biz",
106
+ "phone": "+1-555-0502",
107
+ "job_title": "Fleet Coordinator",
108
+ "company": "Stellar Logistics",
109
+ "website": "https://stellarlogistics.biz"
110
+ },
111
+ {
112
+ "id": 11,
113
+ "first_name": "Robert",
114
+ "last_name": "Kim",
115
+ "email": "robert.kim@nexusfinancial.pro",
116
+ "phone": "+1-555-0601",
117
+ "job_title": "Senior Advisor",
118
+ "company": "Nexus Financial",
119
+ "website": "https://nexusfinancial.pro"
120
+ },
121
+ {
122
+ "id": 12,
123
+ "first_name": "Catherine",
124
+ "last_name": "Lee",
125
+ "email": "catherine@nexusfinancial.pro",
126
+ "phone": "+1-555-0602",
127
+ "job_title": "Investment Analyst",
128
+ "company": "Nexus Financial",
129
+ "website": "https://nexusfinancial.pro"
130
+ },
131
+ {
132
+ "id": 13,
133
+ "first_name": "Michael",
134
+ "last_name": "Johnson",
135
+ "email": "m.johnson@horizonhealth.care",
136
+ "phone": "+1-555-0701",
137
+ "job_title": "Chief Medical Officer",
138
+ "company": "Horizon Health Systems",
139
+ "website": "https://horizonhealth.care"
140
+ },
141
+ {
142
+ "id": 14,
143
+ "first_name": "Jennifer",
144
+ "last_name": "Adams",
145
+ "email": "jennifer.adams@horizonhealth.care",
146
+ "phone": "+1-555-0702",
147
+ "job_title": "Head Nurse",
148
+ "company": "Horizon Health Systems",
149
+ "website": "https://horizonhealth.care"
150
+ },
151
+ {
152
+ "id": 15,
153
+ "first_name": "Tony",
154
+ "last_name": "Ricci",
155
+ "email": "tony.ricci@phoenixmfg.com",
156
+ "phone": "+1-555-0801",
157
+ "job_title": "Plant Manager",
158
+ "company": "Phoenix Manufacturing",
159
+ "website": "https://phoenixmfg.com"
160
+ },
161
+ {
162
+ "id": 16,
163
+ "first_name": "Linda",
164
+ "last_name": "Martinez",
165
+ "email": "linda.martinez@phoenixmfg.com",
166
+ "phone": "+1-555-0802",
167
+ "job_title": "Quality Control Supervisor",
168
+ "company": "Phoenix Manufacturing",
169
+ "website": "https://phoenixmfg.com"
170
+ },
171
+ {
172
+ "id": 17,
173
+ "first_name": "Patricia",
174
+ "last_name": "White",
175
+ "email": "patricia.white@alpineeducation.edu",
176
+ "phone": "+1-555-0901",
177
+ "job_title": "Director of Programs",
178
+ "company": "Alpine Education Group",
179
+ "website": "https://alpineeducation.edu"
180
+ },
181
+ {
182
+ "id": 18,
183
+ "first_name": "Kevin",
184
+ "last_name": "Brown",
185
+ "email": "kevin.brown@alpineeducation.edu",
186
+ "phone": "+1-555-0902",
187
+ "job_title": "Curriculum Specialist",
188
+ "company": "Alpine Education Group",
189
+ "website": "https://alpineeducation.edu"
190
+ },
191
+ {
192
+ "id": 19,
193
+ "first_name": "Sophia",
194
+ "last_name": "Taylor",
195
+ "email": "sophia@crimsoncreative.studio",
196
+ "phone": "+1-555-1001",
197
+ "job_title": "Art Director",
198
+ "company": "Crimson Creative Studio",
199
+ "website": "https://crimsoncreative.studio"
200
+ },
201
+ {
202
+ "id": 20,
203
+ "first_name": "Alex",
204
+ "last_name": "Cooper",
205
+ "email": "alex.cooper@crimsoncreative.studio",
206
+ "phone": "+1-555-1002",
207
+ "job_title": "Graphic Designer",
208
+ "company": "Crimson Creative Studio",
209
+ "website": "https://crimsoncreative.studio"
210
+ }
211
+ ]
212
+
213
+ def extract_domain(url):
214
+ """Extract domain from URL"""
215
+ try:
216
+ parsed = urlparse(url)
217
+ return parsed.netlify.lower()
218
+ except:
219
+ return ""
220
+
221
+ def find_contacts_by_website(website_url):
222
+ """Find contacts that match the website domain"""
223
+ target_domain = extract_domain(website_url)
224
+ if not target_domain:
225
+ return []
226
+
227
+ matching_contacts = []
228
+ for contact in CONTACTS_DB:
229
+ contact_domain = extract_domain(contact['website'])
230
+ if target_domain in contact_domain or contact_domain in target_domain:
231
+ matching_contacts.append(contact)
232
+
233
+ return matching_contacts
234
+
235
+ def simulate_website_scraping(url):
236
+ """Simulate scraping a website and finding contact information"""
237
+ # Add some delay to simulate real scraping
238
+ time.sleep(random.uniform(1, 3))
239
+
240
+ # Find matching contacts from our database
241
+ contacts = find_contacts_by_website(url)
242
+
243
+ if not contacts:
244
+ # If no exact match, return a random subset as if found on the website
245
+ contacts = random.sample(CONTACTS_DB, min(3, len(CONTACTS_DB)))
246
+
247
+ return contacts
248
+
249
+ def search_website_contacts(website_url, max_results=10):
250
+ """Main function to search for contacts on a website"""
251
+ if not website_url:
252
+ return "Please enter a website URL", ""
253
+
254
+ # Clean up URL
255
+ if not website_url.startswith(('http://', 'https://')):
256
+ website_url = 'https://' + website_url
257
+
258
+ try:
259
+ # Simulate finding contacts
260
+ contacts = simulate_website_scraping(website_url)
261
+
262
+ if not contacts:
263
+ return "No contacts found on this website.", ""
264
+
265
+ # Limit results
266
+ contacts = contacts[:max_results]
267
+
268
+ # Format results
269
+ results_text = f"Found {len(contacts)} contacts on {website_url}:\n\n"
270
+
271
+ contact_data = []
272
+ for i, contact in enumerate(contacts, 1):
273
+ results_text += f"**Contact {i}:**\n"
274
+ results_text += f"β€’ First Name: {contact['first_name']}\n"
275
+ results_text += f"β€’ Last Name: {contact['last_name']}\n"
276
+ results_text += f"β€’ Job Title: {contact['job_title']}\n"
277
+ results_text += f"β€’ Email: {contact['email']}\n"
278
+ results_text += f"β€’ Phone: {contact['phone']}\n"
279
+ results_text += f"β€’ Company: {contact['company']}\n\n"
280
+
281
+ # Prepare data for CSV/table format
282
+ contact_data.append([
283
+ contact['first_name'],
284
+ contact['last_name'],
285
+ contact['job_title'],
286
+ contact['email'],
287
+ contact['phone'],
288
+ contact['company']
289
+ ])
290
+
291
+ # Create a simple table format for the second output
292
+ table_text = "First Name,Last Name,Job Title,Email,Phone,Company\n"
293
+ for contact in contacts:
294
+ table_text += f"{contact['first_name']},{contact['last_name']},{contact['job_title']},{contact['email']},{contact['phone']},{contact['company']}\n"
295
+
296
+ return results_text, table_text
297
+
298
+ except Exception as e:
299
+ return f"Error searching website: {str(e)}", ""
300
+
301
+ def get_all_available_websites():
302
+ """Get list of all available websites from the database"""
303
+ websites = list(set([contact['website'] for contact in CONTACTS_DB]))
304
+ return "\n".join(sorted(websites))
305
+
306
+ # Create Gradio interface
307
+ with gr.Blocks(title="Website Contact Finder", theme=gr.themes.Soft()) as app:
308
+ gr.HTML("""
309
+ <div style="text-align: center; padding: 20px;">
310
+ <h1>πŸ” Website Contact Finder</h1>
311
+ <p>Search any website to find contact information including names, job titles, phone numbers, and emails</p>
312
+ </div>
313
+ """)
314
+
315
+ with gr.Row():
316
+ with gr.Column(scale=2):
317
+ website_input = gr.Textbox(
318
+ label="Website URL",
319
+ placeholder="Enter website URL (e.g., techflowsolutions.com or https://greenleafconsult.com)",
320
+ value=""
321
+ )
322
+
323
+ max_results = gr.Slider(
324
+ minimum=1,
325
+ maximum=20,
326
+ value=5,
327
+ step=1,
328
+ label="Maximum Results"
329
+ )
330
+
331
+ search_btn = gr.Button("πŸ” Search Contacts", variant="primary", size="lg")
332
+
333
+ with gr.Column(scale=1):
334
+ gr.HTML("""
335
+ <div style="background: #f0f0f0; padding: 15px; border-radius: 10px;">
336
+ <h3>πŸ’‘ Tips:</h3>
337
+ <ul>
338
+ <li>Enter any website URL</li>
339
+ <li>Works with or without https://</li>
340
+ <li>Try our sample websites below</li>
341
+ <li>Results include full contact details</li>
342
+ </ul>
343
+ </div>
344
+ """)
345
+
346
+ with gr.Row():
347
+ results_display = gr.Textbox(
348
+ label="Contact Results",
349
+ lines=15,
350
+ max_lines=30,
351
+ show_copy_button=True
352
+ )
353
+
354
+ csv_output = gr.Textbox(
355
+ label="CSV Format (Copy & Paste into Excel)",
356
+ lines=15,
357
+ max_lines=30,
358
+ show_copy_button=True
359
+ )
360
+
361
+ # Sample websites section
362
+ with gr.Accordion("πŸ“‹ Available Sample Websites", open=False):
363
+ sample_websites = gr.Textbox(
364
+ label="Sample Websites from Database",
365
+ value=get_all_available_websites(),
366
+ lines=10,
367
+ interactive=False
368
+ )
369
+
370
+ # Quick search buttons for sample websites
371
+ with gr.Row():
372
+ gr.HTML("<h3>πŸš€ Quick Search Sample Websites:</h3>")
373
+
374
+ with gr.Row():
375
+ quick_btn1 = gr.Button("TechFlow Solutions", size="sm")
376
+ quick_btn2 = gr.Button("GreenLeaf Consulting", size="sm")
377
+ quick_btn3 = gr.Button("BlueSky Marketing", size="sm")
378
+ quick_btn4 = gr.Button("Quantum Dynamics", size="sm")
379
+
380
+ with gr.Row():
381
+ quick_btn5 = gr.Button("Stellar Logistics", size="sm")
382
+ quick_btn6 = gr.Button("Nexus Financial", size="sm")
383
+ quick_btn7 = gr.Button("Horizon Health", size="sm")
384
+ quick_btn8 = gr.Button("Phoenix Manufacturing", size="sm")
385
+
386
+ # Event handlers
387
+ search_btn.click(
388
+ fn=search_website_contacts,
389
+ inputs=[website_input, max_results],
390
+ outputs=[results_display, csv_output]
391
+ )
392
+
393
+ # Quick search button handlers
394
+ quick_btn1.click(lambda: "techflowsolutions.com", outputs=website_input)
395
+ quick_btn2.click(lambda: "greenleafconsult.com", outputs=website_input)
396
+ quick_btn3.click(lambda: "blueskymarketing.net", outputs=website_input)
397
+ quick_btn4.click(lambda: "quantumdynamics.org", outputs=website_input)
398
+ quick_btn5.click(lambda: "stellarlogistics.biz", outputs=website_input)
399
+ quick_btn6.click(lambda: "nexusfinancial.pro", outputs=website_input)
400
+ quick_btn7.click(lambda: "horizonhealth.care", outputs=website_input)
401
+ quick_btn8.click(lambda: "phoenixmfg.com", outputs=website_input)
402
+
403
+ # Examples
404
+ gr.Examples(
405
+ examples=[
406
+ ["techflowsolutions.com", 5],
407
+ ["https://greenleafconsult.com", 3],
408
+ ["blueskymarketing.net", 2],
409
+ ["quantumdynamics.org", 4]
410
+ ],
411
+ inputs=[website_input, max_results]
412
+ )
413
+
414
+ if __name__ == "__main__":
415
+ app.launch()