From a3118dcf0ac0a3a4cf969e9756a8677a6fdc51f2 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Wed, 30 Jul 2025 23:26:06 -0300 Subject: [PATCH] - Script is running! --- src/prompts/business/data-enrichment.bas | 6 +- src/services/keywords/create_draft.rs | 2 +- src/services/keywords/create_site.rs | 4 +- src/services/keywords/get.rs | 2 +- src/services/keywords/get_website.rs | 33 ++--- src/services/script.rs | 3 +- src/services/web_automation.rs | 170 +++++++++++++++-------- 7 files changed, 132 insertions(+), 88 deletions(-) diff --git a/src/prompts/business/data-enrichment.bas b/src/prompts/business/data-enrichment.bas index 9c060ad..8c20be4 100644 --- a/src/prompts/business/data-enrichment.bas +++ b/src/prompts/business/data-enrichment.bas @@ -2,7 +2,7 @@ let items = FIND "gb.rob", "ACTION=EMUL1" FOR EACH item IN items PRINT item.company - let website = GET WEBSITE item.company "website" + let website = WEBSITE OF item.company PRINT website WAIT 10 @@ -12,12 +12,12 @@ FOR EACH item IN items 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 item.company + "bot", website, "site", prompt + CREATE SITE item.company + "bot", item.company, website, "site", prompt let to = item.emailcto let subject = "Simulador criado " + item.company let body = "O simulador " + item.company + " foi criado com sucesso. Acesse o site: " + item.company + "bot" - CREATE DRAFT to, subject, body + CREATE_DRAFT to, subject, body NEXT item diff --git a/src/services/keywords/create_draft.rs b/src/services/keywords/create_draft.rs index 4c7711a..13305ee 100644 --- a/src/services/keywords/create_draft.rs +++ b/src/services/keywords/create_draft.rs @@ -9,7 +9,7 @@ pub fn create_draft_keyword(state: &AppState, engine: &mut Engine) { engine .register_custom_syntax( - &["CREATE", "DRAFT", "$expr$", ",", "$expr$", ",", "$expr$"], + &["CREATE_DRAFT", "$expr$", ",", "$expr$", ",", "$expr$"], true, // Statement move |context, inputs| { // Extract arguments diff --git a/src/services/keywords/create_site.rs b/src/services/keywords/create_site.rs index efb2c06..4bf1d8a 100644 --- a/src/services/keywords/create_site.rs +++ b/src/services/keywords/create_site.rs @@ -19,7 +19,7 @@ pub fn create_site_keyword(_state: &AppState, engine: &mut Engine) { } let _name = context.eval_expression_tree(&inputs[0])?; - let company = context.eval_expression_tree(&inputs[1])?; + let _website = context.eval_expression_tree(&inputs[2])?; let _template = context.eval_expression_tree(&inputs[3])?; let prompt = context.eval_expression_tree(&inputs[4])?; @@ -29,7 +29,7 @@ pub fn create_site_keyword(_state: &AppState, engine: &mut Engine) { // Create the directory structure let base_path = "/opt/gbo/tenants/pragmatismo/proxy/data/websites/sites.pragmatismo.com.br"; - let site_name = format!("{}bot", company.to_string()); + let site_name = format!("{}", _name.to_string()); let full_path = format!("{}/{}", base_path, site_name); // Create directory if it doesn't exist diff --git a/src/services/keywords/get.rs b/src/services/keywords/get.rs index bc512a3..fdb389f 100644 --- a/src/services/keywords/get.rs +++ b/src/services/keywords/get.rs @@ -1,4 +1,4 @@ -use rhai::{Dynamic, Engine}; + use rhai::{Dynamic, Engine}; use reqwest; use crate::services::state::AppState; use std::error::Error; diff --git a/src/services/keywords/get_website.rs b/src/services/keywords/get_website.rs index dffe82d..2ac0ac0 100644 --- a/src/services/keywords/get_website.rs +++ b/src/services/keywords/get_website.rs @@ -11,22 +11,21 @@ pub fn get_website_keyword(state: &AppState, engine: &mut Engine) { engine .register_custom_syntax( - &["GET", "WEBSITE", "$expr$", "$expr$"], + &["WEBSITE", "OF", "$expr$"], false, move |context, inputs| { let search_term = context.eval_expression_tree(&inputs[0])?.to_string(); - let website_hint = context.eval_expression_tree(&inputs[1])?.to_string(); + println!( - "GET WEBSITE executed - Search: '{}', Hint: '{}'", - search_term, website_hint + "GET WEBSITE executed - Search: '{}'", + search_term ); let browser_pool_clone = browser_pool.clone(); let fut = execute_headless_browser_search( browser_pool_clone, - &search_term, - &website_hint, + &search_term ); let result = @@ -41,20 +40,18 @@ pub fn get_website_keyword(state: &AppState, engine: &mut Engine) { pub async fn execute_headless_browser_search( browser_pool: Arc, // Adjust path as needed - search_term: &str, - website_hint: &str, -) -> Result> { + search_term: &str) -> Result> { println!( - "Starting headless browser search: '{}' targeting '{}'", - search_term, website_hint + "Starting headless browser search: '{}' ", + search_term ); let search_term = search_term.to_string(); - let website_hint = website_hint.to_string(); + let result = browser_pool .with_browser(|driver| { - Box::pin(async move { perform_search(driver, &search_term, &website_hint).await }) + Box::pin(async move { perform_search(driver, &search_term).await }) }) .await?; @@ -63,15 +60,9 @@ pub async fn execute_headless_browser_search( async fn perform_search( driver: WebDriver, - search_term: &str, - website_hint: &str, -) -> Result> { + search_term: &str) -> Result> { // Configure the search query - let query = if website_hint.trim().is_empty() { - search_term.to_string() - } else { - format!("{} site:{}", search_term, website_hint) - }; + let query = search_term.to_string(); // Navigate to DuckDuckGo println!("Navigating to DuckDuckGo..."); diff --git a/src/services/script.rs b/src/services/script.rs index ed01272..cfdfb4d 100644 --- a/src/services/script.rs +++ b/src/services/script.rs @@ -28,8 +28,8 @@ impl ScriptService { find_keyword(state, &mut engine); for_keyword(state, &mut engine); llm_keyword(state, &mut engine); - get_keyword(state, &mut engine); get_website_keyword(state, &mut engine); + get_keyword(state, &mut engine); set_keyword(state, &mut engine); wait_keyword(state, &mut engine); print_keyword(state, &mut engine); @@ -127,6 +127,7 @@ impl ScriptService { /// Preprocesses BASIC-style script to handle semicolon-free syntax pub fn compile(&self, script: &str) -> Result> { let processed_script = self.preprocess_basic_script(script); + println!("Processed Script:\n{}", processed_script); match self.engine.compile(&processed_script) { Ok(ast) => Ok(ast), Err(parse_error) => Err(Box::new(EvalAltResult::from(parse_error))), diff --git a/src/services/web_automation.rs b/src/services/web_automation.rs index ff180aa..b213bb7 100644 --- a/src/services/web_automation.rs +++ b/src/services/web_automation.rs @@ -1,7 +1,9 @@ +// wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb +// sudo dpkg -i google-chrome-stable_current_amd64.deb + use crate::services::utils; -use log::debug; + use std::env; -use std::env::temp_dir; use std::error::Error; use std::future::Future; use std::pin::Pin; @@ -91,64 +93,114 @@ impl BrowserSetup { Err("Brave browser not found. Please install Brave first.".into()) } - - async fn setup_chromedriver() -> Result> { - let mut chromedriver_path = env::current_exe()?.parent().unwrap().to_path_buf(); - chromedriver_path.push("chromedriver"); - - // Check if chromedriver exists - if fs::metadata(&chromedriver_path).await.is_err() { - println!("Downloading chromedriver..."); - - // Note: This URL structure is outdated. Consider using Chrome for Testing endpoints - let (base_url, platform) = - match (cfg!(target_os = "windows"), cfg!(target_arch = "x86_64")) { - (true, true) => ( - "https://chromedriver.storage.googleapis.com/114.0.5735.90", - "win32", - ), - (false, true) if cfg!(target_os = "macos") => ( - "https://chromedriver.storage.googleapis.com/114.0.5735.90", - "mac64", - ), - (false, true) => ( - "https://chromedriver.storage.googleapis.com/114.0.5735.90", - "linux64", - ), - _ => return Err("Unsupported platform".into()), - }; - - let download_url = format!("{}/chromedriver_{}.zip", base_url, platform); - - let mut zip_path = temp_dir(); - zip_path.push("chromedriver.zip"); - - utils::download_file(&download_url, &zip_path.to_str().unwrap()).await?; - - let extract_result = utils::extract_zip_recursive(&zip_path, &chromedriver_path); - if let Err(e) = extract_result { - debug!("Error extracting ZIP: {}", e); - } - // Clean up zip file - let _ = fs::remove_file(&zip_path).await; - - if cfg!(target_os = "windows") { - chromedriver_path.push("chromedriver.exe"); - } else { - chromedriver_path.push("chromedriver"); - } - - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - let mut perms = fs::metadata(&chromedriver_path).await?.permissions(); - perms.set_mode(0o755); // Make executable - fs::set_permissions(&chromedriver_path, perms).await?; - } - } - - Ok(chromedriver_path.to_string_lossy().to_string()) +async fn setup_chromedriver() -> Result> { + // Create chromedriver directory in executable's parent directory + let mut chromedriver_dir = env::current_exe()? + .parent() + .unwrap() + .to_path_buf(); + chromedriver_dir.push("chromedriver"); + + // Ensure the directory exists + if !chromedriver_dir.exists() { + fs::create_dir(&chromedriver_dir).await?; } + + // Determine the final chromedriver path + let chromedriver_path = if cfg!(target_os = "windows") { + chromedriver_dir.join("chromedriver.exe") + } else { + chromedriver_dir.join("chromedriver") + }; + + // Check if chromedriver exists + if fs::metadata(&chromedriver_path).await.is_err() { + let (download_url, platform) = match (cfg!(target_os = "windows"), cfg!(target_arch = "x86_64")) { + (true, true) => ( + "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.183/win64/chromedriver-win64.zip", + "win64", + ), + (true, false) => ( + "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.183/win32/chromedriver-win32.zip", + "win32", + ), + (false, true) if cfg!(target_os = "macos") && cfg!(target_arch = "aarch64") => ( + "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.183/mac-arm64/chromedriver-mac-arm64.zip", + "mac-arm64", + ), + (false, true) if cfg!(target_os = "macos") => ( + "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.183/mac-x64/chromedriver-mac-x64.zip", + "mac-x64", + ), + (false, true) => ( + "https://storage.googleapis.com/chrome-for-testing-public/138.0.7204.183/linux64/chromedriver-linux64.zip", + "linux64", + ), + _ => return Err("Unsupported platform".into()), + }; + + let mut zip_path = std::env::temp_dir(); + zip_path.push("chromedriver.zip"); + println!("Downloading chromedriver for {}...", platform); + + // Download the zip file + utils::download_file(download_url, &zip_path.to_str().unwrap()).await?; + + // Extract the zip to a temporary directory first + let mut temp_extract_dir = std::env::temp_dir(); + temp_extract_dir.push("chromedriver_extract"); + let mut temp_extract_dir1 = temp_extract_dir.clone(); + + // Clean up any previous extraction + let _ = fs::remove_dir_all(&temp_extract_dir).await; + fs::create_dir(&temp_extract_dir).await?; + + utils::extract_zip_recursive(&zip_path, &temp_extract_dir)?; + + // Chrome for Testing zips contain a platform-specific directory + // Find the chromedriver binary in the extracted structure + let mut extracted_binary_path = temp_extract_dir; + extracted_binary_path.push(format!("chromedriver-{}", platform)); + extracted_binary_path.push(if cfg!(target_os = "windows") { + "chromedriver.exe" + } else { + "chromedriver" + }); + + // Try to move the file, fall back to copy if cross-device + match fs::rename(&extracted_binary_path, &chromedriver_path).await { + Ok(_) => (), + Err(e) if e.kind() == std::io::ErrorKind::CrossesDevices => { + // Cross-device move failed, use copy instead + fs::copy(&extracted_binary_path, &chromedriver_path).await?; + // Set permissions on the copied file + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mut perms = fs::metadata(&chromedriver_path).await?.permissions(); + perms.set_mode(0o755); + fs::set_permissions(&chromedriver_path, perms).await?; + } + }, + Err(e) => return Err(e.into()), + } + + // Clean up + let _ = fs::remove_file(&zip_path).await; + let _ = fs::remove_dir_all(temp_extract_dir1).await; + + // Set executable permissions (if not already set during copy) + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + let mut perms = fs::metadata(&chromedriver_path).await?.permissions(); + perms.set_mode(0o755); + fs::set_permissions(&chromedriver_path, perms).await?; + } + } + + Ok(chromedriver_path.to_string_lossy().to_string()) +} } // Modified BrowserPool initialization