move context objects and builders to dedicated directory
This commit is contained in:
parent
a5f0d991fa
commit
166f4d25ae
|
@ -3,7 +3,7 @@ use rocket::{
|
||||||
form::{Form, FromForm},
|
form::{Form, FromForm},
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
serde::{Deserialize, Serialize},
|
serde::Deserialize,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
|
||||||
|
@ -14,8 +14,9 @@ use peach_lib::{
|
||||||
jsonrpc_core::types::error::ErrorCode,
|
jsonrpc_core::types::error::ErrorCode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::error::PeachWebError;
|
use crate::{
|
||||||
use crate::routes::authentication::Authenticated;
|
context::dns::ConfigureDNSContext, error::PeachWebError, routes::authentication::Authenticated,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, FromForm)]
|
#[derive(Debug, Deserialize, FromForm)]
|
||||||
pub struct DnsForm {
|
pub struct DnsForm {
|
||||||
|
@ -73,40 +74,6 @@ pub fn save_dns_configuration(dns_form: DnsForm) -> Result<(), PeachWebError> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct ConfigureDNSContext {
|
|
||||||
pub external_domain: String,
|
|
||||||
pub dyndns_subdomain: String,
|
|
||||||
pub enable_dyndns: bool,
|
|
||||||
pub is_dyndns_online: bool,
|
|
||||||
pub back: Option<String>,
|
|
||||||
pub title: Option<String>,
|
|
||||||
pub flash_name: Option<String>,
|
|
||||||
pub flash_msg: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConfigureDNSContext {
|
|
||||||
pub fn build() -> ConfigureDNSContext {
|
|
||||||
// TODO: replace `unwrap` with resilient error handling
|
|
||||||
let peach_config = config_manager::load_peach_config().unwrap();
|
|
||||||
let dyndns_fulldomain = peach_config.dyn_domain;
|
|
||||||
let is_dyndns_online = dyndns_client::is_dns_updater_online().unwrap();
|
|
||||||
let dyndns_subdomain =
|
|
||||||
dyndns_client::get_dyndns_subdomain(&dyndns_fulldomain).unwrap_or(dyndns_fulldomain);
|
|
||||||
|
|
||||||
ConfigureDNSContext {
|
|
||||||
external_domain: peach_config.external_domain,
|
|
||||||
dyndns_subdomain,
|
|
||||||
enable_dyndns: peach_config.dyn_enabled,
|
|
||||||
is_dyndns_online,
|
|
||||||
back: None,
|
|
||||||
title: None,
|
|
||||||
flash_name: None,
|
|
||||||
flash_msg: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/dns")]
|
#[get("/dns")]
|
||||||
pub fn configure_dns(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn configure_dns(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = ConfigureDNSContext::build();
|
let mut context = ConfigureDNSContext::build();
|
||||||
|
@ -128,28 +95,23 @@ pub fn configure_dns(flash: Option<FlashMessage>, _auth: Authenticated) -> Templ
|
||||||
#[post("/dns", data = "<dns>")]
|
#[post("/dns", data = "<dns>")]
|
||||||
pub fn configure_dns_post(dns: Form<DnsForm>, _auth: Authenticated) -> Template {
|
pub fn configure_dns_post(dns: Form<DnsForm>, _auth: Authenticated) -> Template {
|
||||||
let result = save_dns_configuration(dns.into_inner());
|
let result = save_dns_configuration(dns.into_inner());
|
||||||
|
|
||||||
|
let mut context = ConfigureDNSContext::build();
|
||||||
|
|
||||||
|
// set back icon link to network route
|
||||||
|
context.back = Some("/settings/network".to_string());
|
||||||
|
context.title = Some("Configure DNS".to_string());
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let mut context = ConfigureDNSContext::build();
|
|
||||||
|
|
||||||
// set back icon link to network route
|
|
||||||
context.back = Some("/settings/network".to_string());
|
|
||||||
context.title = Some("Configure DNS".to_string());
|
|
||||||
context.flash_name = Some("success".to_string());
|
context.flash_name = Some("success".to_string());
|
||||||
context.flash_msg = Some("New dynamic dns configuration is now enabled".to_string());
|
context.flash_msg = Some("New dynamic dns configuration is now enabled".to_string());
|
||||||
|
|
||||||
Template::render("settings/network/configure_dns", &context)
|
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let mut context = ConfigureDNSContext::build();
|
|
||||||
|
|
||||||
// set back icon link to network route
|
|
||||||
context.back = Some("/settings/network".to_string());
|
|
||||||
context.title = Some("Configure DNS".to_string());
|
|
||||||
context.flash_name = Some("error".to_string());
|
context.flash_name = Some("error".to_string());
|
||||||
context.flash_msg = Some(format!("Failed to save dns configurations: {}", err));
|
context.flash_msg = Some(format!("Failed to save dns configurations: {}", err));
|
||||||
|
|
||||||
Template::render("settings/network/configure_dns", &context)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Template::render("settings/network/configure_dns", &context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,24 @@
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
form::{Form, FromForm},
|
form::{Form, FromForm},
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
serde::{Deserialize, Serialize},
|
serde::Deserialize,
|
||||||
uri, UriDisplayQuery,
|
uri, UriDisplayQuery,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::{tera::Context, Template};
|
||||||
|
|
||||||
use peach_lib::{
|
use peach_network::network;
|
||||||
// TODO: replace this with peach_network::network
|
|
||||||
network_client::{AccessPoint, Networks, Scan},
|
use crate::{
|
||||||
stats_client::Traffic,
|
context,
|
||||||
|
context::network::{NetworkAlertContext, NetworkDetailContext, NetworkListContext},
|
||||||
|
routes::authentication::Authenticated,
|
||||||
|
utils::{monitor, monitor::Threshold},
|
||||||
|
AP_IFACE, WLAN_IFACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::routes::authentication::Authenticated;
|
|
||||||
use crate::utils::monitor::{Alert, Data, Threshold};
|
|
||||||
|
|
||||||
// STRUCTS USED BY NETWORK ROUTES
|
// STRUCTS USED BY NETWORK ROUTES
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, FromForm, UriDisplayQuery)]
|
#[derive(Debug, Deserialize, FromForm, UriDisplayQuery)]
|
||||||
|
@ -51,12 +50,12 @@ pub fn wifi_usage_reset(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
pub fn connect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn connect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
let ssid = &network.ssid;
|
let ssid = &network.ssid;
|
||||||
let url = uri!(network_detail(ssid = ssid));
|
let url = uri!(network_detail(ssid = ssid));
|
||||||
match network_client::id("wlan0", ssid) {
|
match network::id(&*WLAN_IFACE, ssid) {
|
||||||
Ok(id) => match network_client::connect(&id, "wlan0") {
|
Ok(Some(id)) => match network::connect(&id, &*WLAN_IFACE) {
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "Connected to chosen network"),
|
Ok(_) => Flash::success(Redirect::to(url), "Connected to chosen network"),
|
||||||
Err(_) => Flash::error(Redirect::to(url), "Failed to connect to chosen network"),
|
Err(_) => Flash::error(Redirect::to(url), "Failed to connect to chosen network"),
|
||||||
},
|
},
|
||||||
Err(_) => Flash::error(Redirect::to(url), "Failed to retrieve the network ID"),
|
_ => Flash::error(Redirect::to(url), "Failed to retrieve the network ID"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ pub fn connect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect
|
||||||
pub fn disconnect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn disconnect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
let ssid = &network.ssid;
|
let ssid = &network.ssid;
|
||||||
let url = uri!(network_home);
|
let url = uri!(network_home);
|
||||||
match network_client::disable("wlan0", ssid) {
|
match network::disable(&*WLAN_IFACE, ssid) {
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "Disconnected from WiFi network"),
|
Ok(_) => Flash::success(Redirect::to(url), "Disconnected from WiFi network"),
|
||||||
Err(_) => Flash::error(Redirect::to(url), "Failed to disconnect from WiFi network"),
|
Err(_) => Flash::error(Redirect::to(url), "Failed to disconnect from WiFi network"),
|
||||||
}
|
}
|
||||||
|
@ -74,7 +73,7 @@ pub fn disconnect_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redir
|
||||||
pub fn forget_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
pub fn forget_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect> {
|
||||||
let ssid = &network.ssid;
|
let ssid = &network.ssid;
|
||||||
let url = uri!(network_home);
|
let url = uri!(network_home);
|
||||||
match network_client::forget("wlan0", ssid) {
|
match network::forget(&*WLAN_IFACE, ssid) {
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "WiFi credentials removed"),
|
Ok(_) => Flash::success(Redirect::to(url), "WiFi credentials removed"),
|
||||||
Err(_) => Flash::error(
|
Err(_) => Flash::error(
|
||||||
Redirect::to(url),
|
Redirect::to(url),
|
||||||
|
@ -85,21 +84,19 @@ pub fn forget_wifi(network: Form<Ssid>, _auth: Authenticated) -> Flash<Redirect>
|
||||||
|
|
||||||
#[get("/wifi/modify?<ssid>")]
|
#[get("/wifi/modify?<ssid>")]
|
||||||
pub fn wifi_password(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn wifi_password(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = NetworkAddContext {
|
let mut context = Context::new();
|
||||||
back: Some("/settings/network/wifi".to_string()),
|
context.insert("back", &Some("/settings/network/wifi".to_string()));
|
||||||
flash_name: None,
|
context.insert("title", &Some("Update WiFi Password".to_string()));
|
||||||
flash_msg: None,
|
context.insert("selected", &Some(ssid.to_string()));
|
||||||
selected: Some(ssid.to_string()),
|
|
||||||
title: Some("Update WiFi Password".to_string()),
|
|
||||||
};
|
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
// add flash message contents to the context object
|
// add flash message contents to the context object
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.insert("flash_name", &Some(flash.kind().to_string()));
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.insert("flash_msg", &Some(flash.message().to_string()));
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
|
||||||
Template::render("settings/network/modify_ap", &context)
|
Template::render("settings/network/modify_ap", &context.into_json())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/wifi/modify", data = "<wifi>")]
|
#[post("/wifi/modify", data = "<wifi>")]
|
||||||
|
@ -107,7 +104,7 @@ pub fn wifi_set_password(wifi: Form<WiFi>, _auth: Authenticated) -> Flash<Redire
|
||||||
let ssid = &wifi.ssid;
|
let ssid = &wifi.ssid;
|
||||||
let pass = &wifi.pass;
|
let pass = &wifi.pass;
|
||||||
let url = uri!(network_detail(ssid = ssid));
|
let url = uri!(network_detail(ssid = ssid));
|
||||||
match network_client::update("wlan0", ssid, pass) {
|
match network::update(&*WLAN_IFACE, ssid, pass) {
|
||||||
Ok(_) => Flash::success(Redirect::to(url), "WiFi password updated".to_string()),
|
Ok(_) => Flash::success(Redirect::to(url), "WiFi password updated".to_string()),
|
||||||
Err(_) => Flash::error(
|
Err(_) => Flash::error(
|
||||||
Redirect::to(url),
|
Redirect::to(url),
|
||||||
|
@ -118,174 +115,23 @@ pub fn wifi_set_password(wifi: Form<WiFi>, _auth: Authenticated) -> Flash<Redire
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network
|
// HELPERS AND ROUTES FOR /settings/network
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct NetworkContext {
|
|
||||||
pub ap_ip: String,
|
|
||||||
pub ap_ssid: String,
|
|
||||||
pub ap_state: String,
|
|
||||||
pub ap_traffic: Option<Traffic>,
|
|
||||||
pub wlan_ip: String,
|
|
||||||
pub wlan_rssi: Option<String>,
|
|
||||||
pub wlan_scan: Option<Vec<Scan>>,
|
|
||||||
pub wlan_ssid: String,
|
|
||||||
pub wlan_state: String,
|
|
||||||
pub wlan_status: String,
|
|
||||||
pub wlan_traffic: Option<Traffic>,
|
|
||||||
pub flash_name: Option<String>,
|
|
||||||
pub flash_msg: Option<String>,
|
|
||||||
// allows for passing in the ssid of a chosen access point
|
|
||||||
// this is used in the network_detail template
|
|
||||||
pub selected: Option<String>,
|
|
||||||
// page title for header in navbar
|
|
||||||
pub title: Option<String>,
|
|
||||||
// url for back-arrow link
|
|
||||||
pub back: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkContext {
|
|
||||||
pub fn build() -> NetworkContext {
|
|
||||||
let ap_ip = match network_client::ip("ap0") {
|
|
||||||
Ok(ip) => ip,
|
|
||||||
Err(_) => "x.x.x.x".to_string(),
|
|
||||||
};
|
|
||||||
let ap_ssid = match network_client::ssid("ap0") {
|
|
||||||
Ok(ssid) => ssid,
|
|
||||||
Err(_) => "Not currently activated".to_string(),
|
|
||||||
};
|
|
||||||
let ap_state = match network_client::state("ap0") {
|
|
||||||
Ok(state) => state,
|
|
||||||
Err(_) => "Interface unavailable".to_string(),
|
|
||||||
};
|
|
||||||
let ap_traffic = match network_client::traffic("ap0") {
|
|
||||||
Ok(traffic) => {
|
|
||||||
let mut t = traffic;
|
|
||||||
// modify traffic values & assign measurement unit
|
|
||||||
// based on received and transmitted values
|
|
||||||
// if received > 999 MB, convert it to GB
|
|
||||||
if t.received > 1_047_527_424 {
|
|
||||||
t.received /= 1_073_741_824;
|
|
||||||
t.rx_unit = Some("GB".to_string());
|
|
||||||
} else if t.received > 0 {
|
|
||||||
// otherwise, convert it to MB
|
|
||||||
t.received = (t.received / 1024) / 1024;
|
|
||||||
t.rx_unit = Some("MB".to_string());
|
|
||||||
} else {
|
|
||||||
t.received = 0;
|
|
||||||
t.rx_unit = Some("MB".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.transmitted > 1_047_527_424 {
|
|
||||||
t.transmitted /= 1_073_741_824;
|
|
||||||
t.tx_unit = Some("GB".to_string());
|
|
||||||
} else if t.transmitted > 0 {
|
|
||||||
t.transmitted = (t.transmitted / 1024) / 1024;
|
|
||||||
t.tx_unit = Some("MB".to_string());
|
|
||||||
} else {
|
|
||||||
t.transmitted = 0;
|
|
||||||
t.tx_unit = Some("MB".to_string());
|
|
||||||
}
|
|
||||||
Some(t)
|
|
||||||
}
|
|
||||||
Err(_) => None,
|
|
||||||
};
|
|
||||||
let wlan_ip = match network_client::ip("wlan0") {
|
|
||||||
Ok(ip) => ip,
|
|
||||||
Err(_) => "x.x.x.x".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_rssi = match network_client::rssi_percent("wlan0") {
|
|
||||||
Ok(rssi) => Some(rssi),
|
|
||||||
Err(_) => None,
|
|
||||||
};
|
|
||||||
let wlan_scan = match network_client::available_networks("wlan0") {
|
|
||||||
Ok(networks) => {
|
|
||||||
let scan: Vec<Scan> = serde_json::from_str(networks.as_str())
|
|
||||||
.expect("Failed to deserialize scan_networks response");
|
|
||||||
Some(scan)
|
|
||||||
}
|
|
||||||
Err(_) => None,
|
|
||||||
};
|
|
||||||
let wlan_ssid = match network_client::ssid("wlan0") {
|
|
||||||
Ok(ssid) => ssid,
|
|
||||||
Err(_) => "Not connected".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_state = match network_client::state("wlan0") {
|
|
||||||
Ok(state) => state,
|
|
||||||
Err(_) => "Interface unavailable".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_status = match network_client::status("wlan0") {
|
|
||||||
Ok(status) => status,
|
|
||||||
Err(_) => "Interface unavailable".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_traffic = match network_client::traffic("wlan0") {
|
|
||||||
Ok(traffic) => {
|
|
||||||
let mut t = traffic;
|
|
||||||
// modify traffic values & assign measurement unit
|
|
||||||
// based on received and transmitted values
|
|
||||||
// if received > 999 MB, convert it to GB
|
|
||||||
if t.received > 1_047_527_424 {
|
|
||||||
t.received /= 1_073_741_824;
|
|
||||||
t.rx_unit = Some("GB".to_string());
|
|
||||||
} else if t.received > 0 {
|
|
||||||
// otherwise, convert it to MB
|
|
||||||
t.received = (t.received / 1024) / 1024;
|
|
||||||
t.rx_unit = Some("MB".to_string());
|
|
||||||
} else {
|
|
||||||
t.received = 0;
|
|
||||||
t.rx_unit = Some("MB".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.transmitted > 1_047_527_424 {
|
|
||||||
t.transmitted /= 1_073_741_824;
|
|
||||||
t.tx_unit = Some("GB".to_string());
|
|
||||||
} else if t.transmitted > 0 {
|
|
||||||
t.transmitted = (t.transmitted / 1024) / 1024;
|
|
||||||
t.tx_unit = Some("MB".to_string());
|
|
||||||
} else {
|
|
||||||
t.transmitted = 0;
|
|
||||||
t.tx_unit = Some("MB".to_string());
|
|
||||||
}
|
|
||||||
Some(t)
|
|
||||||
}
|
|
||||||
Err(_) => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
NetworkContext {
|
|
||||||
ap_ip,
|
|
||||||
ap_ssid,
|
|
||||||
ap_state,
|
|
||||||
ap_traffic,
|
|
||||||
wlan_ip,
|
|
||||||
wlan_rssi,
|
|
||||||
wlan_scan,
|
|
||||||
wlan_ssid,
|
|
||||||
wlan_state,
|
|
||||||
wlan_status,
|
|
||||||
wlan_traffic,
|
|
||||||
flash_name: None,
|
|
||||||
flash_msg: None,
|
|
||||||
selected: None,
|
|
||||||
title: None,
|
|
||||||
back: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub fn network_home(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn network_home(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// assign context through context_builder call
|
// assign context
|
||||||
let mut context = NetworkContext::build();
|
let mut context = Context::new();
|
||||||
// set back button (nav) url
|
context.insert("back", &Some("/settings"));
|
||||||
context.back = Some("/settings".to_string());
|
context.insert("title", &Some("Network Configuration"));
|
||||||
// set page title
|
context.insert("ap_state", &context::network::ap_state());
|
||||||
context.title = Some("Network Configuration".to_string());
|
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
// add flash message contents to the context object
|
// add flash message contents to the context object
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.insert("flash_name", &Some(flash.kind().to_string()));
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.insert("flash_msg", &Some(flash.message().to_string()));
|
||||||
};
|
};
|
||||||
|
|
||||||
// template_dir is set in Rocket.toml
|
// template_dir is set in Rocket.toml
|
||||||
Template::render("settings/network/menu", &context)
|
Template::render("settings/network/menu", &context.into_json())
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/ap/activate
|
// HELPERS AND ROUTES FOR /settings/network/ap/activate
|
||||||
|
@ -294,7 +140,7 @@ pub fn network_home(flash: Option<FlashMessage>, _auth: Authenticated) -> Templa
|
||||||
pub fn deploy_ap(_auth: Authenticated) -> Flash<Redirect> {
|
pub fn deploy_ap(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
// activate the wireless access point
|
// activate the wireless access point
|
||||||
debug!("Activating WiFi access point.");
|
debug!("Activating WiFi access point.");
|
||||||
match network_client::activate_ap() {
|
match network::start_iface_service(&*AP_IFACE) {
|
||||||
Ok(_) => Flash::success(
|
Ok(_) => Flash::success(
|
||||||
Redirect::to("/settings/network"),
|
Redirect::to("/settings/network"),
|
||||||
"Activated WiFi access point",
|
"Activated WiFi access point",
|
||||||
|
@ -308,252 +154,37 @@ pub fn deploy_ap(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/wifi
|
// HELPERS AND ROUTES FOR /settings/network/wifi
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct NetworkListContext {
|
|
||||||
pub ap_state: String,
|
|
||||||
pub back: Option<String>,
|
|
||||||
pub flash_name: Option<String>,
|
|
||||||
pub flash_msg: Option<String>,
|
|
||||||
pub title: Option<String>,
|
|
||||||
pub wlan_networks: HashMap<String, String>,
|
|
||||||
pub wlan_ssid: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkListContext {
|
|
||||||
pub fn build() -> NetworkListContext {
|
|
||||||
// list of networks saved in the wpa_supplicant.conf
|
|
||||||
let wlan_list = match network_client::saved_networks() {
|
|
||||||
Ok(ssids) => {
|
|
||||||
let networks: Vec<Networks> = serde_json::from_str(ssids.as_str())
|
|
||||||
.expect("Failed to deserialize scan_list response");
|
|
||||||
networks
|
|
||||||
}
|
|
||||||
Err(_) => Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// list of networks currently in range (online & accessible)
|
|
||||||
let wlan_scan = match network_client::available_networks("wlan0") {
|
|
||||||
Ok(networks) => {
|
|
||||||
let scan: Vec<Networks> = serde_json::from_str(networks.as_str())
|
|
||||||
.expect("Failed to deserialize scan_networks response");
|
|
||||||
scan
|
|
||||||
}
|
|
||||||
Err(_) => Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let wlan_ssid = match network_client::ssid("wlan0") {
|
|
||||||
Ok(ssid) => ssid,
|
|
||||||
Err(_) => "Not connected".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// create a hashmap to combine wlan_list & wlan_scan without repetition
|
|
||||||
let mut wlan_networks = HashMap::new();
|
|
||||||
for ap in wlan_scan {
|
|
||||||
wlan_networks.insert(ap.ssid, "Available".to_string());
|
|
||||||
}
|
|
||||||
for network in wlan_list {
|
|
||||||
// insert ssid (with state) only if it doesn't already exist
|
|
||||||
wlan_networks
|
|
||||||
.entry(network.ssid)
|
|
||||||
.or_insert_with(|| "Not in range".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
let ap_state = match network_client::state("ap0") {
|
|
||||||
Ok(state) => state,
|
|
||||||
Err(_) => "Interface unavailable".to_string(),
|
|
||||||
};
|
|
||||||
|
|
||||||
NetworkListContext {
|
|
||||||
ap_state,
|
|
||||||
back: None,
|
|
||||||
flash_msg: None,
|
|
||||||
flash_name: None,
|
|
||||||
title: None,
|
|
||||||
wlan_networks,
|
|
||||||
wlan_ssid,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/wifi")]
|
#[get("/wifi")]
|
||||||
pub fn wifi_list(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn wifi_list(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// assign context through context_builder call
|
// assign context through context_builder call
|
||||||
let mut context = NetworkListContext::build();
|
let mut context = NetworkListContext::build();
|
||||||
context.back = Some("/settings/network".to_string());
|
context.back = Some("/settings/network".to_string());
|
||||||
context.title = Some("WiFi Networks".to_string());
|
context.title = Some("WiFi Networks".to_string());
|
||||||
|
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
// add flash message contents to the context object
|
// add flash message contents to the context object
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
|
||||||
Template::render("settings/network/list_aps", &context)
|
Template::render("settings/network/list_aps", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /settings/network/wifi<ssid>
|
// HELPERS AND ROUTES FOR /settings/network/wifi<ssid>
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct NetworkDetailContext {
|
|
||||||
pub back: Option<String>,
|
|
||||||
pub flash_name: Option<String>,
|
|
||||||
pub flash_msg: Option<String>,
|
|
||||||
pub saved_aps: Vec<Networks>,
|
|
||||||
pub selected: Option<String>,
|
|
||||||
pub title: Option<String>,
|
|
||||||
pub wlan_ip: String,
|
|
||||||
pub wlan_networks: HashMap<String, AccessPoint>,
|
|
||||||
pub wlan_rssi: Option<String>,
|
|
||||||
pub wlan_ssid: String,
|
|
||||||
pub wlan_state: String,
|
|
||||||
pub wlan_status: String,
|
|
||||||
pub wlan_traffic: Option<Traffic>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkDetailContext {
|
|
||||||
pub fn build() -> NetworkDetailContext {
|
|
||||||
let wlan_ip = match network_client::ip("wlan0") {
|
|
||||||
Ok(ip) => ip,
|
|
||||||
Err(_) => "x.x.x.x".to_string(),
|
|
||||||
};
|
|
||||||
// list of networks saved in wpa_supplicant.conf
|
|
||||||
let wlan_list = match network_client::saved_networks() {
|
|
||||||
Ok(ssids) => {
|
|
||||||
let networks: Vec<Networks> = serde_json::from_str(ssids.as_str())
|
|
||||||
.expect("Failed to deserialize scan_list response");
|
|
||||||
networks
|
|
||||||
}
|
|
||||||
Err(_) => Vec::new(),
|
|
||||||
};
|
|
||||||
// list of networks saved in wpa_supplicant.conf
|
|
||||||
// HACK: we're running the same function twice (wlan_list)
|
|
||||||
// see if we can implement clone for Vec<Networks> instead
|
|
||||||
let saved_aps = match network_client::saved_networks() {
|
|
||||||
Ok(ssids) => {
|
|
||||||
let networks: Vec<Networks> = serde_json::from_str(ssids.as_str())
|
|
||||||
.expect("Failed to deserialize scan_list response");
|
|
||||||
networks
|
|
||||||
}
|
|
||||||
Err(_) => Vec::new(),
|
|
||||||
};
|
|
||||||
let wlan_rssi = match network_client::rssi_percent("wlan0") {
|
|
||||||
Ok(rssi) => Some(rssi),
|
|
||||||
Err(_) => None,
|
|
||||||
};
|
|
||||||
// list of networks currently in range (online & accessible)
|
|
||||||
let wlan_scan = match network_client::available_networks("wlan0") {
|
|
||||||
Ok(networks) => {
|
|
||||||
let scan: Vec<Scan> = serde_json::from_str(networks.as_str())
|
|
||||||
.expect("Failed to deserialize scan_networks response");
|
|
||||||
scan
|
|
||||||
}
|
|
||||||
Err(_) => Vec::new(),
|
|
||||||
};
|
|
||||||
let wlan_ssid = match network_client::ssid("wlan0") {
|
|
||||||
Ok(ssid) => ssid,
|
|
||||||
Err(_) => "Not connected".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_state = match network_client::state("wlan0") {
|
|
||||||
Ok(state) => state,
|
|
||||||
Err(_) => "Interface unavailable".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_status = match network_client::status("wlan0") {
|
|
||||||
Ok(status) => status,
|
|
||||||
Err(_) => "Interface unavailable".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_traffic = match network_client::traffic("wlan0") {
|
|
||||||
Ok(traffic) => {
|
|
||||||
let mut t = traffic;
|
|
||||||
// modify traffic values & assign measurement unit
|
|
||||||
// based on received and transmitted values
|
|
||||||
// if received > 999 MB, convert it to GB
|
|
||||||
if t.received > 1_047_527_424 {
|
|
||||||
t.received /= 1_073_741_824;
|
|
||||||
t.rx_unit = Some("GB".to_string());
|
|
||||||
} else if t.received > 0 {
|
|
||||||
// otherwise, convert it to MB
|
|
||||||
t.received = (t.received / 1024) / 1024;
|
|
||||||
t.rx_unit = Some("MB".to_string());
|
|
||||||
} else {
|
|
||||||
t.received = 0;
|
|
||||||
t.rx_unit = Some("MB".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if t.transmitted > 1_047_527_424 {
|
|
||||||
t.transmitted /= 1_073_741_824;
|
|
||||||
t.tx_unit = Some("GB".to_string());
|
|
||||||
} else if t.transmitted > 0 {
|
|
||||||
t.transmitted = (t.transmitted / 1024) / 1024;
|
|
||||||
t.tx_unit = Some("MB".to_string());
|
|
||||||
} else {
|
|
||||||
t.transmitted = 0;
|
|
||||||
t.tx_unit = Some("MB".to_string());
|
|
||||||
}
|
|
||||||
Some(t)
|
|
||||||
}
|
|
||||||
Err(_) => None,
|
|
||||||
};
|
|
||||||
// create a hashmap to combine wlan_list & wlan_scan without repetition
|
|
||||||
let mut wlan_networks = HashMap::new();
|
|
||||||
for ap in wlan_scan {
|
|
||||||
let ssid = ap.ssid.clone();
|
|
||||||
let rssi = ap.signal_level.clone();
|
|
||||||
// parse the string to a signed integer (for math)
|
|
||||||
let rssi_parsed = rssi.parse::<i32>().unwrap();
|
|
||||||
// perform rssi (dBm) to quality (%) conversion
|
|
||||||
let quality_percent = 2 * (rssi_parsed + 100);
|
|
||||||
let ap_detail = AccessPoint {
|
|
||||||
detail: Some(ap),
|
|
||||||
state: "Available".to_string(),
|
|
||||||
signal: Some(quality_percent),
|
|
||||||
};
|
|
||||||
wlan_networks.insert(ssid, ap_detail);
|
|
||||||
}
|
|
||||||
for network in wlan_list {
|
|
||||||
// avoid repetition by checking that ssid is not already in list
|
|
||||||
if !wlan_networks.contains_key(&network.ssid) {
|
|
||||||
let ssid = network.ssid.clone();
|
|
||||||
let net_detail = AccessPoint {
|
|
||||||
detail: None,
|
|
||||||
state: "Not in range".to_string(),
|
|
||||||
signal: None,
|
|
||||||
};
|
|
||||||
wlan_networks.insert(ssid, net_detail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkDetailContext {
|
|
||||||
back: None,
|
|
||||||
flash_name: None,
|
|
||||||
flash_msg: None,
|
|
||||||
saved_aps,
|
|
||||||
selected: None,
|
|
||||||
title: None,
|
|
||||||
wlan_ip,
|
|
||||||
wlan_networks,
|
|
||||||
wlan_rssi,
|
|
||||||
wlan_ssid,
|
|
||||||
wlan_state,
|
|
||||||
wlan_status,
|
|
||||||
wlan_traffic,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/wifi?<ssid>")]
|
#[get("/wifi?<ssid>")]
|
||||||
pub fn network_detail(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn network_detail(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// assign context through context_builder call
|
|
||||||
let mut context = NetworkDetailContext::build();
|
let mut context = NetworkDetailContext::build();
|
||||||
context.back = Some("/settings/network/wifi".to_string());
|
context.back = Some("/settings/network/wifi".to_string());
|
||||||
context.title = Some("WiFi Network".to_string());
|
context.title = Some("WiFi Network".to_string());
|
||||||
context.selected = Some(ssid.to_string());
|
context.selected = Some(ssid.to_string());
|
||||||
// check to see if there is a flash message to display
|
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
// add flash message contents to the context object
|
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
|
||||||
Template::render("settings/network/ap_details", &context)
|
Template::render("settings/network/ap_details", &context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,7 +194,7 @@ pub fn network_detail(ssid: &str, flash: Option<FlashMessage>, _auth: Authentica
|
||||||
pub fn deploy_client(_auth: Authenticated) -> Flash<Redirect> {
|
pub fn deploy_client(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
// activate the wireless client
|
// activate the wireless client
|
||||||
debug!("Activating WiFi client mode.");
|
debug!("Activating WiFi client mode.");
|
||||||
match network_client::activate_client() {
|
match network::start_iface_service(&*WLAN_IFACE) {
|
||||||
Ok(_) => Flash::success(Redirect::to("/settings/network"), "Activated WiFi client"),
|
Ok(_) => Flash::success(Redirect::to("/settings/network"), "Activated WiFi client"),
|
||||||
Err(_) => Flash::error(
|
Err(_) => Flash::error(
|
||||||
Redirect::to("/settings/network"),
|
Redirect::to("/settings/network"),
|
||||||
|
@ -576,153 +207,88 @@ pub fn deploy_client(_auth: Authenticated) -> Flash<Redirect> {
|
||||||
|
|
||||||
#[get("/wifi/add")]
|
#[get("/wifi/add")]
|
||||||
pub fn add_wifi(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn add_wifi(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// TODO: use simple context (no need to build entire NetworkContext)
|
let mut context = Context::new();
|
||||||
let mut context = NetworkContext::build();
|
context.insert("back", &Some("/settings/network".to_string()));
|
||||||
// set back icon link to network route
|
context.insert("title", &Some("Add WiFi Network".to_string()));
|
||||||
context.back = Some("/settings/network".to_string());
|
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
// add flash message contents to the context object
|
// add flash message contents to the context object
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.insert("flash_name", &Some(flash.kind().to_string()));
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.insert("flash_msg", &Some(flash.message().to_string()));
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
|
||||||
Template::render("settings/network/add_ap", &context)
|
|
||||||
}
|
|
||||||
|
|
||||||
// used in /settings/network/wifi/add?<ssid>
|
Template::render("settings/network/add_ap", &context.into_json())
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct NetworkAddContext {
|
|
||||||
pub back: Option<String>,
|
|
||||||
pub flash_name: Option<String>,
|
|
||||||
pub flash_msg: Option<String>,
|
|
||||||
pub selected: Option<String>,
|
|
||||||
pub title: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkAddContext {
|
|
||||||
pub fn build() -> NetworkAddContext {
|
|
||||||
NetworkAddContext {
|
|
||||||
back: None,
|
|
||||||
flash_name: None,
|
|
||||||
flash_msg: None,
|
|
||||||
selected: None,
|
|
||||||
title: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/wifi/add?<ssid>")]
|
#[get("/wifi/add?<ssid>")]
|
||||||
pub fn add_ssid(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn add_ssid(ssid: &str, flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = NetworkAddContext::build();
|
let mut context = Context::new();
|
||||||
context.back = Some("/settings/network/wifi".to_string());
|
context.insert("back", &Some("/settings/network".to_string()));
|
||||||
context.selected = Some(ssid.to_string());
|
context.insert("title", &Some("Add WiFi Network".to_string()));
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
context.insert("selected", &Some(ssid.to_string()));
|
||||||
|
|
||||||
// check to see if there is a flash message to display
|
// check to see if there is a flash message to display
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
// add flash message contents to the context object
|
// add flash message contents to the context object
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.insert("flash_name", &Some(flash.kind().to_string()));
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.insert("flash_msg", &Some(flash.message().to_string()));
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
|
||||||
Template::render("settings/network/add_ap", &context)
|
Template::render("settings/network/add_ap", &context.into_json())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/wifi/add", data = "<wifi>")]
|
#[post("/wifi/add", data = "<wifi>")]
|
||||||
pub fn add_credentials(wifi: Form<WiFi>, _auth: Authenticated) -> Template {
|
pub fn add_credentials(wifi: Form<WiFi>, _auth: Authenticated) -> Template {
|
||||||
|
let mut context = Context::new();
|
||||||
|
context.insert("back", &Some("/settings/network".to_string()));
|
||||||
|
context.insert("title", &Some("Add WiFi Network".to_string()));
|
||||||
|
|
||||||
// check if the credentials already exist for this access point
|
// check if the credentials already exist for this access point
|
||||||
// note: this is nicer but it's an unstable feature:
|
// note: this is nicer but it's an unstable feature:
|
||||||
// if check_saved_aps(&wifi.ssid).contains(true)
|
// if check_saved_aps(&wifi.ssid).contains(true)
|
||||||
// use unwrap_or instead, set value to false if err is returned
|
// use unwrap_or instead, set value to false if err is returned
|
||||||
let creds_exist = network_client::saved_ap(&wifi.ssid).unwrap_or(false);
|
//let creds_exist = network::saved_networks(&wifi.ssid).unwrap_or(false);
|
||||||
if creds_exist {
|
let creds_exist = match network::saved_networks() {
|
||||||
let mut context = NetworkAddContext::build();
|
Ok(Some(networks)) => networks.contains(&wifi.ssid),
|
||||||
context.back = Some("/settings/network".to_string());
|
_ => false,
|
||||||
context.flash_name = Some("error".to_string());
|
|
||||||
context.flash_msg =
|
|
||||||
Some("Network credentials already exist for this access point".to_string());
|
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
|
||||||
// return early from handler with "creds already exist" message
|
|
||||||
return Template::render("settings/network/add_ap", &context);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// if credentials not found, generate and write wifi config to wpa_supplicant
|
// if credentials not found, generate and write wifi config to wpa_supplicant
|
||||||
match network_client::add(&wifi.ssid, &wifi.pass) {
|
let (flash_name, flash_msg) = if creds_exist {
|
||||||
Ok(_) => {
|
(
|
||||||
debug!("Added WiFi credentials.");
|
"error".to_string(),
|
||||||
// force reread of wpa_supplicant.conf file with new credentials
|
"Network credentials already exist for this access point".to_string(),
|
||||||
match network_client::reconfigure() {
|
)
|
||||||
Ok(_) => debug!("Successfully reconfigured wpa_supplicant"),
|
} else {
|
||||||
Err(_) => warn!("Failed to reconfigure wpa_supplicant"),
|
match network::add(&*WLAN_IFACE, &wifi.ssid, &wifi.pass) {
|
||||||
|
Ok(_) => {
|
||||||
|
debug!("Added WiFi credentials.");
|
||||||
|
// force reread of wpa_supplicant.conf file with new credentials
|
||||||
|
match network::reconfigure() {
|
||||||
|
Ok(_) => debug!("Successfully reconfigured wpa_supplicant"),
|
||||||
|
Err(_) => warn!("Failed to reconfigure wpa_supplicant"),
|
||||||
|
}
|
||||||
|
("success".to_string(), "Added WiFi credentials".to_string())
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
debug!("Failed to add WiFi credentials.");
|
||||||
|
(
|
||||||
|
"error".to_string(),
|
||||||
|
"Failed to add WiFi credentials".to_string(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
let mut context = NetworkAddContext::build();
|
|
||||||
context.back = Some("/settings/network".to_string());
|
|
||||||
context.flash_name = Some("success".to_string());
|
|
||||||
context.flash_msg = Some("Added WiFi credentials".to_string());
|
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
|
||||||
Template::render("settings/network/add_ap", &context)
|
|
||||||
}
|
}
|
||||||
Err(_) => {
|
};
|
||||||
debug!("Failed to add WiFi credentials.");
|
|
||||||
let mut context = NetworkAddContext::build();
|
context.insert("flash_name", &Some(flash_name));
|
||||||
context.back = Some("/settings/network".to_string());
|
context.insert("flash_msg", &Some(flash_msg));
|
||||||
context.flash_name = Some("error".to_string());
|
|
||||||
context.flash_msg = Some("Failed to add WiFi credentials".to_string());
|
Template::render("settings/network/add_ap", &context.into_json())
|
||||||
context.title = Some("Add WiFi Network".to_string());
|
|
||||||
Template::render("settings/network/add_ap", &context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR WIFI USAGE
|
// HELPERS AND ROUTES FOR WIFI USAGE
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct NetworkAlertContext {
|
|
||||||
pub alert: Alert,
|
|
||||||
pub back: Option<String>,
|
|
||||||
pub data_total: Data, // combined stored and current wifi traffic in bytes
|
|
||||||
pub flash_name: Option<String>,
|
|
||||||
pub flash_msg: Option<String>,
|
|
||||||
pub threshold: Threshold,
|
|
||||||
pub title: Option<String>,
|
|
||||||
pub traffic: Traffic, // current wifi traffic in bytes (since boot)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkAlertContext {
|
|
||||||
pub fn build() -> NetworkAlertContext {
|
|
||||||
let alert = monitor::get_alerts().unwrap();
|
|
||||||
// stored wifi data values as bytes
|
|
||||||
let stored_traffic = monitor::get_data().unwrap();
|
|
||||||
let threshold = monitor::get_thresholds().unwrap();
|
|
||||||
// current wifi traffic values as bytes
|
|
||||||
let traffic = match network_client::traffic("wlan0") {
|
|
||||||
Ok(t) => t,
|
|
||||||
Err(_) => Traffic {
|
|
||||||
received: 0,
|
|
||||||
transmitted: 0,
|
|
||||||
rx_unit: None,
|
|
||||||
tx_unit: None,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let current_traffic = traffic.received + traffic.transmitted;
|
|
||||||
let total = stored_traffic.total + current_traffic;
|
|
||||||
let data_total = Data { total };
|
|
||||||
|
|
||||||
NetworkAlertContext {
|
|
||||||
alert,
|
|
||||||
back: None,
|
|
||||||
data_total,
|
|
||||||
flash_name: None,
|
|
||||||
flash_msg: None,
|
|
||||||
threshold,
|
|
||||||
title: None,
|
|
||||||
traffic,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/wifi/usage")]
|
#[get("/wifi/usage")]
|
||||||
pub fn wifi_usage(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn wifi_usage(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
let mut context = NetworkAlertContext::build();
|
let mut context = NetworkAlertContext::build();
|
||||||
|
|
|
@ -1,162 +1,21 @@
|
||||||
use rocket::{get, request::FlashMessage};
|
use rocket::{get, request::FlashMessage};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use peach_network::{
|
|
||||||
network,
|
|
||||||
network::{Status, Traffic},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
use crate::context::network::NetworkStatusContext;
|
||||||
use crate::routes::authentication::Authenticated;
|
use crate::routes::authentication::Authenticated;
|
||||||
|
|
||||||
// HELPERS AND ROUTES FOR /status/network
|
// HELPERS AND ROUTES FOR /status/network
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct IfaceTraffic {
|
|
||||||
pub rx: u64,
|
|
||||||
pub rx_unit: Option<String>,
|
|
||||||
pub tx: u64,
|
|
||||||
pub tx_unit: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IfaceTraffic {
|
|
||||||
fn default() -> Self {
|
|
||||||
IfaceTraffic {
|
|
||||||
rx: 0,
|
|
||||||
rx_unit: None,
|
|
||||||
tx: 0,
|
|
||||||
tx_unit: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn convert_traffic(traffic: Traffic) -> Option<IfaceTraffic> {
|
|
||||||
let mut t = IfaceTraffic::default();
|
|
||||||
// modify traffic values & assign measurement units
|
|
||||||
// based on received and transmitted values.
|
|
||||||
// if received > 999 MB, convert it to GB
|
|
||||||
if traffic.received > 1_047_527_424 {
|
|
||||||
t.rx = traffic.received / 1_073_741_824;
|
|
||||||
t.rx_unit = Some("GB".to_string());
|
|
||||||
} else if traffic.received > 0 {
|
|
||||||
// otherwise, convert it to MB
|
|
||||||
t.rx = (traffic.received / 1024) / 1024;
|
|
||||||
t.rx_unit = Some("MB".to_string());
|
|
||||||
} else {
|
|
||||||
t.rx = 0;
|
|
||||||
t.rx_unit = Some("MB".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if traffic.transmitted > 1_047_527_424 {
|
|
||||||
t.tx = traffic.transmitted / 1_073_741_824;
|
|
||||||
t.tx_unit = Some("GB".to_string());
|
|
||||||
} else if traffic.transmitted > 0 {
|
|
||||||
t.tx = (traffic.transmitted / 1024) / 1024;
|
|
||||||
t.tx_unit = Some("MB".to_string());
|
|
||||||
} else {
|
|
||||||
t.tx = 0;
|
|
||||||
t.tx_unit = Some("MB".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
pub struct NetworkContext {
|
|
||||||
pub ap_ip: String,
|
|
||||||
pub ap_ssid: String,
|
|
||||||
pub ap_state: String,
|
|
||||||
pub ap_traffic: Option<IfaceTraffic>,
|
|
||||||
pub wlan_ip: String,
|
|
||||||
pub wlan_rssi: Option<String>,
|
|
||||||
pub wlan_ssid: String,
|
|
||||||
pub wlan_state: String,
|
|
||||||
pub wlan_status: Option<Status>,
|
|
||||||
pub wlan_traffic: Option<IfaceTraffic>,
|
|
||||||
pub flash_name: Option<String>,
|
|
||||||
pub flash_msg: Option<String>,
|
|
||||||
// page title for header in navbar
|
|
||||||
pub title: Option<String>,
|
|
||||||
// url for back-arrow link
|
|
||||||
pub back: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkContext {
|
|
||||||
pub fn build() -> NetworkContext {
|
|
||||||
let ap_ip = match network::ip("ap0") {
|
|
||||||
Ok(Some(ip)) => ip,
|
|
||||||
_ => "x.x.x.x".to_string(),
|
|
||||||
};
|
|
||||||
let ap_ssid = match network::ssid("ap0") {
|
|
||||||
Ok(Some(ssid)) => ssid,
|
|
||||||
_ => "Not currently activated".to_string(),
|
|
||||||
};
|
|
||||||
let ap_state = match network::state("ap0") {
|
|
||||||
Ok(Some(state)) => state,
|
|
||||||
_ => "Interface unavailable".to_string(),
|
|
||||||
};
|
|
||||||
let ap_traffic = match network::traffic("ap0") {
|
|
||||||
// convert bytes to mb or gb and add appropriate units
|
|
||||||
Ok(Some(traffic)) => convert_traffic(traffic),
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
let wlan_ip = match network::ip("wlan0") {
|
|
||||||
Ok(Some(ip)) => ip,
|
|
||||||
_ => "x.x.x.x".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_rssi = match network::rssi_percent("wlan0") {
|
|
||||||
Ok(rssi) => rssi,
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
let wlan_ssid = match network::ssid("wlan0") {
|
|
||||||
Ok(Some(ssid)) => ssid,
|
|
||||||
_ => "Not connected".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_state = match network::state("wlan0") {
|
|
||||||
Ok(Some(state)) => state,
|
|
||||||
_ => "Interface unavailable".to_string(),
|
|
||||||
};
|
|
||||||
let wlan_status = match network::status("wlan0") {
|
|
||||||
Ok(status) => status,
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
let wlan_traffic = match network::traffic("wlan0") {
|
|
||||||
// convert bytes to mb or gb and add appropriate units
|
|
||||||
Ok(Some(traffic)) => convert_traffic(traffic),
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
NetworkContext {
|
|
||||||
ap_ip,
|
|
||||||
ap_ssid,
|
|
||||||
ap_state,
|
|
||||||
ap_traffic,
|
|
||||||
wlan_ip,
|
|
||||||
wlan_rssi,
|
|
||||||
wlan_ssid,
|
|
||||||
wlan_state,
|
|
||||||
wlan_status,
|
|
||||||
wlan_traffic,
|
|
||||||
flash_name: None,
|
|
||||||
flash_msg: None,
|
|
||||||
title: None,
|
|
||||||
back: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/network")]
|
#[get("/network")]
|
||||||
pub fn network_status(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
pub fn network_status(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
|
||||||
// assign context through context_builder call
|
let mut context = NetworkStatusContext::build();
|
||||||
let mut context = NetworkContext::build();
|
|
||||||
context.back = Some("/status".to_string());
|
context.back = Some("/status".to_string());
|
||||||
context.title = Some("Network Status".to_string());
|
context.title = Some("Network Status".to_string());
|
||||||
// check to see if there is a flash message to display
|
|
||||||
if let Some(flash) = flash {
|
if let Some(flash) = flash {
|
||||||
// add flash message contents to the context object
|
|
||||||
context.flash_name = Some(flash.kind().to_string());
|
context.flash_name = Some(flash.kind().to_string());
|
||||||
context.flash_msg = Some(flash.message().to_string());
|
context.flash_msg = Some(flash.message().to_string());
|
||||||
};
|
};
|
||||||
// template_dir is set in Rocket.toml
|
|
||||||
Template::render("status/network", &context)
|
Template::render("status/network", &context)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue