From eebe848e4b7b6cbbaaa7ade18a05b02980615479 Mon Sep 17 00:00:00 2001 From: didier amyot Date: Thu, 9 Mar 2023 10:02:14 -0500 Subject: [PATCH] moved template logic into own module. --- src/db/_ledger_internal.rs | 3 +- src/main.rs | 9 ++---- src/services/_authentication.rs | 2 +- src/services/_users.rs | 2 +- src/services/mod.rs | 2 +- src/webui/index_views.rs | 16 +++++----- src/webui/mod.rs | 53 +++++---------------------------- src/webui/services.rs | 4 +-- src/webui/templates.rs | 36 ++++++++++++++++++++++ src/webui/views.rs | 9 +++--- src/webui/worker.rs | 8 ++--- 11 files changed, 68 insertions(+), 76 deletions(-) create mode 100644 src/webui/templates.rs diff --git a/src/db/_ledger_internal.rs b/src/db/_ledger_internal.rs index 26f9004..0c37fbc 100644 --- a/src/db/_ledger_internal.rs +++ b/src/db/_ledger_internal.rs @@ -1,6 +1,6 @@ use crate::util::{CustomResult, Error}; use base64::{engine::general_purpose, Engine as _}; -use rusqlite::{params, Connection, Result, Row, Transaction}; +use rusqlite::{params, Result, Row, Transaction}; pub struct LedgerInternal {} @@ -49,6 +49,7 @@ impl LedgerInternal { mod test_ledger_internal { use super::*; use crate::migration; + use rusqlite::Connection; #[test] fn test_initial_cookie_secret() -> CustomResult<()> { diff --git a/src/main.rs b/src/main.rs index e5ed0ed..633c266 100644 --- a/src/main.rs +++ b/src/main.rs @@ -436,7 +436,6 @@ mod cli_test { "123abc", ]); let mut logic = TestCommandLineLogic::new(); - let mut conn = Connection::open_in_memory().unwrap(); process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?; assert_eq!(logic.create_user_count, 1); Ok(()) @@ -447,7 +446,6 @@ mod cli_test { let cmd = command_line_parser(); let m = cmd.get_matches_from(vec!["test", "users", "ls"]); let mut logic = TestCommandLineLogic::new(); - let mut conn = Connection::open_in_memory().unwrap(); process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?; assert_eq!(logic.list_user_count, 1); Ok(()) @@ -458,7 +456,6 @@ mod cli_test { let cmd = command_line_parser(); let m = cmd.get_matches_from(vec!["test", "securities", "ls"]); let mut logic = TestCommandLineLogic::new(); - let mut conn = Connection::open_in_memory().unwrap(); process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?; assert_eq!(logic.list_securities_count, 1); Ok(()) @@ -469,7 +466,6 @@ mod cli_test { let cmd = command_line_parser(); let m = cmd.get_matches_from(vec!["test", "events", "process", "/dev/null"]); let mut logic = TestCommandLineLogic::new(); - let mut conn = Connection::open_in_memory().unwrap(); process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?; assert_eq!(logic.process_events_count, 1); Ok(()) @@ -480,7 +476,6 @@ mod cli_test { let cmd = command_line_parser(); let m = cmd.get_matches_from(vec!["test", "wui", "run"]); let mut logic = TestCommandLineLogic::new(); - let mut conn = Connection::open_in_memory().unwrap(); process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?; assert_eq!(logic.run_webui_count, 1); Ok(()) @@ -523,8 +518,8 @@ impl CommandLineUserLogic for ProCommandLineLogic { fn process_events( &mut self, - conn: &mut Connection, - files: ValuesRef, + _conn: &mut Connection, + _files: ValuesRef, ) -> CustomResult<()> { // process_event_files(conn, files) Ok(()) diff --git a/src/services/_authentication.rs b/src/services/_authentication.rs index f2a3244..9a1a39b 100644 --- a/src/services/_authentication.rs +++ b/src/services/_authentication.rs @@ -29,7 +29,7 @@ impl SessionService { } fn _decrypt_cookie(&self, cookie: Cookie<'static>) -> Option { - let mut jar = CookieJar::new(); + let jar = CookieJar::new(); jar.private(&self.key).decrypt(cookie) } diff --git a/src/services/_users.rs b/src/services/_users.rs index 452ab20..0296937 100644 --- a/src/services/_users.rs +++ b/src/services/_users.rs @@ -2,7 +2,7 @@ use rusqlite::Connection; use serde::Deserialize; use serde::Serialize; -use crate::db::external_id::UserId; + use crate::db::users::{list_users, User}; use crate::util::CustomResult; diff --git a/src/services/mod.rs b/src/services/mod.rs index 9404c68..64f35ec 100644 --- a/src/services/mod.rs +++ b/src/services/mod.rs @@ -1,4 +1,4 @@ -use crate::{CustomResult, Error}; +use crate::{CustomResult}; use rusqlite::Connection; pub use crate::services::_authentication::SessionService; diff --git a/src/webui/index_views.rs b/src/webui/index_views.rs index 2bafbe0..6e9f905 100644 --- a/src/webui/index_views.rs +++ b/src/webui/index_views.rs @@ -1,18 +1,18 @@ use actix_web::{web, HttpRequest, Responder}; -use cookie::time::macros::datetime; -use cookie::time::OffsetDateTime; -use cookie::{Cookie, CookieJar, Key}; -use std::time::Instant; -use crate::db::external_id::UserId; + + + + + use crate::services::ReadOnlyServiceFactory; -use crate::webui::MiniJinjaRenderer; +use crate::webui::templates::MiniJinjaRenderer; use crate::SQLiteConnectionFactory; use minijinja::context; use serde::Deserialize; #[derive(Deserialize, Debug)] -struct LoginPayload { +pub struct LoginPayload { username: String, password: String, } @@ -30,7 +30,7 @@ pub async fn login( let ctx = context! { name => form.username, }; - let mut ret = tmpl_env + let ret = tmpl_env .render("partials/index/success.html", ctx)? .customize(); Ok(ret.insert_header(("Set-Cookie", cookie.to_string()))) diff --git a/src/webui/mod.rs b/src/webui/mod.rs index 347d0c0..ce2b912 100644 --- a/src/webui/mod.rs +++ b/src/webui/mod.rs @@ -1,65 +1,30 @@ -#![feature(future_join)] - use std::{env, path::PathBuf}; use actix_files; use actix_web::{ dev::ServiceResponse, - error, http::{header::ContentType, StatusCode}, middleware::{ErrorHandlerResponse, ErrorHandlers, Logger}, - web, App, FromRequest, HttpRequest, HttpResponse, HttpServer, Responder, Result, Scope, + web, App, FromRequest, HttpResponse, HttpServer, Responder, Result, Scope, }; -use actix_web_lab::respond::Html; + use async_channel; use futures::{pin_mut, select, FutureExt}; use minijinja; use minijinja_autoreload::AutoReloader; -use rusqlite::Connection; + use crate::events::Event; use crate::util::{CustomResult, Error, SQLiteConnectionFactory}; +use crate::webui::templates::MiniJinjaRenderer; use crate::webui::worker::event_processor_loop; mod index_views; mod services; +mod templates; mod views; mod worker; -struct MiniJinjaRenderer { - tmpl_env: web::Data, -} - -impl MiniJinjaRenderer { - fn render(&self, tmpl: &str, ctx: impl Into) -> Result { - log::info!("Rendering template {:?}", tmpl); - self.tmpl_env - .acquire_env() - .map_err(|_| error::ErrorInternalServerError("could not acquire template env"))? - .get_template(tmpl) - .map_err(|e| error::ErrorInternalServerError(format!("{:?}", e)))? - .render(ctx.into()) - .map(Html) - .map_err(|err| { - log::error!("{err}"); - error::ErrorInternalServerError("template error") - }) - } -} - -impl FromRequest for MiniJinjaRenderer { - type Error = actix_web::Error; - type Future = actix_utils::future::Ready>; - - fn from_request(req: &HttpRequest, _pl: &mut actix_web::dev::Payload) -> Self::Future { - let tmpl_env = >::extract(req) - .into_inner() - .unwrap(); - - actix_utils::future::ready(Ok(Self { tmpl_env })) - } -} - fn create_auto_reloader(enable_template_autoreload: bool) -> AutoReloader { AutoReloader::new(move |notifier| { let mut env: minijinja::Environment<'static> = minijinja::Environment::new(); @@ -102,21 +67,17 @@ pub async fn web_ui_main( port: u16, enable_template_autoreload: bool, ) -> CustomResult<()> { - // The closure is invoked every time the environment is outdated to recreate it. - let tmpl_reloader = create_auto_reloader(enable_template_autoreload); - let (event_sender, event_receiver) = async_channel::unbounded::(); - let tmpl_reloader = web::Data::new(tmpl_reloader); - // use r2d2 for connection pools (https://github.com/sfackler/r2d2 & // https://github.com/ivanceras/r2d2-sqlite) use // https://docs.rs/actix-web/4.3.1/actix_web/web/fn.block.html // in handlers. let cloned_conn_fact = conn_fact.clone(); let server = HttpServer::new(move || { + let template_reloader = create_auto_reloader(enable_template_autoreload); App::new() - .app_data(tmpl_reloader.clone()) + .app_data(web::Data::new(template_reloader)) .app_data(web::Data::new(event_sender.clone())) .app_data(web::Data::new(cloned_conn_fact.clone())) .service(create_static_scope()) diff --git a/src/webui/services.rs b/src/webui/services.rs index 95c5805..c01722b 100644 --- a/src/webui/services.rs +++ b/src/webui/services.rs @@ -1,5 +1,5 @@ -use crate::services::{ReadOnlyServiceFactory, SessionService, UserService}; -use crate::util::{CustomResult, Error, SQLiteConnectionFactory}; +use crate::services::{SessionService}; +use crate::util::{SQLiteConnectionFactory}; struct ServicesCache { session_service: SessionService, diff --git a/src/webui/templates.rs b/src/webui/templates.rs new file mode 100644 index 0000000..9b506cd --- /dev/null +++ b/src/webui/templates.rs @@ -0,0 +1,36 @@ +use actix_web::{error, web, FromRequest, HttpRequest, Result}; +use actix_web_lab::respond::Html; + +pub struct MiniJinjaRenderer { + tmpl_env: web::Data, +} + +impl MiniJinjaRenderer { + pub fn render(&self, tmpl: &str, ctx: impl Into) -> Result { + log::info!("Rendering template {:?}", tmpl); + self.tmpl_env + .acquire_env() + .map_err(|_| error::ErrorInternalServerError("could not acquire template env"))? + .get_template(tmpl) + .map_err(|e| error::ErrorInternalServerError(format!("{:?}", e)))? + .render(ctx.into()) + .map(Html) + .map_err(|err| { + log::error!("{err}"); + error::ErrorInternalServerError("template error") + }) + } +} + +impl FromRequest for MiniJinjaRenderer { + type Error = actix_web::Error; + type Future = actix_utils::future::Ready>; + + fn from_request(req: &HttpRequest, _pl: &mut actix_web::dev::Payload) -> Self::Future { + let tmpl_env = >::extract(req) + .into_inner() + .unwrap(); + + actix_utils::future::ready(Ok(Self { tmpl_env })) + } +} diff --git a/src/webui/views.rs b/src/webui/views.rs index f6533e5..8b7c832 100644 --- a/src/webui/views.rs +++ b/src/webui/views.rs @@ -1,17 +1,16 @@ use std::collections::HashMap; use actix_web::{error, web, HttpRequest, Responder}; -use actix_web_lab::__reexports::futures_util::SinkExt; -use clap::builder::TypedValueParser; + use log::info; use minijinja::context; use serde::Deserialize; -use crate::db::users::list_users; + use crate::events::Event; use crate::services::ReadOnlyServiceFactory; use crate::util::SQLiteConnectionFactory; -use crate::webui::MiniJinjaRenderer; +use crate::webui::templates::MiniJinjaRenderer; #[actix_web::get("/actions")] pub async fn actions(tmpl_env: MiniJinjaRenderer) -> actix_web::Result { @@ -67,7 +66,7 @@ pub async fn actions_partials( } #[derive(Deserialize, Debug)] -struct CreateEventPayload { +pub struct CreateEventPayload { event: Event, event_type: String, } diff --git a/src/webui/worker.rs b/src/webui/worker.rs index 8fee6ce..a158023 100644 --- a/src/webui/worker.rs +++ b/src/webui/worker.rs @@ -1,8 +1,8 @@ -use std::io; -use std::time::Duration; -use rusqlite::Connection; -use tokio::time::sleep; + + + + use crate::event_processor::process_event; use crate::events::Event;