← back to Rentv Sheet Enrich
Write-back APPLIED (Steve approved, Option A): 204 MX-valid inferred emails -> live RENTV sheet, ADD-only
a04a7d79b3b595cbc71427b2efd3f025627bc52d · 2026-08-14 07:35:34 -0700 · Steve Abrams
Files touched
M rentv_recovered_ALL.csvA writeback.py
Diff
commit a04a7d79b3b595cbc71427b2efd3f025627bc52d
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Aug 14 07:35:34 2026 -0700
Write-back APPLIED (Steve approved, Option A): 204 MX-valid inferred emails -> live RENTV sheet, ADD-only
---
rentv_recovered_ALL.csv | 8 +++++
writeback.py | 88 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+)
diff --git a/rentv_recovered_ALL.csv b/rentv_recovered_ALL.csv
index c12e0b4..1cac6ea 100644
--- a/rentv_recovered_ALL.csv
+++ b/rentv_recovered_ALL.csv
@@ -33,6 +33,7 @@ Andy Stone,Vero Capital,andy.stone@verocapital.com,yes,web-lookup,first.last,,Pr
Hamid Rezapour,Vertical Ventures,hamid.rezapour@verticalventuresllc.com,yes,web-lookup,first.last,,Prospect / Follow-up,4
Debbie Chatman,American Landmark Apartments,debbie.chatman@alapts.com,yes,web-lookup,first.last,,Active / Contacted,3
Debra Claytor,American Landmark Apartments,debra.claytor@alapts.com,yes,web-lookup,first.last,,Active / Contacted,3
+Scott Drucker,Arizona Association of Realtors,scott.drucker@aaronline.com,yes,web-lookup,first.last,,Active / Contacted,3
Mark Edelman,Arizona State Land Dept,mark.edelman@land.az.gov,yes,web-lookup,first.last,602-542-4631,Active / Contacted,3
Brad Richardson,Ascent Companies,brad.richardson@ascentcos.com,yes,web-lookup,first.last,,Active / Contacted,3
Robert Hallock,Bridge,rhallock@bridgedev.com,yes,normalization,pattern,,Needs Email / Outreach Pending,3
@@ -52,6 +53,7 @@ Patrick Maloney,Circle Industrial,patrick.maloney@circle-industrial.com,yes,web-
Jason Lentz,Conor Commercial,jason.lentz@conor.com,yes,web-lookup,first.last,,Prospect / Follow-up,3
Kris Miller,Conor Commercial,kris.miller@conor.com,yes,web-lookup,first.last,,Prospect / Follow-up,3
Sven Tustin,Conor Commercial,sven.tustin@conor.com,yes,web-lookup,first.last,,Prospect / Follow-up,3
+Zach Tolson,Creation RE + PE,zach.tolson@creationequity.com,yes,web-lookup,first.last,,Prospect / Follow-up,3
Bert Getz,Globe Corporation,bert.getz@globecor.com,yes,web-lookup,first.last,480-991-0500,Prospect / Follow-up,3
George Getz,Globe Corporation,george.getz@globecor.com,yes,web-lookup,first.last,480-991-0500,Prospect / Follow-up,3
Michael Olsen,Globe Corporation,michael.olsen@globecor.com,yes,web-lookup,first.last,480-991-0500,Prospect / Follow-up,3
@@ -67,6 +69,7 @@ Aiza Kelley,Olympus Property,aiza.kelley@olympusproperty.com,yes,web-lookup,firs
Gerrt Ranglas,R & V Management,gerrt.ranglas@rvmsandiego.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,3
Michael Pappas,R & V Management,michael.pappas@rvmsandiego.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,3
Scott Dale,R & V Management,scott.dale@rvmsandiego.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,3
+Raymond Hightower,ROIClear,raymond.hightower@roiclear.com,yes,web-lookup,first.last,,Prospect / Follow-up,3
Karla Teixeira,Salt River Project,karla.teixeira@srpnet.com,yes,web-lookup,first.last,,Prospect / Follow-up,3
Bryan Ayres,Solid Door Investments,bryan.ayres@soliddoorinvestments.com,yes,web-lookup,first.last,623-850-4577,Prospect / Follow-up,3
Andy Smith,The Empire Group of Companies,andy.smith@builtbyempire.com,yes,web-lookup,first.last,,Prospect / Follow-up,3
@@ -114,6 +117,7 @@ Diane Defibaugh,CIM Group,ddefibaugh@cimgroup.com,yes,normalization,pattern,,Act
Jason Schreider,CIM Group,jschreider@cimgroup.com,yes,normalization,pattern,,Active / Contacted,2
Ken Kahan,California Landmark Group,ken.kahan@californialandmark.com,yes,normalization,first.last,,Needs Email / Outreach Pending,2
Prisciila Annoual-Kirbby,Catalyst Commercial Group,prisciila.annoualkirbby@ccgretail.com,yes,normalization,first.last,,Active / Contacted,2
+Amber Zamora,Concrete West Construction,amber.zamora@concretewest.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,2
Adam Holt,Continental Realty Group,adam.holt@continentalrealtygroup.com,yes,web-lookup,first.last,,Prospect / Follow-up,2
Robert Ireland,Continental Realty Group,robert.ireland@continentalrealtygroup.com,yes,web-lookup,first.last,,Prospect / Follow-up,2
AARON WESTBROOK,Contour LV,aaron.westbrook@contourre.com,yes,web-lookup,first.last,800-964-8110,Active / Contacted,2
@@ -134,6 +138,7 @@ Jennifer Walton,H. Hendy Associates,jennifer.walton@hhendy.com,yes,web-lookup,fi
John Kratzer,JMI Realty,john@jmirealestate.com,yes,normalization,pattern,,Needs Email / Outreach Pending,2
Madison Berry,JW Marriott Scottsdale Camelback Inn,madison.berry@marriott.com,yes,web-lookup,first.last,,Prospect / Follow-up,2
Miriam Campos,JW Marriott Scottsdale Camelback Inn,miriam.campos@marriott.com,yes,web-lookup,first.last,,Prospect / Follow-up,2
+Allan Gutkin,Jag Development,allan.gutkin@jagdevelopment.com,yes,web-lookup,first.last,,Prospect / Follow-up,2
Jeff Dritley,Kearny Real Estate Co,jeff.dritley@kearny.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,2
Steven Hillgren,Kearny Real Estate Co,steven.hillgren@kearny.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,2
Brian Rosella,Kidder,brian.rosella@kidder.com,yes,web-lookup,first.last,,Active / Contacted,2
@@ -170,8 +175,10 @@ Andrew Goncalves,Realconnex,andrew.goncalves@realconnex.com,yes,normalization,fi
Demetrios Louziotis,Realnex,demetrios.louziotis@realnex.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,2
Jeff Finn,Realnex,jeff.finn@realnex.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,2
Mark Kingston,Realnex,mark.kingston@realnex.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,2
+Alyssa Vanessa,Royal Palms Resort & Spa by Hyatt,alyssa.vanessa@hyatt.com,yes,web-lookup,first.last,,Flag / Priority,2
David Frank,SVN Dealpoint Merrill,dfrank@dealpointmerrill.com,yes,normalization,pattern,,Needs Email / Outreach Pending,2
Kevin Maggiacomo,SVN Dealpoint Merrill,kmaggiacomo@dealpointmerrill.com,yes,normalization,pattern,,Active / Contacted,2
+Aaron Gutierrez,SVN Desert Commercial Advisors,aaron.gutierrez@svndesertcommercial.com,yes,web-lookup,first.last,480-425-5500,Active / Contacted,2
Audrey Carlson,SVN | SFR Capital Management,audreycarlson@svn.com,yes,normalization,pattern,,Active / Contacted,2
Jeff Cline,SVN | SFR Capital Management,jeffcline@svn.com,yes,normalization,pattern,,Active / Contacted,2
Christina Blaser,Schnitzer,christina.blaser@harsch.com,yes,normalization,first.last,,Needs Email / Outreach Pending,2
@@ -181,6 +188,7 @@ Ana Munoz,Socotra,ana.munoz@socotracapital.com,yes,normalization,first.last,,Act
Tom Regan,Starwood Capital,tregan@starwood.com,yes,normalization,pattern,,Needs Email / Outreach Pending,2
Steven Ludwig,Strategic Housing Partners,steven.ludwig@coastlinerea.com,yes,normalization,first.last,,Needs Email / Outreach Pending,2
Steve Ludwig,Strategic Housing partners,steve.ludwig@coastlinerea.com,yes,normalization,first.last,,Active / Contacted,2
+Andrea Piering,Sun State Builders,andrea.piering@sunstatebuilders.com,yes,web-lookup,first.last,,Active / Contacted,2
Aaron Feldman,Sunroad Enterprises,aaron.feldman@sunroadenterprises.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,2
Richard Vann,Sunroad Enterprises,richard.vann@sunroadenterprises.com,yes,web-lookup,first.last,,Needs Email / Outreach Pending,2
Arcg For,TCA Archtects,arcg.for@tca-arch.com,yes,web-lookup,first.last,213-553-1100,Needs Email / Outreach Pending,2
diff --git a/writeback.py b/writeback.py
new file mode 100644
index 0000000..ce7f6e1
--- /dev/null
+++ b/writeback.py
@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+"""
+writeback.py — write the recovered emails into the LIVE RENTV sheet's
+"Likely Email (inferred)" column. ADD-only, MX-valid-only (Option A).
+
+Approved by Steve 2026-08-14 ("go approved" -> Option A).
+
+Safety:
+ * reads the LIVE tab (authoritative current state),
+ * writes ONLY the "Likely Email (inferred)" column — NEVER the verified Email,
+ * writes a row ONLY if all three email fields are still EMPTY (never overwrites),
+ * Option A: skips any recovered email whose domain is not MX-valid,
+ * matches each recovered email to its row by (Contact Name + Company/Venue),
+ * --dry-run reports counts and writes NOTHING; --apply performs the batch_fill.
+
+Uses the exact row0 convention infer_emails.py uses (row0 = index into the full
+rows array, 0 = header row).
+"""
+import sys, os, csv
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+import lib
+
+APPLY = "--apply" in sys.argv
+GID = 3823360
+TITLE = "Unique Contacts (all tabs)"
+
+def norm(s): return (s or "").strip()
+
+# 1) load recovered master, Option A filter (MX-valid only)
+recov = [r for r in csv.DictReader(open("rentv_recovered_ALL.csv")) if r["Domain MX"] == "yes"]
+skipped_nomx = sum(1 for r in csv.DictReader(open("rentv_recovered_ALL.csv")) if r["Domain MX"] != "yes")
+# index by (name, company) -> email (first wins)
+want = {}
+for r in recov:
+ k = (norm(r["Contact Name"]).lower(), norm(r["Company"]).lower())
+ want.setdefault(k, r["Recovered Email"])
+
+# 2) live read
+tok = lib.access_token()
+rows = lib.read_tab(tok, TITLE)
+H = [h.strip() for h in rows[0]]
+c = {v: i for i, v in enumerate(H) if v}
+def g(r, i): return norm(r[i]) if (i is not None and i < len(r)) else ""
+NAME, CO = c["Contact Name"], c["Company/Venue"]
+EMAIL, UEM = c["Email"], c["Updated Email (found)"]
+INF = c.get("Likely Email (inferred)")
+if INF is None:
+ INF = max(c.values()) + 1
+ if APPLY:
+ lib.batch_fill(tok, GID, [{"row0": 0, "col0": INF, "value": "Likely Email (inferred)"}])
+ print(f"note: 'Likely Email (inferred)' column created at col {INF}")
+
+# 3) match + build write cells (ADD-only, empty rows only)
+cells = []
+matched, already, nomatch = 0, 0, 0
+used = set()
+for ri in range(1, len(rows)):
+ r = rows[ri]
+ nm, co = g(r, NAME), g(r, CO)
+ if not nm:
+ continue
+ k = (nm.lower(), co.lower())
+ if k not in want:
+ continue
+ # only write if the row currently has NO email in any of the three fields
+ if g(r, EMAIL) or g(r, UEM) or (INF < len(r) and norm(r[INF])):
+ already += 1
+ continue
+ cells.append({"row0": ri, "col0": INF, "value": want[k]})
+ used.add(k)
+ matched += 1
+
+unmatched = [k for k in want if k not in used]
+
+print(f"Option A (MX-valid only): {len(recov)} recovered emails in scope ({skipped_nomx} low-confidence skipped)")
+print(f" rows to WRITE (empty + matched): {matched}")
+print(f" matched rows already had an email (skipped): {already}")
+print(f" recovered emails with NO matching empty live row: {len(unmatched)}")
+if unmatched[:5]:
+ print(" e.g.", [f'{n}@{co}' for n, co in unmatched[:5]])
+
+if not APPLY:
+ print(f"\nDRY-RUN — nothing written. Re-run with --apply to write {matched} cells.")
+else:
+ # batch in chunks to be safe
+ for i in range(0, len(cells), 200):
+ lib.batch_fill(tok, GID, cells[i:i+200])
+ print(f"\nAPPLIED — wrote {len(cells)} inferred emails to '{TITLE}' (green-flagged, ADD-only).")
← 5f935c7 Loop tick 9: +8 domains (69 total), Wren + AT Real Estate he
·
back to Rentv Sheet Enrich
·
Loop tick 10: +7 domains (76 total), PICOR label-disambiguat be06d7e →