initial commit of gitara site
This commit is contained in:
36
src/initializers/admin_seeder.rs
Normal file
36
src/initializers/admin_seeder.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use async_trait::async_trait;
|
||||
use loco_rs::prelude::*;
|
||||
|
||||
use crate::models::users::{self, RegisterParams};
|
||||
|
||||
pub struct AdminSeeder;
|
||||
|
||||
#[async_trait]
|
||||
impl Initializer for AdminSeeder {
|
||||
fn name(&self) -> String {
|
||||
"admin-seeder".to_string()
|
||||
}
|
||||
|
||||
async fn before_run(&self, ctx: &AppContext) -> Result<()> {
|
||||
let email = std::env::var("ADMIN_EMAIL").unwrap_or_default();
|
||||
let password = std::env::var("ADMIN_PASSWORD").unwrap_or_default();
|
||||
let name = std::env::var("ADMIN_NAME").unwrap_or_else(|_| "Admin".to_string());
|
||||
|
||||
if email.is_empty() || password.is_empty() {
|
||||
tracing::warn!("ADMIN_EMAIL / ADMIN_PASSWORD not set in .env; admin not seeded");
|
||||
} else if users::Model::find_by_email(&ctx.db, &email).await.is_err() {
|
||||
users::Model::create_with_password(
|
||||
&ctx.db,
|
||||
&RegisterParams {
|
||||
email: email.clone(),
|
||||
password,
|
||||
name,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
tracing::info!(admin = %email, "admin user seeded");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
2
src/initializers/mod.rs
Normal file
2
src/initializers/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod admin_seeder;
|
||||
pub mod view_engine;
|
||||
46
src/initializers/view_engine.rs
Normal file
46
src/initializers/view_engine.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use async_trait::async_trait;
|
||||
use axum::{Extension, Router as AxumRouter};
|
||||
use fluent_templates::{ArcLoader, FluentLoader};
|
||||
use loco_rs::{
|
||||
app::{AppContext, Initializer},
|
||||
controller::views::{engines, ViewEngine},
|
||||
Error, Result,
|
||||
};
|
||||
use tracing::info;
|
||||
|
||||
const I18N_DIR: &str = "assets/i18n";
|
||||
// Kept outside `I18N_DIR`: fluent-templates >=0.13 scans top-level *.ftl files
|
||||
// in that dir as locales, and "shared" parses as a langid, so a shared.ftl
|
||||
// living there would be loaded twice and fail with a duplicate-resource error.
|
||||
const I18N_SHARED: &str = "assets/i18n_shared/shared.ftl";
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
pub struct ViewEngineInitializer;
|
||||
|
||||
#[async_trait]
|
||||
impl Initializer for ViewEngineInitializer {
|
||||
fn name(&self) -> String {
|
||||
"view-engine".to_string()
|
||||
}
|
||||
|
||||
async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
|
||||
let tera_engine = if std::path::Path::new(I18N_DIR).exists() {
|
||||
let arc = std::sync::Arc::new(
|
||||
ArcLoader::builder(&I18N_DIR, unic_langid::langid!("sk"))
|
||||
.shared_resources(Some(&[I18N_SHARED.into()]))
|
||||
.customize(|bundle| bundle.set_use_isolating(false))
|
||||
.build()
|
||||
.map_err(|e| Error::string(&e.to_string()))?,
|
||||
);
|
||||
info!("locales loaded");
|
||||
|
||||
engines::TeraView::build()?.post_process(move |tera| {
|
||||
tera.register_function("t", FluentLoader::new(arc.clone()));
|
||||
Ok(())
|
||||
})?
|
||||
} else {
|
||||
engines::TeraView::build()?
|
||||
};
|
||||
|
||||
Ok(router.layer(Extension(ViewEngine::from(tera_engine))))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user