-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvoltaire-ez.py
255 lines (227 loc) · 13 KB
/
voltaire-ez.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
import os
import re
import time
import undetected_chromedriver as uc
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
import sqlite3
import random
from dotenv import load_dotenv
load_dotenv()
email = os.getenv('EMAIL')
password = os.getenv('PASSWORD')
def split_text(mistake_text):
# Find the first alphanumeric word or character
match = re.search(r'\b\w+\b', mistake_text)
# If a match is found, return it. Otherwise, return an empty string
return match.group() if match else ''
def send_keys_human_speed(element, keys):
for key in keys:
element.send_keys(key)
time.sleep(0.15) # Adjust the sleep duration to control the typing speed
def main():
driver = uc.Chrome()
driver.maximize_window()
driver.get('https://projet-voltaire.fr/')
print("👋 Welcome to Voltaire Ez!")
# Checks cookie
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CLASS_NAME, "cmpboxbtn"))).click()
# Clicks on the login button
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "authenticateOption"))).click()
# Fills the email and password fields
email_field = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "login-username")))
password_field = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "login-pwd")))
send_keys_human_speed(email_field, email)
send_keys_human_speed(password_field, password)
# Waits for the user to complete the captcha
print("Please resolve the captcha and click the sign in button to continue...")
# Clicks on the cookie button
WebDriverWait(driver, 60).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".modal-footer > button"))).click()
# Enters "orthographe" section
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#applicationOrthographe"))).click()
print("")
print("Entering the training...")
# CSS selectors for the three categories
categories = ['#productTab_1', '#productTab_2', '#productTab_3']
for category in categories:
try:
# Try to enter the category
WebDriverWait(driver, 2).until(EC.element_to_be_clickable((By.CSS_SELECTOR, category))).click()
# Try to start an exercise
WebDriverWait(driver, 2).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.singleRunnable'))).click()
# If an exercise was started, wait for it to load and then break the loop
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".top-side-bar-training")))
break
except TimeoutException:
# If there's no exercise available in this category, continue with the next category
continue
else:
# If there's no exercise available in any category, exit the program
print("❌ No more exercises available. Exiting the program...")
driver.quit()
exit()
print("")
response_auto = input("❓ Do you want to go automatically to the next exercises? (y/n) ")
if response_auto.lower() == 'y':
pass
elif response_auto.lower() == 'n':
pass
else:
print("")
print("❌ Invalid input. Please enter 'y' or 'n'.")
# Connect to the database
with sqlite3.connect('sentences.db') as conn:
# Create a cursor object
c = conn.cursor()
# Create table named 'Sentences' if it doesn't exist
c.execute('''CREATE TABLE IF NOT EXISTS Sentences
(sentence TEXT, no_mistake INTEGER, mistake_text TEXT)''')
# Forloop connected to the database to go through the exercices
while True:
print("")
print("🤞 Starting new exercise...")
# Check if a popup has appeared
try:
WebDriverWait(driver, 1).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".popupPanel")))
# print("")
# print("Popup!")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".understoodButton"))).click()
time.sleep(0.1)
# Click on random buttons
intensive_questions = WebDriverWait(driver, 20).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.intensiveQuestion')))
for question in intensive_questions:
# Randomly choose between .buttonOk and .buttonKo
button = random.choice(['.buttonOk', '.buttonKo'])
question.find_element(By.CSS_SELECTOR, button).click()
time.sleep(0.1)
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".exitButton"))).click()
except TimeoutException:
# print("")
# print("No popup!")
pass
try:
# Find all words within the sentence
span_elements = WebDriverWait(driver, 5).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".sentence .pointAndClickSpan")))
if span_elements:
# Initialize an empty string to store the sentence
sentence = ''
# Iterate over the span elements and concatenate their text
for span in span_elements:
# If the span is empty, add a space to the sentence
if span.text == '':
sentence += ' '
# Otherwise, add the span's text to the sentence
else:
sentence += span.text
# print("")
# print("Sentence is:")
# print(sentence)
# Execute a SELECT query to check if a row with the sentence already exists
c.execute("SELECT * FROM Sentences WHERE sentence = ?", (sentence,))
row = c.fetchone()
# If the row exists, clicks on the mistake
if row is not None:
print("🚀 Sentence already exists in the database!")
no_mistake = row[1] # Assuming no_mistake is the second column in the table
# If there's no mistake
if no_mistake == 1:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".noMistakeButton"))).click()
print("🏅 Gotcha!")
else:
mistake_text = row[2] # Assuming mistake_text is the third column in the table
# print(mistake_text)
for span in span_elements:
if span.text == mistake_text:
span.click()
print("🏅 Gotcha!")
break
# If the row doesn't exist, insert the sentence into the 'Sentences' table
else:
print("⛏️ New sentence found!")
# Clicks on the "No mistake" button
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".noMistakeButton"))).click()
# Waits for the answer to appear
WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".answerStatusBar")))
# Checks if the answer is correct or not
try:
driver.find_element(By.CSS_SELECTOR, '.answerStatusBar.correct')
print("🏅 Gotcha!")
no_mistake = 1
mistake_text = None # No mistake text when there are no mistakes
except:
print("✒️ There's a mistake! Saving it...")
no_mistake = 0
mistake_element = driver.find_element(By.CSS_SELECTOR, '.answerWord')
mistake_text = mistake_element.text
mistake_text = split_text(mistake_text)
# Inserts the sentence and the correctness of the answer into the 'Sentences' table
c.execute("INSERT INTO Sentences VALUES (?, ?, ?)", (sentence, no_mistake, mistake_text))
conn.commit()
# Goes to the next question
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".nextButton"))).click()
except TimeoutException:
# Checks whether we're at the end screen or not
try:
# Check if the element .trainingEndViewDiv is present
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, '.trainingEndViewDiv')))
print("")
print("🎉 Level completed!")
# If the user chose to go manually to the next exercises
if response_auto.lower() == 'n':
response = input("Do you want to continue? (y/n) ")
if response.lower() == 'y':
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".trainingEndViewGoHome"))).click()
for category in categories:
try:
# Try to enter the category
WebDriverWait(driver, 2).until(EC.element_to_be_clickable((By.CSS_SELECTOR, category))).click()
# Try to start an exercise
WebDriverWait(driver, 2).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.singleRunnable'))).click()
# If an exercise was started, wait for it to load and then break the loop
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".top-side-bar-training")))
break
except TimeoutException:
# If there's no exercise available in this category, continue with the next category
continue
else:
# If there's no exercise available in any category, exit the program
print("❌ No more exercises available. Exiting the program...")
break
# Exiting the while loop
elif response.lower() == 'n':
break
else:
print("")
print("❌ Invalid input. Please enter 'y' or 'n'.")
# If the user chose to go automatically to the next exercises
else:
print("🚀 Going to the next exercise...")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".trainingEndViewGoHome"))).click()
for category in categories:
try:
# Try to enter the category
WebDriverWait(driver, 2).until(EC.element_to_be_clickable((By.CSS_SELECTOR, category))).click()
# Try to start an exercise
WebDriverWait(driver, 2).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.singleRunnable'))).click()
# If an exercise was started, wait for it to load and then break the loop
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".top-side-bar-training")))
break
except TimeoutException:
# If there's no exercise available in this category, continue with the next category
continue
else:
# If there's no exercise available in any category, exit the program
print("❌ No more exercises available. Exiting the program...")
break
# If we're not at the end screen, do nothing and continue the loop
except TimeoutException:
pass
# If we get out of the while loop, end the program
print("")
print("❤️ Thanks for using Voltaire Ez!")
driver.quit()
exit()
if __name__ == "__main__":
main()