forked from piair/MsRewards-Reborn
807 lines
30 KiB
Python
807 lines
30 KiB
Python
|
#!/usr/bin/python3.10
|
||
|
from modules.config import *
|
||
|
from modules.error import *
|
||
|
from modules.driver_tools import *
|
||
|
from modules.cards import *
|
||
|
import modules.globals as g
|
||
|
|
||
|
from modules.Classes.Config import Config
|
||
|
from modules.Classes.UserCredentials import UserCredentials
|
||
|
from modules.Tools.logger import warning, info, debug, error, critical
|
||
|
|
||
|
|
||
|
driver = g.driver
|
||
|
display = g.display
|
||
|
|
||
|
|
||
|
# create a webdriver
|
||
|
def create_driver(mobile=False):
|
||
|
PC_USER_AGENT = (
|
||
|
"Mozilla/5.0 (X11; Linux x86_64)"
|
||
|
"AppleWebKit/537.36 (KHTML, like Gecko)"
|
||
|
"Chrome/122.0.0.0 Safari/537.36 Edg/122.0.2088.46"
|
||
|
)
|
||
|
MOBILE_USER_AGENT = (
|
||
|
"Mozilla/5.0 (Linux; Android 7.0; Nexus 5 Build/MRA58N)"
|
||
|
"AppleWebKit/537.36 (KHTML, like Gecko)"
|
||
|
"Chrome/22 Mobile Safari/537.36"
|
||
|
)
|
||
|
chrome_options = webdriver.ChromeOptions()
|
||
|
if mobile:
|
||
|
chrome_options.add_argument(f"--user-agent={MOBILE_USER_AGENT}")
|
||
|
else:
|
||
|
chrome_options.add_argument(f"--user-agent={PC_USER_AGENT}")
|
||
|
# disabled as it may cause detection
|
||
|
if g.proxy_enabled:
|
||
|
chrome_options.add_argument(f'--proxy-server={g.proxy_address}:{g.proxy_port}')
|
||
|
driver = uc.Chrome(options=chrome_options)
|
||
|
set_language(driver)
|
||
|
return driver
|
||
|
|
||
|
|
||
|
def log_error(error_message, l_driver=driver, log=g.full_log):
|
||
|
global driver
|
||
|
if l_driver is None:
|
||
|
l_driver = driver
|
||
|
if type(error_message) is not str:
|
||
|
error_message = format_error(error_message)
|
||
|
|
||
|
error(str(error_message))
|
||
|
if g.discord_enabled_error:
|
||
|
with open("page.html", "w") as f:
|
||
|
try:
|
||
|
f.write(l_driver.page_source)
|
||
|
except:
|
||
|
f.write("the driver has closed or crashed. Can't access page content")
|
||
|
try:
|
||
|
img = display.waitgrab()
|
||
|
img.save("screenshot.png")
|
||
|
except:
|
||
|
l_driver.save_screenshot("screenshot.png")
|
||
|
if not log:
|
||
|
embed = Embed(
|
||
|
title="An Error has occured",
|
||
|
description=str(error_message),
|
||
|
colour=Colour.red(),
|
||
|
)
|
||
|
else:
|
||
|
embed = Embed(
|
||
|
title="Full log is enabled",
|
||
|
description=str(error_message),
|
||
|
colour=Colour.blue(),
|
||
|
)
|
||
|
file = File("screenshot.png")
|
||
|
embed.set_image(url="attachment://screenshot.png")
|
||
|
embed.set_footer(text=g._mail)
|
||
|
webhookFailure.send(embed=embed, username="error", file=file, avatar_url=g.avatar_url)
|
||
|
webhookFailure.send(username="error", file=File("page.html"), avatar_url=g.avatar_url)
|
||
|
|
||
|
|
||
|
# close the tab currently on and go back to the one first, or the one specified
|
||
|
def close_tab(tab, switch_to: int = 0) -> None:
|
||
|
driver.switch_to.window(tab)
|
||
|
driver.close()
|
||
|
driver.switch_to.window(driver.window_handles[switch_to])
|
||
|
|
||
|
|
||
|
# play_quiz[N]([int : override]) make the quiz with N choice each time. They usually have between 4 and 10 questions.
|
||
|
# override is the number of question, by default, it's the number of question in this specific quiz.
|
||
|
# Can be useful in some case, where the program crashes before finishing the quiz
|
||
|
def play_quiz2(override=10) -> None:
|
||
|
info("Starting to play quiz 2.")
|
||
|
debug(f"override: {override}")
|
||
|
for j in range(override):
|
||
|
custom_sleep(uniform(3, 5))
|
||
|
js_function = """
|
||
|
function get_correct_answer(){
|
||
|
function br(n) { for (var r, t = 0, i = 0; i < n.length; i++)t += n.charCodeAt(i); return r = parseInt(_G.IG.substr(_G.IG.length - 2), 16), t += r, t.toString() } // Ms check function
|
||
|
function namedRAValue() { //allow calls to getRAvalue
|
||
|
return _w.getRAValue()
|
||
|
};
|
||
|
if (br(document.getElementById("rqAnswerOption0").attributes["data-option"].value) == namedRAValue()){
|
||
|
return(0);
|
||
|
}
|
||
|
else {
|
||
|
return(1);
|
||
|
}
|
||
|
};
|
||
|
return(get_correct_answer())
|
||
|
"""
|
||
|
correct_answer_value = driver.execute_script(js_function)
|
||
|
try:
|
||
|
answer_elem = driver.find_element(By.ID, f"rqAnswerOption{correct_answer_value}")
|
||
|
answer_elem.click()
|
||
|
except exceptions.ElementNotInteractableException:
|
||
|
answer_elem = driver.find_element(By.ID, f"rqAnswerOption{correct_answer_value}")
|
||
|
driver.execute_script("arguments[0].click();", answer_elem)
|
||
|
except Exception as e:
|
||
|
log_error(e)
|
||
|
break
|
||
|
info("Quiz 2 done.")
|
||
|
custom_sleep(3)
|
||
|
|
||
|
|
||
|
def play_quiz8():
|
||
|
info(f"Starting Quiz 8")
|
||
|
override = len(findall("<span id=\"rqQuestionState.\" class=\"emptyCircle\"></span>", driver.page_source)) + 1
|
||
|
debug(f"override : {override}")
|
||
|
correct_answers = ["Should", "be", "reset", "before", "you", "see", "this."] # supress warning
|
||
|
try:
|
||
|
for _ in range(override):
|
||
|
sleep(uniform(3, 5))
|
||
|
correct_answers = []
|
||
|
for i in range(1, 9): # todo: remove this odd 1-offset
|
||
|
try:
|
||
|
element = driver.find_element(By.ID, f"rqAnswerOption{i - 1}")
|
||
|
if 'iscorrectoption="True"' in element.get_attribute("outerHTML"):
|
||
|
correct_answers.append(f'rqAnswerOption{i - 1}')
|
||
|
except Exception as e:
|
||
|
warning(f"can't find rqAnswerOption{i - 1}. Probably already clicked" + str(e))
|
||
|
shuffle(correct_answers)
|
||
|
for answer_id in correct_answers:
|
||
|
wait_until_visible(By.ID, answer_id, timeout=20, browser=driver)
|
||
|
try:
|
||
|
answer_elem = driver.find_element(By.ID, answer_id)
|
||
|
answer_elem.click()
|
||
|
sleep(1)
|
||
|
except exceptions.NoSuchElementException:
|
||
|
driver.refresh()
|
||
|
sleep(10)
|
||
|
answer_elem = driver.find_element(By.ID, answer_id)
|
||
|
answer_elem.click()
|
||
|
except ElementClickInterceptedException:
|
||
|
rgpd_popup(driver)
|
||
|
correct_answers.append(answer_id)
|
||
|
|
||
|
except Exception as e:
|
||
|
log_error(f"{format_error(e)} \n Good answers : {' '.join(correct_answers)}")
|
||
|
info("Quiz 8 done.")
|
||
|
custom_sleep(3)
|
||
|
|
||
|
|
||
|
def play_quiz4(override: int = None):
|
||
|
info(f"Starting Quiz 4")
|
||
|
|
||
|
if not override:
|
||
|
try: # fidelity quiz are much longer than usual ones
|
||
|
override = int(findall('rqQuestionState([\d]{1,2})"', driver.page_source)[-1])
|
||
|
except:
|
||
|
override = 3
|
||
|
debug(f"Override : {override}")
|
||
|
|
||
|
try:
|
||
|
for i in range(override):
|
||
|
custom_sleep(uniform(3, 5))
|
||
|
txt = driver.page_source
|
||
|
answer_option = search('correctAnswer":"([^"]+)', txt)[1]
|
||
|
answer_option = answer_option.replace("\\u0027", "'") # replace Unicode weird symbols
|
||
|
answer_element = driver.find_element(By.CSS_SELECTOR, f'[data-option="{answer_option}"]')
|
||
|
try:
|
||
|
answer_element.click()
|
||
|
except exceptions.ElementNotInteractableException:
|
||
|
driver.execute_script("arguments[0].click();", answer_element)
|
||
|
|
||
|
except Exception as e:
|
||
|
log_error(e)
|
||
|
raise ValueError(e)
|
||
|
info("Quiz 8 done.")
|
||
|
custom_sleep(3)
|
||
|
|
||
|
|
||
|
# do_poll() answer a random thing to poll, on of daily activities
|
||
|
def do_poll():
|
||
|
info("Starting poll")
|
||
|
try:
|
||
|
answer_elem = driver.find_element(By.ID, f"btoption{choice([0, 1])}")
|
||
|
try:
|
||
|
answer_elem.click()
|
||
|
except exceptions.ElementNotInteractableException:
|
||
|
driver.execute_script("arguments[0].click();", answer_elem)
|
||
|
custom_sleep(uniform(2, 2.5))
|
||
|
except Exception as err:
|
||
|
log_error(err)
|
||
|
raise ValueError(err)
|
||
|
info("Poll done.")
|
||
|
custom_sleep(3)
|
||
|
|
||
|
|
||
|
# Find each playable card and tries to click on it to earn points
|
||
|
# todo : refactor
|
||
|
def all_cards():
|
||
|
driver.get("https://rewards.bing.com")
|
||
|
wait_until_visible(By.CLASS_NAME, "c-card-content", 10, driver)
|
||
|
liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
|
||
|
custom_sleep(2)
|
||
|
try:
|
||
|
promo()
|
||
|
except Exception as e:
|
||
|
info("no promo card")
|
||
|
if (len(liste) < 10): # most likely an error during loading
|
||
|
if "suspendu" in driver.page_source:
|
||
|
raise Banned()
|
||
|
driver.refresh()
|
||
|
liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
|
||
|
if (len(liste) < 10):
|
||
|
log_error("Less than 10 cards. Most likely an error with login.", driver)
|
||
|
return ("PAS ASSEZ DE CARTES")
|
||
|
if (len(liste) < 20): # most likely not in france
|
||
|
printf("moins de 20 cartes. Probablement pas en France.")
|
||
|
for i in range(len(liste)):
|
||
|
printf(f"carte {i}")
|
||
|
try:
|
||
|
checked = ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML"))
|
||
|
except StaleElementReferenceException:
|
||
|
driver.refresh()
|
||
|
liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
|
||
|
printf(f"staled, {len(liste)}")
|
||
|
checked = ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML"))
|
||
|
except IndexError:
|
||
|
driver.get("https://rewards.bing.com")
|
||
|
custom_sleep(10)
|
||
|
liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
|
||
|
try:
|
||
|
checked = ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML"))
|
||
|
except IndexError:
|
||
|
if i == len(liste) & i > 15:
|
||
|
checked = False
|
||
|
# input("2")
|
||
|
if checked:
|
||
|
custom_sleep(1.5)
|
||
|
driver.execute_script("arguments[0].scrollIntoView();", liste[i])
|
||
|
custom_sleep(1.5)
|
||
|
# input("3")
|
||
|
liste[i].click()
|
||
|
# input("4")
|
||
|
if len(driver.window_handles) > 1:
|
||
|
driver.switch_to.window(driver.window_handles[1])
|
||
|
# input("5")
|
||
|
try_play(driver.title)
|
||
|
close_tab(driver.window_handles[1])
|
||
|
try:
|
||
|
driver.refresh()
|
||
|
liste = driver.find_elements(By.CLASS_NAME, "c-card-content")
|
||
|
if ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML")):
|
||
|
printf(f"carte {i} not okay. Retrying.")
|
||
|
try:
|
||
|
liste[i].click()
|
||
|
except:
|
||
|
log_error("problème inconnu ? sauf si c'est un element obscure...", driver)
|
||
|
driver.get("https://rewards.bing.com")
|
||
|
checked = ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML"))
|
||
|
driver.switch_to.window(driver.window_handles[1])
|
||
|
try_play(driver.title)
|
||
|
close_tab(driver.window_handles[1])
|
||
|
if ("mee-icon-AddMedium" in liste[i].get_attribute("innerHTML")):
|
||
|
driver.execute_script("arguments[0].scrollIntoView();", liste[i])
|
||
|
log_error(f"Card {i} Can't be completed. Why MS ?", driver)
|
||
|
liste[i].click()
|
||
|
driver.switch_to.window(driver.window_handles[1])
|
||
|
log_error(f"Cart completion - log - 2", driver)
|
||
|
custom_sleep(10)
|
||
|
log_error(f"Cart completion - log - 3 - after 10 sec", driver)
|
||
|
try:
|
||
|
try_play(driver.title) # go back to the main page
|
||
|
try:
|
||
|
close_tab(driver.window_handles[1])
|
||
|
except:
|
||
|
pass
|
||
|
except:
|
||
|
driver.get("https://rewards.bing.com")
|
||
|
except:
|
||
|
pass
|
||
|
else:
|
||
|
try:
|
||
|
welcome_tour(liste[i], driver)
|
||
|
except Exception as e:
|
||
|
printf("no new windows" + format_error(e))
|
||
|
driver.get("https://rewards.bing.com")
|
||
|
custom_sleep(3)
|
||
|
|
||
|
|
||
|
def promo():
|
||
|
for i in range(5):
|
||
|
elm = driver.find_element(By.ID, "promo-item")
|
||
|
wait_until_visible(By.ID, "promo-item", 5, driver)
|
||
|
if not elm:
|
||
|
break
|
||
|
if i > 3:
|
||
|
log_error("plus de 3 promo cards, probablement une pa skipable", driver)
|
||
|
try:
|
||
|
driver.find_element(By.CSS_SELECTOR,
|
||
|
'i[class="mee-icon pull-left icon mee-icon-Cancel ng-scope"]').click()
|
||
|
except Exception as e:
|
||
|
log_error(f"can't click to close : {e}")
|
||
|
return ()
|
||
|
try:
|
||
|
elm.click()
|
||
|
except Exception as e:
|
||
|
# log_error(e, driver)
|
||
|
driver.execute_script("arguments[0].click();", elm)
|
||
|
# log_error(e, driver)
|
||
|
printf(f"that should't be there (promo), but the workarround seemed to work {e}")
|
||
|
custom_sleep(3)
|
||
|
if len(driver.window_handles) > 1:
|
||
|
driver.switch_to.window(driver.window_handles[len(driver.window_handles) - 1])
|
||
|
try_play(driver.title)
|
||
|
close_tab(driver.window_handles[1])
|
||
|
else:
|
||
|
try:
|
||
|
spotify(driver)
|
||
|
except:
|
||
|
warning("no new windows")
|
||
|
driver.get("https://rewards.bing.com")
|
||
|
driver.refresh()
|
||
|
custom_sleep(3)
|
||
|
|
||
|
|
||
|
# Find out which type of action to do
|
||
|
def try_play(nom="inconnu"):
|
||
|
rgpd_popup(driver)
|
||
|
|
||
|
def play(number):
|
||
|
if number in [8, 9]:
|
||
|
try:
|
||
|
debug(f"Quiz 8 detected on `{nom}`.")
|
||
|
play_quiz8()
|
||
|
except Exception as err:
|
||
|
error(f"fail of PlayQuiz 8. Aborted {err}")
|
||
|
|
||
|
elif number in [4, 5]:
|
||
|
try:
|
||
|
debug(f"Quiz 4 detected on `{nom}`")
|
||
|
play_quiz4()
|
||
|
except Exception as err:
|
||
|
error(f"Fail of PlayQuiz 4. Aborted {err}.")
|
||
|
|
||
|
elif number in [2, 3]:
|
||
|
try:
|
||
|
debug(f"\033[96mQuiz 2 detected on `{nom}`\033[0m")
|
||
|
play_quiz2()
|
||
|
except Exception as err:
|
||
|
error(f"fail of PlayQuiz 2. Aborted {err}")
|
||
|
else:
|
||
|
error("`rqAnswerOption` present in page but no action to do.")
|
||
|
|
||
|
custom_sleep(uniform(3, 5))
|
||
|
|
||
|
if "pas connecté à Microsoft Rewards" in driver.page_source:
|
||
|
custom_sleep(5)
|
||
|
driver.find_element(By.CSS_SELECTOR, '[onclick="setsrchusr()"]').click()
|
||
|
custom_sleep(5)
|
||
|
rgpd_popup(driver)
|
||
|
custom_sleep(5)
|
||
|
debug("Detected and fixed connection popup")
|
||
|
|
||
|
if "bt_PollRadio" in driver.page_source:
|
||
|
debug("Poll detected")
|
||
|
do_poll()
|
||
|
|
||
|
elif "rqQuestionState" in driver.page_source:
|
||
|
number = driver.page_source.count("rqAnswerOption")
|
||
|
warning(f"recovery détecté. quiz : {number}")
|
||
|
play(number - 1)
|
||
|
|
||
|
elif search("([0-9]) de ([0-9]) finalisée", driver.page_source):
|
||
|
info("On fidelity page.")
|
||
|
fidelity()
|
||
|
|
||
|
elif wait_until_visible(By.ID, "rqStartQuiz", 5, driver):
|
||
|
custom_sleep(3)
|
||
|
driver.find_element(By.ID, "rqStartQuiz").click() # start the quiz
|
||
|
answer_number = driver.page_source.count("rqAnswerOption")
|
||
|
play(answer_number)
|
||
|
|
||
|
else:
|
||
|
printf(f"Nothing to do on page `{nom}`")
|
||
|
custom_sleep(uniform(3, 5))
|
||
|
|
||
|
|
||
|
# Login with password or with cookies.
|
||
|
# The driver should be in the same state on both case
|
||
|
def login_part_1(ldriver, cred: UserCredentials):
|
||
|
printf("pwd_login : start")
|
||
|
ldriver.get("https://login.live.com")
|
||
|
wait_until_visible(By.ID, "i0116", browser=ldriver)
|
||
|
mail_elem = ldriver.find_element(By.ID, "i0116")
|
||
|
send_keys_wait(mail_elem, cred.get_mail())
|
||
|
mail_elem.send_keys(Keys.ENTER)
|
||
|
wait_until_visible(By.ID, "i0118", browser=ldriver)
|
||
|
pwd_elem = ldriver.find_element(By.ID, "i0118")
|
||
|
send_keys_wait(pwd_elem, cred.get_password())
|
||
|
pwd_elem.send_keys(Keys.ENTER)
|
||
|
custom_sleep(2)
|
||
|
# 2FA
|
||
|
if "Entrez le code de sécurité" in ldriver.page_source:
|
||
|
try:
|
||
|
a2f_elem = ldriver.find_element(By.ID, "idTxtBx_SAOTCC_OTC")
|
||
|
a2f_elem.send_keys(g._otp.now())
|
||
|
a2f_elem.send_keys(Keys.ENTER)
|
||
|
except Exception as e:
|
||
|
log_error(e)
|
||
|
|
||
|
|
||
|
# Accept all cookies question, and check if the account is locked
|
||
|
def login_part_2(ldriver):
|
||
|
custom_sleep(5)
|
||
|
|
||
|
if 'Abuse' in ldriver.current_url:
|
||
|
raise Banned()
|
||
|
|
||
|
if 'identity' in ldriver.current_url:
|
||
|
raise Identity()
|
||
|
|
||
|
if 'notice' in ldriver.current_url:
|
||
|
ldriver.find_element(By.ID, "id__0").click()
|
||
|
|
||
|
if "proof" in ldriver.current_url:
|
||
|
ldriver.find_element(By.ID, "iLooksGood")
|
||
|
|
||
|
for elm_id in ["iNext", "KmsiCheckboxField", "id__0", "iLooksGood", "idSIButton9", "iCancel"]:
|
||
|
if get_domain(ldriver) == "account.microsoft.com":
|
||
|
break
|
||
|
try:
|
||
|
ldriver.find_element(By.ID, elm_id).click()
|
||
|
except Exception as e:
|
||
|
pass
|
||
|
|
||
|
wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 20, ldriver)
|
||
|
|
||
|
|
||
|
# login() tries to login to your Microsoft account.
|
||
|
# it uses global variable g._mail and g._password to login
|
||
|
def login(ldriver, cred: UserCredentials):
|
||
|
try:
|
||
|
login_part_1(ldriver, cred)
|
||
|
login_part_2(ldriver)
|
||
|
ldriver.get("https://rewards.bing.com/")
|
||
|
except Banned:
|
||
|
raise Banned()
|
||
|
except Identity:
|
||
|
raise Banned()
|
||
|
except Exception as e:
|
||
|
critical("Error not caught during login.")
|
||
|
log_error(e)
|
||
|
ldriver.quit()
|
||
|
return False
|
||
|
|
||
|
|
||
|
# Makes 30 search as PC Edge
|
||
|
def bing_pc_search(override=randint(35, 40)):
|
||
|
mot = choice(Liste_de_mot).replace(" ", "+")
|
||
|
driver.get(f"https://www.bing.com/search?q={mot}")
|
||
|
custom_sleep(uniform(1, 2))
|
||
|
rgpd_popup(driver)
|
||
|
send_keys_wait(
|
||
|
driver.find_element(By.ID, "sb_form_q"),
|
||
|
Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE + Keys.BACKSPACE
|
||
|
)
|
||
|
|
||
|
for _ in range(override):
|
||
|
word = choice(Liste_de_mot)
|
||
|
try:
|
||
|
send_keys_wait(driver.find_element(By.ID, "sb_form_q"), word)
|
||
|
driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER)
|
||
|
except Exception as e:
|
||
|
error(e)
|
||
|
sleep(10)
|
||
|
driver.get(f'https://www.bing.com/search?q={word}')
|
||
|
sleep(3)
|
||
|
send_keys_wait(driver.find_element(By.ID, "sb_form_q"), word)
|
||
|
driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER)
|
||
|
custom_sleep(uniform(3, 7))
|
||
|
try:
|
||
|
driver.find_element(By.ID, "sb_form_q").clear()
|
||
|
except Exception as e:
|
||
|
error(e)
|
||
|
try:
|
||
|
driver.get('https://www.bing.com/search?q=plans')
|
||
|
driver.find_element(By.ID, "sb_form_q").clear()
|
||
|
except Exception as e:
|
||
|
log_error(f"clear la barre de recherche - {format_error(e)}") # what is this message ??? todo
|
||
|
|
||
|
|
||
|
# Sends points to database, discord and whatever service you want
|
||
|
# todo: refactor
|
||
|
def log_points(account="unknown"):
|
||
|
def get_points():
|
||
|
driver.get("https://rewards.bing.com")
|
||
|
custom_sleep(1)
|
||
|
wait_until_visible(By.CSS_SELECTOR, 'span[mee-element-ready="$ctrl.loadCounterAnimation()"]', browser=driver)
|
||
|
try:
|
||
|
point = search('availablePoints\":([\d]+)', driver.page_source)[1]
|
||
|
except Exception as e:
|
||
|
log_error(
|
||
|
f"Dev error, checking why it doesn't work (waited a bit, is this still white ?) {format_error(e)}",
|
||
|
driver)
|
||
|
error("Can't get points.")
|
||
|
return -1
|
||
|
return point
|
||
|
|
||
|
points = get_points()
|
||
|
custom_sleep(uniform(3, 20))
|
||
|
account_name = account.split("@")[0]
|
||
|
|
||
|
if g.discord_enabled_success:
|
||
|
if g.discord_embed:
|
||
|
embed = Embed(
|
||
|
title=f"{account_name} actuellement à {str(points)} points", colour=Colour.green()
|
||
|
)
|
||
|
embed.set_footer(text=account_name)
|
||
|
webhookSuccess.send(embed=embed)
|
||
|
else:
|
||
|
webhookSuccess.send(f"{account_name} actuellement à {str(points)} points")
|
||
|
|
||
|
try:
|
||
|
add_to_database(account_name, points)
|
||
|
except Exception as e:
|
||
|
log_error(e)
|
||
|
|
||
|
|
||
|
# todo: refactor and check if it works at all
|
||
|
def fidelity():
|
||
|
def sub_fidelity():
|
||
|
try:
|
||
|
wait_until_visible(By.CSS_SELECTOR, 'div[class="pull-left spacer-48-bottom punchcard-row"]', browser=driver)
|
||
|
answer_number = search("([0-9]) of ([0-9]) completed", driver.page_source)
|
||
|
if answer_number is None:
|
||
|
answer_number = search("([0-9]) défi\(s\) terminé\(s\) sur ([0-9])", driver.page_source)
|
||
|
if answer_number is None:
|
||
|
answer_number = search("([0-9]) de ([0-9]) finalisé", driver.page_source)
|
||
|
if answer_number is None:
|
||
|
answer_number = search("([0-9]) licence\(s\) sur ([0-9]) disponible\(s\)", driver.page_source)
|
||
|
if answer_number is None:
|
||
|
answer_number = [0, 0, 0]
|
||
|
for _ in range(int(answer_number[2]) - int(answer_number[1])):
|
||
|
driver.refresh()
|
||
|
custom_sleep(2)
|
||
|
card_elem = driver.find_element(By.CLASS_NAME, "spacer-48-bottom")
|
||
|
try:
|
||
|
button_text = search('<span class="pull-left margin-right-15">([^<^>]+)</span>',
|
||
|
card_elem.get_attribute("innerHTML"))[1]
|
||
|
bouton_card = driver.find_element(By.XPATH, f'//span[text()="{button_text}"]')
|
||
|
bouton_card.click()
|
||
|
except Exception as e1:
|
||
|
try:
|
||
|
recover_elem = driver.find_element(By.XPATH,
|
||
|
'/html/body/div[1]/div[2]/main/div[2]/div[2]/div[7]/div[3]/div[1]/a')
|
||
|
recover_elem.click()
|
||
|
except Exception as e2:
|
||
|
log_error(f"fidélité - double erreur - e1 : {format_error(e1)} - e2 {format_error(e2)}")
|
||
|
break
|
||
|
custom_sleep(uniform(3, 5))
|
||
|
driver.switch_to.window(driver.window_handles[2])
|
||
|
try_play(driver.title)
|
||
|
custom_sleep(uniform(3, 5))
|
||
|
try:
|
||
|
close_tab(driver.window_handles[2], 1)
|
||
|
except Exception as e:
|
||
|
printf(e)
|
||
|
printf("fidelity - done")
|
||
|
except Exception as e:
|
||
|
log_error(e)
|
||
|
|
||
|
if driver.current_url != "https://rewards.bing.com":
|
||
|
driver.get("https://rewards.bing.com")
|
||
|
try:
|
||
|
pause = driver.find_element(By.CSS_SELECTOR,
|
||
|
f'[class="c-action-toggle c-glyph f-toggle glyph-pause"]') # mettre le truc en pause
|
||
|
pause.click()
|
||
|
except Exception as e:
|
||
|
printf(f"erreur lors du click de pause: probablement pas de cartes {e}")
|
||
|
return ("no cards")
|
||
|
cartes = driver.find_elements(By.CSS_SELECTOR, f'[ng-repeat="item in $ctrl.transcludedItems"]')
|
||
|
nb_cartes = len(cartes)
|
||
|
checked_list_all = driver.find_elements(By.CSS_SELECTOR, f'[ng-if="$ctrl.complete"]')
|
||
|
for i in range(nb_cartes):
|
||
|
cartes[i].click() # affiche la bonne carte
|
||
|
checked_txt = checked_list_all[i].get_attribute("innerHTML")
|
||
|
ok = checked_txt.count("StatusCircleOuter checkmark")
|
||
|
total = checked_txt.count("StatusCircleOuter")
|
||
|
if (ok != total):
|
||
|
elm = driver.find_elements(By.CLASS_NAME, 'clickable-link')[i]
|
||
|
if not "moviesandtv" in elm.get_attribute("innerHTML"): # not the film card
|
||
|
elm.click()
|
||
|
driver.switch_to.window(driver.window_handles[len(driver.window_handles) - 1])
|
||
|
sub_fidelity()
|
||
|
close_tab(driver.window_handles[1])
|
||
|
custom_sleep(1)
|
||
|
cartes = driver.find_elements(By.CSS_SELECTOR, f'[ng-repeat="item in $ctrl.transcludedItems"]')
|
||
|
checked_list_all = driver.find_elements(By.CSS_SELECTOR, f'[ng-if="$ctrl.complete"]')
|
||
|
|
||
|
|
||
|
def mobile_alert_popup():
|
||
|
try:
|
||
|
alert = mobile_driver.switch_to.alert
|
||
|
alert.dismiss()
|
||
|
except exceptions.NoAlertPresentException:
|
||
|
pass
|
||
|
except Exception as err:
|
||
|
log_error(err, mobile_driver)
|
||
|
|
||
|
|
||
|
# todo: be coherent with pc search regarding error management
|
||
|
def bing_mobile_search(cred: UserCredentials, override=randint(22, 25)):
|
||
|
global mobile_driver
|
||
|
mobile_driver = create_driver(mobile=True)
|
||
|
try:
|
||
|
login(mobile_driver, cred)
|
||
|
mot = choice(Liste_de_mot).replace(" ", "+")
|
||
|
mobile_driver.get(f"https://www.bing.com/search?q={mot}")
|
||
|
custom_sleep(uniform(1, 2))
|
||
|
rgpd_popup(mobile_driver)
|
||
|
custom_sleep(uniform(1, 1.5))
|
||
|
for i in range(override): # 20
|
||
|
try:
|
||
|
mot = choice(Liste_de_mot)
|
||
|
send_keys_wait(mobile_driver.find_element(By.ID, "sb_form_q"), mot)
|
||
|
mobile_driver.find_element(By.ID, "sb_form_q").send_keys(Keys.ENTER)
|
||
|
custom_sleep(uniform(3, 7))
|
||
|
mobile_alert_popup() # check for alert (asking for position or for allowing notifications)
|
||
|
mobile_driver.find_element(By.ID, "sb_form_q").clear()
|
||
|
except Exception as err:
|
||
|
error(err)
|
||
|
mobile_driver.refresh()
|
||
|
custom_sleep(30)
|
||
|
i -= 1
|
||
|
mobile_driver.quit()
|
||
|
|
||
|
except Exception as err:
|
||
|
log_error(err, mobile_driver)
|
||
|
mobile_driver.quit()
|
||
|
|
||
|
|
||
|
def daily_routine(cred: UserCredentials, custom=False):
|
||
|
try:
|
||
|
if not custom: # custom already is logged in
|
||
|
login(driver, cred)
|
||
|
except Banned:
|
||
|
log_error("This account is locked.", driver)
|
||
|
return
|
||
|
except Identity:
|
||
|
log_error("This account has an issue.", driver)
|
||
|
return
|
||
|
|
||
|
try:
|
||
|
all_cards()
|
||
|
except Banned:
|
||
|
log_error("banned", driver)
|
||
|
raise Banned
|
||
|
except Exception as err:
|
||
|
log_error(err)
|
||
|
|
||
|
try:
|
||
|
fidelity()
|
||
|
except Exception as err:
|
||
|
log_error(err)
|
||
|
|
||
|
try:
|
||
|
bing_pc_search()
|
||
|
except Exception as err:
|
||
|
log_error(err)
|
||
|
|
||
|
try:
|
||
|
bing_mobile_search(cred)
|
||
|
except Exception as err:
|
||
|
log_error(err)
|
||
|
|
||
|
try:
|
||
|
log_points(cred.get_mail())
|
||
|
except Exception as err:
|
||
|
log_error(err)
|
||
|
|
||
|
|
||
|
def json_start(json_entry, cred: UserCredentials):
|
||
|
global driver
|
||
|
display = SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=2345, color_depth=24)
|
||
|
display.start()
|
||
|
|
||
|
for i in range(5):
|
||
|
start = False
|
||
|
for j in ["unban", "tout", "pc", "mobile", "daily"]:
|
||
|
try:
|
||
|
if str(i) in json_entry[j]:
|
||
|
start = True
|
||
|
info(f"{cred.get_mail()} : {j}")
|
||
|
except KeyError:
|
||
|
pass
|
||
|
if start:
|
||
|
driver = create_driver()
|
||
|
try:
|
||
|
if str(i) in json_entry["unban"]:
|
||
|
login_part_1(driver, cred)
|
||
|
print("\nGO TO example.com TO PROCEED or wait 1200 secs.")
|
||
|
for _ in range(1200):
|
||
|
sleep(1)
|
||
|
if driver.current_url == "https://example.com/":
|
||
|
print("proceeding")
|
||
|
break
|
||
|
else:
|
||
|
login(driver, cred)
|
||
|
except KeyError:
|
||
|
login(driver, cred)
|
||
|
try:
|
||
|
if str(i) in json_entry["tout"]:
|
||
|
daily_routine(cred)
|
||
|
except KeyError:
|
||
|
pass
|
||
|
# print("none is set to \"tout\"")
|
||
|
else:
|
||
|
try:
|
||
|
if str(i) in json_entry["daily"]:
|
||
|
try:
|
||
|
all_cards()
|
||
|
except Exception as e:
|
||
|
log_error(e)
|
||
|
except KeyError:
|
||
|
pass
|
||
|
# print("none is set to \"daily\"")
|
||
|
try:
|
||
|
if str(i) in json_entry["pc"]:
|
||
|
try:
|
||
|
bing_pc_search()
|
||
|
except Exception as e:
|
||
|
log_error(e)
|
||
|
except KeyError:
|
||
|
pass
|
||
|
try:
|
||
|
if str(i) in json_entry["mobile"]:
|
||
|
try:
|
||
|
bing_mobile_search(cred)
|
||
|
except Exception as e:
|
||
|
log_error(e)
|
||
|
except KeyError:
|
||
|
pass
|
||
|
try:
|
||
|
log_points(g._mail)
|
||
|
except Exception as e:
|
||
|
printf(f"CustomStart {e}")
|
||
|
driver.close()
|
||
|
cred.next_account()
|
||
|
display.stop()
|
||
|
|
||
|
|
||
|
c = Config(args)
|
||
|
|
||
|
if g.json_start:
|
||
|
dict_data = json.loads(g.json_start.replace("'", "\""))
|
||
|
json_start(dict_data, c.UserCredentials)
|
||
|
|
||
|
else:
|
||
|
|
||
|
if g.vnc_enabled or g.dev:
|
||
|
display = SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=g.vnc_port, color_depth=24)
|
||
|
else:
|
||
|
display = SmartDisplay(size=(1920, 1080))
|
||
|
display.start()
|
||
|
|
||
|
if g.update_version != "None":
|
||
|
if g.discord_enabled_error:
|
||
|
webhookFailure.send(f"Updated to {g.update_version}", username="UPDATE",
|
||
|
avatar_url="https://cdn-icons-png.flaticon.com/512/1688/1688988.png")
|
||
|
|
||
|
while c.UserCredentials.is_valid():
|
||
|
custom_sleep(1)
|
||
|
info("Starting driver.")
|
||
|
driver = create_driver()
|
||
|
info("Driver started.")
|
||
|
driver.implicitly_wait(3)
|
||
|
try:
|
||
|
wait_time = uniform(1200, 3600)
|
||
|
info(f"Waiting for {round(wait_time / 60)}min before starting")
|
||
|
daily_routine(c.UserCredentials)
|
||
|
driver.quit()
|
||
|
custom_sleep(wait_time)
|
||
|
except KeyboardInterrupt:
|
||
|
critical("Canceled by user. Closing driver and display.")
|
||
|
driver.quit()
|
||
|
display.stop()
|
||
|
break
|
||
|
except Exception as e:
|
||
|
log_error(f"Error not caught. Skipping this account. " + format_error(e), driver)
|
||
|
critical(f"Error not caught. Skipping this account. {e}")
|
||
|
driver.quit()
|
||
|
|
||
|
c.UserCredentials.next_account()
|
||
|
|
||
|
display.stop()
|