This commit is contained in:
parent
50bfad7642
commit
c15bd364c1
7 changed files with 64 additions and 19 deletions
|
@ -5,21 +5,20 @@ FOR EACH item IN items
|
||||||
let website = WEBSITE OF item.company
|
let website = WEBSITE OF item.company
|
||||||
PRINT website
|
PRINT website
|
||||||
|
|
||||||
|
|
||||||
let page = GET website
|
let page = GET website
|
||||||
|
|
||||||
let prompt = "Build the same simulator , but for " + item.company + " using just *content about the company* from its website, so it is possible to create a good and useful emulator in the same langue as the content: " + page
|
let prompt = "Build the same simulator , but for " + item.company + " using just *content about the company* from its website, so it is possible to create a good and useful emulator in the same langue as the content: " + page
|
||||||
|
|
||||||
let alias = LLM "Return a single word for " + item.company + " like a token, no spaces, no special characters, no numbers, no uppercase letters."
|
let alias = LLM "Return a single word for " + item.company + " like a token, no spaces, no special characters, no numbers, no uppercase letters."
|
||||||
|
|
||||||
|
CREATE_SITE alias, "OpenSourceCars", prompt
|
||||||
|
|
||||||
let to = item.emailcto
|
let to = item.emailcto
|
||||||
let subject = "General Bots"
|
let subject = "Simulador " + alias
|
||||||
let body = "Oi, tudo bem? Criamos o simulador " + alias + " especificamente para vocês!" + "\n\n Acesse o site: https://sites.pragmatismo.com.br/" + alias + "\n\n" + "Para acessar o simulador, clique no link acima ou copie e cole no seu navegador." + "\n\n" + "Para iniciar, clique no ícone de Play." + "\n\n" + "Atenciosamente,\nDário Vieira"
|
let body = "Oi, " + FIRST(item.Contact) + "! Tudo bem? Estou empolgado, pois criamos o simulador " + alias + " especificamente para vocês!" + "\n\n Acesse o site: https://sites.pragmatismo.com.br/" + alias + "\n\n" + "Para acessar o simulador, clique no link acima ou copie e cole no seu navegador." + "\n\n" + "Para iniciar, clique no ícone de Play." + "\n\n" + "Atenciosamente,\nDário Vieira\n\n"
|
||||||
|
|
||||||
CREATE_DRAFT to, subject, body
|
CREATE_DRAFT to, subject, body
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NEXT item
|
NEXT item
|
21
src/services/keywords/first.rs
Normal file
21
src/services/keywords/first.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use rhai::Dynamic;
|
||||||
|
use rhai::Engine;
|
||||||
|
|
||||||
|
pub fn first_keyword(engine: &mut Engine) {
|
||||||
|
engine
|
||||||
|
.register_custom_syntax(&["FIRST", "$expr$"], false, {
|
||||||
|
move |context, inputs| {
|
||||||
|
let input_string = context.eval_expression_tree(&inputs[0])?;
|
||||||
|
let input_str = input_string.to_string();
|
||||||
|
|
||||||
|
// Extract first word by splitting on whitespace
|
||||||
|
let first_word = input_str.split_whitespace()
|
||||||
|
.next()
|
||||||
|
.unwrap_or("")
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
Ok(Dynamic::from(first_word))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
|
@ -77,8 +77,8 @@ async fn perform_search(
|
||||||
|
|
||||||
// Extract results
|
// Extract results
|
||||||
let results = extract_search_results(&driver).await?;
|
let results = extract_search_results(&driver).await?;
|
||||||
driver.quit().await?;
|
driver.close_window().await?;
|
||||||
|
|
||||||
if !results.is_empty() {
|
if !results.is_empty() {
|
||||||
Ok(results[0].clone())
|
Ok(results[0].clone())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod create_draft;
|
pub mod create_draft;
|
||||||
pub mod create_site;
|
pub mod create_site;
|
||||||
pub mod find;
|
pub mod find;
|
||||||
|
pub mod first;
|
||||||
pub mod for_next;
|
pub mod for_next;
|
||||||
pub mod get;
|
pub mod get;
|
||||||
pub mod get_website;
|
pub mod get_website;
|
||||||
|
|
|
@ -53,11 +53,13 @@ pub async fn execute_set(
|
||||||
table_str, filter_str, updates_str
|
table_str, filter_str, updates_str
|
||||||
);
|
);
|
||||||
|
|
||||||
// Parse the filter condition
|
// Parse the updates first to know how many parameters we'll have
|
||||||
let (where_clause, filter_params) = utils::parse_filter(filter_str).map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
// Parse the updates
|
|
||||||
let (set_clause, update_params) = parse_updates(updates_str).map_err(|e| e.to_string())?;
|
let (set_clause, update_params) = parse_updates(updates_str).map_err(|e| e.to_string())?;
|
||||||
|
let update_params_count = update_params.len();
|
||||||
|
|
||||||
|
// Parse the filter condition with an offset for parameter indices
|
||||||
|
let (where_clause, filter_params) = utils::parse_filter_with_offset(filter_str, update_params_count)
|
||||||
|
.map_err(|e| e.to_string())?;
|
||||||
|
|
||||||
// Combine all parameters (updates first, then filter)
|
// Combine all parameters (updates first, then filter)
|
||||||
let mut params = update_params;
|
let mut params = update_params;
|
||||||
|
@ -69,11 +71,13 @@ pub async fn execute_set(
|
||||||
);
|
);
|
||||||
println!("Executing query: {}", query);
|
println!("Executing query: {}", query);
|
||||||
|
|
||||||
// Execute the update
|
// Execute the update with all parameters
|
||||||
let result = sqlx::query(&query)
|
let mut query_builder = sqlx::query(&query);
|
||||||
.bind(¶ms[0]) // First update value
|
for param in ¶ms {
|
||||||
.bind(¶ms[1]) // Second update value if exists
|
query_builder = query_builder.bind(param);
|
||||||
.bind(¶ms[2]) // Filter value
|
}
|
||||||
|
|
||||||
|
let result = query_builder
|
||||||
.execute(pool)
|
.execute(pool)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
@ -98,7 +102,7 @@ fn parse_updates(updates_str: &str) -> Result<(String, Vec<String>), Box<dyn Err
|
||||||
let mut params = Vec::new();
|
let mut params = Vec::new();
|
||||||
|
|
||||||
// Split multiple updates by comma
|
// Split multiple updates by comma
|
||||||
for update in updates_str.split(',') {
|
for (i, update) in updates_str.split(',').enumerate() {
|
||||||
let parts: Vec<&str> = update.split('=').collect();
|
let parts: Vec<&str> = update.split('=').collect();
|
||||||
if parts.len() != 2 {
|
if parts.len() != 2 {
|
||||||
return Err("Invalid update format. Expected 'KEY=VALUE'".into());
|
return Err("Invalid update format. Expected 'KEY=VALUE'".into());
|
||||||
|
@ -112,7 +116,7 @@ fn parse_updates(updates_str: &str) -> Result<(String, Vec<String>), Box<dyn Err
|
||||||
return Err("Invalid column name in update".into());
|
return Err("Invalid column name in update".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
set_clauses.push(format!("{} = ${}", column, set_clauses.len() + 1));
|
set_clauses.push(format!("{} = ${}", column, i + 1));
|
||||||
params.push(value.to_string());
|
params.push(value.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::services::keywords::llm_keyword::llm_keyword;
|
||||||
use crate::services::keywords::print::print_keyword;
|
use crate::services::keywords::print::print_keyword;
|
||||||
use crate::services::keywords::set::set_keyword;
|
use crate::services::keywords::set::set_keyword;
|
||||||
use crate::services::keywords::wait::wait_keyword;
|
use crate::services::keywords::wait::wait_keyword;
|
||||||
|
use crate::services::keywords::first::first_keyword;
|
||||||
use crate::services::state::AppState;
|
use crate::services::state::AppState;
|
||||||
|
|
||||||
pub struct ScriptService {
|
pub struct ScriptService {
|
||||||
|
@ -26,7 +27,8 @@ impl ScriptService {
|
||||||
create_draft_keyword(state, &mut engine);
|
create_draft_keyword(state, &mut engine);
|
||||||
create_site_keyword(state, &mut engine);
|
create_site_keyword(state, &mut engine);
|
||||||
find_keyword(state, &mut engine);
|
find_keyword(state, &mut engine);
|
||||||
for_keyword(state, &mut engine);
|
for_keyword(state, &mut engine);
|
||||||
|
first_keyword(&mut engine);
|
||||||
llm_keyword(state, &mut engine);
|
llm_keyword(state, &mut engine);
|
||||||
get_website_keyword(state, &mut engine);
|
get_website_keyword(state, &mut engine);
|
||||||
get_keyword(state, &mut engine);
|
get_keyword(state, &mut engine);
|
||||||
|
|
|
@ -238,3 +238,21 @@ pub fn parse_filter(filter_str: &str) -> Result<(String, Vec<String>), Box<dyn E
|
||||||
// Return the parameterized query part and the value separately
|
// Return the parameterized query part and the value separately
|
||||||
Ok((format!("{} = $1", column), vec![value.to_string()]))
|
Ok((format!("{} = $1", column), vec![value.to_string()]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_filter_with_offset(filter_str: &str, offset: usize) -> Result<(String, Vec<String>), Box<dyn Error>> {
|
||||||
|
let parts: Vec<&str> = filter_str.split('=').collect();
|
||||||
|
if parts.len() != 2 {
|
||||||
|
return Err("Invalid filter format. Expected 'KEY=VALUE'".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let column = parts[0].trim();
|
||||||
|
let value = parts[1].trim();
|
||||||
|
|
||||||
|
// Validate column name to prevent SQL injection
|
||||||
|
if !column.chars().all(|c| c.is_ascii_alphanumeric() || c == '_') {
|
||||||
|
return Err("Invalid column name in filter".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the offset + 1 for the parameter number
|
||||||
|
Ok((format!("{} = ${}", column, offset + 1), vec![value.to_string()]))
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue