mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-27 03:08:41 +02:00
in progress, routers and main split up
This commit is contained in:
30
crates/common/src/utils/config.rs
Normal file
30
crates/common/src/utils/config.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use config::{Config, ConfigError, File};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AppConfig {
|
||||
pub smtp_username: String,
|
||||
pub smtp_password: String,
|
||||
pub smtp_relayer: String,
|
||||
pub surrealdb_address: String,
|
||||
pub surrealdb_username: String,
|
||||
pub surrealdb_password: String,
|
||||
pub surrealdb_namespace: String,
|
||||
pub surrealdb_database: String,
|
||||
}
|
||||
|
||||
pub fn get_config() -> Result<AppConfig, ConfigError> {
|
||||
let config = Config::builder()
|
||||
.add_source(File::with_name("config"))
|
||||
.build()?;
|
||||
|
||||
Ok(AppConfig {
|
||||
smtp_username: config.get_string("SMTP_USERNAME")?,
|
||||
smtp_password: config.get_string("SMTP_PASSWORD")?,
|
||||
smtp_relayer: config.get_string("SMTP_RELAYER")?,
|
||||
surrealdb_address: config.get_string("SURREALDB_ADDRESS")?,
|
||||
surrealdb_username: config.get_string("SURREALDB_USERNAME")?,
|
||||
surrealdb_password: config.get_string("SURREALDB_PASSWORD")?,
|
||||
surrealdb_namespace: config.get_string("SURREALDB_NAMESPACE")?,
|
||||
surrealdb_database: config.get_string("SURREALDB_DATABASE")?,
|
||||
})
|
||||
}
|
||||
48
crates/common/src/utils/embedding.rs
Normal file
48
crates/common/src/utils/embedding.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use async_openai::types::CreateEmbeddingRequestArgs;
|
||||
|
||||
use crate::error::AppError;
|
||||
/// Generates an embedding vector for the given input text using OpenAI's embedding model.
|
||||
///
|
||||
/// This function takes a text input and converts it into a numerical vector representation (embedding)
|
||||
/// using OpenAI's text-embedding-3-small model. These embeddings can be used for semantic similarity
|
||||
/// comparisons, vector search, and other natural language processing tasks.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `client`: The OpenAI client instance used to make API requests.
|
||||
/// * `input`: The text string to generate embeddings for.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a `Result` containing either:
|
||||
/// * `Ok(Vec<f32>)`: A vector of 32-bit floating point numbers representing the text embedding
|
||||
/// * `Err(ProcessingError)`: An error if the embedding generation fails
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function can return a `AppError` in the following cases:
|
||||
/// * If the OpenAI API request fails
|
||||
/// * If the request building fails
|
||||
/// * If no embedding data is received in the response
|
||||
pub async fn generate_embedding(
|
||||
client: &async_openai::Client<async_openai::config::OpenAIConfig>,
|
||||
input: &str,
|
||||
) -> Result<Vec<f32>, AppError> {
|
||||
let request = CreateEmbeddingRequestArgs::default()
|
||||
.model("text-embedding-3-small")
|
||||
.input([input])
|
||||
.build()?;
|
||||
|
||||
// Send the request to OpenAI
|
||||
let response = client.embeddings().create(request).await?;
|
||||
|
||||
// Extract the embedding vector
|
||||
let embedding: Vec<f32> = response
|
||||
.data
|
||||
.first()
|
||||
.ok_or_else(|| AppError::LLMParsing("No embedding data received".into()))?
|
||||
.embedding
|
||||
.clone();
|
||||
|
||||
Ok(embedding)
|
||||
}
|
||||
81
crates/common/src/utils/mailer.rs
Normal file
81
crates/common/src/utils/mailer.rs
Normal file
@@ -0,0 +1,81 @@
|
||||
use lettre::address::AddressError;
|
||||
use lettre::message::MultiPart;
|
||||
use lettre::{transport::smtp::authentication::Credentials, SmtpTransport};
|
||||
use lettre::{Message, Transport};
|
||||
use minijinja::context;
|
||||
use minijinja_autoreload::AutoReloader;
|
||||
use thiserror::Error;
|
||||
use tracing::info;
|
||||
|
||||
pub struct Mailer {
|
||||
pub mailer: SmtpTransport,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum EmailError {
|
||||
#[error("Email construction error: {0}")]
|
||||
EmailParsingError(#[from] AddressError),
|
||||
|
||||
#[error("Email sending error: {0}")]
|
||||
SendingError(#[from] lettre::transport::smtp::Error),
|
||||
|
||||
#[error("Body constructing error: {0}")]
|
||||
BodyError(#[from] lettre::error::Error),
|
||||
|
||||
#[error("Templating error: {0}")]
|
||||
TemplatingError(#[from] minijinja::Error),
|
||||
}
|
||||
|
||||
impl Mailer {
|
||||
pub fn new(
|
||||
username: &str,
|
||||
relayer: &str,
|
||||
password: &str,
|
||||
) -> Result<Self, lettre::transport::smtp::Error> {
|
||||
let creds = Credentials::new(username.to_owned(), password.to_owned());
|
||||
|
||||
let mailer = SmtpTransport::relay(&relayer)?.credentials(creds).build();
|
||||
|
||||
Ok(Mailer { mailer })
|
||||
}
|
||||
|
||||
pub fn send_email_verification(
|
||||
&self,
|
||||
email_to: &str,
|
||||
verification_code: &str,
|
||||
templates: &AutoReloader,
|
||||
) -> Result<(), EmailError> {
|
||||
let name = email_to
|
||||
.split('@')
|
||||
.next()
|
||||
.unwrap_or("User")
|
||||
.chars()
|
||||
.enumerate()
|
||||
.map(|(i, c)| if i == 0 { c.to_ascii_uppercase() } else { c })
|
||||
.collect::<String>();
|
||||
|
||||
let context = context! {
|
||||
name => name,
|
||||
verification_code => verification_code
|
||||
};
|
||||
|
||||
let env = templates.acquire_env()?;
|
||||
let html = env
|
||||
.get_template("email/email_verification.html")?
|
||||
.render(&context)?;
|
||||
let plain = env
|
||||
.get_template("email/email_verification.txt")?
|
||||
.render(&context)?;
|
||||
|
||||
let email = Message::builder()
|
||||
.from("Admin <minne@starks.cloud>".parse()?)
|
||||
.reply_to("Admin <minne@starks.cloud>".parse()?)
|
||||
.to(format!("{} <{}>", name, email_to).parse()?)
|
||||
.subject("Verify Your Email Address")
|
||||
.multipart(MultiPart::alternative_plain_html(plain, html))?;
|
||||
|
||||
info!("Sending email to: {}", email_to);
|
||||
self.mailer.send(&email)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
3
crates/common/src/utils/mod.rs
Normal file
3
crates/common/src/utils/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod config;
|
||||
pub mod embedding;
|
||||
pub mod mailer;
|
||||
Reference in New Issue
Block a user