From 926e8e9a6a65d6a2515b9a3e9143f37f34eb3cb3 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Fri, 13 Jan 2023 17:38:12 +0100 Subject: [PATCH] add cli interface --- Cargo.lock | 244 +++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 11 ++- README.md | 21 +++++ src/main.rs | 77 +++++++++++++++- src/marks.rs | 3 + src/utils.rs | 12 +++ 6 files changed, 364 insertions(+), 4 deletions(-) create mode 100644 src/marks.rs create mode 100644 src/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 4ad6a02..c62e353 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,6 +50,43 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa91278560fc226a5d9d736cc21e485ff9aad47d26b8ffe1f54cba868b684b9f" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -112,6 +149,26 @@ dependencies = [ "syn", ] +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dtoa" version = "0.4.8" @@ -142,6 +199,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "1.8.0" @@ -295,6 +373,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.2.6" @@ -418,12 +502,34 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "ipnet" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi", + "io-lifetimes", + "rustix", + "windows-sys", +] + [[package]] name = "itoa" version = "0.4.8" @@ -457,6 +563,12 @@ version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "lock_api" version = "0.4.9" @@ -617,6 +729,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + [[package]] name = "parking_lot" version = "0.12.1" @@ -768,6 +886,30 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -882,6 +1024,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom 0.2.8", + "redox_syscall", + "thiserror", +] + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -937,6 +1090,20 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.36.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "ryu" version = "1.0.12" @@ -1028,6 +1195,20 @@ name = "serde" version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "serde_json" @@ -1134,6 +1315,12 @@ dependencies = [ "quote", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.107" @@ -1170,12 +1357,41 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thin-slice" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1246,6 +1462,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f" +dependencies = [ + "serde", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -1326,9 +1551,13 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" name = "uwm" version = "0.1.0" dependencies = [ + "clap", + "directories", "reqwest", "scraper", + "serde", "tokio", + "toml", ] [[package]] @@ -1337,6 +1566,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "want" version = "0.3.0" @@ -1451,6 +1686,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index a5da1a4..18025a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,18 @@ [package] name = "uwm" version = "0.1.0" +authors = ["Mylloon"] edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +description = "Retrieves grades from the Paris 8 website" +readme = "README.md" +repository = "https://git.kennel.ml/Anri/UWM" +publish = false [dependencies] +directories = "4.0.1" +toml = "0.5.10" +serde = { version = "1.0.152", features = ["derive"] } reqwest = "0.11" tokio = { version = ">=1.23.1", features = ["full"] } scraper = "0.14" +clap = { version = "4.0.32", features = ["derive"] } diff --git a/README.md b/README.md index 1cbf996..a0ac6e2 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,27 @@ Récupère les notes depuis le site de Paris 8 [![dependency status](https://deps.rs/repo/gitea/git.kennel.ml/Anri/uportalWrapperMarks/status.svg)](https://deps.rs/repo/gitea/git.kennel.ml/Anri/uportalWrapperMarks) +## Usage + +### En ligne de commande + +``` +$ uwm prenom.nom +``` + +### Avec un fichier de configuration `config.toml` + +```toml +username = "prenom.nom" +password = "password" # Facultatif +``` + +_Attention : le mot de passe est stocké en clair_ + +- Linux : `~/.config/uwm/config.toml` +- Windows : `%APPDATA%\anri\uwm/config.toml` +- MacOS : `~/Library/Application Support/com.anri.uwm/config.toml` + --- Anciennement [uPortalWrapperMarks](https://git.kennel.ml/Anri/uportalWrapperMarks/src/branch/python). diff --git a/src/main.rs b/src/main.rs index e7a11a9..a467351 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,76 @@ -fn main() { - println!("Hello, world!"); +use clap::Parser; +use directories::ProjectDirs; +use serde::Deserialize; + +mod marks; +mod utils; + +#[derive(Deserialize)] +struct Config { + username: String, + password: Option, +} + +#[derive(Parser)] +#[clap(version, about, long_about = None)] +struct Args { + /// Your username, before the @ of the email address + #[clap(value_parser)] + username: Option, +} + +#[tokio::main] +async fn main() { + let args = Args::parse(); + + if let Some(proj_dirs) = ProjectDirs::from("com", "anri", "uwm") { + let config_dir = proj_dirs.config_dir(); + + let file_path = config_dir.join("config.toml"); + + let config_file = std::fs::read_to_string(&file_path); + + let mut config = match config_file { + Ok(file) => match toml::from_str(&file) { + Ok(stored_config) => stored_config, + Err(file_error) => { + // Error in config file + if args.username.is_none() + && file_error.to_string().contains("missing field `username`") + { + // Show error message if needed + println!("Error in config file: {}", file_error); + } + Config { + username: if args.username.is_some() { + args.username.unwrap() + } else { + utils::ask("Username: ") + }, + password: Some(utils::ask("Password: ")), + } + } + }, + Err(_) => Config { + // No config file, ask for creds + username: if args.username.is_some() { + args.username.unwrap() + } else { + // Only ask if nothing has been given in args + utils::ask("Username: ") + }, + password: Some(utils::ask("Password: ")), + }, + }; + + if config.password.is_none() { + config.password = Some(utils::ask("Password: ")); + } + + let user_agent = format!("uwm/{}", env!("CARGO_PKG_VERSION")); + + let marks = marks::get_marks(config.username, config.password.unwrap(), &user_agent).await; + + println!("{:#?}", marks); + } } diff --git a/src/marks.rs b/src/marks.rs new file mode 100644 index 0000000..384da9c --- /dev/null +++ b/src/marks.rs @@ -0,0 +1,3 @@ +pub async fn get_marks(username: String, password: String, user_agent: &str) -> String { + format!("{}/{}/{}", username, password, user_agent) +} diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..d73d5db --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,12 @@ +use std::io::{self, Write}; + +pub fn ask(text: &str) -> std::string::String { + let mut user_input = String::new(); + let stdin = io::stdin(); + + print!("{}", text); + io::stdout().flush().unwrap(); + stdin.read_line(&mut user_input).unwrap(); + + user_input.trim_end().to_string() +}