AutonomousVehicleControlBeginnersGuide
Python sample codes and documents about Autonomous vehicle control algorithm. This project can be used as a technical guide book to study the algorithms and the software architectures for beginners.
翻訳待ち
Just a better fucking untis app
翻訳待ち
Loading the full README. The saved excerpt is shown below.
A school timetable app for AP Hogeschool students: fetches lessons directly from the WebUntis REST API (the same source the AP-WebUntisToICS-Node server uses), stores everything offline, and stays out of your way.
• React Native + Expo SDK 57 (expo-router), bun
• React Native Reusables (RNR) components + NativeWind v4, dark theme
• Syncs once, then works fully offline (AsyncStorage)
• No server needed on mobile — Android/iOS call WebUntis directlyRead the full README ↗A school timetable app for AP Hogeschool students: fetches lessons directly from the WebUntis REST API (the same source the AP-WebUntisToICS-Node server uses), stores everything offline, and stays out of your way.
bun install
bun start # dev server (scan QR for Expo Go / dev build)
The first launch walks you through: WebUntis server → school year → class.
bun run web:build # expo export --platform web → dist/
bun run web:serve # serves dist/ on http://localhost:8080
Or run the web preview in Docker (no local bun/node needed):
docker build -f Dockerfile.web -t calendar-web .
docker run -d -p 8080:8080 calendar-web # → http://localhost:8080
Browsers require CORS preflight approval for the API's custom
anonymous-school header, which WebUntis does not grant. The web build
therefore goes through the same-origin proxy at /proxy?url=<encoded>
(which forwards that header) served by web:serve. Running under bun start
alone has no proxy — you'll get HTML instead of JSON.
Android/iOS are unaffected and hit the API directly.
Base URL (the API_BASE_URL from the reference project's .env.example):
https://ap.webuntis.com/WebUntis/api/rest/view/v1
The school tenant is selected with the anonymous-school: ap request header.
Responses are cached in memory with the reference server's TTLs: school
years / class lists for 7 days, timetable entries for 15 minutes.
| Endpoint | Used for |
|---|---|
GET /schoolyears | available school years |
GET /app/data | current school year (default date range) |
GET /timetable/filter?resourceType=CLASS&start=&end= | class list for a year |
GET /timetable/entries?resourceType=CLASS&start=&end=&resources=<id> | timetable entries |
Lessons are mapped from the raw grid entries (positions 1–7 → subject / teachers / rooms / info / classes) the same way the reference server does, including merging same-slot lessons and subject filtering (hidden subjects are excluded at sync time).
The app is distributed as a self-hosted APK: the landing page (website/index.html, plain HTML, no build step) offers the download; install once, and receive JS-only fixes silently via EAS Update
(no reinstall). Native changes require a new APK; the fingerprint
runtime-version policy guarantees devices only get compatible updates.
The landing page resolves the newest release at runtime via the GitHub API, so its download button always points at the latest APK without redeploying. Host it anywhere static files work — e.g. with the bundled Dockerfile:
docker build -t betteruntis-site .
docker run -d -p 8080:80 betteruntis-site # → http://localhost:8080
bun run site:serve # local preview without Docker
Both containers together (landing page on :5200, web preview on :5201):
docker compose up -d --build
| Pipeline | Trigger | Output |
|---|---|---|
deploy.yml | push to main | Rebuilds and redeploys both web containers on the own server via docker compose (landing page :5200, web preview :5201) |
update.yml | push to main | EAS OTA update (JS-only, typechecked first) |
release.yml | tag v*.*.* | APK built on EAS cloud, attached to a GitHub Release (= download button target) |
release.yml also carries a version failsafe: it rewrites app.json,
package.json and android.versionCode from the pushed tag (e.g. tag
v1.0.2 → version 1.0.2, versionCode 10002), commits that back to
main, and only then builds — so a release can never ship with a stale
version number or a versionCode too low to install over the previous APK.
fingerprint.config.js keeps version fields out of the update fingerprint,
so those bumps don't break in-app OTA updates for older installs.
Both need an EXPO_TOKEN repo secret (create at expo.dev/settings/access-tokens).
Manual equivalents:
eas update --auto --branch production # push an OTA update
eas build -p android --profile apk # build APK on EAS cloud (same as the release pipeline)
In-app, Settings → "Check for updates" fetches and applies OTA updates immediately; otherwise they apply on the next launch.
bun run typecheck # typecheck app + server
bunx expo run:android # native build
src/app/ — routes: setup wizard, calendar, settingssrc/components/ — week grid (3/5/7-day), agenda, now banner, lesson & add-lesson sheetssrc/lib/ — data layer: WebUntis client + mappers (webuntis.ts), sync, storage, ICS/CSV export, hidden-rule logicsrc/context/calendar-context.tsx — app state, repeat expansion, persistencesrc/components/ui/ — RNR primitivesserver/ — static web server with the CORS proxy (web only; mobile needs no server)