This commit is contained in:
2025-07-18 14:48:58 -05:00
parent eade487b9f
commit 525e43441f
3 changed files with 115 additions and 12 deletions
+38
View File
@@ -70,6 +70,14 @@ fn apps_file_path() -> PathBuf {
apps_dir().join("apps.json") 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<App> { pub fn init() -> Vec<App> {
let path = apps_file_path(); let path = apps_file_path();
@@ -94,6 +102,22 @@ pub fn save_apps(apps: &[App]) {
} }
pub fn uninstall_app(apps: &mut Vec<App>, id: &str) { pub fn uninstall_app(apps: &mut Vec<App>, id: &str) {
let id = {
let url = id.trim_end_matches(".git");
if url.starts_with("git@") {
// Format: [email protected]: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 if let Some(index) = apps
.iter() .iter()
.position(|app| app.id().expect("Unable to obtain id") == id) .position(|app| app.id().expect("Unable to obtain id") == id)
@@ -116,10 +140,14 @@ pub fn uninstall_app(apps: &mut Vec<App>, id: &str) {
app.id_system().expect("Unable to obtain id") app.id_system().expect("Unable to obtain id")
)); ));
println!("Removing service file: {:?}", service_path);
remove_file(service_path).unwrap_or_else(|e| { remove_file(service_path).unwrap_or_else(|e| {
eprintln!("Failed to remove service file: {}", e); eprintln!("Failed to remove service file: {}", e);
}); });
update_systemd();
apps.remove(index); apps.remove(index);
save_apps(apps); save_apps(apps);
} else { } else {
@@ -201,6 +229,8 @@ pub fn install_app(apps: &mut Vec<App>, app: App) {
return; return;
} }
update_systemd();
// Add to app list and save // Add to app list and save
apps.push(app); apps.push(app);
save_apps(apps); save_apps(apps);
@@ -240,3 +270,11 @@ pub fn restart_app(id: &str) {
.status() .status()
.expect("Failed to restart app"); .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()))
}
+44 -11
View File
@@ -1,7 +1,7 @@
pub mod app_manager; pub mod app_manager;
pub mod server_config; 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 crate::server_config::ServerStats;
use std::sync::Arc; use std::sync::Arc;
use std::thread::spawn; use std::thread::spawn;
@@ -12,8 +12,13 @@ use tungstenite::accept;
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub enum Method { pub enum Method {
Install(App), Install(App),
SetEnabled(usize, bool), SetEnabled(String, bool),
Edit(usize, App), Edit(String, App),
Uninstall(String),
Toggle(String, bool),
Start(String),
Stop(String),
Restart(String),
} }
fn main() { fn main() {
@@ -67,20 +72,48 @@ fn main() {
install_app(&mut apps, app); install_app(&mut apps, app);
} }
Method::SetEnabled(i, b) => { Method::SetEnabled(i, b) => {
if let Some(app) = apps.get_mut(i) { let app = get_app_by_id_mut(&mut apps, &i).expect("App not found");
} else { if let Some(id) = app.id_system() {
eprintln!("App index {} not found", i); app_manager::toggle_app_state(&format!("{}.service", id), b);
} }
app_manager::save_apps(&apps); app_manager::save_apps(&apps);
} }
Method::Edit(i, app) => { Method::Edit(i, app) => {
if let Some(existing_app) = apps.get_mut(i) { let existing_app = get_app_by_id_mut(&mut apps, &i).expect("App not found");
*existing_app = app; *existing_app = app;
} else {
eprintln!("App index {} not found", i);
}
app_manager::save_apps(&apps); 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));
}
} }
}); });
+33 -1
View File
@@ -1,11 +1,25 @@
const ws = new WebSocket("ws://localhost:5273"); 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.onmessage = (msg) => console.log("Received:", msg.data);
ws.onopen = () => { ws.onopen = () => {
ws.send("my-key"); ws.send("my-key");
ws.send( ws.send(
JSON.stringify({ JSON.stringify({
Uninstall: { Install: {
repo: "[email protected]:osui-rs/osui.git", repo: "[email protected]:osui-rs/osui.git",
branch: "master", branch: "master",
install_command: "", 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: "[email protected]:osui-rs/osui.git"
// })
// );
}; };