Contains: - 1m-brag - tem - VaultMesh_Catalog_v1 - VAULTMESH-ETERNAL-PATTERN 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
78 lines
2.5 KiB
Python
78 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
import csv
|
|
import argparse
|
|
import datetime as dt
|
|
from collections import defaultdict
|
|
|
|
|
|
def parse_args():
|
|
p = argparse.ArgumentParser(
|
|
description="Generate consortium summary markdown from CSV"
|
|
)
|
|
p.add_argument(
|
|
"--csv",
|
|
default="consortium/consortium-tracker.csv",
|
|
help="Path to consortium-tracker.csv",
|
|
)
|
|
return p.parse_args()
|
|
|
|
|
|
def to_float(val: str) -> float:
|
|
try:
|
|
return float(str(val).replace(",", "").strip())
|
|
except Exception:
|
|
return 0.0
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
|
|
proposals = defaultdict(list)
|
|
with open(args.csv, newline="", encoding="utf-8") as f:
|
|
reader = csv.DictReader(f)
|
|
for row in reader:
|
|
track = row.get("Proposal Track", "Unknown") or "Unknown"
|
|
proposals[track].append(row)
|
|
|
|
today = dt.date.today().isoformat()
|
|
print(f"# Consortium Summary\n")
|
|
print(f"Generated: {today}\n")
|
|
|
|
grand_total = 0.0
|
|
for track in sorted(proposals.keys()):
|
|
rows = proposals[track]
|
|
partners = [r for r in rows if r.get("Partner Name") and r["Partner Name"] != "[Template Row]"]
|
|
if not partners:
|
|
continue
|
|
|
|
approved = sum(1 for r in partners if r.get("LOI Status", "").lower() == "approved")
|
|
pending = sum(1 for r in partners if r.get("LOI Status", "").lower() == "pending")
|
|
under_review = sum(1 for r in partners if r.get("LOI Status", "").lower() == "under review")
|
|
|
|
total_budget = sum(to_float(r.get("Budget (€)", 0)) for r in partners)
|
|
grand_total += total_budget
|
|
|
|
print(f"## {track}")
|
|
print(f"Partners: {len(partners)} | LOIs Approved: {approved} | Under Review: {under_review} | Pending: {pending}")
|
|
print(f"Total Budget (reported): €{total_budget:,.0f}\n")
|
|
print("| Partner | Country | Type | Budget (€) | PM | LOI | Contact | Email |")
|
|
print("|---|---|---:|---:|---:|---|---|---|")
|
|
for r in partners:
|
|
name = r.get("Partner Name", "")
|
|
country = r.get("Country", "")
|
|
ptype = r.get("Partner Type", "")
|
|
budget = r.get("Budget (€)", "")
|
|
pm = r.get("Person-Months", "")
|
|
loi = r.get("LOI Status", "")
|
|
contact = r.get("Primary Contact", "")
|
|
email = r.get("Email", "")
|
|
print(f"| {name} | {country} | {ptype} | {budget} | {pm} | {loi} | {contact} | {email} |")
|
|
print()
|
|
|
|
print(f"---\n\nGrand Total Budget (reported): €{grand_total:,.0f}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|