added nextloud tracker
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
# ctf_status.py
|
||||
|
||||
Reads the per-author challenge folders straight off the Nextcloud share (WebDAV,
|
||||
no sync, no mount) and tells you who to scream at.
|
||||
|
||||
## Setup
|
||||
|
||||
```sh
|
||||
cp ctf_status.env.example ctf_status.env && chmod 600 ctf_status.env
|
||||
$EDITOR ctf_status.env # app password from Nextcloud → Settings → Security
|
||||
```
|
||||
|
||||
## Use
|
||||
|
||||
```sh
|
||||
./ctf_status.py # terminal summary
|
||||
./ctf_status.py -o overview.md # + HedgeDoc markdown to a file
|
||||
./ctf_status.py --stdout | wl-copy # straight to clipboard, paste into HedgeDoc
|
||||
./ctf_status.py --update # overwrite the note in HEDGEDOC_NOTE
|
||||
./ctf_status.py --update <note-url> # ... or an explicit one
|
||||
```
|
||||
|
||||
## Keeping a HedgeDoc note up to date
|
||||
|
||||
`--update` overwrites an **existing** note in place, so the URL you share stays the
|
||||
same. Every run rewrites the whole body, starting with
|
||||
|
||||
```
|
||||
---
|
||||
tags: Logistics, h4tum CTF 2026
|
||||
---
|
||||
```
|
||||
|
||||
and a `**Last updated:** <date> <time> <tz>` line under the heading, so a stale note
|
||||
is obvious at a glance. Tags come from `HEDGEDOC_TAGS` (or `--tags`).
|
||||
|
||||
The note's permission has to be **freely** (Menu → Permission), because the run is
|
||||
anonymous. HedgeDoc 1.x has no REST API for editing a note, so the script talks the
|
||||
editor's own engine.io/socket.io + OT protocol over long-polling — it reads the
|
||||
current text, sends one "delete everything, insert this" operation, waits for the
|
||||
server's `ack`, and reads the note back to confirm. Anyone with the note open sees
|
||||
the change live. Still `requests`-only, no new dependencies.
|
||||
|
||||
`--hedgedoc <instance>` (POST a *new* note) is unrelated and only works where
|
||||
anonymous note creation is enabled — on `hedgedoc.cit.tum.de` it is not.
|
||||
|
||||
## Every 30 minutes, on a server
|
||||
|
||||
Copy the repo to the server, create `ctf_status.env` there (it is gitignored, so it
|
||||
does not travel with the code), then:
|
||||
|
||||
```sh
|
||||
./install-timer.sh
|
||||
```
|
||||
|
||||
It writes systemd **user** units into `~/.config/systemd/user/`, substituting
|
||||
whatever directory the repo actually sits in, enables the timer, turns on lingering
|
||||
so it keeps firing when you are not logged in, and does one run to prove it works.
|
||||
Re-run it any time; it just overwrites the units.
|
||||
|
||||
```sh
|
||||
systemctl --user list-timers ctf-status.timer # when it next fires
|
||||
journalctl --user -u ctf-status.service -n 50 # what it did
|
||||
systemctl --user start ctf-status.service # run it now
|
||||
systemctl --user disable --now ctf-status.timer # stop it
|
||||
```
|
||||
|
||||
The timer fires at `:00` and `:30` with up to a minute of jitter, and
|
||||
`Persistent=true` catches up a run missed while the machine was down. Plain cron
|
||||
works too, if you would rather:
|
||||
|
||||
```
|
||||
*/30 * * * * /path/to/planner/ctf_status.py --update --quiet
|
||||
```
|
||||
|
||||
`--quiet` keeps a successful run silent, so you only hear about it when the note
|
||||
changed or something broke. Overlapping runs are prevented by a lock file, and the
|
||||
HedgeDoc write is retried (`--retries`, default 3) before the run gives up with a
|
||||
one-line error and a non-zero exit.
|
||||
|
||||
## What it flags
|
||||
|
||||
| verdict | meaning |
|
||||
| --- | --- |
|
||||
| 🔴 SCREAM | nothing submitted, **or** they filled out `template.md` in place |
|
||||
| 🟡 NAG | submitted, but placeholders / empty sections remain |
|
||||
| 🟢 OK | every challenge fully filled out |
|
||||
|
||||
A `template.md` that is still pristine is ignored. One that has real content in it
|
||||
is counted as a challenge *and* flagged — so nobody's work is lost, they just get
|
||||
yelled at.
|
||||
|
||||
Also flagged per challenge: unnamed challenge, `[placeholder]` values left in any
|
||||
of Category/Difficulty/Event/Author/Tester/Status, empty prose sections, and
|
||||
category/difficulty values outside the allowed set.
|
||||
|
||||
## Layout it expects
|
||||
|
||||
```
|
||||
<NC_ROOT>/
|
||||
alice/
|
||||
README.md # ignored
|
||||
template.md # ignored while pristine
|
||||
baby-rsa.md # ← a challenge, any filename
|
||||
bob/
|
||||
```
|
||||
|
||||
Any `.md` that isn't `README.md` is parsed as a challenge, so the file naming
|
||||
convention doesn't have to be enforced by the script. If you want it enforced,
|
||||
add the check in `Challenge.problems`.
|
||||
Reference in New Issue
Block a user