Compare commits

..

11 Commits

Author SHA1 Message Date
021e030ded fix: Package import 2026-02-12 08:35:49 +01:00
bb0b31e84d chore: Bump version 2026-02-10 19:07:22 +01:00
549968dbf3 fix: Make teacher param in absence nullable 2026-02-10 19:06:11 +01:00
9c9fbfeede fix: Report url path 2026-02-10 19:05:11 +01:00
5d21a8ad9e chore: Bump 2026-02-09 17:12:29 +01:00
7738043a80 feat: Reporting 2026-02-09 17:11:49 +01:00
7090595505 feat: Reporting 2026-02-09 17:11:48 +01:00
0f48c24009 chore: Bump and fix some stuff 2026-02-07 23:31:17 +01:00
2595cc5cf0 chore: Bump version 2026-02-07 17:57:47 +01:00
c59b55c66b feat: Add all and remove test 2026-02-07 17:56:28 +01:00
a3cfcd52c5 chore: Change package name and upload build_all.sh 2026-02-07 14:22:22 +01:00
13 changed files with 450 additions and 287 deletions

4
.gitignore vendored
View File

@@ -1,9 +1,7 @@
# Rust # Rust
/target/ /target/
/build_all.sh /bindings/kotlin/src/main/kotlin/cz/jzitnik
/bindings/kotlin/src/main/kotlin/uniffi/
/bindings/kotlin/src/main/resources/lib/ /bindings/kotlin/src/main/resources/lib/
/bindings/kotlin/src/main/resources/linux-x86-64/ /bindings/kotlin/src/main/resources/linux-x86-64/
/bindings/kotlin/src/main/resources/win32-x86-64/ /bindings/kotlin/src/main/resources/win32-x86-64/

377
Cargo.lock generated
View File

@@ -2,15 +2,6 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 4
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.21" version = "0.6.21"
@@ -133,10 +124,10 @@ dependencies = [
] ]
[[package]] [[package]]
name = "bumpalo" name = "bitflags"
version = "3.19.1" version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
[[package]] [[package]]
name = "bytes" name = "bytes"
@@ -192,20 +183,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chrono"
version = "0.4.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
dependencies = [
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-link",
]
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.53" version = "4.5.53"
@@ -252,18 +229,59 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "core-foundation"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "core-foundation-sys" name = "core-foundation-sys"
version = "0.8.7" version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.9" version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]] [[package]]
name = "fs-err" name = "fs-err"
version = "2.11.0" version = "2.11.0"
@@ -284,6 +302,18 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasip2",
]
[[package]] [[package]]
name = "glob" name = "glob"
version = "0.3.3" version = "0.3.3"
@@ -313,30 +343,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "iana-time-zone"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "is_terminal_polyfill" name = "is_terminal_polyfill"
version = "1.70.2" version = "1.70.2"
@@ -351,9 +357,8 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
[[package]] [[package]]
name = "jecna_supl_client" name = "jecna_supl_client"
version = "0.1.1" version = "0.2.3"
dependencies = [ dependencies = [
"chrono",
"minreq", "minreq",
"serde", "serde",
"serde_json", "serde_json",
@@ -361,22 +366,18 @@ dependencies = [
"uniffi", "uniffi",
] ]
[[package]]
name = "js-sys"
version = "0.3.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.180" version = "0.2.180"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
[[package]]
name = "linux-raw-sys"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.29" version = "0.4.29"
@@ -417,6 +418,7 @@ version = "2.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05015102dad0f7d61691ca347e9d9d9006685a64aefb3d79eecf62665de2153d" checksum = "05015102dad0f7d61691ca347e9d9d9006685a64aefb3d79eecf62665de2153d"
dependencies = [ dependencies = [
"native-tls",
"rustls", "rustls",
"rustls-webpki", "rustls-webpki",
"serde", "serde",
@@ -424,6 +426,23 @@ dependencies = [
"webpki-roots", "webpki-roots",
] ]
[[package]]
name = "native-tls"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@@ -434,15 +453,6 @@ dependencies = [
"minimal-lexical", "minimal-lexical",
] ]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.21.3" version = "1.21.3"
@@ -455,12 +465,62 @@ version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "openssl"
version = "0.10.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
dependencies = [
"bitflags",
"cfg-if",
"foreign-types",
"libc",
"once_cell",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "openssl-probe"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
[[package]]
name = "openssl-sys"
version = "0.9.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.15" version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]] [[package]]
name = "plain" name = "plain"
version = "0.2.3" version = "0.2.3"
@@ -485,6 +545,12 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.17.14" version = "0.17.14"
@@ -493,12 +559,25 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if", "cfg-if",
"getrandom", "getrandom 0.2.17",
"libc", "libc",
"untrusted", "untrusted",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "rustix"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.21.12" version = "0.21.12"
@@ -522,10 +601,13 @@ dependencies = [
] ]
[[package]] [[package]]
name = "rustversion" name = "schannel"
version = "1.0.22" version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
dependencies = [
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "scroll" name = "scroll"
@@ -557,6 +639,29 @@ dependencies = [
"untrusted", "untrusted",
] ]
[[package]]
name = "security-framework"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "semver" name = "semver"
version = "1.0.27" version = "1.0.27"
@@ -651,6 +756,19 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "tempfile"
version = "3.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c"
dependencies = [
"fastrand",
"getrandom 0.3.4",
"once_cell",
"rustix",
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.16.2" version = "0.16.2"
@@ -853,6 +971,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.1+wasi-snapshot-preview1" version = "0.11.1+wasi-snapshot-preview1"
@@ -860,48 +984,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasip2"
version = "0.2.108" version = "1.0.2+wasi-0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
dependencies = [ dependencies = [
"cfg-if", "wit-bindgen",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12"
dependencies = [
"unicode-ident",
] ]
[[package]] [[package]]
@@ -919,65 +1007,12 @@ dependencies = [
"nom", "nom",
] ]
[[package]]
name = "windows-core"
version = "0.62.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "windows-link" name = "windows-link"
version = "0.2.1" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-result"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
dependencies = [
"windows-link",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
@@ -1060,6 +1095,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "wit-bindgen"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
[[package]] [[package]]
name = "zmij" name = "zmij"
version = "1.0.19" version = "1.0.19"

View File

@@ -1,15 +1,20 @@
[package] [package]
name = "jecna_supl_client" name = "jecna_supl_client"
version = "0.1.1" version = "0.2.3"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
chrono = { version = "0.4.39", features = ["serde"] } serde = { version = "1.0", default-features = false, features = ["derive"] }
minreq = { version = "2.13", features = ["json-using-serde", "https-rustls"] } serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
serde = { version = "1.0", features = ["derive"] } thiserror = { version = "2.0.11", default-features = false }
serde_json = "1.0" uniffi = { version = "0.27", default-features = false }
thiserror = "2.0.11"
uniffi = { version = "0.27" } [target.'cfg(not(target_os = "android"))'.dependencies]
minreq = { version = "2.14", default-features = false, features = ["json-using-serde", "https-native"] }
[target.'cfg(target_os = "android")'.dependencies]
minreq = { version = "2.14", default-features = false, features = ["json-using-serde", "https-rustls"] }
[features] [features]
uniffi-cli = ["uniffi/cli"] uniffi-cli = ["uniffi/cli"]
@@ -23,7 +28,9 @@ required-features = ["uniffi-cli"]
[profile.release] [profile.release]
opt-level = "z" opt-level = "z"
lto = true lto = "fat"
codegen-units = 1 codegen-units = 1
panic = "abort" panic = "abort"
strip = false strip = false
incremental = false
debug = false

View File

@@ -6,7 +6,7 @@ plugins {
} }
group = "cz.jzitnik" group = "cz.jzitnik"
version = "0.1.1" version = "0.2.3"
repositories { repositories {
mavenCentral() mavenCentral()

View File

@@ -6,7 +6,7 @@
<groupId>cz.jzitnik</groupId> <groupId>cz.jzitnik</groupId>
<artifactId>jecna-supl-client</artifactId> <artifactId>jecna-supl-client</artifactId>
<version>0.1.1</version> <version>0.2.3</version>
<name>Jecna Supl Client</name> <name>Jecna Supl Client</name>
<description>Kotlin bindings for the Jecna Supl Rust library</description> <description>Kotlin bindings for the Jecna Supl Rust library</description>
<url>https://gitea.jzitnik.dev/jzitnik/jecna-supl-client</url> <url>https://gitea.jzitnik.dev/jzitnik/jecna-supl-client</url>

88
build_all.sh Executable file
View File

@@ -0,0 +1,88 @@
#!/bin/bash
set -e
#export ANDROID_NDK_HOME=/home/kuba/.Android/Sdk/ndk/29.0.14206865/
export ANDROID_NDK_HOME=/home/kuba/.Android/Sdk/ndk/27.0.12077973/
# Configuration
PROJECT_NAME="jecna_supl_client"
LIB_NAME="lib${PROJECT_NAME}"
KOTLIN_RES_DIR="bindings/kotlin/src/main/resources"
KOTLIN_SRC_DIR="bindings/kotlin/src/main/kotlin"
# Targets
LINUX_TARGET="x86_64-unknown-linux-gnu"
ANDROID_TARGETS=("aarch64-linux-android" "armv7-linux-androideabi" "x86_64-linux-android")
WINDOWS_TARGET="x86_64-pc-windows-gnu"
echo "=== Building for Linux ($LINUX_TARGET) ==="
cargo build --release --target $LINUX_TARGET
echo "=== Building for Android ==="
for target in "${ANDROID_TARGETS[@]}"; do
echo "--- Building $target ---"
cargo ndk -t $target build --release
done
echo "=== Building for Windows ($WINDOWS_TARGET) ==="
if rustup target list --installed | grep -q "$WINDOWS_TARGET" && command -v x86_64-w64-mingw32-gcc >/dev/null; then
cargo build --release --target $WINDOWS_TARGET
else
echo "Warning: Windows target or x86_64-w64-mingw32-gcc not found. Skipping Windows build."
fi
echo "=== Generating Kotlin Bindings ==="
# Use the Linux library for metadata extraction
GEN_LIB_PATH="target/$LINUX_TARGET/release/${LIB_NAME}.so"
if [ ! -f "$GEN_LIB_PATH" ]; then
# Fallback to host build if linux target failed/was different
GEN_LIB_PATH="target/release/${LIB_NAME}.so"
fi
cargo run --features uniffi-cli --bin uniffi-bindgen generate \
--library "$GEN_LIB_PATH" \
--language kotlin \
--out-dir "$KOTLIN_SRC_DIR" \
--no-format
echo "=== Organizing Native Libraries ==="
if [ -n "$ANDROID_NDK_HOME" ] && [ -f "$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip" ]; then
STRIP="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip"
else
STRIP="strip"
fi
echo "Using strip tool: $STRIP"
# Linux x86_64
mkdir -p "$KOTLIN_RES_DIR/linux-x86-64"
cp "target/$LINUX_TARGET/release/${LIB_NAME}.so" "$KOTLIN_RES_DIR/linux-x86-64/${LIB_NAME}.so"
"$STRIP" --strip-all "$KOTLIN_RES_DIR/linux-x86-64/${LIB_NAME}.so"
# Android
mkdir -p "$KOTLIN_RES_DIR/lib/arm64-v8a"
cp "target/aarch64-linux-android/release/${LIB_NAME}.so" "$KOTLIN_RES_DIR/lib/arm64-v8a/${LIB_NAME}.so"
"$STRIP" --strip-all "$KOTLIN_RES_DIR/lib/arm64-v8a/${LIB_NAME}.so"
mkdir -p "$KOTLIN_RES_DIR/lib/armeabi-v7a"
cp "target/armv7-linux-androideabi/release/${LIB_NAME}.so" "$KOTLIN_RES_DIR/lib/armeabi-v7a/${LIB_NAME}.so"
"$STRIP" --strip-all "$KOTLIN_RES_DIR/lib/armeabi-v7a/${LIB_NAME}.so"
mkdir -p "$KOTLIN_RES_DIR/lib/x86_64"
cp "target/x86_64-linux-android/release/${LIB_NAME}.so" "$KOTLIN_RES_DIR/lib/x86_64/${LIB_NAME}.so"
"$STRIP" --strip-all "$KOTLIN_RES_DIR/lib/x86_64/${LIB_NAME}.so"
# Windows
WIN_DLL="target/$WINDOWS_TARGET/release/${PROJECT_NAME}.dll"
if [ -f "$WIN_DLL" ]; then
mkdir -p "$KOTLIN_RES_DIR/win32-x86-64"
cp "$WIN_DLL" "$KOTLIN_RES_DIR/win32-x86-64/${PROJECT_NAME}.dll"
fi
# This is just for me cuz I have memory like a goldfish and I will forget how to upload it to central... Leave me alone
echo "=== Build Complete ==="
echo "To upload to Sonatype Central:"
echo "1. cd bindings/kotlin"
echo "2. JAVA_HOME=/usr/lib/jvm/java-17-openjdk ./gradlew clean zipBundle"
echo "3. Upload the file 'bindings/kotlin/build/distributions/sonatype-bundle.zip'"
echo " at https://central.sonatype.com/publishing/deployments"

5
src/all.rs Normal file
View File

@@ -0,0 +1,5 @@
use crate::{api::fetch_api, ApiResponse, SuplError};
pub fn get_all_impl(provider_url: &str) -> Result<ApiResponse, SuplError> {
fetch_api(provider_url)
}

View File

@@ -1,3 +1,5 @@
use serde::Deserialize;
use crate::models::{ApiResponse, SuplError}; use crate::models::{ApiResponse, SuplError};
pub fn fetch_api(provider_url: &str) -> Result<ApiResponse, SuplError> { pub fn fetch_api(provider_url: &str) -> Result<ApiResponse, SuplError> {
@@ -14,3 +16,34 @@ pub fn fetch_api(provider_url: &str) -> Result<ApiResponse, SuplError> {
reason: e.to_string(), reason: e.to_string(),
}) })
} }
#[derive(Deserialize)]
struct StatusResponse {
working: bool,
message: Option<String>,
}
pub fn test_api(provider_url: &str) -> Result<(), SuplError> {
let trimmed = provider_url.trim_end_matches('/');
let url = format!("{}/status", trimmed);
let status: StatusResponse = minreq::get(&url)
.send()
.map_err(|e| SuplError::NetworkError {
reason: e.to_string(),
})?
.json()
.map_err(|e| SuplError::ParseError {
reason: e.to_string(),
})?;
if status.working {
Ok(())
} else {
Err(SuplError::ParseError {
reason: status
.message
.unwrap_or_else(|| "Provider reported not working".to_string()),
})
}
}

View File

@@ -1,97 +0,0 @@
use jecna_supl_client::{AbsenceEntry, JecnaSuplClient};
fn main() {
let client = JecnaSuplClient::new();
println!("Fetching schedule for E4...");
match client.get_schedule("E4".to_string()) {
Ok(result) => {
println!("Last updated: {}", result.status.last_updated);
if result.schedule.is_empty() {
println!("No substitution schedule found for the upcoming days.");
}
for (date, day) in result.schedule {
println!("\nDate: {}", date);
println!("In work: {}", day.info.in_work);
if !day.takes_place.is_empty() {
println!("Extra info: {}", day.takes_place);
}
println!("Changes:");
for (i, change) in day.changes.iter().enumerate() {
if let Some(c) = change {
println!(" Lesson {}: {}", i + 1, c.text);
}
}
println!("Absences:");
for entry in day.absence {
print_absence(entry);
}
}
}
Err(e) => eprintln!("Error fetching schedule: {:?}", e),
}
println!("\nFetching all teacher absences...");
match client.get_teacher_absence() {
Ok(result) => {
for (date, entries) in result.absences {
println!("\nDate: {}", date);
for entry in entries {
print_absence(entry);
}
}
}
Err(e) => eprintln!("Error fetching teacher absences: {:?}", e),
}
}
fn print_absence(entry: AbsenceEntry) {
match entry {
AbsenceEntry::WholeDay {
teacher,
teacher_code,
} => {
println!(" {} ({}): Whole day", teacher, teacher_code);
}
AbsenceEntry::Single {
teacher,
teacher_code,
hours,
} => {
println!(" {} ({}): Lesson {}", teacher, teacher_code, hours);
}
AbsenceEntry::Range {
teacher,
teacher_code,
hours,
} => {
println!(
" {} ({}): Lessons {}-{}",
teacher, teacher_code, hours.from, hours.to
);
}
AbsenceEntry::Exkurze {
teacher,
teacher_code,
} => {
println!(" {} ({}): Excursion", teacher, teacher_code);
}
AbsenceEntry::Zastoupen {
teacher,
teacher_code,
zastupuje,
} => {
println!(
" {} ({}): Represented by {} ({})",
teacher, teacher_code, zastupuje.teacher, zastupuje.teacher_code
);
}
AbsenceEntry::Invalid { original } => {
println!(" Invalid entry: {}", original);
}
}
}

View File

@@ -2,10 +2,15 @@ mod api;
mod models; mod models;
mod schedule; mod schedule;
mod teacher_absence; mod teacher_absence;
mod all;
mod report;
use std::sync::RwLock; use std::sync::RwLock;
pub use models::*; pub use models::*;
pub use report::ReportLocation;
use crate::report::{report_impl, ReportLocation};
uniffi::setup_scaffolding!(); uniffi::setup_scaffolding!();
@@ -30,11 +35,29 @@ impl JecnaSuplClient {
pub fn get_schedule(&self, class_name: String) -> Result<SuplResult, SuplError> { pub fn get_schedule(&self, class_name: String) -> Result<SuplResult, SuplError> {
let provider = self.provider_url.read().unwrap(); let provider = self.provider_url.read().unwrap();
api::test_api(&provider)?;
schedule::get_schedule_impl(&provider, class_name) schedule::get_schedule_impl(&provider, class_name)
} }
pub fn get_teacher_absence(&self) -> Result<TeacherAbsenceResult, SuplError> { pub fn get_teacher_absence(&self) -> Result<TeacherAbsenceResult, SuplError> {
let provider = self.provider_url.read().unwrap(); let provider = self.provider_url.read().unwrap();
api::test_api(&provider)?;
teacher_absence::get_teacher_absence_impl(&provider) teacher_absence::get_teacher_absence_impl(&provider)
} }
pub fn get_all(&self) -> Result<ApiResponse, SuplError> {
let provider = self.provider_url.read().unwrap();
api::test_api(&provider)?;
all::get_all_impl(&provider)
}
pub fn report(&self, content: String, class: String, report_location: ReportLocation) -> Result<(), SuplError> {
let provider = self.provider_url.read().unwrap();
api::test_api(&provider)?;
report_impl(&provider, content, class, report_location)
}
} }

View File

@@ -18,33 +18,33 @@ pub enum SuplError {
pub enum AbsenceEntry { pub enum AbsenceEntry {
#[serde(rename = "wholeDay")] #[serde(rename = "wholeDay")]
WholeDay { WholeDay {
teacher: String, teacher: Option<String>,
#[serde(rename = "teacherCode")] #[serde(rename = "teacherCode")]
teacher_code: String, teacher_code: String,
}, },
#[serde(rename = "single")] #[serde(rename = "single")]
Single { Single {
teacher: String, teacher: Option<String>,
#[serde(rename = "teacherCode")] #[serde(rename = "teacherCode")]
teacher_code: String, teacher_code: String,
hours: u16, hours: u16,
}, },
#[serde(rename = "range")] #[serde(rename = "range")]
Range { Range {
teacher: String, teacher: Option<String>,
#[serde(rename = "teacherCode")] #[serde(rename = "teacherCode")]
teacher_code: String, teacher_code: String,
hours: AbsenceRange, hours: AbsenceRange,
}, },
#[serde(rename = "exkurze")] #[serde(rename = "exkurze")]
Exkurze { Exkurze {
teacher: String, teacher: Option<String>,
#[serde(rename = "teacherCode")] #[serde(rename = "teacherCode")]
teacher_code: String, teacher_code: String,
}, },
#[serde(rename = "zastoupen")] #[serde(rename = "zastoupen")]
Zastoupen { Zastoupen {
teacher: String, teacher: Option<String>,
#[serde(rename = "teacherCode")] #[serde(rename = "teacherCode")]
teacher_code: String, teacher_code: String,
zastupuje: SubstituteInfo, zastupuje: SubstituteInfo,
@@ -61,7 +61,7 @@ pub struct AbsenceRange {
#[derive(Deserialize, Debug, uniffi::Record, Clone)] #[derive(Deserialize, Debug, uniffi::Record, Clone)]
pub struct SubstituteInfo { pub struct SubstituteInfo {
pub teacher: String, pub teacher: Option<String>,
#[serde(rename = "teacherCode")] #[serde(rename = "teacherCode")]
pub teacher_code: String, pub teacher_code: String,
} }
@@ -71,17 +71,19 @@ pub struct ChangeEntry {
pub text: String, pub text: String,
#[serde(rename = "backgroundColor")] #[serde(rename = "backgroundColor")]
pub background_color: Option<String>, pub background_color: Option<String>,
#[serde(rename = "foregroundColor")]
pub foreground_color: Option<String>,
#[serde(rename = "willBeSpecified")] #[serde(rename = "willBeSpecified")]
pub will_be_specified: Option<bool>, pub will_be_specified: Option<bool>,
} }
#[derive(Deserialize)] #[derive(Deserialize, Debug, uniffi::Record)]
pub struct ApiResponse { pub struct ApiResponse {
pub status: Status, pub status: Status,
pub schedule: HashMap<String, DailyData>, pub schedule: HashMap<String, DailyData>,
} }
#[derive(Deserialize, Clone)] #[derive(Deserialize, Clone, Debug, uniffi::Record)]
pub struct DailyData { pub struct DailyData {
pub info: DayInfo, pub info: DayInfo,
pub changes: HashMap<String, Vec<Option<ChangeEntry>>>, pub changes: HashMap<String, Vec<Option<ChangeEntry>>>,
@@ -89,7 +91,7 @@ pub struct DailyData {
#[serde(rename = "takesPlace")] #[serde(rename = "takesPlace")]
pub takes_place: String, pub takes_place: String,
#[serde(rename = "reservedRooms")] #[serde(rename = "reservedRooms")]
pub reserved_rooms: Vec<String>, pub reserved_rooms: Vec<Option<String>>,
} }
#[derive(Deserialize, Debug, uniffi::Record, Clone)] #[derive(Deserialize, Debug, uniffi::Record, Clone)]

61
src/report.rs Normal file
View File

@@ -0,0 +1,61 @@
use serde::Serialize;
use crate::SuplError;
#[derive(uniffi::Enum)]
pub enum ReportLocation {
Timetable,
TeacherAbsence,
TakesPlace
}
impl ReportLocation {
fn to_str(&self) -> &'static str {
match self {
ReportLocation::Timetable => "TIMETABLE",
ReportLocation::TeacherAbsence => "ABSENCE",
ReportLocation::TakesPlace => "TAKES_PLACE"
}
}
}
#[derive(Serialize)]
struct ReportRequest {
content: String,
class: String,
location: String,
}
pub fn report_impl(
provider: &str,
content: String,
class: String,
report_location: ReportLocation,
) -> Result<(), SuplError> {
let trimmed = provider.trim_end_matches('/');
let url = format!("{}/report", trimmed);
let body = ReportRequest {
content,
class,
location: report_location.to_str().to_string(),
};
let json = serde_json::to_string(&body)
.map_err(|e| SuplError::ParseError { reason: e.to_string() })?;
let response = minreq::post(url)
.with_header("Content-Type", "application/json")
.with_body(json)
.send()
.map_err(|e| SuplError::NetworkError { reason: e.to_string() })?;
if response.status_code >= 400 {
return Err(SuplError::RuntimeError {
reason: format!("Server returned HTTP {}", response.status_code),
});
}
Ok(())
}

2
uniffi.toml Normal file
View File

@@ -0,0 +1,2 @@
[bindings.kotlin]
package_name = "cz.jzitnik.jecna_supl_client"