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"
|
||||
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"
|
||||
|
@ -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"
|
||||
|
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::{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<HttpsConnector<HttpConnector>>,
|
||||
@ -56,16 +55,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||
);
|
||||
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<dyn std::error::Error + Send + Sync>> {
|
||||
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.");
|
||||
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)]
|
||||
|
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