secubox-deb/packages/secubox-metablogizer
CyberMind e83fc3ba5b
fix(secubox-metablogizer): v1.2.1 — uvicorn --log-level info, surface webhook deploy success (#329)
debian/secubox-metablogizer.service: lower uvicorn --log-level from
warning to info so the webhook deploy success line
`logger.info("deploy site=…")` reaches journald. Previously only
error paths were visible, making successful auto-deploys silent.

The 8 info-level log sites in api/main.py are all event-driven
(startup + webhook + sync) — no flood concern.

Closes #119.

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
2026-05-22 07:07:17 +02:00
..
api fix(metablog-webhook): pass safe.directory to git on every call (ref #117) 2026-05-13 07:43:18 +02:00
config feat(packages): Sync source packages with MOCHAbin deployed configs 2026-05-06 09:22:29 +02:00
debian fix(secubox-metablogizer): v1.2.1 — uvicorn --log-level info, surface webhook deploy success (#329) 2026-05-22 07:07:17 +02:00
menu.d feat(navbar): consolidate to 6 charter categories + fix dropped menu entries (closes #306) (#307) 2026-05-21 10:03:05 +02:00
nginx feat: modular nginx config + hub roadmap + new modules 2026-03-21 20:34:01 +01:00
sbin feat(metablogizer,droplet): orchestrate haproxy + mitmproxy on publish (closes #200) (#209) 2026-05-19 07:42:38 +02:00
schema feat(metablog): JSON Schema draft-07 for site.json (ref #101) 2026-05-12 17:15:14 +02:00
www/metablogizer feat(metablogizer): simplify UI to single Sites tab with rich tooltip 2026-05-14 09:19:27 +02:00
README.md docs(metablog-webhook): tracking + README deploy section (ref #113) 2026-05-13 07:32:36 +02:00

📝 Metablogizer

Static site publisher with Tor

Category: Publishing

Screenshot

Metablogizer

Features

  • Static sites
  • Tor publishing
  • Templates
  • Markdown

Gitea ingest

The 166 sites under /srv/metablogizer/sites/* are tracked in Gitea at https://gitea.gk2.secubox.in/gandalf/?tab=repositories&q=metablog as gandalf/metablog-<sitename> repositories, each with a v1.0.0 tag on the initial state.

Initial ingest is driven by three scripts in scripts/:

bash scripts/metablog-ingest-gitea-config.sh   # one-time: enables push-create
bash scripts/lib/gitea-ssh-preflight.sh --check  # verify SSH path
bash scripts/metablog-ingest.sh                # full run

Flags on metablog-ingest.sh: --dry-run, --limit N, --site <name>, --halt-on-fail.

Idempotent — re-running picks up new sites and skips ones already in sync. Per-site outcome lands in output/ingest-report.json. Important: the SSH URL uses gitea@ (NOT git@) because Gitea's built-in SSH server validates the username against the OS user it runs as.

Version metadata (site.json)

Every site under /srv/metablogizer/sites/ carries a site.json describing it. The formal schema lives at packages/secubox-metablogizer/schema/site.json.schema.json.

Required fields: name, domain, published. Optional: version, title, description, category, streamlit_app, tags, last_updated.

If version and/or last_updated are absent, the API derives them from the local git state (git describe --tags --exact-match and git log -1 --format=%cI).

The /api/v1/metablogizer/sites endpoint returns the enriched form; consumers (e.g. the upcoming sub-D dashboard) see one consistent shape.

Backfill

To create or merge site.json files in bulk:

bash scripts/metablog-site-backfill.sh --dry-run        # preview
bash scripts/metablog-site-backfill.sh                  # create missing
bash scripts/metablog-site-backfill.sh --force          # merge missing fields
bash scripts/metablog-site-backfill.sh --site <name>    # one site only

Per-run JSON report at output/metablog-backfill-report.json. The backfill auto-detects streamlit_app by probing the Gitea repo gandalf/streamlit-<name>.git (sub-F).

Version dashboard

The Hub exposes a per-site dashboard at:

  • List: https://admin.gk2.secubox.in/metablogizer/

    • 8 columns: Name · Domain · Version · Streamlit · Updated · Status · Size · Actions
    • Inline filter (matches name and domain)
    • Sortable headers (Name, Domain, Version, Updated)
    • Auto-refresh every 60s; paused when the tab is hidden
  • Per-site drill-in: https://admin.gk2.secubox.in/metablogizer/site.html?name=<sitename>

    • All site.json fields
    • Three quick links: 🌐 live site, 🦊 Gitea repo, 🎨 Streamlit app (if any)
    • Tag history is not shown inline; click the Gitea link and use its Releases tab (auth required, handled by your Gitea session)

Data comes from /api/v1/metablogizer/sites and /api/v1/metablogizer/site/<name> (sub-C, PR #102). The dashboard is pure vanilla JS — no framework, no router.

Deploy webhook

A push to the default branch of any metablog-* repo on Gitea triggers an automatic deploy of the live site.

  • Endpoint: POST https://admin.gk2.secubox.in/api/v1/metablogizer/webhook
  • Auth: HMAC-SHA256 in X-Gitea-Signature header, shared secret in /etc/secubox/metablogizer-webhook.secret (chmod 600, owner secubox)
  • Action: git fetch + git reset --hard origin/<default> under a per-site asyncio.Lock; invalidates the dashboard cache; reloads nginx only if site.json:domain changed.

Provisioning the secret (one-shot on the MOCHAbin)

sudo install -o secubox -g secubox -m 600 /dev/stdin \
  /etc/secubox/metablogizer-webhook.secret <<< "$(openssl rand -hex 32)"
sudo systemctl restart secubox-metablogizer

Registering the webhook on every Gitea repo

scripts/metablog-webhook-install.sh \
  --gitea-token <admin-or-repo-token> \
  --secret-file /etc/secubox/metablogizer-webhook.secret

The installer is idempotent — re-run after adding new sites.

Observability

  • journalctl -u secubox-metablogizer | grep '^deploy '
  • GET /api/v1/metablogizer/deploys (JWT-gated) returns the last 50 deploys

Installation

# Add SecuBox repository
curl -fsSL https://apt.secubox.in/install.sh | sudo bash

# Install package
sudo apt install secubox-metablogizer

Configuration

Configuration file: /etc/secubox/metablogizer.toml

API Endpoints

  • GET /api/v1/metablogizer/status - Module status
  • GET /api/v1/metablogizer/health - Health check

License

MIT License - CyberMind © 2024-2026