Wire since filter and refresh semester metadata

This commit is contained in:
2025-11-15 01:25:53 +01:00
parent c12310efca
commit d8de882cdd
7 changed files with 181 additions and 33 deletions

View File

@@ -30,14 +30,14 @@ This document equips future agents with the current mental model for the `studip
1. `studip-sync init-config` writes a config template (optionally overriding `download_root` and guarded by `--force`).
2. `studip-sync auth` collects credentials (CL flags, env, or interactive prompts), Base64-encodes `username:password`, and persists it in the active profile.
3. `studip-sync list-courses` builds a `StudipClient`, resolves/caches the user ID via `/users/me`, paginates `/users/{id}/courses`, fetches missing semesters, upserts course metadata into `state.toml`, and prints a table sorted by semester/title.
3. `studip-sync list-courses` builds a `StudipClient`, resolves/caches the user ID via `/users/me`, paginates `/users/{id}/courses`, fetches missing semesters (including start/end timestamps and re-fetching cached semesters that lack them), upserts course metadata into `state.toml`, and prints a table sorted by semester/title.
4. `studip-sync sync`:
- Resolves download root (`config.download_root` or `$XDG_DATA_HOME/studip-sync/downloads`) and ensures directories exist unless `--dry-run`.
- Refreshes course + semester info, then for each course performs a depth-first walk: `/courses/{id}/folders``/folders/{id}/file-refs``/folders/{id}/folders`. Pagination is handled by `fetch_all_pages`.
- Normalizes path components and uses `NameRegistry` to avoid collisions, guaranteeing human-readable yet unique names.
- Checks file state (size, modified timestamp, checksum) against `state.toml` to skip unchanged files; downloads stream to `*.part` before rename.
- Records remote metadata + local path hints in state. `--dry-run` reports actions without touching disk; `--prune` (plus nondry-run) deletes stray files/dirs with `walkdir`.
- `--since <ISO8601>` is accepted for future incremental sync work; at the moment it is recorded in logs/state but no API filters are issued.
- Records remote metadata + local path hints in state. `--dry-run` reports actions without touching disk; `--prune` (plus nondry-run) deletes stray files/dirs with `walkdir`.
- `--since <semester|date>` now resolves either a semester key (e.g., `ws2526`) to its cached start timestamp or a date string (`DDMMYY`, `DDMMYYYY`, RFC3339) and skips remote files whose `chdate` precedes that cutoff.
5. HTTP errors propagate via `anyhow`, but 401/403 currently surface as generic failures—production UX should point users to `studip-sync auth`.
## Configuration & State
@@ -45,7 +45,7 @@ This document equips future agents with the current mental model for the `studip
- Config path: `${XDG_CONFIG_HOME:-~/.config}/studip-sync/config.toml`. Override with `--config-dir` when needed. Example keys: `base_url`, `jsonapi_path`, `basic_auth_b64`, `download_root`, `max_concurrent_downloads`.
- State path: `${XDG_DATA_HOME:-~/.local/share}/studip-sync/state.toml`. `--data-dir` relocates this tree (and the default `downloads/` folder). Explicitly setting `download_root` decouples downloads from the data dir; otherwise it defaults to `<data-dir>/downloads`.
- `profiles.<name>.user_id` caches `/users/me`.
- `profiles.<name>.semesters.<key>` stores semester IDs/titles/keys.
- `profiles.<name>.semesters.<key>` stores semester IDs/titles/keys plus `start`/`end` timestamps (needed for `--since ws2526`). Running `list-courses --refresh` will also refresh already-known semesters missing those timestamps so `sync --since …` can resolve properly.
- `profiles.<name>.courses.<id>` keeps display names + `last_sync`.
- `profiles.<name>.files.<file_ref_id>` remembers size, checksum, timestamps, and the last local path to avoid redundant downloads.
- Multiple profiles are supported; `--profile` switches, otherwise the configs `default_profile` is used.
@@ -65,7 +65,7 @@ This document equips future agents with the current mental model for the `studip
## Known Gaps / Backlog
- `ConfigProfile::max_concurrent_downloads` is defined but unused; downloads happen sequentially. Introduce a bounded task queue if concurrency is needed.
- `SyncArgs::since` exists but is not wired into any API calls; ideal future work would leverage Stud.IP filters or local timestamps.
- Server-side filtering (`filter[since]`, if supported) is not used yet. Local cutoff logic relies on Stud.IP timestamps; future work could add conditional API query parameters once officially documented.
- No automated tests (unit/integration) are present; critical helpers like `semesters::infer_key`, `normalize_component`, and state transitions should gain coverage.
- Error UX for auth failures could be clearer (detect 401/403 and prompt users to re-run `auth`).
- There is no CI config; if one is added, ensure it runs fmt/clippy/test.