considering tera and minijinja

This commit is contained in:
Per Stark
2024-12-18 18:24:18 +01:00
parent 291c473d00
commit fa6283485c
22 changed files with 1211 additions and 2125 deletions

View File

@@ -7,7 +7,9 @@ use axum::{
use axum_session::{SessionConfig, SessionLayer, SessionStore};
use axum_session_auth::{AuthConfig, AuthSessionLayer};
use axum_session_surreal::SessionSurrealPool;
use std::sync::Arc;
use minijinja::{path_loader, Environment};
use minijinja_autoreload::AutoReloader;
use std::{path::PathBuf, sync::Arc};
use surrealdb::{engine::any::Any, Surreal};
use tera::Tera;
use tower_http::services::ServeDir;
@@ -48,12 +50,23 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
routing_key: "my_key".to_string(),
};
let reloader = AutoReloader::new(move |notifier| {
let template_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("templates");
let mut env = Environment::new();
env.set_loader(path_loader(&template_path));
notifier.set_fast_reload(true);
notifier.watch_path(&template_path, true);
Ok(env)
});
let app_state = AppState {
rabbitmq_producer: Arc::new(RabbitMQProducer::new(&config).await?),
rabbitmq_consumer: Arc::new(RabbitMQConsumer::new(&config, false).await?),
surreal_db_client: Arc::new(SurrealDbClient::new().await?),
tera: Arc::new(Tera::new("src/server/templates/**/*.html").unwrap()),
// tera: Arc::new(Tera::new("templates/**/*.html").unwrap()),
openai_client: Arc::new(async_openai::Client::new()),
templates: Arc::new(reloader),
};
// setup_auth(&app_state.surreal_db_client).await?;
@@ -116,7 +129,7 @@ fn html_routes(
.route("/", get(index_handler))
.route("/search", get(search_result_handler))
.route("/signup", get(show_signup_form).post(signup_handler))
.nest_service("/assets", ServeDir::new("src/server/assets"))
.nest_service("/assets", ServeDir::new("assets/"))
.layer(
AuthSessionLayer::<User, String, SessionSurrealPool<Any>, Surreal<Any>>::new(Some(
db_client,

View File

@@ -1 +0,0 @@
HI

View File

@@ -1,3 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,9 @@
use crate::rabbitmq::consumer::RabbitMQConsumer;
use crate::rabbitmq::publisher::RabbitMQProducer;
use crate::storage::db::SurrealDbClient;
use minijinja_autoreload::AutoReloader;
use std::sync::Arc;
use tera::Tera;
// use tera::Tera;
pub mod middleware_api_auth;
pub mod routes;
@@ -12,6 +13,7 @@ pub struct AppState {
pub rabbitmq_producer: Arc<RabbitMQProducer>,
pub rabbitmq_consumer: Arc<RabbitMQConsumer>,
pub surreal_db_client: Arc<SurrealDbClient>,
pub tera: Arc<Tera>,
// pub tera: Arc<Tera>,
pub openai_client: Arc<async_openai::Client<async_openai::config::OpenAIConfig>>,
pub templates: Arc<AutoReloader>,
}

View File

@@ -3,6 +3,7 @@ use axum::{
response::{Html, IntoResponse},
Form,
};
use axum_htmx::HxBoosted;
use axum_session_auth::AuthSession;
use axum_session_surreal::SessionSurrealPool;
use serde::{Deserialize, Serialize};
@@ -16,13 +17,17 @@ pub struct SignupParams {
pub password: String,
}
pub async fn show_signup_form(State(state): State<AppState>) -> Html<String> {
let context = tera::Context::new();
let html = state
.tera
.render("auth/signup.html", &context)
.unwrap_or_else(|_| "<h1>Error rendering template</h1>".to_string());
Html(html)
pub async fn show_signup_form(
State(state): State<AppState>,
HxBoosted(boosted): HxBoosted,
) -> Html<String> {
let mut context = tera::Context::new();
context.insert("boosted", &boosted);
// let html = state
// .tera
// .render("auth/signup_form.html", &context)
// .unwrap_or_else(|_| "<h1>Error rendering template</h1>".to_string());
Html("html".to_string())
}
pub async fn signup_handler(

View File

@@ -1,9 +1,11 @@
use axum::{extract::State, response::Html};
use axum_session_auth::AuthSession;
use axum_session_surreal::SessionSurrealPool;
use minijinja::context;
use serde_json::json;
use surrealdb::{engine::any::Any, Surreal};
use surrealdb::{engine::any::Any, sql::Relation, Surreal};
use tera::Context;
// use tera::Context;
use tracing::info;
use crate::{error::ApiError, server::AppState, storage::types::user::User};
@@ -18,14 +20,21 @@ pub async fn index_handler(
let queue_length = state.rabbitmq_consumer.get_queue_length().await?;
let output = state
.tera
.render(
"index.html",
&Context::from_value(json!({"adjective": "CRAYCRAY", "queue_length": queue_length}))
.unwrap(),
)
.unwrap();
// let output = state
// .tera
// .render(
// "index.html",
// &Context::from_value(json!({"adjective": "CRAYCRAY", "queue_length": queue_length}))
// .unwrap(),
// )
// .unwrap();
// Ok(output.into())
//
let env = state.templates.acquire_env().unwrap();
let context = context!(queue_length => "2000");
let tmpl = env.get_template("index.html").unwrap();
let output = tmpl.render(context).unwrap();
Ok(output.into())
}

View File

@@ -37,16 +37,17 @@ pub async fn search_result_handler(
)
.await?;
let output = state
.tera
.render(
"search_result.html",
&Context::from_value(
json!({"result": answer.content, "references": answer.references}),
)
.unwrap(),
)
.unwrap();
Ok(Html("Hello".to_string()))
// let output = state
// .tera
// .render(
// "search_result.html",
// &Context::from_value(
// json!({"result": answer.content, "references": answer.references}),
// )
// .unwrap(),
// )
// .unwrap();
Ok(output.into())
// Ok(output.into())
}

View File

@@ -1,62 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div class="min-h-screen bg-base-200 flex items-center justify-center">
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title text-2xl font-bold text-center mb-4">Sign Up</h2>
<form hx-post="/signup" hx-target="#signup-result" class="space-y-4">
<div class="form-control w-full">
<label class="label">
<span class="label-text">Email</span>
</label>
<input type="text" name="email" placeholder="Enter username" class="input input-bordered w-full" required />
</div>
<div class="form-control w-full">
<label class="label">
<span class="label-text">Password</span>
</label>
<input type="password" name="password" placeholder="Enter password" class="input input-bordered w-full"
required />
</div>
<div class="form-control mt-6">
<button class="btn btn-primary">
Sign Up
<span class="loading loading-spinner hidden"></span>
</button>
</div>
<div id="signup-result"></div>
<div class="divider">OR</div>
<div class="text-center text-sm">
Already have an account?
<a href="/login" class="link link-primary">Login</a>
</div>
</form>
</div>
</div>
</div>
<!-- Add loading indicator when form is submitting -->
<script>
document.body.addEventListener('htmx:beforeRequest', function (evt) {
if (evt.target.tagName === 'FORM') {
evt.target.querySelector('.loading-spinner').classList.remove('hidden');
evt.target.querySelector('button').disabled = true;
}
});
document.body.addEventListener('htmx:afterRequest', function (evt) {
if (evt.target.tagName === 'FORM') {
evt.target.querySelector('.loading-spinner').classList.add('hidden');
evt.target.querySelector('button').disabled = false;
}
});
</script>
{% endblock %}

View File

@@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}radien{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="assets/style.css">
<script src="https://unpkg.com/htmx.org@2.0.3"></script>
</head>
<body class="min-h-screen">
<!-- Navbar -->
<nav class="navbar bg-base-200">
<div class="flex-1">
<a class="btn btn-ghost text-xl">radien</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1">
<li><a>Link</a></li>
<li>
<details>
<summary>Parent</summary>
<ul class="bg-base-100 rounded-t-none p-2">
<li><a>Link 1</a></li>
<li><a>Link 2</a></li>
</ul>
</details>
</li>
</ul>
</div>
</nav>
<!-- Main Content -->
<main class="container mx-auto px-4 py-8">
{% block content %}{% endblock %}
</main>
</body>
</html>

View File

@@ -1,30 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div class="flex flex-col items-center justify-center min-h-[80vh] space-y-8">
<!-- Hero Section -->
<div class="text-center space-y-4 mb-8">
<h1
class="text-5xl font-bold bg-gradient-to-r from-blue-400 via-purple-500 to-pink-500 text-transparent bg-clip-text">
Welcome to radien
</h1>
<p class="text-gray-400 text-xl">
An experiment in creating a second brain
</p>
<p class="text-gray-400 text-lg">
There are {{queue_length}} messages queued for ingression.
</p>
</div>
<!-- Search Bar -->
<div class="w-full max-w-2xl">
<input type="text" placeholder="Enter your search query" class="input input-bordered w-full" name="query"
hx-get="/search" hx-target="#search-results" />
</div>
<!-- Search Results -->
<div id="search-results" class="w-full max-w-2xl mt-4">
<!-- Results will be populated here by HTMX -->
</div>
</div>
{% endblock %}

View File

@@ -1,9 +0,0 @@
<div class="border-">
<div class="chat chat-start">
<div class="chat-bubble">
{{result}}
<hr />
{{references}}
</div>
</div>
</div>