From ca7c46e535ac60a976a8c60477fa9424c46b6e3f Mon Sep 17 00:00:00 2001 From: alyx Date: Fri, 5 Apr 2024 13:30:39 -0400 Subject: lua loading --- Cargo.toml | 2 +- src/config.rs | 6 +++-- src/theming/hbs.rs | 2 +- src/theming/lua.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 66 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4d73c1e..69a8430 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ env_logger = "0.10.0" handlebars = { version = "4.3.7", features = ["dir_source"] } http = "0.2.9" log = "0.4.19" -mlua = { version = "0.9.6", features = ["serialize", "send", "luau", "async"] } +mlua = { version = "0.9.7", features = ["serialize", "send", "luau", "async", "unstable"] } reqwest = { version = "0.11.18", features = ["gzip", "deflate", "brotli", "json"] } serde = { version = "1.0.183", features = ["derive", "rc", "alloc"] } serde_json = "1.0.104" diff --git a/src/config.rs b/src/config.rs index 350786d..008eb7a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -21,7 +21,8 @@ pub struct Config { pub(crate) default_theme: Arc, pub(crate) theme_dir: Option>, - pub(crate) theme_ext: Arc, + pub(crate) theme_ext_hbs: Arc, + pub(crate) theme_ext_lua: Arc, pub(crate) theme_debug: bool, pub(crate) allowlist: BTreeSet, @@ -45,7 +46,8 @@ impl Config { default_theme: var("LFME_THEME_DEFAULT").map(Into::into).unwrap_or_else(|_| "plain".into()), theme_dir: var("LFME_THEME_DIR").ok().map(Into::into), - theme_ext: var("LFME_THEME_EXT").unwrap_or_else(|_| ".hbs".into()).into(), + theme_ext_hbs: var("LFME_THEME_EXT_HBS").unwrap_or_else(|_| ".hbs".into()).into(), + theme_ext_lua: var("LFME_THEME_EXT_LUA").unwrap_or_else(|_| ".lua".into()).into(), theme_debug: var("LFME_THEME_DEV").map(|h| &h == "1").unwrap_or(false), allowlist: var("LFME_WHITELIST").or_else(|_| var("LFME_ALLOWLIST")).ok().map(|w| w.split(',').map(|s| s.trim().to_string()).collect()).unwrap_or_default(), diff --git a/src/theming/hbs.rs b/src/theming/hbs.rs index 6da8385..e5da0cd 100644 --- a/src/theming/hbs.rs +++ b/src/theming/hbs.rs @@ -22,7 +22,7 @@ static HANDLEBARS: LazyLock = LazyLock::new(|| { if let Some(themes_dir) = CONFIG.theme_dir.as_ref() { log::info!("Registering theme dir `{themes_dir}`"); - hb.register_templates_directory(&CONFIG.theme_ext, themes_dir.as_ref()).unwrap(); + hb.register_templates_directory(&CONFIG.theme_ext_hbs, themes_dir.as_ref()).unwrap(); } hb diff --git a/src/theming/lua.rs b/src/theming/lua.rs index 22ad4d6..c9168cb 100644 --- a/src/theming/lua.rs +++ b/src/theming/lua.rs @@ -1,13 +1,16 @@ // SPDX-License-Identifier: AGPL-3.0-only use std::sync::LazyLock; -use std::collections::BTreeMap; use std::ops::Deref; +use std::path::Path; use tokio::sync::Mutex; -use mlua::*; +use mlua::{Lua, Compiler, StdLib, Value, LuaOptions}; +use http::StatusCode; use crate::CONFIG; +static INTERNAL_THEMES: &[(&str, &str)] = &[]; + static LUA: LazyLock> = LazyLock::new(|| { let stdlib = StdLib::TABLE | StdLib::STRING | StdLib::UTF8 | StdLib::BIT | StdLib::MATH; let lua = Lua::new_with(stdlib, LuaOptions::new().thread_pool_size(2)).expect("lua initialization"); @@ -23,13 +26,66 @@ static LUA: LazyLock> = LazyLock::new(|| { .set_compiler(Compiler::new().set_optimization_level(2).set_debug_level(1)) .eval() .expect("expect.lua loading"); - lua.globals().set("expect", expect); + lua.globals().set("expect", expect).unwrap(); let html: Value = lua.load(include_str!("lua-lib/html.lua")) .set_compiler(Compiler::new().set_optimization_level(2).set_debug_level(1)) .eval() .expect("html.lua loading"); - lua.globals().set("html", html); + lua.globals().set("html", html).unwrap(); + + let themes = lua.create_table().expect("creating themes table"); + + for (k, v) in INTERNAL_THEMES { + let _ = themes.set(*k, lua.load(*v).into_function().expect("loading internal theme")); + } + + if let Some(theme_dir) = CONFIG.theme_dir.as_ref() { + for (k, v) in walk_dir(theme_dir.as_ref().as_ref()).expect("walking theme dir") { + let _ = themes.set(k, lua.load(v).into_function().expect("loading internal theme")); + } + } + + let _ = lua.globals().set("__themes", themes).unwrap(); + + lua.globals().set_readonly(true); Mutex::new(lua) }); + +fn walk_dir(path: &Path) -> std::io::Result> { + use std::fs; + + let mut path_bits = vec![]; + let mut dir_readers = vec![fs::read_dir(path)?]; + + let mut ret = vec![]; + + while let Some(r) = dir_readers.iter_mut().last() { + if let Some(ent) = r.next() { + let ent = ent?; + let name = ent.file_name().into_string().expect("why do you have such FUCKED UP FILE PATHS"); + let ty = ent.file_type()?; + if ty.is_file() && name.ends_with(CONFIG.theme_ext_lua.as_ref()) { + ret.push((path_bits.join("") + &name, fs::read_to_string(ent.path())?)); + } + else if ty.is_dir() { + path_bits.push(name); + dir_readers.push(fs::read_dir(ent.path())?); + } + } + else { + dir_readers.pop(); + } + } + + Ok(ret) +} + +pub fn touch() { + let _ = LUA.deref(); +} + +pub fn render_theme(name: &str, ctx: &crate::ctx::Ctx) -> Option> { + return None +} -- cgit v1.2.3-54-g00ecf