#!/usr/bin/env python3
"""
build_botlinks.py -- AI / crawler discovery files for msosorg.com
Generates two things from the pages that already exist on disk, so they stay
current automatically whenever a page is added or removed:
1. /llms.txt an llmstxt.org-style Markdown index (English)
2. /links-for-bots/index.html a single, lightweight, fully-linked crawl hub
covering EN / MK / SI
Run after adding or removing pages:
python tools/build_botlinks.py
It only reads each page's
and , so it never
depends on the visual markup and is safe to re-run (idempotent).
"""
import io, os, re
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE = "https://msosorg.com"
LANGS = ("en", "mk", "si")
LANG_LABEL = {"en": "English", "mk": "Македонски", "si": "Slovenščina"}
# (top-level directory under a language, human label). Order = display order.
SECTIONS = [
("student-welcome-guide", "Student guide"),
("blog", "Blog"),
("news", "News"),
("projects", "Events & projects"),
("get-to-know-slovenia", "Get to know Slovenia"),
("get-to-know-macedonia", "Get to know Macedonia"),
]
# Single top-level pages (their own index.html directly under the language dir).
MAIN_PAGES = [
"about-us", "msos-hub", "become-a-member", "support", "gallery",
"faq", "timeline-and-milestones", "legal", "privacy-policy", "cookie-policy",
]
TITLE_RE = re.compile(r"(.*?)", re.DOTALL | re.I)
DESC_RE = re.compile(r'", ">")
.replace('"', """))
def build_llms_txt():
"""English llmstxt.org-style index."""
data = collect("en")
lines = []
lines.append("# MSOS — Macedonian Student Organisation in Slovenia")
lines.append("")
lines.append("> MSOS is the first official Macedonian student organisation in Slovenia. "
"This site helps Macedonian students move to and study in Slovenia — "
"enrolment guides, events, community news and support. Content is "
"student-written and informative; official sources should always be verified.")
lines.append("")
lines.append(f"Full multilingual crawl index (EN/MK/SI): {BASE}/links-for-bots/")
lines.append("")
# preferred section order for llms.txt
order = ["Main pages", "Student guide", "Blog", "News", "Events & projects",
"Get to know Slovenia", "Get to know Macedonia"]
for label in order:
rows = data.get(label)
if not rows:
continue
lines.append(f"## {label}")
for title, url, desc in rows:
if desc:
lines.append(f"- [{title}]({url}): {desc}")
else:
lines.append(f"- [{title}]({url})")
lines.append("")
txt = "\n".join(lines).rstrip() + "\n"
io.open(os.path.join(ROOT, "llms.txt"), "w", encoding="utf-8", newline="\n").write(txt)
return sum(len(v) for v in data.values())
def build_links_page():
"""A single lightweight HTML hub linking every page, grouped by language + section."""
blocks = []
total = 0
for lang in LANGS:
data = collect(lang)
order = ["Main pages", "Student guide", "Blog", "News", "Events & projects",
"Get to know Slovenia", "Get to know Macedonia"]
secs = []
for label in order:
rows = data.get(label)
if not rows:
continue
items = "\n".join(
f'