# Retry: build the HTML using placeholder substitution to avoid f-string conflicts with JS template literals. from pathlib import Path import re, json raw_entries = [ ("Fellowship, Crown of Life", "Phone: (717) 575-9091"), ("SVPM", "Phone: (717) 467-1637"), ("Bell, JD", "Phone: (423) 883-3229"), ("High Impact Property Management", "Mobile: (814) 244-6528"), ("Pristine Clean", "Phone: (717) 219-7199"), ("Mariano & Sam T-Shirt Business LLC", "Phone: (717) 945-8695"), ("Groff, Stephanie", "mobile: (717) 471-0451"), ("Dasgupta, Sri", "mobile: (650) 704-5384"), ("Higher Impact", "Phone: (717) 201-8536"), ("Wolfe, Lee", "Phone: (717) 587-6805"), ("Referral Partners Plus Lancaster East Chapter", "Phone: (717) 394-5009"), ("Akita Pest Control", ""), ("Hoover, Steve", "Home: (717) 224-1313"), ("Floor Coverings International", "Mobile: +1(717) 587-2992"), ("Preferred Office Network", "Phone: (571) 895-7916"), ("Attain ABA", "Phone: (848) 266-0569"), ("CCCPA", "Phone: (717) 858-2803"), ("CCCPA", "Phone: (717) 858-2803"), ("Preferred Office Network", "Phone: (571) 895-7916"), ("EMR Associates", "Phone: (717) 344-4174"), ("Flores, Rachel", "Phone: (717) 421-6552"), ("Liberty Marketing Inc.", "Phone: (609) 205-0129"), ("Pure Clean", "Phone: (410) 365-2686"), ("United Family Inclusive Living Center Inc", "Home: (267) 235-7909"), ("Bollard, Dave", "Phone: (609) 577-6885"), ("CPH Security Group", "Phone: (267) 473-5373, Phone: (609) 577-6885"), ("Referral Partners Plus", "Phone: (717) 394-5009"), ("GM Property Solutions", "Phone: (717) 471-4742"), ("Fairway Independent Mortgage Corporation", "Phone: (717) 571-6384"), ("Fairway Independent Mortgage Corporation", "Phone: (717) 571-6384"), ("Home365", "Phone: (619) 992-5998"), ("Lancaster Roofing Company", "Phone: (717) 205-1900"), ] def parse_numbers(field): results = [] parts = [p.strip() for p in field.split(",") if p.strip()] if field else [] if not parts and field: parts = [field] import re for p in parts: t_match = re.match(r"(Mobile|mobile|Phone|Home)\s*:\s*(.*)", p) ptype = None rest = p if t_match: ptype = t_match.group(1).capitalize() rest = t_match.group(2) nums = re.findall(r"\+?\d[\d\-\s\(\)]{6,}\d", rest) if not nums: continue for n in nums: display = n digits = re.sub(r"[^\d+]", "", n) just = re.sub(r"\D", "", digits) if digits and digits[0] != '+' and len(just) == 10: digits_norm = f"+1{just}" else: if len(just) == 11 and just.startswith("1"): digits_norm = f"+{just}" else: digits_norm = digits if digits.startswith("+") else (f"+{just}" if just else "") results.append({"type": ptype or "Phone", "display": display, "digits": digits_norm}) return results tenants = {} for name, field in raw_entries: numbers = parse_numbers(field) if name not in tenants: tenants[name] = {"name": name, "phones": []} for num in numbers: if num["digits"] and all(num["digits"] != e["digits"] for e in tenants[name]["phones"]): tenants[name]["phones"].append(num) tenant_list = sorted(tenants.values(), key=lambda x: x["name"].lower()) tenants_json = json.dumps(tenant_list, indent=2) html_base = """ The Hive • Tenant Directory
The Hive • Tenant Directory
""" html = html_base.replace("__TENANTS__", tenants_json) out = Path("/mnt/data/hive-directory.html") out.write_text(html, encoding="utf-8") print(str(out))