From 8cbb295c3aeb2db84471d00a5d43afe0e4bdaadf Mon Sep 17 00:00:00 2001 From: glyph Date: Mon, 28 Nov 2022 09:10:42 +0200 Subject: [PATCH] add power menu to settings menu and mount routes --- peach-web/src/private_router.rs | 16 ++++++--- peach-web/src/routes/mod.rs | 1 - peach-web/src/routes/power/mod.rs | 1 - peach-web/src/routes/settings/menu.rs | 4 ++- peach-web/src/routes/settings/mod.rs | 1 + .../src/routes/{ => settings}/power/menu.rs | 19 ++++++++-- peach-web/src/routes/settings/power/mod.rs | 3 ++ peach-web/src/routes/settings/power/reboot.rs | 36 +++++++++++++++++++ .../src/routes/settings/power/shutdown.rs | 35 ++++++++++++++++++ 9 files changed, 106 insertions(+), 10 deletions(-) delete mode 100644 peach-web/src/routes/power/mod.rs rename peach-web/src/routes/{ => settings}/power/menu.rs (56%) create mode 100644 peach-web/src/routes/settings/power/mod.rs create mode 100644 peach-web/src/routes/settings/power/reboot.rs create mode 100644 peach-web/src/routes/settings/power/shutdown.rs diff --git a/peach-web/src/private_router.rs b/peach-web/src/private_router.rs index b858e31..944cccd 100644 --- a/peach-web/src/private_router.rs +++ b/peach-web/src/private_router.rs @@ -49,10 +49,6 @@ pub fn mount_peachpub_routes( Response::html(routes::guide::build_template()) }, - (GET) (/power) => { - Response::html(routes::power::menu::build_template()) - }, - (POST) (/scuttlebutt/block) => { routes::scuttlebutt::block::handle_form(request) }, @@ -170,6 +166,18 @@ pub fn mount_peachpub_routes( routes::settings::admin::delete::handle_form(request) }, + (GET) (/settings/power) => { + Response::html(routes::settings::power::menu::build_template(request)) + }, + + (GET) (/settings/power/reboot) => { + routes::settings::power::reboot::handle_reboot() + }, + + (GET) (/settings/power/shutdown) => { + routes::settings::power::shutdown::handle_shutdown() + }, + (GET) (/settings/scuttlebutt) => { Response::html(routes::settings::scuttlebutt::menu::build_template(request)) .reset_flash() diff --git a/peach-web/src/routes/mod.rs b/peach-web/src/routes/mod.rs index 43f5527..fdc9575 100644 --- a/peach-web/src/routes/mod.rs +++ b/peach-web/src/routes/mod.rs @@ -3,7 +3,6 @@ pub mod authentication; //pub mod index; pub mod guide; pub mod home; -pub mod power; pub mod scuttlebutt; pub mod settings; pub mod status; diff --git a/peach-web/src/routes/power/mod.rs b/peach-web/src/routes/power/mod.rs deleted file mode 100644 index b9a0e3e..0000000 --- a/peach-web/src/routes/power/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod menu; diff --git a/peach-web/src/routes/settings/menu.rs b/peach-web/src/routes/settings/menu.rs index ad122b5..919601f 100644 --- a/peach-web/src/routes/settings/menu.rs +++ b/peach-web/src/routes/settings/menu.rs @@ -11,8 +11,10 @@ pub fn build_template() -> PreEscaped { div class="card center" { (PreEscaped("")) div id="settingsButtons" { - // render the network settings button if we're not in standalone mode + // render the network settings and power menu buttons if we're + // not in standalone mode @if !SERVER_CONFIG.standalone_mode { + a id="power" class="button button-primary center" href="/settings/power" title="Power Menu" { "Power" } a id="network" class="button button-primary center" href="/settings/network" title="Network Settings" { "Network" } } a id="scuttlebutt" class="button button-primary center" href="/settings/scuttlebutt" title="Scuttlebutt Settings" { "Scuttlebutt" } diff --git a/peach-web/src/routes/settings/mod.rs b/peach-web/src/routes/settings/mod.rs index b864d03..7f4c31c 100644 --- a/peach-web/src/routes/settings/mod.rs +++ b/peach-web/src/routes/settings/mod.rs @@ -2,5 +2,6 @@ pub mod admin; //pub mod dns; pub mod menu; pub mod network; +pub mod power; pub mod scuttlebutt; pub mod theme; diff --git a/peach-web/src/routes/power/menu.rs b/peach-web/src/routes/settings/power/menu.rs similarity index 56% rename from peach-web/src/routes/power/menu.rs rename to peach-web/src/routes/settings/power/menu.rs index 8d88d9d..42dc28b 100644 --- a/peach-web/src/routes/power/menu.rs +++ b/peach-web/src/routes/settings/power/menu.rs @@ -1,8 +1,17 @@ use maud::{html, PreEscaped}; +use rouille::Request; -use crate::{templates, utils::theme}; +use crate::{ + templates, + utils::{flash::FlashRequest, theme}, +}; + +/// Power menu template builder. +/// +/// Presents options for rebooting or shutting down the device. +pub fn build_template(request: &Request) -> PreEscaped { + let (flash_name, flash_msg) = request.retrieve_flash(); -pub fn build_template() -> PreEscaped { let power_menu_template = html! { (PreEscaped("")) div class="card center" { @@ -10,7 +19,11 @@ pub fn build_template() -> PreEscaped { div id="buttons" { a id="rebootBtn" class="button button-primary center" href="/reboot" title="Reboot Device" { "Reboot" } a id="shutdownBtn" class="button button-warning center" href="/shutdown" title="Shutdown Device" { "Shutdown" } - a id="cancelBtn" class="button button-secondary center" href="/" title="Cancel" { "Cancel" } + a id="cancelBtn" class="button button-secondary center" href="/settings" title="Cancel" { "Cancel" } + } + @if let (Some(name), Some(msg)) = (flash_name, flash_msg) { + (PreEscaped("")) + (templates::flash::build_template(name, msg)) } } } diff --git a/peach-web/src/routes/settings/power/mod.rs b/peach-web/src/routes/settings/power/mod.rs new file mode 100644 index 0000000..380e31c --- /dev/null +++ b/peach-web/src/routes/settings/power/mod.rs @@ -0,0 +1,3 @@ +pub mod menu; +pub mod reboot; +pub mod shutdown; diff --git a/peach-web/src/routes/settings/power/reboot.rs b/peach-web/src/routes/settings/power/reboot.rs new file mode 100644 index 0000000..5c1ba7b --- /dev/null +++ b/peach-web/src/routes/settings/power/reboot.rs @@ -0,0 +1,36 @@ +use log::info; +use rouille::Response; + +use std::{ + io::Result, + process::{Command, Output}, +}; + +use crate::utils::flash::FlashResponse; + +/// Executes a system command to reboot the device immediately. +fn reboot() -> Result { + info!("Rebooting the device"); + // ideally, we'd like to reboot after 5 seconds to allow time for JSON + // response but this is not possible with the `shutdown` command alone. + // TODO: send "rebooting..." message to `peach-oled` for display + Command::new("sudo") + .arg("shutdown") + .arg("-r") + .arg("now") + .output() +} + +pub fn handle_reboot() -> Response { + let (name, msg) = match reboot() { + Ok(_) => ("success".to_string(), "Rebooting the device".to_string()), + Err(err) => ( + "error".to_string(), + format!("Failed to reboot the device: {}", err), + ), + }; + + let (flash_name, flash_msg) = (format!("flash_name={}", name), format!("flash_msg={}", msg)); + + Response::redirect_303("/power").add_flash(flash_name, flash_msg) +} diff --git a/peach-web/src/routes/settings/power/shutdown.rs b/peach-web/src/routes/settings/power/shutdown.rs new file mode 100644 index 0000000..ae1dfa3 --- /dev/null +++ b/peach-web/src/routes/settings/power/shutdown.rs @@ -0,0 +1,35 @@ +use log::info; +use rouille::Response; + +use std::{ + io::Result, + process::{Command, Output}, +}; + +use crate::utils::flash::FlashResponse; + +/// Executes a system command to shutdown the device immediately. +fn shutdown() -> Result { + info!("Shutting down the device"); + // ideally, we'd like to shutdown after 5 seconds to allow time for JSON + // response but this is not possible with the `shutdown` command alone. + // TODO: send "shutting down..." message to `peach-oled` for display + Command::new("sudo").arg("shutdown").arg("now").output() +} + +pub fn handle_shutdown() -> Response { + let (name, msg) = match shutdown() { + Ok(_) => ( + "success".to_string(), + "Shutting down the device".to_string(), + ), + Err(err) => ( + "error".to_string(), + format!("Failed to shutdown the device: {}", err), + ), + }; + + let (flash_name, flash_msg) = (format!("flash_name={}", name), format!("flash_msg={}", msg)); + + Response::redirect_303("/power").add_flash(flash_name, flash_msg) +}