diff --git a/src/app_manager.rs b/src/app_manager.rs index 594c776..922126c 100644 --- a/src/app_manager.rs +++ b/src/app_manager.rs @@ -70,6 +70,14 @@ fn apps_file_path() -> PathBuf { apps_dir().join("apps.json") } +fn update_systemd() { + Command::new("systemctl") + .arg("--user") + .arg("daemon-reload") + .status() + .expect("Failed to reload systemd daemon"); +} + pub fn init() -> Vec { let path = apps_file_path(); @@ -94,6 +102,22 @@ pub fn save_apps(apps: &[App]) { } pub fn uninstall_app(apps: &mut Vec, id: &str) { + let id = { + let url = id.trim_end_matches(".git"); + + if url.starts_with("git@") { + // Format: git@github.com:usr/repo + url.split_once(':').map(|(_, path)| path.to_string()) + } else if url.starts_with("https://") || url.starts_with("http://") { + // Format: https://github.com/usr/repo + url.split_once("github.com/") + .map(|(_, path)| path.to_string()) + } else { + None + } + } + .unwrap(); + if let Some(index) = apps .iter() .position(|app| app.id().expect("Unable to obtain id") == id) @@ -116,10 +140,14 @@ pub fn uninstall_app(apps: &mut Vec, id: &str) { app.id_system().expect("Unable to obtain id") )); + println!("Removing service file: {:?}", service_path); + remove_file(service_path).unwrap_or_else(|e| { eprintln!("Failed to remove service file: {}", e); }); + update_systemd(); + apps.remove(index); save_apps(apps); } else { @@ -201,6 +229,8 @@ pub fn install_app(apps: &mut Vec, app: App) { return; } + update_systemd(); + // Add to app list and save apps.push(app); save_apps(apps); @@ -240,3 +270,11 @@ pub fn restart_app(id: &str) { .status() .expect("Failed to restart app"); } + +pub fn get_app_by_id<'a>(apps: &'a [App], id: &str) -> Option<&'a App> { + apps.iter().find(|app| app.id() == Some(id.to_string())) +} + +pub fn get_app_by_id_mut<'a>(apps: &'a mut [App], id: &str) -> Option<&'a mut App> { + apps.iter_mut().find(|app| app.id() == Some(id.to_string())) +} diff --git a/src/main.rs b/src/main.rs index dc724b5..16f118f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ pub mod app_manager; pub mod server_config; -use crate::app_manager::{install_app, App}; +use crate::app_manager::{get_app_by_id, get_app_by_id_mut, install_app, App}; use crate::server_config::ServerStats; use std::sync::Arc; use std::thread::spawn; @@ -12,8 +12,13 @@ use tungstenite::accept; #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] pub enum Method { Install(App), - SetEnabled(usize, bool), - Edit(usize, App), + SetEnabled(String, bool), + Edit(String, App), + Uninstall(String), + Toggle(String, bool), + Start(String), + Stop(String), + Restart(String), } fn main() { @@ -67,20 +72,48 @@ fn main() { install_app(&mut apps, app); } Method::SetEnabled(i, b) => { - if let Some(app) = apps.get_mut(i) { - } else { - eprintln!("App index {} not found", i); + let app = get_app_by_id_mut(&mut apps, &i).expect("App not found"); + if let Some(id) = app.id_system() { + app_manager::toggle_app_state(&format!("{}.service", id), b); } app_manager::save_apps(&apps); } Method::Edit(i, app) => { - if let Some(existing_app) = apps.get_mut(i) { - *existing_app = app; - } else { - eprintln!("App index {} not found", i); - } + let existing_app = get_app_by_id_mut(&mut apps, &i).expect("App not found"); + *existing_app = app; app_manager::save_apps(&apps); } + Method::Uninstall(id) => { + app_manager::uninstall_app(&mut apps, &id); + } + Method::Toggle(id, enable) => { + let id = get_app_by_id(&mut apps, &id) + .expect("App not found") + .id_system() + .unwrap(); + app_manager::toggle_app_state(&format!("{}.service", id), enable); + } + Method::Start(id) => { + let id = get_app_by_id(&mut apps, &id) + .expect("App not found") + .id_system() + .unwrap(); + app_manager::start_app(&format!("{}.service", id)); + } + Method::Stop(id) => { + let id = get_app_by_id(&mut apps, &id) + .expect("App not found") + .id_system() + .unwrap(); + app_manager::stop_app(&format!("{}.service", id)); + } + Method::Restart(id) => { + let id = get_app_by_id(&mut apps, &id) + .expect("App not found") + .id_system() + .unwrap(); + app_manager::restart_app(&format!("{}.service", id)); + } } }); diff --git a/test.js b/test.js index 7bafcf6..c3ee8ae 100644 --- a/test.js +++ b/test.js @@ -1,11 +1,25 @@ const ws = new WebSocket("ws://localhost:5273"); +/* +pub enum Method { + Install(App), + SetEnabled(String, bool), + Edit(String, App), + Uninstall(String), + Toggle(String, bool), + Start(String), + Stop(String), + Restart(String), +} +*/ + ws.onmessage = (msg) => console.log("Received:", msg.data); ws.onopen = () => { ws.send("my-key"); + ws.send( JSON.stringify({ - Uninstall: { + Install: { repo: "git@github.com:osui-rs/osui.git", branch: "master", install_command: "", @@ -13,4 +27,22 @@ ws.onopen = () => { } }) ); + + ws.send( + JSON.stringify({ + SetEnabled: ["osui-rs/osui", true] + }) + ); + + ws.send( + JSON.stringify({ + Start: "osui-rs/osui" + }) + ); + + // ws.send( + // JSON.stringify({ + // Uninstall: "git@github.com:osui-rs/osui.git" + // }) + // ); };