← back to Rentv Sheet Enrich

analyze_colors.py

71 lines

#!/usr/bin/env python3
"""
analyze_colors.py — READ-ONLY. For every tab, tally the EXACT background color of every
non-white, non-enrichment-green cell, BY COLUMN, so we can see which column carries each
row's status color-coding. Writes NOTHING.
"""
import sys, os, json, urllib.request, urllib.parse
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import lib

def api(url, tok):
    r = urllib.request.Request(url, headers={"Authorization": f"Bearer {tok}"})
    return json.load(urllib.request.urlopen(r))

G = lib.GREEN
def is_green(bg):
    return bool(bg) and abs(bg.get("red",1)-G["red"])<0.06 and \
        abs(bg.get("green",1)-G["green"])<0.06 and abs(bg.get("blue",1)-G["blue"])<0.06
def hexc(bg):
    if not bg: return None
    r,g,b = bg.get("red",0.0),bg.get("green",0.0),bg.get("blue",0.0)
    if r>0.96 and g>0.96 and b>0.96: return None
    if (max(r,g,b)-min(r,g,b))<0.04 and min(r,g,b)>0.91: return None
    return "#%02x%02x%02x" % (round(r*255),round(g*255),round(b*255))

tok = lib.access_token()
sheets = [(s["properties"]["sheetId"], s["properties"]["title"])
          for s in lib.get_meta(tok)["sheets"]]
qs = "&".join("ranges="+urllib.parse.quote("'"+t.replace("'","''")+"'",safe="") for _,t in sheets)
# values (for headers) + backgrounds
vals = api(f"{lib.API}/{lib.SID}/values:batchGet?{qs}&majorDimension=ROWS&valueRenderOption=FORMATTED_VALUE", tok)
vr = {t: v.get("values",[]) for (_,t),v in zip(sheets, vals.get("valueRanges",[]))}
fmt = api(f"{lib.API}/{lib.SID}?{qs}&includeGridData=true"
          "&fields=sheets(properties(sheetId,title),data.rowData.values.effectiveFormat.backgroundColor)", tok)

def header_row(rows):
    best,bi=-1,0
    for i in range(min(4,len(rows))):
        n=sum(1 for c in rows[i] if str(c).strip())
        if n>best: best,bi=n,i
    return bi

overall={}
print("=== PER-TAB, PER-COLUMN COLOR TALLY (data rows only) ===")
for sh in fmt.get("sheets",[]):
    gid=sh["properties"]["sheetId"]; title=sh["properties"]["title"]
    rows=vr.get(title,[])
    if not rows: continue
    hr=header_row(rows)
    hdr=[str(x).strip() for x in rows[hr]]
    grid=(sh.get("data") or [{}])[0].get("rowData",[])
    colcolors={}  # col -> {hex:count}
    for ri,row in enumerate(grid):
        if ri<=hr: continue
        for ci,cell in enumerate(row.get("values",[]) or []):
            bg=(cell.get("effectiveFormat") or {}).get("backgroundColor")
            if is_green(bg): continue
            hx=hexc(bg)
            if hx:
                colcolors.setdefault(ci,{}); colcolors[ci][hx]=colcolors[ci].get(hx,0)+1
                overall[hx]=overall.get(hx,0)+1
    if not colcolors: continue
    print(f"\n## {title}  (gid={gid}, header_row={hr}, cols={len(hdr)})")
    for ci in sorted(colcolors):
        h = hdr[ci] if ci<len(hdr) else ""
        dist=", ".join(f"{k}:{v}" for k,v in sorted(colcolors[ci].items(),key=lambda kv:-kv[1]))
        print(f"  col{ci:>2} [{h[:28]:28}] {dist}")
print("\n=== OVERALL COLOR TOTALS ===")
for k,v in sorted(overall.items(),key=lambda kv:-kv[1]):
    print(f"  {k}: {v}")