From c84646671ee4e4bde00c0f20d232e8c2dc30c75e Mon Sep 17 00:00:00 2001 From: Louis Vallat Date: Wed, 27 Oct 2021 11:44:15 +0200 Subject: [PATCH] Refactored the whole project to have a proper config file system instead of using a .env file Signed-off-by: Louis Vallat --- .env.example | 4 --- Cargo.lock | 21 ++++++++++------ Cargo.toml | 3 ++- src/config.rs | 57 ++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 68 +++++++------------------------------------------- src/session.rs | 2 +- src/utils.rs | 36 ++++++++++++++++++++++++++ 7 files changed, 119 insertions(+), 72 deletions(-) delete mode 100644 .env.example create mode 100644 src/config.rs create mode 100644 src/utils.rs diff --git a/.env.example b/.env.example deleted file mode 100644 index 6593d80..0000000 --- a/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -LYCHEE_ENDPOINT="" -LYCHEE_API_KEY="" -LYCHEE_USERNAME="" -LYCHEE_PASSWORD="" diff --git a/Cargo.lock b/Cargo.lock index 9e52917..6ac2380 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -194,12 +194,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - [[package]] name = "fnv" version = "1.0.7" @@ -455,13 +449,14 @@ dependencies = [ "clap", "cookie", "dirs", - "dotenv", "hyper", "hyper-tls", "json", "mockito", + "serde", "tokio", "tokio-test", + "toml", ] [[package]] @@ -830,6 +825,9 @@ name = "serde" version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_derive" @@ -1117,6 +1115,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + [[package]] name = "tower-service" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 79d12dd..9738979 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,11 +10,12 @@ hyper = { version = "0.14", features = ["full"] } tokio = { version = "1", features = ["full"] } tokio-test = "0.4.2" hyper-tls = "0.5.0" -dotenv = "0.15.0" json = "0.12.4" clap = "2.33.3" dirs = "4.0.0" cookie = "0.15.1" +toml = "0.5.8" +serde = { version = "1", features = ["derive"] } [dev-dependencies] mockito = "0.30.0" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..3087595 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,57 @@ +use std::{fs::{read_to_string, create_dir_all, File}, path::{PathBuf, Path}}; +use serde::{Serialize, Deserialize}; + +use crate::utils::write_to_file; + +#[derive(Deserialize, Serialize)] +pub struct Config { + pub api_key: String, + pub endpoint: String +} + + +pub fn save_config(c: &Config) { + let conf = toml::to_string(c).unwrap(); + write_to_file(conf.as_str(), get_config_file().to_str().unwrap()); +} + +pub fn read_config() -> Config { + let c = read_to_string(get_config_file().to_str().unwrap().to_string()).unwrap(); + let conf: Config = toml::from_str(c.as_str()).expect("Invalid configuration file."); + return conf; +} + +pub fn setup_config_data_storage() { + create_dir_all(get_config_folder()).expect("Cannot create config base folder."); + let s = get_session_file(); + if !Path::new(s.to_str().unwrap()).exists() { + File::create(s).expect("Cannot create session file."); + } + let c = get_config_file(); + if !Path::new(c.to_str().unwrap()).exists() { + let conf = Config { + api_key: "YOUR API KEY HERE".to_string(), + endpoint: "YOUR ENDPOINT HERE".to_string() + }; + save_config(&conf); + panic!("Warning, new configuration file created, consider editing '{}' before running", c.to_str().unwrap()); + } +} + +fn get_config_folder() -> PathBuf { + let mut p = dirs::config_dir().unwrap(); + p.push("Lychee_CLIent"); + return p; +} + +pub fn get_config_file() -> PathBuf { + let mut p = get_config_folder(); + p.push("config.toml"); + return p; +} + +pub fn get_session_file() -> PathBuf { + let mut p = get_config_folder(); + p.push("session"); + return p; +} diff --git a/src/main.rs b/src/main.rs index f1314b1..97e7952 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,14 @@ -use std::{fs::{File, create_dir_all}, io::{Read, Write}, path::{Path, PathBuf}}; - +use crate::{albums::get_albums, config::{get_session_file, read_config, setup_config_data_storage}, session::login, utils::{write_to_file, read_from_file, body_to_str}}; use hyper_tls::HttpsConnector; -use hyper::{Body, Client, body, client::HttpConnector}; +use hyper::{Client, client::HttpConnector}; use clap::{App, Arg, SubCommand, crate_version}; use session::logout; use cookie::Cookie; -use crate::{albums::get_albums, session::login}; -use dotenv::dotenv; -mod session; mod albums; +mod session; +mod utils; +mod config; pub struct LycheeClient { client: Client>, @@ -56,16 +55,15 @@ async fn main() -> Result<(), Box> { ); let matches = app.clone().get_matches(); - dotenv().ok(); + let c = read_config(); let client = LycheeClient { client: Client::builder().build::<_, hyper::Body>(HttpsConnector::new()), - endpoint: std::env::var("LYCHEE_ENDPOINT").unwrap(), - api_key: std::env::var("LYCHEE_API_KEY").unwrap() + endpoint: c.endpoint, + api_key: c.api_key }; - let mut session_path = get_config_folder(); - session_path.push("session"); + let session_path = get_session_file(); let lychee_session = Cookie::parse(read_from_file(session_path.to_str().unwrap())) .expect("Cannot parse cookie from session storage."); let lychee_session_cookie = lychee_session.name().to_string() + "=" + lychee_session.value(); @@ -89,51 +87,3 @@ async fn main() -> Result<(), Box> { Ok(()) } -pub async fn body_to_str(res: Body) -> String { - return String::from_utf8(body::to_bytes(res).await.unwrap().to_vec()).unwrap(); -} - -fn setup_config_data_storage() { - create_dir_all(get_config_folder()).expect("Cannot create folder."); - let mut session = get_config_folder(); - session.push("session"); - if !Path::new(session.to_str().expect("Cannot check path existence.")).exists() { - File::create(session).expect("Cannot create session file."); - } -} - -fn get_config_folder() -> PathBuf { - let mut p = dirs::config_dir().unwrap(); - p.push("Lychee_CLIent"); - return p; -} - -fn write_to_file(d: &str, p: &str) { - let mut o = File::create(p).expect("Cannot create file."); - o.write_all(d.as_bytes()).expect("Cannot write to file."); -} - -fn read_from_file(p: &str) -> String { - if !Path::new(p).exists() { return "".to_string(); } - let mut d = String::new(); - let mut ifile = File::open(p).expect("Cannot open file."); - ifile.read_to_string(&mut d).expect("Cannot read file."); - return d; -} - -#[cfg(test)] -mod tests_main { - use hyper::Body; - use crate::body_to_str; - - #[test] - fn body_to_str_empty() { - assert_eq!("", tokio_test::block_on(body_to_str(Body::empty()))); - } - - #[test] - fn body_to_str_not_empty() { - assert_eq!("demo", tokio_test::block_on(body_to_str(Body::from("demo")))); - assert_eq!("hello world", tokio_test::block_on(body_to_str(Body::from("hello world")))); - } -} diff --git a/src/session.rs b/src/session.rs index 687e60e..95799ac 100644 --- a/src/session.rs +++ b/src/session.rs @@ -32,7 +32,7 @@ pub async fn logout(client: &LycheeClient, lychee_session: &str) { .expect("Cannot request Session::logout."); let res = client.client.request(req).await.unwrap(); let body = body_to_str(res.into_body()).await; - if body != "true" { panic!("Error while logging in, expected true, server returned: {}", body); } + if body != "true" { panic!("Error while logging out, expected true, server returned: {}", body); } } #[cfg(test)] diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..0715f1c --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,36 @@ +use std::{fs::File, io::{Read, Write}, path::Path}; +use hyper::{Body, body}; + +pub async fn body_to_str(res: Body) -> String { + return String::from_utf8(body::to_bytes(res).await.unwrap().to_vec()).unwrap(); +} + +pub fn write_to_file(d: &str, p: &str) { + let mut o = File::create(p).expect("Cannot create file."); + o.write_all(d.as_bytes()).expect("Cannot write to file."); +} + +pub fn read_from_file(p: &str) -> String { + if !Path::new(p).exists() { return "".to_string(); } + let mut d = String::new(); + let mut ifile = File::open(p).expect("Cannot open file."); + ifile.read_to_string(&mut d).expect("Cannot read file."); + return d; +} + +#[cfg(test)] +mod utils_tests { + use hyper::Body; + use crate::utils::body_to_str; + + #[test] + fn body_to_str_empty() { + assert_eq!("", tokio_test::block_on(body_to_str(Body::empty()))); + } + + #[test] + fn body_to_str_not_empty() { + assert_eq!("demo", tokio_test::block_on(body_to_str(Body::from("demo")))); + assert_eq!("hello world", tokio_test::block_on(body_to_str(Body::from("hello world")))); + } +}