From e00f40eaf46cc5c1e005bbafb281fa26e59e34e5 Mon Sep 17 00:00:00 2001 From: cato447 Date: Tue, 20 Oct 2026 19:40:24 +0200 Subject: [PATCH] Split ctf_status.py into a tracker package, config from .env only ctf_status.py is now just the command line; the work lives in tracker/. The rules that decide whether a challenge is believed are in tracker/checks.py, one function per rule, listed in README_CHECKS and REPO_CHECKS. Output is unchanged. Read the config from .env only (ctf_status.env.example -> .env.example), let single_run_lock() hold its own lock files, and rewrite the README as a short overview of what the repo does and how to run it. Co-Authored-By: Claude Opus 5.5 --- ctf_status.env.example => .env.example | 13 +- .gitignore | 1 - README.md | 254 +++----- ctf_status.py | 818 +------------------------ install-timer.sh | 18 +- tracker/__init__.py | 13 + tracker/challenge.py | 159 +++++ tracker/challs.py | 17 + tracker/checks.py | 198 ++++++ tracker/config.py | 35 ++ tracker/gitlab.py | 121 ++++ tracker/hedgedoc.py | 180 ++++++ tracker/markdown.py | 114 ++++ tracker/overview.py | 78 +++ tracker/terminal.py | 63 ++ 15 files changed, 1098 insertions(+), 984 deletions(-) rename ctf_status.env.example => .env.example (55%) create mode 100644 tracker/__init__.py create mode 100644 tracker/challenge.py create mode 100644 tracker/challs.py create mode 100644 tracker/checks.py create mode 100644 tracker/config.py create mode 100644 tracker/gitlab.py create mode 100644 tracker/hedgedoc.py create mode 100644 tracker/markdown.py create mode 100644 tracker/overview.py create mode 100644 tracker/terminal.py diff --git a/ctf_status.env.example b/.env.example similarity index 55% rename from ctf_status.env.example rename to .env.example index eeb2eb7..488b473 100644 --- a/ctf_status.env.example +++ b/.env.example @@ -1,22 +1,21 @@ -# cp to ctf_status.env and chmod 600 (a plain .env next to the script works too) +# cp .env.example .env && chmod 600 .env # --- GitLab: the group holding one repo per challenge ----------------------- GITLAB_GROUP_URL=https://gitlab.lrz.de/h4tum-ctf/h4tum-ctf-2026/challenges # fine-grained personal access token, scoped to that group, with # Project: Read (list the repos) -# Repository: Read (download each README.md) +# Repository: Read (download README.md and description.yml, list the files) GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx -# --- HedgeDoc: the existing note that gets overwritten every run ------------ -# full URL of the note (its permission must be "freely" so an anonymous -# run may write to it), e.g. https://hedgedoc.cit.tum.de/AbCdEf123 +# --- HedgeDoc: the existing note that --update overwrites ------------------- +# full URL of the note; its permission must be "freely" so an anonymous run +# may write to it HEDGEDOC_NOTE= # YAML front-matter tags written at the top of the note HEDGEDOC_TAGS=Logistics, h4tum CTF 2026 # --- deployment repo: --challs keeps in it up to date -------- -# one clone URL per line for every challenge at Testing Ready or beyond. The -# token additionally needs, on this project: Repository: Read + Repository: Write +# the token additionally needs, on this project: Repository: Read + Write CHALLS_REPO_URL=https://gitlab.lrz.de/h4tum-ctf/h4tum-ctf-deployment/ctf-deployment CHALLS_PATH=2026/challs.txt CHALLS_BRANCH=main diff --git a/.gitignore b/.gitignore index 3d47cce..9bdb4db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ __pycache__/ -ctf_status.env *.md.out .env diff --git a/README.md b/README.md index 9388acb..de3569a 100644 --- a/README.md +++ b/README.md @@ -1,198 +1,126 @@ -# ctf_status.py +# CTF challenge status tracker -Reads the `README.md` of every repo in the GitLab challenges group (REST API, no -clone) and shows which categories have challenges in which state, at which -difficulty — in the terminal and as a HedgeDoc note. A status of Testing Ready -or beyond is only believed if the repo backs it up (see -[Checking the repo](#checking-the-repo)). +Tracks the progress of the h4tum CTF challenges. It reads every repo in the +GitLab challenges group, works out each challenge's status, category and +difficulty from its `README.md`, and checks that challenges marked as ready +really are. The result goes to: -Needs `requests` and `PyYAML` (`python-requests python-yaml` on Arch, -`python3-requests python3-yaml` on Debian). +- **a HedgeDoc note**: an overview of all challenges, refreshed every 30 minutes +- **`challs.txt` in the deployment repo**: the clone URLs of every challenge + ready for infra testing, updated daily +- **the terminal**: the same overview, for a quick look -## Setup +## Requirements + +- Python 3.9+ +- [`requests`](https://pypi.org/project/requests/) and [`PyYAML`](https://pypi.org/project/PyYAML/) + (`python-requests python-yaml` on Arch, `python3-requests python3-yaml` on Debian) + +## Configuration ```sh -cp ctf_status.env.example ctf_status.env && chmod 600 ctf_status.env -$EDITOR ctf_status.env # GitLab group URL + token, HedgeDoc note +cp .env.example .env && chmod 600 .env ``` -## 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 # ... or an explicit one -``` - -The token is a fine-grained personal access token on the challenges group with -**Project: Read** (to list the repos) and **Repository: Read** (to download the -READMEs and `description.yml`, and to list the repo's files). A plain `.env` with `GL_PAT=` / `GITLAB_URL=` is read as well. - -## 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:**