| |
| """ |
| WordPress Elementor Design Agent (Basic Implementation) |
| """ |
|
|
| import time |
| import logging |
| import argparse |
| import os |
| from typing import Optional |
| from selenium import webdriver |
| from selenium.webdriver.chrome.service import Service |
| from selenium.webdriver.chrome.options import Options |
| from selenium.webdriver.common.by import By |
| from selenium.webdriver.support.ui import WebDriverWait |
| from selenium.webdriver.support import expected_conditions as EC |
| from webdriver_manager.chrome import ChromeDriverManager |
|
|
| |
| logging.basicConfig( |
| level=logging.INFO, |
| format='%(asctime)s - %(levelname)s - %(message)s' |
| ) |
| logger = logging.getLogger(__name__) |
|
|
| class ElementorAgent: |
| """ |
| Agent for automating Elementor page builder tasks in WordPress (Basic Implementation). |
| """ |
| |
| def __init__(self, url: str, username: str, password: str, post_id: Optional[int] = None, headless: bool = False): |
| """ |
| Initialize the Elementor agent. |
| """ |
| self.url = url |
| self.username = username |
| self.password = password |
| self.post_id = post_id |
| self.headless = headless |
| self.driver: Optional[webdriver.Chrome] = None |
| |
| def start(self) -> bool: |
| """ |
| Start the browser and log in to WordPress (Placeholder Implementation). |
| """ |
| logger.info(f"Starting Elementor Agent (basic) for {self.url}") |
| |
| chrome_options = Options() |
| if self.headless: |
| chrome_options.add_argument("--headless") |
| chrome_options.add_argument("--no-sandbox") |
| chrome_options.add_argument("--disable-dev-shm-usage") |
| |
| try: |
| self.driver = webdriver.Chrome( |
| service=Service(ChromeDriverManager().install()), |
| options=chrome_options |
| ) |
| |
| |
| logger.info(f"Navigating to {self.url}") |
| self.driver.get(self.url) |
| |
| |
| username_field = WebDriverWait(self.driver, 10).until( |
| EC.presence_of_element_located((By.ID, "user_login")) |
| ) |
| password_field = self.driver.find_element(By.ID, "user_pass") |
| |
| |
| username_field.send_keys(self.username) |
| password_field.send_keys(self.password) |
| |
| |
| password_field.submit() |
| |
| |
| WebDriverWait(self.driver, 10).until( |
| EC.presence_of_element_located((By.ID, "wpadminbar")) |
| ) |
| |
| logger.info("Successfully logged in to WordPress") |
| |
| |
| if self.post_id: |
| self.navigate_to_elementor() |
| |
| return True |
| |
| except Exception as e: |
| logger.error(f"Error starting browser: {e}") |
| if self.driver: |
| self.driver.quit() |
| self.driver = None |
| return False |
| |
| def navigate_to_elementor(self) -> bool: |
| """ |
| Navigate to the Elementor editor for the specified post. |
| """ |
| if not self.driver or not self.post_id: |
| return False |
| |
| try: |
| editor_url = f"{self.url}post.php?post={self.post_id}&action=elementor" |
| logger.info(f"Navigating to Elementor editor: {editor_url}") |
| self.driver.get(editor_url) |
| |
| |
| WebDriverWait(self.driver, 30).until( |
| EC.presence_of_element_located((By.ID, "elementor-preview-iframe")) |
| ) |
| |
| logger.info("Successfully loaded Elementor editor") |
| return True |
| |
| except Exception as e: |
| logger.error(f"Error navigating to Elementor: {e}") |
| return False |
| |
| def close(self) -> None: |
| """ |
| Close the browser and clean up. |
| """ |
| if self.driver: |
| logger.info("Closing browser") |
| self.driver.quit() |
| self.driver = None |
| |
| def add_widget(self, widget_type: str) -> bool: |
| """ |
| Add a widget to the Elementor page. |
| """ |
| if not self.driver: |
| return False |
| |
| try: |
| |
| preview_iframe = self.driver.find_element(By.ID, "elementor-preview-iframe") |
| self.driver.switch_to.frame(preview_iframe) |
| |
| |
| add_section = WebDriverWait(self.driver, 10).until( |
| EC.element_to_be_clickable((By.CLASS_NAME, "elementor-add-section-button")) |
| ) |
| add_section.click() |
| |
| |
| self.driver.switch_to.default_content() |
| |
| |
| search_input = WebDriverWait(self.driver, 10).until( |
| EC.presence_of_element_located((By.CSS_SELECTOR, ".elementor-panel-search-input")) |
| ) |
| search_input.send_keys(widget_type) |
| |
| |
| widget_element = WebDriverWait(self.driver, 10).until( |
| EC.element_to_be_clickable((By.XPATH, f"//div[contains(@class, 'elementor-element-title-wrapper') and contains(text(), '{widget_type}')]")) |
| ) |
| widget_element.click() |
| |
| logger.info(f"Added widget: {widget_type}") |
| return True |
| |
| except Exception as e: |
| logger.error(f"Error adding widget: {e}") |
| return False |
|
|
| def edit_text(self, element_selector: str, text: str) -> bool: |
| """ |
| Edit text content of an Elementor element. |
| """ |
| if not self.driver: |
| return False |
| |
| try: |
| |
| preview_iframe = self.driver.find_element(By.ID, "elementor-preview-iframe") |
| self.driver.switch_to.frame(preview_iframe) |
| |
| |
| element = WebDriverWait(self.driver, 10).until( |
| EC.element_to_be_clickable((By.CSS_SELECTOR, element_selector)) |
| ) |
| element.click() |
| |
| |
| self.driver.switch_to.default_content() |
| |
| |
| text_editor = WebDriverWait(self.driver, 10).until( |
| EC.presence_of_element_located((By.CSS_SELECTOR, ".elementor-control-content [data-setting='editor']")) |
| ) |
| |
| |
| self.driver.execute_script("arguments[0].innerHTML = arguments[1]", text_editor, text) |
| |
| logger.info(f"Edited text for selector: {element_selector}") |
| return True |
| |
| except Exception as e: |
| logger.error(f"Error editing text: {e}") |
| return False |
|
|
| def save_changes(self) -> bool: |
| """ |
| Save changes made in the Elementor editor. |
| """ |
| if not self.driver: |
| return False |
| |
| try: |
| |
| self.driver.switch_to.default_content() |
| |
| |
| save_button = WebDriverWait(self.driver, 10).until( |
| EC.element_to_be_clickable((By.CSS_SELECTOR, ".elementor-button.elementor-button-success")) |
| ) |
| save_button.click() |
| |
| |
| WebDriverWait(self.driver, 10).until( |
| EC.visibility_of_element_located((By.CSS_SELECTOR, ".elementor-button-success .elementor-state-icon")) |
| ) |
| |
| logger.info("Successfully saved changes") |
| return True |
| |
| except Exception as e: |
| logger.error(f"Error saving changes: {e}") |
| return False |
|
|
| def take_screenshot(self, filename: str = "elementor_screenshot.png") -> bool: |
| """ |
| Take a screenshot of the current state of the Elementor editor. |
| """ |
| if not self.driver: |
| return False |
| |
| try: |
| |
| self.driver.switch_to.default_content() |
| |
| |
| self.driver.save_screenshot(filename) |
| logger.info(f"Screenshot saved: {filename}") |
| return True |
| |
| except Exception as e: |
| logger.error(f"Error taking screenshot: {e}") |
| return False |
|
|
|
|
| def parse_arguments(): |
| """Parse command line arguments.""" |
| parser = argparse.ArgumentParser(description='WordPress Elementor Design Agent (Basic)') |
| parser.add_argument('--url', default=os.environ.get('WP_ADMIN_URL', 'http://localhost/wp-admin/'), |
| help='WordPress admin URL') |
| parser.add_argument('--username', default=os.environ.get('WP_USERNAME', 'admin'), |
| help='WordPress username') |
| parser.add_argument('--password', default=os.environ.get('WP_PASSWORD', ''), |
| help='WordPress password') |
| parser.add_argument('--post-id', type=int, default=os.environ.get('WP_POST_ID', 1), |
| help='Post ID to edit with Elementor') |
| parser.add_argument('--headless', action='store_true', |
| help='Run browser in headless mode') |
| parser.add_argument('--screenshot', action='store_true', |
| help='Take a screenshot after loading Elementor') |
| parser.add_argument('--screenshot-path', default='elementor_editor.png', |
| help='Path to save the screenshot') |
| parser.add_argument('--wait-time', type=int, default=5, |
| help='Time to wait after loading Elementor (seconds)') |
|
|
| return parser.parse_arguments() |
|
|
|
|
| def main(): |
| """Main function to run the script.""" |
| args = parse_arguments() |
|
|
| agent = ElementorAgent( |
| url=args.url, |
| username=args.username, |
| password=args.password, |
| post_id=args.post_id, |
| headless=args.headless |
| ) |
|
|
| if agent.start(): |
| try: |
| logger.info(f"Elementor Agent (basic) started successfully for post ID {args.post_id}") |
|
|
| |
| if args.screenshot: |
| agent.take_screenshot(args.screenshot_path) |
|
|
| |
| if args.wait_time > 0: |
| logger.info(f"Waiting for {args.wait_time} seconds...") |
| time.sleep(args.wait_time) |
|
|
| finally: |
| agent.close() |
| else: |
| logger.error("Failed to start Elementor Agent (basic)") |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|