suggest-orgs / src /render.py
amanydv2112's picture
Upload folder using huggingface_hub
818799a verified
Raw
History Blame Contribute Delete
9.73 kB
"""Server-rendered HTML for company detail pages (SEO-friendly)."""
import os
from html import escape
SITE_URL = os.environ.get("SITE_URL", "https://amanydv2112-suggest-orgs.hf.space").rstrip("/")
SOURCE_LABELS = {
"yc": "Y Combinator",
"a16z": "a16z",
"spc": "South Park Commons",
"sequoia": "Sequoia",
}
def _esc(v) -> str:
return escape(str(v)) if v else ""
def _truncate(text: str, n: int) -> str:
text = (text or "").strip()
return text if len(text) <= n else text[: n - 1].rstrip() + "…"
def company_path(c: dict) -> str:
return f"/company/{c['source']}/{c['slug']}"
def company_url(c: dict) -> str:
return SITE_URL + company_path(c)
# ── section builders (each returns "" when there's nothing to show) ─────────
def _pills(c: dict) -> str:
parts = []
label = SOURCE_LABELS.get(c.get("source"), c.get("source") or "")
parts.append(f'<span class="pill source-{_esc(c.get("source"))}">{_esc(label)}</span>')
if c.get("batch"):
parts.append(f'<span class="pill batch">{_esc(c["batch"])}</span>')
if c.get("status"):
parts.append(f'<span class="pill status-{_esc(str(c["status"]).lower())}">{_esc(c["status"])}</span>')
for ind in (c.get("industries") or [])[:3]:
parts.append(f'<span class="pill">{_esc(ind)}</span>')
for tag in (c.get("tags") or [])[:4]:
parts.append(f'<span class="pill">{_esc(tag)}</span>')
return "".join(parts)
def _socials(c: dict) -> str:
s = c.get("_socials") or {}
links = []
if c.get("website"):
links.append(f'<a class="social-link primary" href="{_esc(c["website"])}" target="_blank" rel="noopener">Visit website β†—</a>')
for key, label in [("linkedin", "LinkedIn"), ("twitter", "X"), ("github", "GitHub"), ("crunchbase", "Crunchbase")]:
if s.get(key):
links.append(f'<a class="social-link" href="{_esc(s[key])}" target="_blank" rel="noopener">{label} β†—</a>')
return f'<div class="social-row">{"".join(links)}</div>' if links else ""
def _narrative(c: dict) -> str:
rows = []
for label, key in [("Problem", "_problem"), ("Solution", "_solution"), ("Who it's for", "_customer")]:
if c.get(key):
rows.append(f'<div class="narrative-row"><span class="narrative-label">{label}</span><p>{_esc(c[key])}</p></div>')
if not rows and c.get("long_description"):
rows.append(f'<div class="narrative-row"><p>{_esc(c["long_description"])}</p></div>')
return f'<section class="detail-section"><h2>What they do</h2>{"".join(rows)}</section>' if rows else ""
def _timeline(c: dict) -> str:
events = []
if c.get("_year_founded"):
events.append(("Founded", str(c["_year_founded"])))
if c.get("batch") and c.get("source") == "yc":
events.append(("YC batch", str(c["batch"])))
if c.get("acquirer"):
events.append(("Acquired", f'by {c["acquirer"]}'))
if c.get("status"):
events.append(("Status", str(c["status"])))
if c.get("team_size"):
events.append(("Team size", f'{c["team_size"]} people'))
if c.get("location"):
events.append(("Location", str(c["location"])))
if not events:
return ""
items = "".join(
f'<li><span class="tl-label">{_esc(l)}</span><span class="tl-value">{_esc(v)}</span></li>'
for l, v in events
)
return f'<section class="detail-section"><h2>Company timeline</h2><ul class="timeline">{items}</ul></section>'
def _founders(c: dict) -> str:
founders = c.get("_founders") or []
if not founders:
return ""
cards = []
for f in founders:
avatar = (
f'<img class="founder-avatar" src="{_esc(f["avatar_url"])}" alt="" loading="lazy" onerror="this.style.display=\'none\'">'
if f.get("avatar_url") else '<div class="founder-avatar placeholder"></div>'
)
socials = []
if f.get("linkedin"):
socials.append(f'<a href="{_esc(f["linkedin"])}" target="_blank" rel="noopener">LinkedIn</a>')
if f.get("twitter"):
socials.append(f'<a href="{_esc(f["twitter"])}" target="_blank" rel="noopener">X</a>')
if f.get("profile_url"):
socials.append(f'<a href="{_esc(f["profile_url"])}" target="_blank" rel="noopener">Profile</a>')
social_html = f'<div class="founder-socials">{" Β· ".join(socials)}</div>' if socials else ""
title = f'<div class="founder-title">{_esc(f["title"])}</div>' if f.get("title") else ""
bio = f'<p class="founder-bio">{_esc(f["bio"])}</p>' if f.get("bio") else ""
cards.append(
f'<div class="founder-card">{avatar}<div class="founder-body">'
f'<div class="founder-name">{_esc(f.get("name"))}</div>{title}{bio}{social_html}'
f'</div></div>'
)
return f'<section class="detail-section"><h2>Founders</h2><div class="founder-grid">{"".join(cards)}</div></section>'
def _jobs(c: dict) -> str:
jobs = c.get("_jobs") or []
if not jobs:
return ""
rows = []
for j in jobs:
meta = " Β· ".join(
_esc(x) for x in [j.get("location"), j.get("type"), j.get("salary"), j.get("equity")] if x
)
apply = j.get("apply_url") or j.get("url")
btn = f'<a class="job-apply" href="{_esc(apply)}" target="_blank" rel="noopener">Apply β†—</a>' if apply else ""
rows.append(
f'<div class="job-row"><div class="job-info"><div class="job-title">{_esc(j.get("title"))}</div>'
f'{f"<div class=\"job-meta\">{meta}</div>" if meta else ""}</div>{btn}</div>'
)
return (
f'<section class="detail-section"><h2>Open roles <span class="count">{len(jobs)}</span></h2>'
f'<div class="job-list">{"".join(rows)}</div></section>'
)
def _similar(similar: list[dict]) -> str:
if not similar:
return ""
cards = []
for s in similar:
logo = (
f'<img class="sim-logo" src="{_esc(s["logo_url"])}" alt="" loading="lazy" onerror="this.style.display=\'none\'">'
if s.get("logo_url") else '<div class="sim-logo placeholder"></div>'
)
cards.append(
f'<a class="sim-card" href="{_esc(company_path(s))}">{logo}'
f'<div class="sim-body"><div class="sim-name">{_esc(s.get("name"))}</div>'
f'<div class="sim-oneliner">{_esc(_truncate(s.get("one_liner") or "", 70))}</div></div></a>'
)
return f'<section class="detail-section"><h2>Similar startups</h2><div class="sim-grid">{"".join(cards)}</div></section>'
# ── page shell ───────────────────────────────────────────────────────────────
def render_company_page(company: dict, similar: list[dict], git_rev: str = "1") -> str:
c = company
name = c.get("name") or "Company"
one_liner = c.get("one_liner") or ""
source_label = SOURCE_LABELS.get(c.get("source"), c.get("source") or "")
desc = _truncate(c.get("_problem") or one_liner or c.get("long_description") or "", 155)
tagline = _truncate(one_liner, 60)
title = f"{name} β€” {tagline} | NicheFind" if tagline else f"{name} | NicheFind"
canonical = company_url(c)
og_image = c.get("logo_url") or f"{SITE_URL}/static/og-image.png"
logo = (
f'<img class="detail-logo" src="{_esc(c["logo_url"])}" alt="{_esc(name)} logo" onerror="this.style.display=\'none\'">'
if c.get("logo_url") else '<div class="detail-logo placeholder"></div>'
)
body = "".join([
_narrative(c),
_founders(c),
_jobs(c),
_timeline(c),
_similar(similar),
])
return f"""<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{_esc(title)}</title>
<meta name="description" content="{_esc(desc)}">
<link rel="canonical" href="{_esc(canonical)}">
<meta property="og:title" content="{_esc(name)} β€” {_esc(source_label)}">
<meta property="og:description" content="{_esc(desc)}">
<meta property="og:type" content="website">
<meta property="og:url" content="{_esc(canonical)}">
<meta property="og:image" content="{_esc(og_image)}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{_esc(name)} β€” {_esc(source_label)}">
<meta name="twitter:description" content="{_esc(desc)}">
<meta name="twitter:image" content="{_esc(og_image)}">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/static/style.css?v={git_rev}">
<link rel="stylesheet" href="/static/company.css?v={git_rev}">
<script defer src="https://cloud.umami.is/script.js" data-website-id="4cad66f8-6c9d-40a2-b339-c18e5df9507a"></script>
</head>
<body>
<div class="container detail-container">
<a class="back-link" id="back-link" href="/">← Back to search</a>
<header class="detail-header">
{logo}
<div class="detail-heading">
<h1>{_esc(name)}</h1>
<p class="detail-oneliner">{_esc(one_liner)}</p>
<div class="detail-pills">{_pills(c)}</div>
</div>
</header>
{_socials(c)}
{body}
</div>
<footer class="site-footer">
<p>Data sourced from public accelerator portfolios. <a href="/">Search all startups β†’</a></p>
</footer>
<script src="/static/company.js?v={git_rev}"></script>
</body>
</html>"""