xMBx commited on
Commit
314a377
·
verified ·
1 Parent(s): b3c695a

Upload elementor-agent.py

Browse files
Files changed (1) hide show
  1. elementor-agent.py +311 -0
elementor-agent.py ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ """
3
+ WordPress Elementor Design Agent (Basic Implementation)
4
+ """
5
+
6
+ import time
7
+ import logging
8
+ import argparse
9
+ import os
10
+ from typing import Optional
11
+ from selenium import webdriver
12
+ from selenium.webdriver.chrome.service import Service
13
+ from selenium.webdriver.chrome.options import Options
14
+ from selenium.webdriver.common.by import By
15
+ from selenium.webdriver.support.ui import WebDriverWait
16
+ from selenium.webdriver.support import expected_conditions as EC
17
+ from webdriver_manager.chrome import ChromeDriverManager
18
+
19
+ # Set up logging
20
+ logging.basicConfig(
21
+ level=logging.INFO,
22
+ format='%(asctime)s - %(levelname)s - %(message)s'
23
+ )
24
+ logger = logging.getLogger(__name__)
25
+
26
+ class ElementorAgent:
27
+ """
28
+ Agent for automating Elementor page builder tasks in WordPress (Basic Implementation).
29
+ """
30
+
31
+ def __init__(self, url: str, username: str, password: str, post_id: Optional[int] = None, headless: bool = False):
32
+ """
33
+ Initialize the Elementor agent.
34
+ """
35
+ self.url = url
36
+ self.username = username
37
+ self.password = password
38
+ self.post_id = post_id
39
+ self.headless = headless
40
+ self.driver: Optional[webdriver.Chrome] = None
41
+
42
+ def start(self) -> bool:
43
+ """
44
+ Start the browser and log in to WordPress (Placeholder Implementation).
45
+ """
46
+ logger.info(f"Starting Elementor Agent (basic) for {self.url}")
47
+
48
+ chrome_options = Options()
49
+ if self.headless:
50
+ chrome_options.add_argument("--headless")
51
+ chrome_options.add_argument("--no-sandbox")
52
+ chrome_options.add_argument("--disable-dev-shm-usage")
53
+
54
+ try:
55
+ self.driver = webdriver.Chrome(
56
+ service=Service(ChromeDriverManager().install()),
57
+ options=chrome_options
58
+ )
59
+
60
+ # Login to WordPress
61
+ logger.info(f"Navigating to {self.url}")
62
+ self.driver.get(self.url)
63
+
64
+ # Wait for login form
65
+ username_field = WebDriverWait(self.driver, 10).until(
66
+ EC.presence_of_element_located((By.ID, "user_login"))
67
+ )
68
+ password_field = self.driver.find_element(By.ID, "user_pass")
69
+
70
+ # Fill login form
71
+ username_field.send_keys(self.username)
72
+ password_field.send_keys(self.password)
73
+
74
+ # Submit form
75
+ password_field.submit()
76
+
77
+ # Wait for admin dashboard
78
+ WebDriverWait(self.driver, 10).until(
79
+ EC.presence_of_element_located((By.ID, "wpadminbar"))
80
+ )
81
+
82
+ logger.info("Successfully logged in to WordPress")
83
+
84
+ # If post_id is provided, navigate to Elementor editor
85
+ if self.post_id:
86
+ self.navigate_to_elementor()
87
+
88
+ return True
89
+
90
+ except Exception as e:
91
+ logger.error(f"Error starting browser: {e}")
92
+ if self.driver:
93
+ self.driver.quit()
94
+ self.driver = None
95
+ return False
96
+
97
+ def navigate_to_elementor(self) -> bool:
98
+ """
99
+ Navigate to the Elementor editor for the specified post.
100
+ """
101
+ if not self.driver or not self.post_id:
102
+ return False
103
+
104
+ try:
105
+ editor_url = f"{self.url}post.php?post={self.post_id}&action=elementor"
106
+ logger.info(f"Navigating to Elementor editor: {editor_url}")
107
+ self.driver.get(editor_url)
108
+
109
+ # Wait for Elementor to load
110
+ WebDriverWait(self.driver, 30).until(
111
+ EC.presence_of_element_located((By.ID, "elementor-preview-iframe"))
112
+ )
113
+
114
+ logger.info("Successfully loaded Elementor editor")
115
+ return True
116
+
117
+ except Exception as e:
118
+ logger.error(f"Error navigating to Elementor: {e}")
119
+ return False
120
+
121
+ def close(self) -> None:
122
+ """
123
+ Close the browser and clean up.
124
+ """
125
+ if self.driver:
126
+ logger.info("Closing browser")
127
+ self.driver.quit()
128
+ self.driver = None
129
+
130
+ def add_widget(self, widget_type: str) -> bool:
131
+ """
132
+ Add a widget to the Elementor page.
133
+ """
134
+ if not self.driver:
135
+ return False
136
+
137
+ try:
138
+ # Switch to Elementor iframe
139
+ preview_iframe = self.driver.find_element(By.ID, "elementor-preview-iframe")
140
+ self.driver.switch_to.frame(preview_iframe)
141
+
142
+ # Click on add widget button
143
+ add_section = WebDriverWait(self.driver, 10).until(
144
+ EC.element_to_be_clickable((By.CLASS_NAME, "elementor-add-section-button"))
145
+ )
146
+ add_section.click()
147
+
148
+ # Switch back to main frame to interact with widget panel
149
+ self.driver.switch_to.default_content()
150
+
151
+ # Search for widget
152
+ search_input = WebDriverWait(self.driver, 10).until(
153
+ EC.presence_of_element_located((By.CSS_SELECTOR, ".elementor-panel-search-input"))
154
+ )
155
+ search_input.send_keys(widget_type)
156
+
157
+ # Find and click on widget
158
+ widget_element = WebDriverWait(self.driver, 10).until(
159
+ EC.element_to_be_clickable((By.XPATH, f"//div[contains(@class, 'elementor-element-title-wrapper') and contains(text(), '{widget_type}')]"))
160
+ )
161
+ widget_element.click()
162
+
163
+ logger.info(f"Added widget: {widget_type}")
164
+ return True
165
+
166
+ except Exception as e:
167
+ logger.error(f"Error adding widget: {e}")
168
+ return False
169
+
170
+ def edit_text(self, element_selector: str, text: str) -> bool:
171
+ """
172
+ Edit text content of an Elementor element.
173
+ """
174
+ if not self.driver:
175
+ return False
176
+
177
+ try:
178
+ # Switch to Elementor iframe
179
+ preview_iframe = self.driver.find_element(By.ID, "elementor-preview-iframe")
180
+ self.driver.switch_to.frame(preview_iframe)
181
+
182
+ # Find and click the element to edit
183
+ element = WebDriverWait(self.driver, 10).until(
184
+ EC.element_to_be_clickable((By.CSS_SELECTOR, element_selector))
185
+ )
186
+ element.click()
187
+
188
+ # Switch back to main frame to interact with panel
189
+ self.driver.switch_to.default_content()
190
+
191
+ # Find text editor input
192
+ text_editor = WebDriverWait(self.driver, 10).until(
193
+ EC.presence_of_element_located((By.CSS_SELECTOR, ".elementor-control-content [data-setting='editor']"))
194
+ )
195
+
196
+ # Clear existing text and set new text
197
+ self.driver.execute_script("arguments[0].innerHTML = arguments[1]", text_editor, text)
198
+
199
+ logger.info(f"Edited text for selector: {element_selector}")
200
+ return True
201
+
202
+ except Exception as e:
203
+ logger.error(f"Error editing text: {e}")
204
+ return False
205
+
206
+ def save_changes(self) -> bool:
207
+ """
208
+ Save changes made in the Elementor editor.
209
+ """
210
+ if not self.driver:
211
+ return False
212
+
213
+ try:
214
+ # Make sure we're in the main frame
215
+ self.driver.switch_to.default_content()
216
+
217
+ # Click the save button
218
+ save_button = WebDriverWait(self.driver, 10).until(
219
+ EC.element_to_be_clickable((By.CSS_SELECTOR, ".elementor-button.elementor-button-success"))
220
+ )
221
+ save_button.click()
222
+
223
+ # Wait for save to complete
224
+ WebDriverWait(self.driver, 10).until(
225
+ EC.visibility_of_element_located((By.CSS_SELECTOR, ".elementor-button-success .elementor-state-icon"))
226
+ )
227
+
228
+ logger.info("Successfully saved changes")
229
+ return True
230
+
231
+ except Exception as e:
232
+ logger.error(f"Error saving changes: {e}")
233
+ return False
234
+
235
+ def take_screenshot(self, filename: str = "elementor_screenshot.png") -> bool:
236
+ """
237
+ Take a screenshot of the current state of the Elementor editor.
238
+ """
239
+ if not self.driver:
240
+ return False
241
+
242
+ try:
243
+ # Make sure we're in the main frame
244
+ self.driver.switch_to.default_content()
245
+
246
+ # Take screenshot
247
+ self.driver.save_screenshot(filename)
248
+ logger.info(f"Screenshot saved: {filename}")
249
+ return True
250
+
251
+ except Exception as e:
252
+ logger.error(f"Error taking screenshot: {e}")
253
+ return False
254
+
255
+
256
+ def parse_arguments():
257
+ """Parse command line arguments."""
258
+ parser = argparse.ArgumentParser(description='WordPress Elementor Design Agent (Basic)')
259
+ parser.add_argument('--url', default=os.environ.get('WP_ADMIN_URL', 'http://localhost/wp-admin/'),
260
+ help='WordPress admin URL')
261
+ parser.add_argument('--username', default=os.environ.get('WP_USERNAME', 'admin'),
262
+ help='WordPress username')
263
+ parser.add_argument('--password', default=os.environ.get('WP_PASSWORD', ''),
264
+ help='WordPress password')
265
+ parser.add_argument('--post-id', type=int, default=os.environ.get('WP_POST_ID', 1),
266
+ help='Post ID to edit with Elementor')
267
+ parser.add_argument('--headless', action='store_true',
268
+ help='Run browser in headless mode')
269
+ parser.add_argument('--screenshot', action='store_true',
270
+ help='Take a screenshot after loading Elementor')
271
+ parser.add_argument('--screenshot-path', default='elementor_editor.png',
272
+ help='Path to save the screenshot')
273
+ parser.add_argument('--wait-time', type=int, default=5,
274
+ help='Time to wait after loading Elementor (seconds)')
275
+
276
+ return parser.parse_arguments()
277
+
278
+
279
+ def main():
280
+ """Main function to run the script."""
281
+ args = parse_arguments()
282
+
283
+ agent = ElementorAgent(
284
+ url=args.url,
285
+ username=args.username,
286
+ password=args.password,
287
+ post_id=args.post_id,
288
+ headless=args.headless
289
+ )
290
+
291
+ if agent.start():
292
+ try:
293
+ logger.info(f"Elementor Agent (basic) started successfully for post ID {args.post_id}")
294
+
295
+ # Take a screenshot if requested
296
+ if args.screenshot:
297
+ agent.take_screenshot(args.screenshot_path)
298
+
299
+ # Wait the specified time
300
+ if args.wait_time > 0:
301
+ logger.info(f"Waiting for {args.wait_time} seconds...")
302
+ time.sleep(args.wait_time)
303
+
304
+ finally:
305
+ agent.close()
306
+ else:
307
+ logger.error("Failed to start Elementor Agent (basic)")
308
+
309
+
310
+ if __name__ == "__main__":
311
+ main()