# OI Contest Fetch en/[zh](README_zh.md) Fetch programming contest schedules from several online judge platforms and export them as JSON. The repository also includes a small PHP page that can read the generated JSON and display upcoming contests. ## Supported Platforms - Codeforces - AtCoder - UOJ - Nowcoder ## Output Files Running the fetch script writes one JSON file to the repository root: - `contests_all.json`: contests that have not ended yet, including upcoming and currently running contests, plus contests that finished within the last 30 days. The JSON file has this top-level shape. `generated_at` is the Unix timestamp in seconds when the file was written. ```json { "generated_at": 1784550894, "contests": [ { "platform": "AtCoder", "title": "AtCoder Beginner Contest 468", "start_time": 1784980800, "end_time": 1784986800, "status": "upcoming", "url": "https://atcoder.jp/contests/abc468" } ] } ``` Each contest item is stored under `contests`. `start_time` and `end_time` are Unix timestamps in seconds. `status` can be one of: - `finished` - `running` - `upcoming` ## Requirements - Python 3 - PHP 5.4 or newer, only if you want to use the page under `server/` Python packages: ```bash pip install requests beautifulsoup4 ``` ## Usage Run the fetch script from the repository root: ```bash python fetch_contests.py ``` After a successful run, the script prints counts similar to: ```text Total active contests: 13 Total contests finished in last 30 days: 139 ``` ## Web Page `server/index.php` reads the public raw GitHub URL for `contests_all.json`, caches it locally for 5 minutes, and renders upcoming contests with a client-side countdown plus recently finished contests. It also shows the JSON `generated_at` value as the last update time in the detected time zone. The page detects the browser/system language and time zone, syncs them to cookies, and uses them for localized text and contest times on later page loads. Unsupported languages fall back to English. If you deploy it yourself, update this constant in `server/index.php` if your repository path or branch changes: ```php define('JSON_URL', 'https://raw.githubusercontent.com/hanyixuanten/OI-contest-fetch/master/contests_all.json'); ``` The cache file is written next to `index.php` as `contests_all_cache.json`, so the web server process needs write permission for the `server/` directory. ## Automation A typical automation flow is: 1. Run `python fetch_contests.py` on a schedule. 2. Commit the updated JSON file. 3. Push them to GitHub. 4. Let `server/index.php` read the latest `contests_all.json` from GitHub raw content. For GitHub Actions, install the Python dependencies before running the script. ## Development Notes AI coding agents and maintainers should follow [AGENTS.md](AGENTS.md) when changing providers, output contracts, workflow behavior, or documentation. ## Notes - AtCoder uses the AtCoder Problems API and falls back to the official AtCoder contest page for upcoming contests when needed. - UOJ is parsed from its public contests page, including the timeanddate duration parameters used by contest links. - Nowcoder is parsed from the embedded contest metadata on its VIP contest index page. - Network or upstream API changes can temporarily reduce the number of fetched contests.