diff --git a/.env.example b/.env.example index f4395b4..32e16f6 100644 --- a/.env.example +++ b/.env.example @@ -4,7 +4,7 @@ POSTGRES_PASSWORD="bvplan" RABBITMQ_USER="bvplan" RABBITMQ_PASSWORD="bvplan" -BACKEND_UNTIS_API_URL="https://mese.webuntis.com/WebUntis/api/" +BACKEND_UNTIS_API_URL="https://mese.webuntis.com/WebUntis/" BACKEND_UNTIS_RPC_URL="https://mese.webuntis.com/WebUntis/jsonrpc.do" BACKEND_UNTIS_CLIENT_NAME="bvplan" BACKEND_UNTIS_SCHOOL= diff --git a/README.md b/README.md new file mode 100644 index 0000000..d79a070 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# bvplan + +Bessrer Vertretungsplan + +Nutzt die semi-öffentliche undokumentierte Untis-JsonRpc-API, als auch die genauso nicht dokumentierte WebUntis-API. diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 47e0660..8961c8f 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -83,16 +83,16 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.2.2" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724" +checksum = "0070905b2c4a98d184c4e81025253cb192aa8a73827553f38e9410801ceb35bb" dependencies = [ "actix-codec", "actix-rt", "actix-service", "actix-utils", "ahash", - "base64 0.13.1", + "base64 0.21.0", "bitflags", "brotli", "bytes", @@ -114,6 +114,8 @@ dependencies = [ "rand 0.8.5", "sha1 0.10.5", "smallvec", + "tokio", + "tokio-util 0.7.4", "tracing", "zstd", ] @@ -143,9 +145,9 @@ dependencies = [ [[package]] name = "actix-rt" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000" +checksum = "15265b6b8e2347670eb363c47fc8c75208b4a4994b27192f345fcbe707804f3e" dependencies = [ "futures-core", "tokio", @@ -153,9 +155,9 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824" +checksum = "3e8613a75dd50cc45f473cee3c34d59ed677c0f7b44480ce3b8247d7dc519327" dependencies = [ "actix-rt", "actix-service", @@ -192,9 +194,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.2.1" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9" +checksum = "464e0fddc668ede5f26ec1f9557a8d44eda948732f40c6b0ad79126930eb775f" dependencies = [ "actix-codec", "actix-http", @@ -233,9 +235,9 @@ dependencies = [ [[package]] name = "actix-web-actors" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31efe7896f3933ce03dd4710be560254272334bb321a18fd8ff62b1a557d9d19" +checksum = "bf6e9ccc371cfddbed7aa842256a4abc7a6dcac9f3fce392fe1d0f68cfd136b2" dependencies = [ "actix 0.13.0", "actix-codec", @@ -246,6 +248,7 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util 0.7.4", ] [[package]] @@ -500,9 +503,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" [[package]] name = "async-trait" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705339e0e4a9690e2908d2b3d049d85682cf19fbd5782494498fbf7003a6a282" +checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1" dependencies = [ "proc-macro2", "quote", @@ -511,9 +514,9 @@ dependencies = [ [[package]] name = "atomic-waker" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" +checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" [[package]] name = "atty" @@ -549,6 +552,7 @@ dependencies = [ "lazy_static", "log", "r2d2_redis", + "regex", "reqwest", "scraper", "serde", @@ -637,9 +641,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.3.2" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -674,9 +678,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byteorder" @@ -837,9 +841,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" dependencies = [ "crossbeam-utils", ] @@ -959,9 +963,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" +checksum = "322296e2f2e5af4270b54df9e85a02ff037e271af20ba3e7fe1575515dc840b8" dependencies = [ "cc", "cxxbridge-flags", @@ -971,9 +975,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" +checksum = "017a1385b05d631e7875b1f151c9f012d37b53491e2a87f65bff5c262b2111d8" dependencies = [ "cc", "codespan-reporting", @@ -986,15 +990,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" +checksum = "c26bbb078acf09bc1ecda02d4223f03bdd28bd4874edcb0379138efc499ce971" [[package]] name = "cxxbridge-macro" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" +checksum = "357f40d1f06a24b60ae1fe122542c1fb05d28d32acb2aed064e84bc2ad1e252e" dependencies = [ "proc-macro2", "quote", @@ -1036,9 +1040,9 @@ dependencies = [ [[package]] name = "diesel" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68c186a7418a2aac330bb76cde82f16c36b03a66fb91db32d20214311f9f6545" +checksum = "4391a22b19c916e50bec4d6140f29bdda3e3bb187223fe6e3ea0b6e4d1021c04" dependencies = [ "bitflags", "byteorder", @@ -1101,9 +1105,9 @@ checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "encoding_rs" @@ -1406,9 +1410,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" [[package]] name = "globset" @@ -1866,9 +1870,9 @@ checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "matches" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" @@ -1941,9 +1945,9 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "nom" -version = "7.1.2" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5507769c4919c998e69e49c839d9dc6e693ede4cc4290d6ad8b41d4f09c548c" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", @@ -1980,9 +1984,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.2" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c786513eb403643f2a88c244c2aaa270ef2153f55094587d0c48a3cf22a83" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] @@ -2330,9 +2334,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] @@ -2542,11 +2546,11 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.13" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" dependencies = [ - "base64 0.13.1", + "base64 0.21.0", "bytes", "encoding_rs", "futures-core", @@ -2716,9 +2720,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "7c4437699b6d34972de58652c68b98cb5b53a4199ab126db8e20ec8ded29a721" dependencies = [ "bitflags", "core-foundation", @@ -2729,9 +2733,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -3007,9 +3011,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -3116,9 +3120,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.24.1" +version = "1.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" +checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" dependencies = [ "autocfg", "bytes", @@ -3260,9 +3264,9 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" @@ -3592,18 +3596,18 @@ checksum = "aed2e7a52e3744ab4d0c05c20aa065258e84c49fd4226f5191b2ed29712710b4" [[package]] name = "zstd" -version = "0.11.2+zstd.1.5.2" +version = "0.12.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +checksum = "e9262a83dc741c0b0ffec209881b45dbc232c21b02a2b9cb1adb93266e41303d" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "5.0.2+zstd.1.5.2" +version = "6.0.2+zstd.1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +checksum = "a6cf39f730b440bab43da8fb5faf5f254574462f73f260f85f7987f32154ff17" dependencies = [ "libc", "zstd-sys", diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 71a87ed..6e65875 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -29,6 +29,7 @@ juniper_actix = "0.4.0" lazy_static = "1.4.0" log = "0.4.17" r2d2_redis = "0.14.0" +regex = "1.7.1" reqwest = "0.11.13" scraper = "0.14.0" serde = "1.0.148" diff --git a/backend/Dockerfile b/backend/Dockerfile index ee07834..b775a3d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -12,9 +12,9 @@ RUN cargo chef prepare --recipe-path recipe.json FROM chef as builder WORKDIR /usr/src/backend COPY --from=planner /usr/src/backend/recipe.json . -RUN cargo chef cook --release --recipe-path recipe.json +RUN cargo chef cook --recipe-path recipe.json COPY ./src ./src -RUN cargo build --release +RUN cargo build FROM docker.io/debian:bullseye-slim as runner RUN apt update @@ -29,6 +29,6 @@ WORKDIR /usr/src/backend COPY ./run.sh . RUN chmod +x ./run.sh COPY ./migrations ./migrations -COPY --from=builder /usr/src/backend/target/release/api /usr/src/backend/target/release/worker ./bin/ +COPY --from=builder /usr/src/backend/target/debug/api /usr/src/backend/target/debug/worker ./bin/ EXPOSE 80 ENTRYPOINT [ "./run.sh" ] diff --git a/backend/src/worker/update_info.rs b/backend/src/worker/update_info.rs index 508a1e1..ef4378a 100644 --- a/backend/src/worker/update_info.rs +++ b/backend/src/worker/update_info.rs @@ -1,10 +1,11 @@ -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result}; use celery::error::TaskError; use celery::task::TaskResult; use chrono::prelude::*; use diesel::prelude::*; use lazy_static::lazy_static; use r2d2_redis::redis; +use regex::Regex; use std::ops::DerefMut; use std::thread; use std::time::Duration; @@ -269,16 +270,19 @@ async fn fetch_holidays( Ok(()) } -lazy_static! { - static ref TITLE_SELECTOR: scraper::Selector = scraper::Selector::parse(".mon_title").unwrap(); -} - async fn fetch_substitutions( client: &untis::Client, db_conn: &mut PgConnection, redis_conn: &mut cache::ConnectionPool, schoolyear_id: i32, ) -> Result<()> { + lazy_static! { + static ref TITLE_SELECTOR: scraper::Selector = + scraper::Selector::parse(".mon_title").unwrap(); + static ref DATE_REGEX: Regex = Regex::new(r"([^\s]+)").unwrap(); + static ref WEEK_TYPE_REGEX: Regex = Regex::new(r"\bWoche\s+\K\S+").unwrap(); + } + let (date, week_type) = { let html = reqwest::Client::new() .get(&config::CONFIG.untis_vplan_url) @@ -302,30 +306,36 @@ async fn fetch_substitutions( .context("No element in vplan html which is selectable class \"mon_title\"")? .text() .next() - .context("\"mon_title\" element is empty")? - .split_once(',') - .context("Could not split \"mon_title\" string")?; + .context("\"mon_title\" element is empty")?; + dbg!(title); + dbg!(DATE_REGEX.captures(title)); + dbg!(WEEK_TYPE_REGEX.captures(title)); ( - chrono::NaiveDate::parse_from_str( - title - .0 - .split_whitespace() - .next() - .context("Could not find date")?, - "%d.%m.%Y", - )?, - match title - .1 - .split_whitespace() - .last() - .context("Could not find week type indicator")? - { - "A" => db::models::WeekType::A, - "B" => db::models::WeekType::B, - x => bail!("Invalid week type: {:?}", x), - }, + chrono::NaiveDate::parse_from_str("18.1.2023", "%d.%m.%Y")?, + db::models::WeekType::A, ) + + // ( + // chrono::NaiveDate::parse_from_str( + // title + // .0 + // .split_whitespace() + // .next() + // .context("Could not find date")?, + // "%d.%m.%Y", + // )?, + // match title + // .1 + // .split_whitespace() + // .last() + // .context("Could not find week type indicator")? + // { + // "A" => db::models::WeekType::A, + // "B" => db::models::WeekType::B, + // x => bail!("Invalid week type: {:?}", x), + // }, + // ) }; let substitution_query_id = diesel::insert_into(db::schema::substitution_queries::table)