Skip to content

Latest commit

 

History

History
181 lines (137 loc) · 14.1 KB

DEV.md

File metadata and controls

181 lines (137 loc) · 14.1 KB

Fejlesztői Dokumentáció

Ez a leírás a Pala felépítését, a Kréta API sajátosságait, valamint az ellenőrzési és kiadási folyamatot foglalja össze.

Felépítés

A Pala egy közös Dart magra épülő több kliensből áll:

Mappa Tartalom
lib/, bin/ Közös mag (API, modellek, állapot) és a terminálos alkalmazás (TUI). Tiszta Dart, Flutter nélkül, így gyorsan AOT-fordítható natív binárissá.
app/ Flutter asztali és mobil alkalmazás (pala --desktop): Windows, macOS, Linux, Android, és kísérletként iOS. A lib/-et a package:pala függőségen keresztül használja.
extension/ Manifest V3 böngésző-kiterjesztés (Chrome, Brave, Edge), sima JavaScript, build lépés nélkül.
website/ Next.js weboldal (pala-app.hu), statikus exporttal, Vercelen. A kiadási adatokat a build kéri le a GitHubtól. Részletek: website/README.md.

Fontos: a kiterjesztés nem tudja használni a Dart kódot. Ha a lib/api/ vagy a lib/models/ viselkedése megváltozik, ugyanazt a változtatást kézzel át kell vezetni az extension/shared/kreta_api.js fájlba is. Ugyanez vonatkozik a demó adatokra: a lib/api/demo_data.dart és a kreta_api.js DEMO_* konstansai legyenek szinkronban.

Közös mag és TUI (lib/)

Kiemelt függőségek:

  • interact: interaktív terminálfelület (menük, bevitel, maszkolás).
  • http: kommunikáció a Kréta IDP és V3 (Ellenőrző) API-kkal. A KRETA_API_KEY konstans (lib/api/api.dart, extension/shared/kreta_api.js) a hivatalos Kréta mobilalkalmazás publikus API-kulcsa, amelyet minden nyílt forráskódú Kréta-kliens (rsfilc, Firka stb.) ugyanígy használ. Nem titok, ezért szándékosan szerepel a forráskódban.
  • args: parancssori argumentumok feldolgozása.

Fő modulok:

  • api/client.dart: hálózati réteg és OAuth2 token-kezelés. A token-frissítés (refreshAccessToken) aszinkron zárral (_activeRefreshFuture) védett, így párhuzamos API-hívásoknál sem sérül az auth.json írása és titkosítása.
  • models/: típusbiztos modellek (Grade, Student, Absence, TimetableEntry stb.). Az UTC dátumokat azonnal helyi időre alakítják. Az isSummaryGrade ékezetes és ékezet nélküli szűréssel is kiszűri a félévi és év végi összefoglaló jegyeket.
  • app/state/app_state.dart: singleton a helyi beállításokhoz (state.json és a titkosított auth.json) a ~/.config/pala/ mappában, a témával és az ASCII banner beállításaival együtt. Az offline API-gyorsítótár (cache.json) ettől külön, a cacheDir szerinti OS gyorsítótár-mappában van (%LOCALAPPDATA%\pala\cache, ~/.cache/pala, ~/Library/Caches/pala, mobilon a getTemporaryDirectory() alatt); a régi helyről automatikusan átkerül.
  • app/theme.dart: a terminál globális témája és színei (PalaTheme).
  • app/views/:
    • dashboard_view.dart: aszinkron billentyűzet-eseményhurok és óra-visszaszámláló. Külön alfolyamatként indul, így az aszinkron stdin nem akad össze a főprogram konzoljával.
    • wrapped_view.dart: a Pala Wrapped éves statisztika diái.
    • absences_view.dart: Veszélyzóna kalkulátor, osztályátlag- és eltérés-táblázat, heti jegy-trendek.
    • grades_view.dart: Szellem jegy kalkulátor, jegy-heatmap és az ékezet-érzéketlen kereső.
  • app/components/utf8_input.dart: saját beviteli réteg, amely Windows konzolon is helyesen kezeli a karakterek visszaírását (echo).
  • utils/win32_console.dart: Win32 API FFI hívások. A forceRestoreConsoleMode() visszaállítja a billentyűzet-echót (ENABLE_ECHO_INPUT), és kikapcsolja a 0x0200 (virtual terminal input) módot, hogy a backspace helyesen töröljön.
  • utils/chart_generator.dart: ANSI terminálgrafikonok. A generateLineChart az adatokhoz igazítja az y-tengelyt, így az átlaggrafikon nem lesz lapos.
  • utils/ics_exporter.dart: RFC 5545 kompatibilis naptárexport.
  • web/pala_web_server.dart és web/pala_web_html.dart: beágyazott HTTP szerver és HTML nézetek.

Asztali és mobil alkalmazás (app/)

  • Képernyők az app/lib/views/ és az app/lib/features/ alatt (bejelentkezés, dashboard, jegyek, hiányzások, órarend, feladatok, üzenetírás, kereső, statisztika, Wrapped, beállítások).
  • Állapotkezelés: app/lib/state/app_model.dart (ChangeNotifier).
  • Adaptív elrendezés: app/lib/core/adaptive/ (600 dp alatt alsó navigáció, felette oldalsáv).
  • Értesítések: app/lib/notifications/. A háttérellenőrzés (WorkManager) csak Androidon fut; iOS-en az adatok megnyitáskor frissülnek.

Böngésző-kiterjesztés (extension/)

  • shared/kreta_api.js: közös API és OAuth2 réteg, valamint a demó motor.
  • background/service_worker.js: token-megújítás a háttérben és háttérszinkron.
  • popup/ és dashboard/: a felhasználói felületek.

A Kréta API sajátosságai

  • UTC időpontok: a Kréta API a dátumokat (például az órák kezdetét) UTC-ben adja vissza. Közvetlen megjelenítésnél a napok elcsúszhatnak, ezért a modellek fromJson metódusai minden dátumra meghívják a .toLocal() függvényt.
  • Kötelező paraméterek: a V3 végpontok szigorúak. A HaziFeladatok például 500 Internal Server Error hibát ad, ha hiányzik a datumTol paraméter, ezért 30 napos alapértelmezett időablakot használunk.
  • Inkonzisztens típusok: a JSON mezők típusa (például a Tantargy kulcsé) változhat, ezért a kliensoldali típusellenőrzés (null check, típuskonverzió) elengedhetetlen.
  • Windows kódolás: a PowerShell alapértelmezett Windows-1252 kódolása miatt az UTF-8 karakterek és a táblázatrajzoló elemek külön kezelést igényelnek.
  • Mezőnevek: a jegy súlya SulySzazalekErteke, a késés perce KesesPercben, az igazolás állapota IgazolasAllapota (Igazolt, Igazolatlan, Igazolando). A Tipus objektumban a Leiras az olvasható név, a Nev a kód (például felevi_jegy_ertekeles); a kliensek előbb a Leiras-t olvassák.

Számítási szabályok

Minden kliens (TUI, asztali és mobil app, kiterjesztés, helyi webes felület) ugyanezeket a szabályokat követi. A Dart oldalon a lib/rules/ valósítja meg, a kiterjesztésben a KretaApi azonos nevű függvényei. A tesztvektorok a fixtures/rules/ mappában vannak, és mindkét oldal teszteli őket (test/rules_test.dart, extension/test/rules.test.mjs). Szabályváltozásnál előbb a vektort kell módosítani.

Átlag

  • Egy jegy akkor számít, ha 1 és 5 közötti számjegy, nem félévi, év végi, negyedéves vagy osztályozó vizsga eredménye, és a súlya 0-nál nagyobb.
  • A hiányzó súly 100%. A 0%-os súlyú jegy nem számít bele az átlagba.
  • A szöveges és a százalékos értékelés nem számít.
  • A tantárgyi átlag a beszámított jegyek súlyozott átlaga.
  • Az összesített (tanulmányi) átlag a tantárgyi átlagok egyszerű átlaga, ahogy a bizonyítványban. A tantárgy, amelyben nincs beszámított jegy, kimarad.

Mulasztás

  • Minden mulasztás egy tanórát jelent.
  • Késés az a bejegyzés, amelynek van KesesPercben értéke, vagy a típusa „késés”. A késés nem számít bele a 250 órás keretbe, a percei külön összegződnek. (A késések percekből órává összeadását a Pala nem modellezi.)
  • Igazolt csak az Igazolt, igazolatlan csak az Igazolatlan állapot. Minden más (például Igazolando) még nyitott, ezt a felület „igazolandó”-ként mutatja.

Ellenőrzés commit előtt

A CI a Dart és Flutter ellenőrzéseket minden main-re történő pushnál és pull requestnél lefuttatja, és bármilyen hibánál elbukik. A megváltoztatott részekre futtasd le helyben is:

Változás helye Parancs
lib/, bin/, test/ dart analyze --fatal-infos és dart test a repó gyökerében. A sima dart analyze nem elég: a CI az info szintű jelzéseket is hibának veszi.
app/ flutter analyze és flutter test az app/ mappában.
extension/ node --check <fájl> minden módosított JS fájlra, és node --test extension/test/*.test.mjs a repó gyökerében (függőség nélkül fut).
website/ bun run lint, bun run build és node scripts/check-contrast.mjs a website/ mappában (vagy npm-mel).
fixtures/rules/ Mindkét tesztsor: dart test test/rules_test.dart és node --test extension/test/*.test.mjs.

Gyors kézi próba: dart run bin/pala.dart --demo bejelentkezés és hálózat nélkül, fiktív adatokkal indítja a TUI-t.

Weboldal előnézeti képek

A weboldal nyitóoldalán látható képek (website/public/previews/*.webp) a valódi alkalmazásokról készülnek, demó módban. Ha valamelyik kliens felülete megváltozik, készítsd el őket újra:

cd app && flutter test test/preview_capture_test.dart --dart-define=CAPTURE_PREVIEWS=true && cd ..
node scripts/previews/capture_extension.mjs
python scripts/previews/to_webp.py
  • Az első parancs az asztali és a telefonos nézetet rögzíti (sötét és világos téma), a második a bővítmény felugró ablakát egy Chromium-alapú böngészővel (Edge, Chrome vagy Brave), a harmadik WebP-be alakítja és átméretezi a képeket.
  • A nyers PNG-k a build/previews/ mappába kerülnek (gitignore alatt).
  • A képek a futtatás napjának órarendjét mutatják: hétköznap, tanítási időben futtatva a vezérlőpult a következő órát jeleníti meg.
  • A to_webp.py a Pillow csomagot igényli (pip install pillow).

Build és kiadás

A natív terminálos bináris előállítása:

dart compile exe bin/pala.dart -o pala

A Windows Feladatütemezőből háttérben indított példány (--daemon) láthatatlan módban fut.

GitHub Actions

  • ci.yml: minden main-re történő pushnál és pull requestnél négy feladat fut:
    • mag és TUI: dart analyze --fatal-infos lib bin test és dart test,
    • alkalmazás: flutter analyze és flutter test az app/ mappában,
    • kiterjesztés: node --check minden JS fájlra és node --test extension/test/*.test.mjs,
    • weboldal: bun run lint, bun run build és node scripts/check-contrast.mjs.
  • release.yml: egy GitHub Release közzétételekor (vagy kézi indításra) elkészíti és a kiadáshoz csatolja:
    • a terminálos binárisokat Windowsra, Linuxra és macOS-re (zip, .deb és .tar.gz csomagokkal),
    • az asztali alkalmazást: Windows telepítő (Pala-Setup.exe), macOS DMG (Pala-macOS.dmg), Linux AppImage (Pala-x86_64.AppImage),
    • az Android APK-kat (pala-universal.apk és architektúránként),
    • az aláíratlan iOS alkalmazást (Pala.ipa),
    • a böngésző-kiterjesztés zip fájlját (pala-extension.zip),
    • a fentiek SHA-256 ellenőrzőösszegeit (SHA256SUMS),
    • az APT tárolót, frissíti a Scoop (bucket/pala.json) és Homebrew (Formula/pala.rb) manifesteket, majd stabil v* kiadásnál közzéteszi az AUR pala-bin csomagot.
  • aur.yml: csak kézi indításra, az AUR csomag újbóli közzétételéhez a main ágról.

iOS build

Az iOS-build csak macOS-en (Xcode-dal) készíthető el, a kiadásban a release.yml macOS-futója végzi:

cd app && flutter build ios --release --no-codesign

Az eredmény (build/ios/iphoneos/Runner.app) egy Payload/ mappába csomagolva, zipelve lesz Pala.ipa. Fizetős Apple fejlesztői fiók nincs: a felhasználók a saját ingyenes Apple ID-jükkel írják alá AltStore-ral vagy Sideloadlyval, ezért a telepítés 7 napig érvényes. Az iOS-változat kísérleti, valódi iPhone-on még ki kell próbálni (bejelentkezés, mentett munkamenet a kulcskarikában).

Asztali build előfeltételek

A flutter_secure_storage miatt az asztali alkalmazás buildjéhez kell:

  • Windows: a Visual Studio (vagy Build Tools) „C++ ATL for latest build tools” összetevője (Microsoft.VisualStudio.Component.VC.ATL), különben a build atlstr.h hibával leáll.
  • Linux: a libsecret-1-dev csomag, futáskor pedig egy kulcstartó szolgáltatás (például GNOME Keyring vagy KWallet).

Android aláíró kulcs

Az Android csak akkor telepít frissítést, ha az ugyanazzal a kulccsal van aláírva, mint a már telepített verzió. Ezért a kiadott APK-kat egy állandó kulcs írja alá, amelyet a release.yml a GitHub titkokból állít elő. Ha a titkok hiányoznak, a build figyelmeztetéssel lefut, de az APK egy eldobható debug kulccsal lesz aláírva, amely nem frissíthető a következő kiadással.

Egyszeri beállítás (a karbantartó végzi):

  1. Kulcs létrehozása (a jelszavakat és a fájlt biztonságos helyen, például jelszókezelőben kell megőrizni; ha elveszik, a meglévő telepítések többé nem frissíthetők):
    keytool -genkey -v -keystore pala-release.jks -keyalg RSA -keysize 2048 -validity 10000 -alias pala
  2. A kulcsfájl base64 kódolása egyetlen sorba:
    base64 -w 0 pala-release.jks > pala-release.jks.b64
    Windows PowerShellben: [Convert]::ToBase64String([IO.File]::ReadAllBytes("pala-release.jks")) | Set-Content pala-release.jks.b64
  3. A repó Settings > Secrets and variables > Actions oldalán négy titok felvétele:
    • ANDROID_KEYSTORE_BASE64: a pala-release.jks.b64 tartalma,
    • ANDROID_KEYSTORE_PASSWORD: a kulcstár jelszava,
    • ANDROID_KEY_ALIAS: pala,
    • ANDROID_KEY_PASSWORD: a kulcs jelszava (alapértelmezésben megegyezik a kulcstár jelszavával).
  4. A .b64 fájl törlése. A kulcsfájlt és a key.properties fájlt soha nem szabad commitolni (a .gitignore kizárja őket).

Helyi aláírt buildhez az app/android/key.properties fájl kell:

storeFile=pala-release.jks
storePassword=...
keyAlias=pala
keyPassword=...

A storeFile az app/android/app/ mappához képest relatív (vagy abszolút útvonal). Ha a fájl nincs meg, a flutter build apk --release a debug kulccsal ír alá.

Az első, új kulccsal aláírt kiadásra váltáskor a korábbi (debug kulcsos) telepítést egyszer el kell távolítani; utána a frissítések már eltávolítás nélkül települnek.