#!/usr/bin/env python3 """ build_listings.py -- keep the homepage "Latest news" in sync with the News hub. Problem it solves: the landing page's "Latest news" block used to be a separate hard-coded copy, so editing the News page never updated the homepage. Source of truth = each language's News hub (`/news/index.html`), which is edited by hand (it may include curated teaser cards without a detail page). This script copies the first 3 News-hub cards into the homepage's "Latest news" block, converting them to the homepage card format and fixing relative paths. Run after editing any News page: python tools/build_listings.py Idempotent and safe to re-run. The homepage block is wrapped in markers. """ import io, os, re ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) LANGS = ("en", "mk", "si") N_LATEST = 3 CARD_RE = re.compile(r'
', re.DOTALL) EXCERPT_RE = re.compile(r'\s*

.*?

', re.DOTALL) # homepage .news-articles content, anchored by the trailing "See all" button LANDING_RE = re.compile( r'(
)(.*?)(
\s*)', re.DOTALL, ) def hub_to_landing(card): """Convert one News-hub card to the homepage news-card format.""" card = EXCERPT_RE.sub("", card) # homepage cards have no excerpt card = (card .replace('class="newshub-card"', 'class="news-card"') .replace('class="newshub-media"', 'class="news-card-media"') .replace('class="newshub-body"', 'class="card-content"') .replace('class="newshub-date"', 'class="author"')) # homepage is one directory shallower than the News hub card = card.replace('href="../../', 'href="../').replace('src="../../', 'src="../') return card.strip() def sync_lang(lang): hub_path = os.path.join(ROOT, lang, "news", "index.html") home_path = os.path.join(ROOT, lang, "index.html") if not (os.path.exists(hub_path) and os.path.exists(home_path)): print(f" [{lang}] skipped (missing news hub or homepage)") return 0 hub = io.open(hub_path, encoding="utf-8").read() cards = CARD_RE.findall(hub)[:N_LATEST] if not cards: print(f" [{lang}] no News-hub cards found") return 0 inner = "\n".join(" " + hub_to_landing(c) for c in cards) block = ("\n \n" f"{inner}\n" " \n ") home = io.open(home_path, encoding="utf-8").read() if not LANDING_RE.search(home): print(f" [{lang}] could not find the homepage 'Latest news' block") return 0 home = LANDING_RE.sub(lambda m: m.group(1) + block + m.group(3), home, count=1) io.open(home_path, "w", encoding="utf-8", newline="").write(home) print(f" [{lang}] homepage 'Latest news' <- {len(cards)} cards from the News hub") return len(cards) if __name__ == "__main__": print("Syncing homepage 'Latest news' from each News hub:") total = sum(sync_lang(l) for l in LANGS) print(f"Done ({total} cards written).")