Skip to content

Instantly share code, notes, and snippets.

@thibaudcolas
Created October 25, 2025 12:14
Show Gist options
  • Select an option

  • Save thibaudcolas/10016feb5c4328e0df9dae3ea3218090 to your computer and use it in GitHub Desktop.

Select an option

Save thibaudcolas/10016feb5c4328e0df9dae3ea3218090 to your computer and use it in GitHub Desktop.
frab_to_csv conference schedule pretalx
#!/usr/bin/env python3
"""
Convert a frab/pretalx schedule JSON to CSV for Google Sheets.
Usage:
python frab_to_csv.py input.json > output.csv
"""
import sys, json, csv
from datetime import datetime
REQUIRED_ORDER = [
"Day",
"Time",
"Talk / slot title",
"Speaker name(s)",
"URL",
"Full timestamp",
"Venue",
"Duration",
"Slot type",
"Speaker bio",
"Speaker picture URL",
]
def parse_iso(iso_str):
try:
# Handles "2025-09-19T11:00:00+01:00"
return datetime.fromisoformat(iso_str)
except Exception:
return None
def day_name(dt):
return dt.strftime("%A") if dt else ""
def time_24h(dt, fallback=""):
return dt.strftime("%H:%M") if dt else fallback
def pick_name(p):
return p.get("public_name") or p.get("name") or ""
def pick_bio(p):
return p.get("biography") or ""
def pick_avatar(p):
return p.get("avatar") or ""
def extract_rows(data):
rows = []
schedule = data.get("schedule", {})
conference = schedule.get("conference", {})
for day in conference.get("days", []):
day_date = day.get("date", "")
rooms = day.get("rooms", {})
for room_name, items in rooms.items():
for it in items:
iso = it.get("date") or ""
dt = parse_iso(iso)
persons = it.get("persons") or []
names = ", ".join([n for p in persons if (n := pick_name(p))])
bios = " | ".join([b for p in persons if (b := pick_bio(p))])
avatars = " | ".join([a for p in persons if (a := pick_avatar(p))])
row = {
"Day": day_name(dt) or day_date,
"Time": time_24h(dt, it.get("start") or ""),
"Talk / slot title": it.get("title") or "",
"Speaker name(s)": names,
"URL": it.get("url") or it.get("origin_url") or "",
"Full timestamp": iso,
"Venue": it.get("room") or room_name or "",
"Duration": it.get("duration") or "",
"Slot type": it.get("type") or "",
"Speaker bio": bios,
"Speaker picture URL": avatars,
}
sort_key = dt.isoformat() if dt else f"{day_date}T{it.get('start','')}"
rows.append((sort_key, row))
rows.sort(key=lambda x: x[0])
return [r for _, r in rows]
def main():
if len(sys.argv) < 2:
print("Usage: python frab_to_csv.py input.json > output.csv", file=sys.stderr)
sys.exit(1)
with open(sys.argv[1], "r", encoding="utf-8") as f:
data = json.load(f)
rows = extract_rows(data)
writer = csv.DictWriter(sys.stdout, fieldnames=REQUIRED_ORDER)
writer.writeheader()
for r in rows:
writer.writerow(r)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment