#!/usr/bin/env python3 """Render the index page for https://asger.weirsoe.dk/tarballz/. Reads the sidecar .json files that publish-tarball.sh writes next to each tarball (on stdin, one JSON object per line) and emits a standalone HTML page. The theme tokens are inlined rather than linked to the main site's stylesheet: that file is content-hashed (_astro/_slug_..css) and its name changes on every site rebuild, so a link would silently rot. Inlining costs a few hundred bytes and cannot break. """ import html import json import os import sys from datetime import datetime, timezone GITEA_URL = "https://gitea.weircon.dk/agw/jasp-desktop-bin" AUR_URL = "https://aur.archlinux.org/packages/jasp-desktop-bin" PAGE = """ Tarballs · Asger Weirsøe

Tarballs

Prækompilerede JASP-binærer til Arch Linux. JASP udgiver kun installere til Windows og macOS, så disse er bygget fra kildekoden af en automatisk pipeline og udgivet på AUR som jasp-desktop-bin.

Du behøver normalt ikke hente herfra manuelt — brug AUR:

yay -S jasp-desktop-bin

Tilgængelige builds

{releases}

Hver build indeholder sin egen R og de biblioteker den linker mod, så den ikke bindes til bestemte versioner af noget på dit system. Kun de nyeste {keep} builds gemmes.

""" def human_size(n: int) -> str: for unit in ("B", "KB", "MB", "GB"): if n < 1024 or unit == "GB": return f"{n:.1f} {unit}".replace(".0 ", " ") n /= 1024 return f"{n} B" def main() -> int: entries = [] for line in sys.stdin: line = line.strip() if not line: continue try: entries.append(json.loads(line)) except json.JSONDecodeError: print(f"warning: skipping unparsable sidecar line", file=sys.stderr) # Newest first. entries.sort(key=lambda e: e.get("built", ""), reverse=True) if entries: items = [] for e in entries: name = html.escape(e["tarball"]) ver = html.escape(e.get("jasp_version", "?")) built = e.get("built", "") try: built_h = datetime.fromisoformat(built).strftime("%d-%m-%Y") except ValueError: built_h = html.escape(built) size = human_size(int(e.get("size_bytes", 0))) sha = html.escape(e.get("sha256", "")) r = html.escape(e.get("bundled_r_version", "")) qt = html.escape(e.get("qt6_minor", "")) items.append( f'
  • \n' f'
    \n' f' JASP {ver}\n' f' Hent · {size}\n' f'
    \n' f'
    {built_h} · x86_64 · bundlet R {r} · bygget mod Qt {qt}
    \n' f'
    sha256 {sha}
    \n' f'
  • ' ) releases = '" else: releases = '

    Ingen builds tilgængelige lige nu.

    ' sys.stdout.write( PAGE.format( releases=releases, gitea=GITEA_URL, aur=AUR_URL, keep=len(entries) if entries else 3, year=datetime.now(timezone.utc).year, ) ) return 0 if __name__ == "__main__": sys.exit(main())