OpenAthlete
AGPLv3 endurance training platform: EU-oriented hosting, transparent CTL/ATL/TSB logic in code, self-hosting, and full export. Built in Grenoble.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Self-updating tracker of UK running races and ballot windows, with calendar reminders. A daily bot checks official pages and an LLM proposes updates as pull requests with quoted evidence.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A free, self-updating tracker of major UK running races and their ballot windows, with calendar feeds that remind runners before ballots open and close. Built for a running club whose race news was scattered across WhatsApp posts, so people kept missing ballots.
Always confirm dates on the official site. Not affiliated with any race.查看完整 README ↗A free, self-updating tracker of major UK running races and their ballot windows, with calendar feeds that remind runners before ballots open and close. Built for a running club whose race news was scattered across WhatsApp posts, so people kept missing ballots.
Live site: https://ukracetracker.github.io/uk-race-tracker/
Always confirm dates on the official site. Not affiliated with any race.
all, marathons, halves or ballots-only). Each ballot creates "Ballot opens", "Ballot closes in 2 days" and "Ballot closes today" events, and changed dates update in subscribers' calendars automatically.flowchart LR
Y[(races.yaml)] --> B[build.py]
B --> S[Static site]
B --> C[.ics calendar feeds]
D[Daily page check<br/>GitHub Actions] -->|page changed| L[Gemini reads the page<br/>quotes every value]
L --> V[Validation]
V -->|new values| PR[Pull request<br/>with evidence]
V -->|nothing new| I[Closed issue<br/>kept as a record]
PR -->|a person merges| Y
The whole system is one GitHub repo. A YAML file is the database, GitHub Actions does the work, pull requests are the review queue and GitHub Pages serves the result. Nothing reaches the live site without a person approving it.
The daily check (check_pages.py):
monitoring: auto, which is only used where the site's terms allow automated checks. The bot identifies itself, honours robots.txt and waits between requests to the same site.races.yaml and shows the old value, new value and evidence for each field. Merging it rebuilds the site and calendar feeds. If the race's details didn't change (a new menu button, say), the bot files an already-closed issue as a record instead, so noise needs no attention; if the LLM couldn't run or found something it won't fill in itself, the issue stays open for a person.If a page fails to load for 7 days in a row (some sites block cloud servers), the bot opens an issue suggesting the race be checked by hand, and closes it if the page comes back. Pages that stop being watched have their saved copy deleted.
evaluate_extraction.py runs extraction against every automatically checked race whose details were verified by hand, and scores each field. It runs in CI whenever the prompt or model changes.
Latest run (7 races, gemini-3.5-flash-lite):
trafilatura was the first choice for cleaning pages, but it threw away banner text, which is exactly where some races put their date (Bath Half). Keeping all visible text minus scripts, menus and footers was more reliable.races.yaml, keeping comments and making review diffs tiny.last_verified only changes when a person confirms details. The site adds what the daily check knows, so stale data never looks fresh and fresh data doesn't look stale.| Area | Tools |
|---|---|
| Data and validation | YAML, Pydantic, generated JSON Schema |
| Fetching and cleaning | httpx, lxml, urllib.robotparser |
| LLM extraction | Google Gemini API (generateContent with a response schema), free tier |
| Site and feeds | Jinja2, vanilla JS, icalendar |
| Automation | GitHub Actions (daily check, build, evaluation), GitHub Pages |
| Analytics | GoatCounter (no cookies, no personal data) |
| Tests | pytest, with the network and LLM faked; no test touches a real site or API |
Requires Python 3.11+.
py -m venv .venv
.venv\Scripts\activate # macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt
python -m pytest # run the tests
python build.py # validate races.yaml and build site/ and the .ics feeds
python -m http.server 8000 --directory site # preview at http://localhost:8000
python check_pages.py # check the race pages and print what changed
| Path | What it is |
|---|---|
races.yaml | The data: one record per race edition |
build.py | Validates the data and builds the site and calendar feeds |
check_pages.py | The daily page check, LLM proposals and alerts |
evaluate_extraction.py | Scores LLM extraction against hand-verified races |
tracker/ | Models, fetching, cleaning, extraction, GitHub integration |
templates/ | The site template |
schema/races.schema.json | JSON Schema generated from the model (python build.py --write-schema) |
Configuration (repo secrets and variables, all optional):
| Name | Purpose |
|---|---|
GEMINI_API_KEY (secret) | Turns on LLM extraction and pull requests; without it, changes are reported as issues |
GEMINI_MODEL | Overrides the default model (gemini-3.5-flash-lite) |
GOATCOUNTER_URL | Turns on visit counting |
To try the pull-request flow without waiting for a real change, run the Check race pages workflow by hand with a race id in propose for.
Each race edition is one record in races.yaml (london-marathon-2027), so past years stay as history.
| Field | Example | Notes |
|---|---|---|
id | london-marathon-2027 | slug + year |
name, distance, location, country | London Marathon, marathon, London, UK | distance: marathon / half / 10k / ultra / other |
race_date, race_date_end | 2027-04-24, 2027-04-25 | end date only for multi-day races |
entry_type | [ballot, charity, gfa] | ballot / general / charity / gfa |
ballot_opens, ballot_closes | 2026-04-27T10:00 | UK local time |
ballot_results, general_entry_opens, price_gbp | 2026-07-01 | optional |
official_url, source_url | pages that are checked daily | |
status | ballot_open | unannounced / announced / ballot_open / ballot_closed / sold_out / done |
confidence | confirmed | confirmed / expected / estimated; only confirmed dates go into calendars |
last_verified | 2026-10-02 | when a person last confirmed the details |
monitoring | auto | auto only where the site's terms allow automated checks; otherwise manual |
notes | short and plain |
manual and checked by hand. Aggregators, which usually forbid scraping, are never used.