Refactored the whole project to have a proper config file system instead of using a .env file
Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
This commit is contained in:
parent
636e77ab05
commit
c84646671e
@ -1,4 +0,0 @@
|
|||||||
LYCHEE_ENDPOINT=""
|
|
||||||
LYCHEE_API_KEY=""
|
|
||||||
LYCHEE_USERNAME=""
|
|
||||||
LYCHEE_PASSWORD=""
|
|
21
Cargo.lock
generated
21
Cargo.lock
generated
@ -194,12 +194,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 = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dotenv"
|
|
||||||
version = "0.15.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@ -455,13 +449,14 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"cookie",
|
"cookie",
|
||||||
"dirs",
|
"dirs",
|
||||||
"dotenv",
|
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-tls",
|
"hyper-tls",
|
||||||
"json",
|
"json",
|
||||||
"mockito",
|
"mockito",
|
||||||
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-test",
|
"tokio-test",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -830,6 +825,9 @@ name = "serde"
|
|||||||
version = "1.0.130"
|
version = "1.0.130"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
@ -1117,6 +1115,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"
|
||||||
|
@ -10,11 +10,12 @@ hyper = { version = "0.14", features = ["full"] }
|
|||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tokio-test = "0.4.2"
|
tokio-test = "0.4.2"
|
||||||
hyper-tls = "0.5.0"
|
hyper-tls = "0.5.0"
|
||||||
dotenv = "0.15.0"
|
|
||||||
json = "0.12.4"
|
json = "0.12.4"
|
||||||
clap = "2.33.3"
|
clap = "2.33.3"
|
||||||
dirs = "4.0.0"
|
dirs = "4.0.0"
|
||||||
cookie = "0.15.1"
|
cookie = "0.15.1"
|
||||||
|
toml = "0.5.8"
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
mockito = "0.30.0"
|
mockito = "0.30.0"
|
||||||
|
57
src/config.rs
Normal file
57
src/config.rs
Normal file
@ -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;
|
||||||
|
}
|
68
src/main.rs
68
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_tls::HttpsConnector;
|
||||||
use hyper::{Body, Client, body, client::HttpConnector};
|
use hyper::{Client, client::HttpConnector};
|
||||||
use clap::{App, Arg, SubCommand, crate_version};
|
use clap::{App, Arg, SubCommand, crate_version};
|
||||||
use session::logout;
|
use session::logout;
|
||||||
use cookie::Cookie;
|
use cookie::Cookie;
|
||||||
use crate::{albums::get_albums, session::login};
|
|
||||||
|
|
||||||
use dotenv::dotenv;
|
|
||||||
mod session;
|
|
||||||
mod albums;
|
mod albums;
|
||||||
|
mod session;
|
||||||
|
mod utils;
|
||||||
|
mod config;
|
||||||
|
|
||||||
pub struct LycheeClient {
|
pub struct LycheeClient {
|
||||||
client: Client<HttpsConnector<HttpConnector>>,
|
client: Client<HttpsConnector<HttpConnector>>,
|
||||||
@ -56,16 +55,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||||||
);
|
);
|
||||||
let matches = app.clone().get_matches();
|
let matches = app.clone().get_matches();
|
||||||
|
|
||||||
dotenv().ok();
|
let c = read_config();
|
||||||
|
|
||||||
let client = LycheeClient {
|
let client = LycheeClient {
|
||||||
client: Client::builder().build::<_, hyper::Body>(HttpsConnector::new()),
|
client: Client::builder().build::<_, hyper::Body>(HttpsConnector::new()),
|
||||||
endpoint: std::env::var("LYCHEE_ENDPOINT").unwrap(),
|
endpoint: c.endpoint,
|
||||||
api_key: std::env::var("LYCHEE_API_KEY").unwrap()
|
api_key: c.api_key
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut session_path = get_config_folder();
|
let session_path = get_session_file();
|
||||||
session_path.push("session");
|
|
||||||
let lychee_session = Cookie::parse(read_from_file(session_path.to_str().unwrap()))
|
let lychee_session = Cookie::parse(read_from_file(session_path.to_str().unwrap()))
|
||||||
.expect("Cannot parse cookie from session storage.");
|
.expect("Cannot parse cookie from session storage.");
|
||||||
let lychee_session_cookie = lychee_session.name().to_string() + "=" + lychee_session.value();
|
let lychee_session_cookie = lychee_session.name().to_string() + "=" + lychee_session.value();
|
||||||
@ -89,51 +87,3 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
|||||||
Ok(())
|
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"))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -32,7 +32,7 @@ pub async fn logout(client: &LycheeClient, lychee_session: &str) {
|
|||||||
.expect("Cannot request Session::logout.");
|
.expect("Cannot request Session::logout.");
|
||||||
let res = client.client.request(req).await.unwrap();
|
let res = client.client.request(req).await.unwrap();
|
||||||
let body = body_to_str(res.into_body()).await;
|
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)]
|
#[cfg(test)]
|
||||||
|
36
src/utils.rs
Normal file
36
src/utils.rs
Normal file
@ -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"))));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user