aboutsummaryrefslogtreecommitdiffstats
path: root/src/theming
diff options
context:
space:
mode:
Diffstat (limited to 'src/theming')
-rw-r--r--src/theming/hbs.rs6
-rw-r--r--src/theming/lua.rs45
2 files changed, 40 insertions, 11 deletions
diff --git a/src/theming/hbs.rs b/src/theming/hbs.rs
index 67a2ae4..398715a 100644
--- a/src/theming/hbs.rs
+++ b/src/theming/hbs.rs
@@ -18,7 +18,7 @@ static HANDLEBARS: LazyLock<Handlebars> = LazyLock::new(|| {
log::info!("Registering internal handlebars theme `{key}`");
hb.register_template_string(key, fulltext).unwrap();
}
- hb.set_dev_mode(CONFIG.theme_debug);
+ hb.set_dev_mode(CONFIG.theme_dev);
if let Some(themes_dir) = CONFIG.theme_dir.as_ref() {
log::info!("Registering handlebars theme dir `{themes_dir}` with extension `{}`.", CONFIG.theme_ext_hbs);
@@ -34,3 +34,7 @@ pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option<Result<String,
let render = templ.renders(&HANDLEBARS, &ctx, &mut RenderContext::new(Some(&name.into()))).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR);
Some(render)
}
+
+pub fn touch() {
+ LazyLock::force(&HANDLEBARS);
+}
diff --git a/src/theming/lua.rs b/src/theming/lua.rs
index 6bd6989..0699f09 100644
--- a/src/theming/lua.rs
+++ b/src/theming/lua.rs
@@ -18,7 +18,7 @@ static LUA: LazyLock<Mutex<Lua>> = LazyLock::new(|| {
lua.sandbox(true).expect("lua initialization");
lua.set_compiler(
- if CONFIG.theme_debug { Compiler::new().set_optimization_level(0).set_debug_level(2) }
+ if CONFIG.theme_dev { Compiler::new().set_optimization_level(0).set_debug_level(2) }
else { Compiler::new().set_optimization_level(2).set_debug_level(1) }
);
@@ -38,14 +38,19 @@ static LUA: LazyLock<Mutex<Lua>> = LazyLock::new(|| {
for (k, v) in INTERNAL_THEMES {
log::info!("Registering compiled lua theme `{k}`.");
- let _ = themes.set(*k, lua.load(*v).into_function().expect("loading internal theme"));
+ let _ = themes.set(*k, lua.load(*v).eval::<Value>().expect("loading internal theme"));
}
if let Some(theme_dir) = CONFIG.theme_dir.as_ref() {
- log::info!("Registering lua theme dir `{theme_dir}` with extension `{}`.", CONFIG.theme_ext_lua);
- for (k, v) in walk_dir(theme_dir.as_ref().as_ref()).expect("walking theme dir") {
- log::info!("Registering runtime lua theme `{k}`.");
- let _ = themes.set(k, lua.load(v).eval::<Value>().expect("loading internal theme"));
+ if !CONFIG.theme_dev {
+ log::info!("Registering lua theme dir `{theme_dir}` with extension `{}`.", CONFIG.theme_ext_lua);
+ for (k, v) in walk_dir(theme_dir.as_ref().as_ref()).expect("walking theme dir") {
+ log::info!("Registering runtime lua theme `{k}`.");
+ let _ = themes.set(k, lua.load(v).eval::<Value>().expect("loading external theme"));
+ }
+ }
+ else {
+ log::info!("Ready to dev-load lua themes from `{theme_dir}` with extension `{}`.", CONFIG.theme_ext_lua);
}
}
@@ -86,13 +91,29 @@ fn walk_dir(path: &Path) -> std::io::Result<Vec<(String, String)>> {
}
pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option<Result<String, StatusCode>> {
+ if name == ".." || name.starts_with("../") || name.ends_with("/..") || name.contains("/../") {
+ return Some(Err(StatusCode::BAD_REQUEST))
+ }
+
LUA.clear_poison();
let lua = LUA.lock().expect("FIXME: Mutex poisoning race condition.");
let themes: Table = lua.globals().get("__themes").unwrap();
- let Ok(Value::Function(theme)) = themes.get(name)
- else {
- return None;
- };
+ let theme;
+ match themes.get(name) {
+ Ok(Value::Function(themefn)) => { theme = themefn; },
+ Ok(Value::Nil) if !CONFIG.theme_dev || CONFIG.theme_dir.is_none() => { return None; },
+ Ok(Value::Nil) => {
+ let code = fs::read_to_string(CONFIG.theme_dir.as_ref().unwrap().to_string() + "/" + name + &CONFIG.theme_ext_lua).ok()?;
+ let res = lua.load(code).eval::<Value>();
+ match res {
+ Ok(Value::Function(themefn)) => { theme = themefn; },
+ Ok(v) => { log::error!("Got `{v:?}` instead of Function when dev-loading `{name}`."); return Some(Err(StatusCode::INTERNAL_SERVER_ERROR)); },
+ Err(e) => { log::error!("Error dev-loading `{name}`: {e}"); return Some(Err(StatusCode::INTERNAL_SERVER_ERROR)); },
+ }
+ },
+ Ok(v) => { log::error!("Got `{v:?}` instead of Function when loading `{name}`."); return Some(Err(StatusCode::INTERNAL_SERVER_ERROR)); }
+ Err(e) => { log::error!("Error loading `{name}`: {e}"); return Some(Err(StatusCode::INTERNAL_SERVER_ERROR)); }, //TODO: gate behind flag
+ }
let ctx = match lua.to_value(ctx) {
Ok(ok) => ok,
@@ -104,3 +125,7 @@ pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option<Result<String,
Some(theme.call((ctx,)).map_err(|e| { log::error!("Lua theme execution error: {e}"); StatusCode::INTERNAL_SERVER_ERROR }))
}
+
+pub fn touch() {
+ LazyLock::force(&LUA);
+}