Caching the ServerInformation for CLI
This commit is contained in:
parent
4003dfe246
commit
a1d3c64765
|
@ -15,7 +15,7 @@ async fn main() {
|
||||||
let args = Cli::from_args();
|
let args = Cli::from_args();
|
||||||
let config = load_config();
|
let config = load_config();
|
||||||
|
|
||||||
let sv = init_client(&config).await;
|
let (sv, mut cached) = init_all(&config).await;
|
||||||
|
|
||||||
if let Some(cmd) = args.commands {
|
if let Some(cmd) = args.commands {
|
||||||
match cmd {
|
match cmd {
|
||||||
|
@ -234,8 +234,10 @@ async fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sv.save_session(&config.sessions_file)
|
// todo: maybe save these again ONLY if modified
|
||||||
// .expect("Couldn't save the session");
|
cached
|
||||||
|
.save(&config.cached_stuff_path)
|
||||||
|
.expect("Couldn't save cached stuff");
|
||||||
std::fs::write(&config.session_file, sv.session.serialize()).unwrap();
|
std::fs::write(&config.session_file, sv.session.serialize()).unwrap();
|
||||||
save_config(&config).expect("Couldn't save the config");
|
save_config(&config).expect("Couldn't save the config");
|
||||||
}
|
}
|
||||||
|
|
105
cli/src/utils.rs
105
cli/src/utils.rs
|
@ -1,15 +1,18 @@
|
||||||
use rpassword::read_password;
|
use rpassword::read_password;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::io::{stdin, stdout, Write};
|
use std::io::{stdin, stdout, Write};
|
||||||
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
use crate::error::MyFriendlyError;
|
use crate::error::MyFriendlyError;
|
||||||
use socialvoid::session::SessionHolder;
|
use socialvoid::session::SessionHolder;
|
||||||
|
use socialvoid_types::ServerInformation;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub session_file: String,
|
pub session_file: String,
|
||||||
pub base_path: String,
|
pub base_path: String,
|
||||||
pub config_path: String,
|
pub config_path: String,
|
||||||
|
pub cached_stuff_path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_config() -> Config {
|
pub fn load_config() -> Config {
|
||||||
|
@ -33,6 +36,7 @@ pub fn load_config() -> Config {
|
||||||
},
|
},
|
||||||
Err(_err) => Config {
|
Err(_err) => Config {
|
||||||
session_file: format!("{}/session", base_path),
|
session_file: format!("{}/session", base_path),
|
||||||
|
cached_stuff_path: format!("{}/cached_stuff", base_path),
|
||||||
base_path,
|
base_path,
|
||||||
config_path,
|
config_path,
|
||||||
},
|
},
|
||||||
|
@ -65,14 +69,54 @@ pub fn prompt_password(prompt: &str) -> String {
|
||||||
read_password().expect("Couldn't read the password")
|
read_password().expect("Couldn't read the password")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn init_client(config: &Config) -> socialvoid::Client {
|
pub async fn init_all(config: &Config) -> (socialvoid::Client, CachedStuff) {
|
||||||
match std::fs::read(&config.session_file) {
|
//TODO: only send errors from here and let the main.rs handle situations for panics
|
||||||
Ok(bytes) => match socialvoid::new(SessionHolder::deserialize(bytes)).await {
|
|
||||||
Ok(client) => client,
|
//load cached stuff
|
||||||
Err(_) => panic!(
|
let mut cached: CachedStuff = match std::fs::read_to_string(&config.cached_stuff_path) {
|
||||||
|
Ok(cached_stuff_str) => {
|
||||||
|
serde_json::from_str(&cached_stuff_str).unwrap_or_else(|_| CachedStuff::default())
|
||||||
|
}
|
||||||
|
Err(_err) => CachedStuff::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Ok(cache_last_updated) = SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH + Duration::from_secs(cached.last_updated_on))
|
||||||
|
{
|
||||||
|
if cache_last_updated.as_secs() > cached.update_after {
|
||||||
|
cached.update().await;
|
||||||
|
match cached.save(&config.cached_stuff_path) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => println!("Error while saving cache.\n{}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cached.update().await;
|
||||||
|
match cached.save(&config.cached_stuff_path) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => println!("Error while saving cache.\n{}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//load sessions
|
||||||
|
let client = match std::fs::read(&config.session_file) {
|
||||||
|
Ok(bytes) => {
|
||||||
|
match socialvoid::new(
|
||||||
|
SessionHolder::deserialize(bytes),
|
||||||
|
cached.rpc_url.clone(),
|
||||||
|
cached
|
||||||
|
.server_info
|
||||||
|
.as_ref()
|
||||||
|
.map(|server_info| server_info.cdn_server.clone()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(client) => client,
|
||||||
|
Err(_) => panic!(
|
||||||
"The session file may be corrupt. try deleting it to have a new session created."
|
"The session file may be corrupt. try deleting it to have a new session created."
|
||||||
),
|
),
|
||||||
},
|
}
|
||||||
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
println!(
|
println!(
|
||||||
"There was a problem while reading the session file.\n{}",
|
"There was a problem while reading the session file.\n{}",
|
||||||
|
@ -89,5 +133,52 @@ pub async fn init_client(config: &Config) -> socialvoid::Client {
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(client, cached)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct CachedStuff {
|
||||||
|
/// unix timestamp when cache updated last time
|
||||||
|
last_updated_on: u64,
|
||||||
|
/// update cache if `update_after` seconds have passed after updating
|
||||||
|
/// it the last time (since `last_updated_on`).
|
||||||
|
update_after: u64,
|
||||||
|
|
||||||
|
pub rpc_url: Option<String>, //only updated by the user
|
||||||
|
|
||||||
|
pub server_info: Option<ServerInformation>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CachedStuff {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
last_updated_on: 0,
|
||||||
|
update_after: 86400, // 1 day
|
||||||
|
rpc_url: Some("http://socialvoid.qlg1.com:5601/".to_string()),
|
||||||
|
server_info: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CachedStuff {
|
||||||
|
async fn update(&mut self) {
|
||||||
|
let sv = socialvoid::new_with_host(self.rpc_url.clone());
|
||||||
|
if let Ok(server_info) = sv.help.get_server_information().await {
|
||||||
|
self.server_info = Some(server_info);
|
||||||
|
|
||||||
|
self.last_updated_on = SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs();
|
||||||
|
} else {
|
||||||
|
println!("There was a problem while updating the cache.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(&self, path: &str) -> Result<(), std::io::Error> {
|
||||||
|
std::fs::write(path, serde_json::to_string(&self).unwrap())?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,12 +63,49 @@ async fn make_cdn_client_from(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a client with user defined session
|
/// Creates a new client with the given rpc url, default cdn url and no sessions
|
||||||
|
pub fn new_with_host(rpc_url: Option<String>) -> Client {
|
||||||
|
let rpc_client = if let Some(rpc_url) = rpc_url {
|
||||||
|
Arc::new(socialvoid_rawclient::with_host(&rpc_url))
|
||||||
|
} else {
|
||||||
|
Arc::new(socialvoid_rawclient::new())
|
||||||
|
};
|
||||||
|
let cdn_client = Arc::new(socialvoid_rawclient::CdnClient::new());
|
||||||
|
let client_info = Arc::new(ClientInfo::generate());
|
||||||
|
let session_holder = Arc::new(Mutex::new(SessionHolder::new(Arc::clone(&client_info))));
|
||||||
|
let (session, network, account, timeline, help) = init_methods(
|
||||||
|
Arc::clone(&rpc_client),
|
||||||
|
Arc::clone(&cdn_client),
|
||||||
|
Arc::clone(&session_holder),
|
||||||
|
);
|
||||||
|
Client {
|
||||||
|
session,
|
||||||
|
cdn_client,
|
||||||
|
help,
|
||||||
|
timeline,
|
||||||
|
network,
|
||||||
|
account,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a client with user defined session, (optional)rpc server url and (optional)cdn server url
|
||||||
/// And CDN as given in the server information
|
/// And CDN as given in the server information
|
||||||
/// TODO: maybe verify the session and return an error if session is invalid
|
/// TODO: maybe verify the session and return an error if session is invalid
|
||||||
pub async fn new(session: SessionHolder) -> Result<Client, SocialvoidError> {
|
pub async fn new(
|
||||||
let rpc_client = Arc::new(socialvoid_rawclient::new());
|
session: SessionHolder,
|
||||||
let cdn_client = Arc::new(make_cdn_client_from(Arc::clone(&rpc_client)).await?);
|
rpc_url: Option<String>,
|
||||||
|
cdn_url: Option<String>,
|
||||||
|
) -> Result<Client, SocialvoidError> {
|
||||||
|
let rpc_client = if let Some(rpc_url) = rpc_url {
|
||||||
|
Arc::new(socialvoid_rawclient::with_host(&rpc_url))
|
||||||
|
} else {
|
||||||
|
Arc::new(socialvoid_rawclient::new())
|
||||||
|
};
|
||||||
|
let cdn_client = if let Some(cdn_url) = cdn_url {
|
||||||
|
Arc::new(socialvoid_rawclient::CdnClient::with_cdn_url(cdn_url))
|
||||||
|
} else {
|
||||||
|
Arc::new(make_cdn_client_from(Arc::clone(&rpc_client)).await?)
|
||||||
|
};
|
||||||
let session_holder = Arc::new(Mutex::new(session));
|
let session_holder = Arc::new(Mutex::new(session));
|
||||||
let (session, network, account, timeline, help) = init_methods(
|
let (session, network, account, timeline, help) = init_methods(
|
||||||
Arc::clone(&rpc_client),
|
Arc::clone(&rpc_client),
|
||||||
|
|
|
@ -37,10 +37,10 @@ impl Client {
|
||||||
) -> Result<T, RpcError> {
|
) -> Result<T, RpcError> {
|
||||||
let request = RawRequest::new(Some(generate_id()), method.to_string(), Some(params));
|
let request = RawRequest::new(Some(generate_id()), method.to_string(), Some(params));
|
||||||
|
|
||||||
// dbg!(
|
println!(
|
||||||
// "Request: {}",
|
"Request: {}",
|
||||||
// serde_json::to_string_pretty(&request).unwrap()
|
serde_json::to_string_pretty(&request).unwrap()
|
||||||
// );
|
);
|
||||||
|
|
||||||
//TODO: maybe check the response better as well??
|
//TODO: maybe check the response better as well??
|
||||||
let resp: serde_json::Value = self
|
let resp: serde_json::Value = self
|
||||||
|
@ -52,7 +52,11 @@ impl Client {
|
||||||
.json()
|
.json()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// dbg!("{}", serde_json::to_string_pretty(&resp).unwrap());
|
println!(
|
||||||
|
"Response to `{}`: {}",
|
||||||
|
method,
|
||||||
|
serde_json::to_string_pretty(&resp).unwrap()
|
||||||
|
);
|
||||||
let resp: RawResponse<T> = serde_json::value::from_value(resp).unwrap();
|
let resp: RawResponse<T> = serde_json::value::from_value(resp).unwrap();
|
||||||
resp.result()
|
resp.result()
|
||||||
}
|
}
|
||||||
|
@ -116,7 +120,7 @@ impl std::convert::From<reqwest::Error> for RpcError {
|
||||||
fn from(error: reqwest::Error) -> Self {
|
fn from(error: reqwest::Error) -> Self {
|
||||||
RpcError {
|
RpcError {
|
||||||
code: -1,
|
code: -1,
|
||||||
message: Some(format!("Reqwest error: {}", error)),
|
message: Some(format!("Reqwest error: {:?}", error)),
|
||||||
data: None,
|
data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue