Add an option to rename course names with a .toml file

This commit is contained in:
lukasprobst 2021-09-30 16:58:42 +02:00
parent 1e3a241baf
commit 2483ee1906
5 changed files with 82 additions and 91 deletions

133
Cargo.lock generated
View File

@ -30,6 +30,7 @@ dependencies = [
"structopt", "structopt",
"tokio", "tokio",
"tokio-util", "tokio-util",
"toml",
"url", "url",
] ]
@ -338,9 +339,9 @@ checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.1.5" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -412,14 +413,13 @@ dependencies = [
[[package]] [[package]]
name = "derive_more" name = "derive_more"
version = "0.99.16" version = "0.99.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" checksum = "5cc7b9cef1e351660e5443924e4f43ab25fbbed3e9a5f052df3677deb4d6b320"
dependencies = [ dependencies = [
"convert_case", "convert_case",
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustc_version 0.3.3",
"syn", "syn",
] ]
@ -653,9 +653,9 @@ dependencies = [
[[package]] [[package]]
name = "globset" name = "globset"
version = "0.4.8" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" checksum = "f0fc1b9fa0e64ffb1aa5b95daa0f0f167734fd528b7c02eabc581d9d843649b1"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"bstr", "bstr",
@ -683,6 +683,12 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.11.2" version = "0.11.2"
@ -700,9 +706,9 @@ dependencies = [
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.19" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -777,9 +783,9 @@ checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.10" version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7728a72c4c7d72665fde02204bcbd93b247721025b222ef78606f14513e0fd03" checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-channel", "futures-channel",
@ -845,12 +851,12 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.7.0" version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"hashbrown", "hashbrown 0.9.1",
] ]
[[package]] [[package]]
@ -906,9 +912,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.98" version = "0.2.97"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
[[package]] [[package]]
name = "log" name = "log"
@ -1120,15 +1126,6 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
[[package]]
name = "pest"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
dependencies = [
"ucd-trie",
]
[[package]] [[package]]
name = "phf" name = "phf"
version = "0.8.0" version = "0.8.0"
@ -1185,9 +1182,9 @@ dependencies = [
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.7" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905"
[[package]] [[package]]
name = "pin-utils" name = "pin-utils"
@ -1275,7 +1272,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3ac055aef7cc7a1caefbc65144be879e862467dcd9b8a8d57b64a13e7dce15d" checksum = "c3ac055aef7cc7a1caefbc65144be879e862467dcd9b8a8d57b64a13e7dce15d"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"hashbrown", "hashbrown 0.11.2",
"idna", "idna",
"psl-types", "psl-types",
] ]
@ -1359,9 +1356,9 @@ checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.11.4" version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124"
dependencies = [ dependencies = [
"async-compression", "async-compression",
"base64", "base64",
@ -1449,16 +1446,7 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [ dependencies = [
"semver 0.9.0", "semver",
]
[[package]]
name = "rustc_version"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
dependencies = [
"semver 0.11.0",
] ]
[[package]] [[package]]
@ -1580,16 +1568,7 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [ dependencies = [
"semver-parser 0.7.0", "semver-parser",
]
[[package]]
name = "semver"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
dependencies = [
"semver-parser 0.10.2",
] ]
[[package]] [[package]]
@ -1598,15 +1577,6 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "semver-parser"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
dependencies = [
"pest",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.126" version = "1.0.126"
@ -1735,7 +1705,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
dependencies = [ dependencies = [
"discard", "discard",
"rustc_version 0.2.3", "rustc_version",
"stdweb-derive", "stdweb-derive",
"stdweb-internal-macros", "stdweb-internal-macros",
"stdweb-internal-runtime", "stdweb-internal-runtime",
@ -1810,9 +1780,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]] [[package]]
name = "structopt" name = "structopt"
version = "0.3.22" version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69b041cdcb67226aca307e6e7be44c8806423d83e018bd662360a93dabce4d71" checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c"
dependencies = [ dependencies = [
"clap", "clap",
"lazy_static", "lazy_static",
@ -1821,9 +1791,9 @@ dependencies = [
[[package]] [[package]]
name = "structopt-derive" name = "structopt-derive"
version = "0.4.15" version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10" checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error", "proc-macro-error",
@ -1887,18 +1857,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.26" version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "1.0.26" version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -1969,9 +1939,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.8.1" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98c8b05dc14c75ea83d63dd391100353789f5f24b8b3866542a5e85c8be8e985" checksum = "c79ba603c337335df6ba6dd6afc38c38a7d5e1b0c871678439ea973cd62a118e"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"bytes", "bytes",
@ -1986,9 +1956,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "1.3.0" version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -2032,6 +2002,15 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "toml"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
"serde",
]
[[package]] [[package]]
name = "tower-service" name = "tower-service"
version = "0.3.1" version = "0.3.1"
@ -2070,12 +2049,6 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]]
name = "ucd-trie"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]] [[package]]
name = "unicode-bidi" name = "unicode-bidi"
version = "0.3.5" version = "0.3.5"
@ -2096,9 +2069,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.8.0" version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"

View File

@ -33,6 +33,7 @@ h2 = "0.3.3"
cookie_store = "0.14.0" cookie_store = "0.14.0"
reqwest_cookie_store = "0.1.5" reqwest_cookie_store = "0.1.5"
bytes = "1.0.1" bytes = "1.0.1"
toml = "0.5.8"
[features] [features]
default = [] default = []

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
use std::{error::Error as _, io::Write, sync::Arc}; use std::{collections::HashMap, error::Error as _, io::Write, sync::Arc};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use cookie_store::CookieStore; use cookie_store::CookieStore;
@ -35,6 +35,7 @@ pub struct ILIAS {
pub ignore: Gitignore, pub ignore: Gitignore,
client: Client, client: Client,
cookies: Arc<CookieStoreMutex>, cookies: Arc<CookieStoreMutex>,
pub course_names: HashMap<String, String>,
} }
/// Returns true if the error is caused by: /// Returns true if the error is caused by:
@ -54,7 +55,7 @@ fn error_is_http2(error: &reqwest::Error) -> bool {
impl ILIAS { impl ILIAS {
// TODO: de-duplicate the logic below // TODO: de-duplicate the logic below
pub async fn with_session(opt: Opt, session: Arc<CookieStoreMutex>, ignore: Gitignore) -> Result<Self> { pub async fn with_session(opt: Opt, session: Arc<CookieStoreMutex>, ignore: Gitignore, course_names: HashMap<String, String>) -> Result<Self> {
let mut builder = Client::builder() let mut builder = Client::builder()
.cookie_provider(Arc::clone(&session)) .cookie_provider(Arc::clone(&session))
.user_agent(concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"))); .user_agent(concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION")));
@ -71,10 +72,11 @@ impl ILIAS {
ignore, ignore,
client, client,
cookies: session, cookies: session,
course_names,
}) })
} }
pub async fn login(opt: Opt, user: &str, pass: &str, ignore: Gitignore) -> Result<Self> { pub async fn login(opt: Opt, user: &str, pass: &str, ignore: Gitignore, course_names: HashMap<String, String>) -> Result<Self> {
let cookie_store = CookieStore::default(); let cookie_store = CookieStore::default();
let cookie_store = reqwest_cookie_store::CookieStoreMutex::new(cookie_store); let cookie_store = reqwest_cookie_store::CookieStoreMutex::new(cookie_store);
let cookie_store = std::sync::Arc::new(cookie_store); let cookie_store = std::sync::Arc::new(cookie_store);
@ -93,6 +95,7 @@ impl ILIAS {
ignore, ignore,
client, client,
cookies: cookie_store, cookies: cookie_store,
course_names,
}; };
info!("Logging into ILIAS using KIT account.."); info!("Logging into ILIAS using KIT account..");
let session_establishment = this let session_establishment = this

View File

@ -20,7 +20,7 @@ pub async fn download(path: &Path, ilias: Arc<ILIAS>, url: &URL) -> Result<()> {
} }
for item in content.0 { for item in content.0 {
let item = item?; let item = item?;
let path = path.join(file_escape(item.name())); let path = path.join(file_escape(ilias.course_names.get(item.name()).map(|x| &**x).unwrap_or(item.name())));
let ilias = Arc::clone(&ilias); let ilias = Arc::clone(&ilias);
spawn(process_gracefully(ilias, path, item)); spawn(process_gracefully(ilias, path, item));
} }

View File

@ -8,6 +8,7 @@ use indicatif::{ProgressDrawTarget, ProgressStyle};
use structopt::StructOpt; use structopt::StructOpt;
use tokio::fs; use tokio::fs;
use std::collections::HashMap;
use std::future::Future; use std::future::Future;
use std::io::BufReader; use std::io::BufReader;
use std::path::PathBuf; use std::path::PathBuf;
@ -38,7 +39,7 @@ async fn main() {
} }
} }
async fn try_to_load_session(opt: Opt, ignore: Gitignore) -> Result<ILIAS> { async fn try_to_load_session(opt: Opt, ignore: Gitignore, course_names: HashMap<String, String>) -> Result<ILIAS> {
let session_path = opt.output.join(".iliassession"); let session_path = opt.output.join(".iliassession");
let meta = tokio::fs::metadata(&session_path).await?; let meta = tokio::fs::metadata(&session_path).await?;
let modified = meta.modified()?; let modified = meta.modified()?;
@ -52,16 +53,16 @@ async fn try_to_load_session(opt: Opt, ignore: Gitignore) -> Result<ILIAS> {
.context("failed to load session cookies")?; .context("failed to load session cookies")?;
let cookie_store = reqwest_cookie_store::CookieStoreMutex::new(cookies); let cookie_store = reqwest_cookie_store::CookieStoreMutex::new(cookies);
let cookie_store = std::sync::Arc::new(cookie_store); let cookie_store = std::sync::Arc::new(cookie_store);
Ok(ILIAS::with_session(opt, cookie_store, ignore).await?) Ok(ILIAS::with_session(opt, cookie_store, ignore, course_names).await?)
} else { } else {
Err(anyhow!("session data too old")) Err(anyhow!("session data too old"))
} }
} }
async fn login(opt: Opt, ignore: Gitignore) -> Result<ILIAS> { async fn login(opt: Opt, ignore: Gitignore, course_names: HashMap<String, String>) -> Result<ILIAS> {
// load .iliassession file // load .iliassession file
if opt.keep_session { if opt.keep_session {
match try_to_load_session(opt.clone(), ignore.clone()) match try_to_load_session(opt.clone(), ignore.clone(), course_names.clone())
.await .await
.context("failed to load previous session") .context("failed to load previous session")
{ {
@ -79,7 +80,7 @@ async fn login(opt: Opt, ignore: Gitignore) -> Result<ILIAS> {
} }
} }
// loac .iliaslogin file // load .iliaslogin file
let iliaslogin = opt.output.join(".iliaslogin"); let iliaslogin = opt.output.join(".iliaslogin");
let login = std::fs::read_to_string(&iliaslogin); let login = std::fs::read_to_string(&iliaslogin);
let (user, pass) = if let Ok(login) = login { let (user, pass) = if let Ok(login) = login {
@ -93,7 +94,7 @@ async fn login(opt: Opt, ignore: Gitignore) -> Result<ILIAS> {
ask_user_pass(&opt).context("credentials input failed")? ask_user_pass(&opt).context("credentials input failed")?
}; };
let ilias = match ILIAS::login(opt, &user, &pass, ignore).await { let ilias = match ILIAS::login(opt, &user, &pass, ignore, course_names).await {
Ok(ilias) => ilias, Ok(ilias) => ilias,
Err(e) => { Err(e) => {
error!(e); error!(e);
@ -118,13 +119,26 @@ async fn real_main(mut opt: Opt) -> Result<()> {
// load .iliasignore file // load .iliasignore file
let (ignore, error) = Gitignore::new(opt.output.join(".iliasignore")); let (ignore, error) = Gitignore::new(opt.output.join(".iliasignore"));
// Load course_names.toml file
let course_names_path = opt.output.join("course_names.toml");
let course_names: HashMap<String, String>;
if fs::metadata(&course_names_path).await.is_ok() {
fs::read_to_string(&course_names_path).await.context("reading course_names.toml")?;
course_names = toml::from_str(&fs::read_to_string(course_names_path).await?).unwrap();
} else {
// If file doesn't exist, initialise course_names with empty HashMap
course_names = HashMap::new();
}
if let Some(err) = error { if let Some(err) = error {
warning!(err); warning!(err);
} }
queue::set_download_rate(opt.rate); queue::set_download_rate(opt.rate);
let ilias = login(opt, ignore).await?; let ilias = login(opt, ignore, course_names).await?;
if ilias.opt.content_tree { if ilias.opt.content_tree {
if let Err(e) = ilias if let Err(e) = ilias