Compare commits

...

3 Commits

Author SHA1 Message Date
8b7f592099 add save/load of config 2023-05-06 21:19:45 +03:00
f2963a3d4e optimize release build 2023-05-06 20:29:33 +03:00
e8dc59a82f update source code url 2023-05-06 20:25:19 +03:00
3 changed files with 49 additions and 10 deletions

2
Cargo.lock generated
View File

@ -2756,7 +2756,7 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]] [[package]]
name = "ubusman" name = "ubusman"
version = "0.1.0" version = "1.0.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-ssh2-lite", "async-ssh2-lite",

View File

@ -1,10 +1,8 @@
[package] [package]
name = "ubusman" name = "ubusman"
version = "0.1.0" version = "1.0.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
anyhow = "1.0.70" anyhow = "1.0.70"
async-ssh2-lite = { version = "0.4.5", features = ["async-io"] } async-ssh2-lite = { version = "0.4.5", features = ["async-io"] }
@ -26,3 +24,9 @@ thiserror = "1.0.40"
tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread"] }
toml = "0.7.3" toml = "0.7.3"
version = "3.0.0" version = "3.0.0"
[profile.release]
opt-level = 'z' # Optimize for size
lto = true # Enable link-time optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations
strip = true # Strip symbols from binary*

View File

@ -1,14 +1,16 @@
use std::{ use std::{
net::{SocketAddr, SocketAddrV4}, net::{SocketAddr, SocketAddrV4},
sync::{mpsc::{Receiver, Sender}, Arc}, sync::{mpsc::{Receiver, Sender}, Arc},
vec, rc::Rc, time::SystemTime, vec, rc::Rc, time::SystemTime, path::{PathBuf, Path}, fs,
}; };
use anyhow::Result; use anyhow::{Result, anyhow};
use async_ssh2_lite::{AsyncIoTcpStream, AsyncSession}; use async_ssh2_lite::{AsyncIoTcpStream, AsyncSession};
use directories_next::ProjectDirs;
use eframe::CreationContext; use eframe::CreationContext;
use egui::{text::LayoutJob, Color32, ColorImage, TextureHandle}; use egui::{text::LayoutJob, Color32, ColorImage, TextureHandle};
use lazy_regex::regex_replace_all; use lazy_regex::regex_replace_all;
use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
@ -24,7 +26,7 @@ lazy_static! {
.expect("Failed to load copy icon") as ColorImage; .expect("Failed to load copy icon") as ColorImage;
} }
const SOURCE_CODE_URL: &str = "https://example.com"; const SOURCE_CODE_URL: &str = "https://git.rpuzonas.com/rpuzonas/ubusman";
const VERSION: &str = version!(); const VERSION: &str = version!();
const GIT_VERSION: &str = git_version!(args = ["--always", "--dirty=*"]); const GIT_VERSION: &str = git_version!(args = ["--always", "--dirty=*"]);
@ -46,6 +48,7 @@ pub enum AsyncEvent {
Call(Result<Value>) Call(Result<Value>)
} }
#[derive(Deserialize, Serialize)]
pub struct AppSettings { pub struct AppSettings {
address: String, address: String,
port: u16, port: u16,
@ -79,13 +82,20 @@ pub struct App {
copy_texture: Option<TextureHandle> copy_texture: Option<TextureHandle>
} }
fn get_config_path() -> PathBuf {
let project_dirs = ProjectDirs::from("", "", "ubusman")
.expect("Failed to determine home directory");
let config_dir = project_dirs.config_dir();
config_dir.join("config.toml")
}
impl Default for App { impl Default for App {
fn default() -> Self { fn default() -> Self {
let (tx, rx) = std::sync::mpsc::channel(); let (tx, rx) = std::sync::mpsc::channel();
Self { Self {
settings: AppSettings { settings: AppSettings {
address: "172.24.224.1".into(), //"192.168.1.1".to_owned(), address: "192.168.1.1".to_owned(),
port: 22, port: 22,
username: "root".to_owned(), username: "root".to_owned(),
password: "admin01".to_owned(), password: "admin01".to_owned(),
@ -175,13 +185,34 @@ impl App {
self.start_connect(socket_addr, username.clone(), password.clone()); self.start_connect(socket_addr, username.clone(), password.clone());
} }
self.copy_texture = Some(cc.egui_ctx.load_texture( self.copy_texture = Some(cc.egui_ctx.load_texture(
"clipboard", "clipboard",
COPY_ICON.clone(), COPY_ICON.clone(),
Default::default() Default::default()
)); ));
self.load_config();
}
fn load_config(&mut self) -> Result<()> {
let config_path = get_config_path();
if let Ok(contents) = fs::read_to_string(config_path) {
self.settings = toml::from_str(&contents)?;
}
Ok(())
}
fn save_config(&self) -> Result<()> {
let config_path = get_config_path();
let directory = Path::parent(&config_path)
.expect("Failed to get config parent directory");
if !Path::is_dir(directory) {
fs::create_dir_all(directory)?;
}
fs::write(&config_path, toml::to_string_pretty(&self.settings)?)?;
Ok(())
} }
pub fn get_selected_object(&self) -> Option<&str> { pub fn get_selected_object(&self) -> Option<&str> {
@ -599,4 +630,8 @@ impl eframe::App for App {
.show_inside(ui, |ui| self.show_central_panel(ui)); .show_inside(ui, |ui| self.show_central_panel(ui));
}); });
} }
fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) {
self.save_config();
}
} }