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.
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.
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_KEYkonstans (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 azauth.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ítottauth.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, acacheDirszerinti OS gyorsítótár-mappában van (%LOCALAPPDATA%\pala\cache,~/.cache/pala,~/Library/Caches/pala, mobilon agetTemporaryDirectory()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
stdinnem 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ő.
- dashboard_view.dart: aszinkron billentyűzet-eseményhurok és óra-visszaszámláló. Külön alfolyamatként indul, így az aszinkron
- 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 a0x0200(virtual terminal input) módot, hogy a backspace helyesen töröljön. - utils/chart_generator.dart: ANSI terminálgrafikonok. A
generateLineChartaz 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.
- Képernyők az
app/lib/views/és azapp/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.
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/ésdashboard/: a felhasználói felületek.
- 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
fromJsonmetódusai minden dátumra meghívják a.toLocal()függvényt. - Kötelező paraméterek: a V3 végpontok szigorúak. A
HaziFeladatokpéldául500 Internal Server Errorhibát ad, ha hiányzik adatumTolparaméter, ezért 30 napos alapértelmezett időablakot használunk. - Inkonzisztens típusok: a JSON mezők típusa (például a
Tantargykulcsé) 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 perceKesesPercben, az igazolás állapotaIgazolasAllapota(Igazolt,Igazolatlan,Igazolando). ATipusobjektumban aLeirasaz olvasható név, aNeva kód (példáulfelevi_jegy_ertekeles); a kliensek előbb aLeiras-t olvassák.
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 azIgazolatlanállapot. Minden más (példáulIgazolando) még nyitott, ezt a felület „igazolandó”-ként mutatja.
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.
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.pya Pillow csomagot igényli (pip install pillow).
A natív terminálos bináris előállítása:
dart compile exe bin/pala.dart -o palaA Windows Feladatütemezőből háttérben indított példány (--daemon) láthatatlan módban fut.
- 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ésdart test, - alkalmazás:
flutter analyzeésflutter testazapp/mappában, - kiterjesztés:
node --checkminden JS fájlra ésnode --test extension/test/*.test.mjs, - weboldal:
bun run lint,bun run buildésnode scripts/check-contrast.mjs.
- mag és TUI:
- 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.gzcsomagokkal), - 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 stabilv*kiadásnál közzéteszi az AURpala-bincsomagot.
- a terminálos binárisokat Windowsra, Linuxra és macOS-re (zip,
- aur.yml: csak kézi indításra, az AUR csomag újbóli közzétételéhez a
mainágról.
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-codesignAz 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).
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 buildatlstr.hhibával leáll. - Linux: a
libsecret-1-devcsomag, futáskor pedig egy kulcstartó szolgáltatás (például GNOME Keyring vagy KWallet).
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):
- 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
- A kulcsfájl base64 kódolása egyetlen sorba:
Windows PowerShellben:
base64 -w 0 pala-release.jks > pala-release.jks.b64[Convert]::ToBase64String([IO.File]::ReadAllBytes("pala-release.jks")) | Set-Content pala-release.jks.b64 - A repó Settings > Secrets and variables > Actions oldalán négy titok felvétele:
ANDROID_KEYSTORE_BASE64: apala-release.jks.b64tartalma,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).
- A
.b64fájl törlése. A kulcsfájlt és akey.propertiesfájlt soha nem szabad commitolni (a.gitignorekizá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.