Skip to content

Commit 8bf4cb3

Browse files
feat: add custom visualization support (custom_static) (#301)
Co-authored-by: Erik Bjäreholt <[email protected]>
1 parent 1b9aa1b commit 8bf4cb3

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

aw-server/src/config.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
88

99
use crate::dirs;
1010

11-
/* Far from an optimal way to solve it, but works and is simple */
11+
// Far from an optimal way to solve it, but works and is simple
1212
static mut TESTING: bool = true;
1313
pub fn set_testing(testing: bool) {
1414
unsafe {
@@ -23,12 +23,20 @@ pub fn is_testing() -> bool {
2323
pub struct AWConfig {
2424
#[serde(default = "default_address")]
2525
pub address: String,
26+
2627
#[serde(default = "default_port")]
2728
pub port: u16,
29+
2830
#[serde(skip, default = "default_testing")]
2931
pub testing: bool, // This is not written to the config file (serde(skip))
32+
3033
#[serde(default = "default_cors")]
3134
pub cors: Vec<String>,
35+
36+
// A mapping of watcher names to paths where the
37+
// custom visualizations are located.
38+
#[serde(default = "default_custom_static")]
39+
pub custom_static: std::collections::HashMap<String, String>,
3240
}
3341

3442
impl Default for AWConfig {
@@ -38,6 +46,7 @@ impl Default for AWConfig {
3846
port: default_port(),
3947
testing: default_testing(),
4048
cors: default_cors(),
49+
custom_static: default_custom_static(),
4150
}
4251
}
4352
}
@@ -86,6 +95,10 @@ fn default_port() -> u16 {
8695
}
8796
}
8897

98+
fn default_custom_static() -> std::collections::HashMap<String, String> {
99+
std::collections::HashMap::new()
100+
}
101+
89102
pub fn create_config(testing: bool) -> AWConfig {
90103
set_testing(testing);
91104
let mut config_path = dirs::get_config_dir().unwrap();

aw-server/src/endpoints/mod.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ use std::path::PathBuf;
22
use std::sync::Mutex;
33

44
use gethostname::gethostname;
5+
use rocket::fs::FileServer;
56
use rocket::fs::NamedFile;
67
use rocket::serde::json::Json;
78
use rocket::State;
89

910
use crate::config::AWConfig;
11+
use crate::dirs;
1012

1113
use aw_datastore::Datastore;
1214
use aw_models::Info;
@@ -92,7 +94,9 @@ pub fn build_rocket(server_state: ServerState, config: AWConfig) -> rocket::Rock
9294
);
9395
let cors = cors::cors(&config);
9496
let hostcheck = hostcheck::HostCheck::new(&config);
95-
rocket::custom(config.to_rocket_config())
97+
let custom_static = config.custom_static.clone();
98+
99+
let mut rocket = rocket::custom(config.to_rocket_config())
96100
.attach(cors.clone())
97101
.attach(hostcheck)
98102
.manage(cors)
@@ -141,5 +145,15 @@ pub fn build_rocket(server_state: ServerState, config: AWConfig) -> rocket::Rock
141145
settings::setting_delete
142146
],
143147
)
144-
.mount("/", rocket_cors::catch_all_options_routes())
148+
.mount("/", rocket_cors::catch_all_options_routes());
149+
150+
// for each custom static directory, mount it at the given name
151+
for (name, dir) in custom_static {
152+
info!(
153+
"Serving /pages/{} custom static directory from {}",
154+
name, dir
155+
);
156+
rocket = rocket.mount(&format!("/pages/{}", name), FileServer::from(dir));
157+
}
158+
rocket
145159
}

aw-server/src/main.rs

+27
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ struct Opts {
3939
#[clap(long)]
4040
webpath: Option<String>,
4141

42+
/// Mapping of custom static paths to serve, in the format: watcher1=/path,watcher2=/path2
43+
#[clap(long)]
44+
custom_static: Option<String>,
45+
4246
/// Device ID override
4347
#[clap(long)]
4448
device_id: Option<String>,
@@ -79,6 +83,29 @@ async fn main() -> Result<(), rocket::Error> {
7983
config.port = port.parse().unwrap();
8084
}
8185

86+
// set custom_static if overridden, transform into map
87+
if let Some(custom_static_str) = opts.custom_static {
88+
let custom_static_map: std::collections::HashMap<String, String> = custom_static_str
89+
.split(',')
90+
.map(|s| {
91+
let mut split = s.split('=');
92+
let key = split.next().unwrap().to_string();
93+
let value = split.next().unwrap().to_string();
94+
(key, value)
95+
})
96+
.collect();
97+
config.custom_static.extend(custom_static_map);
98+
99+
// validate paths, log error if invalid
100+
// remove invalid paths
101+
for (name, path) in config.custom_static.clone().iter() {
102+
if !std::path::Path::new(path).exists() {
103+
error!("custom_static path for {} does not exist ({})", name, path);
104+
config.custom_static.remove(name);
105+
}
106+
}
107+
}
108+
82109
// Set db path if overridden
83110
let db_path: String = if let Some(dbpath) = opts.dbpath.clone() {
84111
dbpath

0 commit comments

Comments
 (0)