# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands **Install dependencies:** ```bash pip install -r requirements.txt ``` **Run a downloader manually:** ```bash python3 src/config_downloader.py --config config/parentzone_config.json python3 src/config_snapshot_downloader.py --config config/snapshot_config.json ``` **Start the web server:** ```bash python3 src/webserver.py --host 0.0.0.0 --port 8080 --snapshots-dir ./data/snapshots ``` **Run a test script:** ```bash PYTHONPATH=. python3 tests/test_snapshot_downloader.py PYTHONPATH=. python3 tests/test_asset_tracking.py ``` **Docker:** ```bash docker-compose up --build ``` ## Architecture All source code lives in `src/`. The module hierarchy has two layers: **Core layer** — the main async classes that talk directly to the ParentZone API: - `ImageDownloader` — fetches asset lists from a gallery endpoint, downloads media files concurrently (semaphore-controlled), and preserves original `updated` timestamps on disk - `SnapshotDownloader` — fetches daily event snapshots with cursor-based pagination and renders them to self-contained HTML files (inline assets) - `AuthManager` — handles both auth modes: API key (`x-api-key` header for list, `key` param for download URLs) and login-based (POST to `/v1/auth/login`, session token in subsequent requests) - `AssetTracker` — persists a JSON sidecar file per output directory tracking asset IDs and metadata to skip already-downloaded files - `SnapshotsWebServer` — aiohttp web server that serves the generated HTML reports with directory listing **Config layer** — thin wrappers that load JSON config files and delegate to the core layer: - `ConfigImageDownloader` — loads `parentzone_config.json`, calls `ImageDownloader` - `ConfigSnapshotDownloader` — loads `snapshot_config.json`, calls `SnapshotDownloader` These config-layer modules are the actual entry points invoked by `scripts/scheduler.sh` in the Docker container. **Deployment flow:** Docker container runs `scripts/startup.sh`, which starts `cron` (scheduled via `scripts/crontab`) and the web server. The cron job calls `scripts/scheduler.sh` nightly, which runs both config-layer downloaders. **Tests** are standalone integration-style scripts (not pytest) in `tests/`, each with their own mock server or test runner class. Run with `PYTHONPATH=.` so imports resolve from the repo root. **Config files** in `config/` are gitignored (contain credentials). Use `config_example.json` and `snapshot_config_example.json` as templates.