23 Commits

Author SHA1 Message Date
024b556f5e bruh 2023-04-13 09:11:12 +02:00
b4c9204bf2 oh gosh 2023-04-12 18:25:12 +02:00
f810f0ee3c test 2023-04-12 14:40:32 +02:00
afac7e9539 bump 2023-04-12 13:29:40 +02:00
ae12c18270 not stable either, but something need to change 2023-04-12 13:29:06 +02:00
dfd51bc040 uéuéué faster, more reliable, ... 2023-04-12 00:01:24 +02:00
12a6968ee0 well, SadPanda is still here ;( 2023-04-09 23:41:31 +02:00
8726785dc8 random test 2023-04-08 12:08:26 +02:00
e9f629dee4 sadpanda + typo 2023-04-08 11:51:27 +02:00
c9a838d368 faster overall + better discord error + better login 2023-04-07 23:28:48 +02:00
808916ddd3 testing is everything 2023-04-07 10:04:59 +02:00
c51c463338 the passage to 5.3 wasn't justified ( at least not enough) so i added a new feature 2023-04-07 10:01:47 +02:00
a22d1e6ddb you can manually add points to database 2023-04-07 09:53:11 +02:00
93bb634f7c some fixes here and there 2023-04-06 23:41:11 +02:00
31426a1dfd well, it should be really more robust as it doesn't rely on XPATH everywhere anymore 2023-04-06 23:04:57 +02:00
f862af8699 version control 2023-04-04 21:27:02 +02:00
78e7342acf last update of the night ? 2023-04-04 21:26:40 +02:00
4d8157ba1e better stronger faster 2023-04-04 21:18:09 +02:00
661566aade no clue if that's better 2023-04-04 21:07:12 +02:00
eb2b9dc2d3 you should now start using main : it can finally pass args 2023-04-04 20:59:45 +02:00
3385540350 better way if manually updated 2023-04-04 20:50:56 +02:00
0588180dda should be good for now 2023-04-04 20:46:10 +02:00
9995bc8e25 Auto Updates ? 2023-04-04 20:37:48 +02:00
12 changed files with 298 additions and 344 deletions

2
.gitignore vendored
View File

@ -11,3 +11,5 @@ data
/user_data
install.sh
nohup.out
test.py
points.csv

View File

@ -3,7 +3,7 @@
A Microsoft reward automator, designed to work headless on any server.
Using a discord webhook or SQL to log points everyday.
Using Selenium and geckodriver.
Using Selenium and Geckodriver.
## If you're using docker (way easier)
to use docker, run
@ -12,17 +12,17 @@ sudo docker build .
#copy the build id
sudo docker run -ti --name MsRewards [build id]
```
Then, fill the config and start the programm everydays with
Then, fill the config and start the program everyday with
```
sudo docker start MsRewards
```
## Other configuration
To use the database, I recommand MySql, Create a database with the name you want and create a table `daily`, like the one from the image :
To use the database, I recommend MySql, Create a database with the name you want and create a table `daily`, like the one from the image :
![B96F2F6D-7257-4F12-BFA7-0BEC3FB72993](https://user-images.githubusercontent.com/74496300/172872979-05396b6b-b682-471a-b71b-41602d816504.jpeg)
You have to use the default worldlist (`sudo apt install wfrench`). The language is french by default, but you can change it if you want.
You have to use the default world list (`sudo apt install wfrench`). The language is french by default, but you can change it if you want.
You can add a link to a website where content is only the link of the monthly fidelity card.

400
V5.py
View File

@ -5,19 +5,15 @@ from modules.config import *
from modules.tools import *
from modules.error import *
from modules.driver_tools import *
import modules.globals as g
global driver
driver = None
global _mail, _password, _otp, display
# TODO : replace by a better print (with logging, cf https://realpython.com/python-logging/)
def printf(e):
printf2(str(e), _mail)
driver = g.driver
display = g.display
# TODO
# handle "panda"'s error: error while logging in preventing some task to be done
# check that each card worked (lot of misses lately) -- test that -- don't crash at least
# Fix l'affichage du compteur de custom_sleep
# handle "panda"'s error: error while logging in preventing some task to be done SadPanda.svg:
# create a webdriver
@ -44,11 +40,11 @@ def firefox_driver(mobile=False, headless=False):
if mobile :
options.set_preference("general.useragent.override", MOBILE_USER_AGENT)
driver = webdriver.Firefox(options=options)
driver.set_window_size(1070 + hash(_mail)%20 , 1900 + hash(_password + "salt")%10) # mobile resolution are crazy high now, right ?
driver.set_window_size(1070 + hash(g._mail)%20 , 1900 + hash(g._password + "salt")%10) # mobile resolution are crazy high now, right ?
else :
options.set_preference("general.useragent.override", PC_USER_AGENT)
driver = webdriver.Firefox(options=options)
driver.set_window_size(1900 + hash(_mail)%20 , 1070 + hash(_password + "salt")%10)
driver.set_window_size(1900 + hash(g._mail)%20 , 1070 + hash(g._password + "salt")%10)
return(driver)
@ -84,10 +80,9 @@ def log_error(error, ldriver=driver, log=FULL_LOG):
)
file = File("screenshot.png")
embed.set_image(url="attachment://screenshot.png")
embed.set_footer(text=_mail)
webhookFailure.send(embed=embed, file=file)
webhookFailure.send(file=File("page.html"))
embed.set_footer(text=g._mail)
webhookFailure.send(embed=embed, username="error", file=file, avatar_url = AVATAR_URL)
webhookFailure.send(username="error", file=File("page.html"), avatar_url = AVATAR_URL)
# close the tab currently on and go back to the one first, or the one specified
@ -103,7 +98,7 @@ def play_quiz2(override=10) -> None:
printf("starting play_quiz2")
for j in range(override):
try:
rgpd_popup(driver)
# rgpd_popup(driver)
custom_sleep(uniform(3, 5))
page_html = driver.page_source
secret_answer = search('IG:"([^"]+)"', page_html)[1] # variable used to calculate offset
@ -137,9 +132,9 @@ def play_quiz8():
printf(f"play_quiz8 : start, override : {override}")
try:
counter = 0
rgpd_popup(driver)
# rgpd_popup(driver)
for _ in range(override):
custom_sleep(uniform(3, 5))
sleep(uniform(3, 5))
correct_answers = []
for i in range(1,9):
try :
@ -156,10 +151,10 @@ def play_quiz8():
try:
answer_elem = driver.find_element(By.ID, answer_id)
answer_elem.click()
custom_sleep(1)
sleep(1)
except exceptions.NoSuchElementException :
driver.refresh()
custom_sleep(10)
sleep(10)
answer_elem = driver.find_element(By.ID, answer_id)
answer_elem.click()
except ElementClickInterceptedException :
@ -184,7 +179,7 @@ def play_quiz4(override=None):
for i in range(override):
custom_sleep(uniform(3, 5))
txt = driver.page_source
rgpd_popup(driver)
# rgpd_popup(driver)
answer_option = search('correctAnswer":"([^"]+)', txt)[1]
answer_option = answer_option.replace("\\u0027", "'") # replace Unicode weird symbols
try:
@ -221,9 +216,10 @@ def all_cards(): # return to the main page and closes all other tabs
if len(driver.window_handles) == 1:
driver.get("https://www.bing.com/rewardsapp/flyout")
if part2:
driver.find_element(
By.XPATH, "/html/body/div/div/div[3]/div[2]/div[2]/div[2]/div[1]"
).click()
row_element = driver.find_elements(By.CSS_SELECTOR, f'[class="i-h rw-sh fp_row"]')[1]
expanded = row_element.get_attribute("aria-expanded")
if expanded != "true":
row_element.click()
else:
driver.switch_to.window(driver.window_handles[1])
printf(f"fermeture : {driver.current_url}")
@ -233,10 +229,10 @@ def all_cards(): # return to the main page and closes all other tabs
driver.get("https://www.bing.com/rewardsapp/flyout")
reset(part2)
def daily_cards(): # cartes de la premiere partie (renouvelées chaque jours).
def daily_cards(): # cartes de la premiere partie (renouvelée chaque jour).
try:
# make sure that the daily area is expanded
row_element = driver.find_element(By.XPATH, "/html/body/div/div/div[3]/div[2]/div[1]/div[1]")
row_element = driver.find_elements(By.CSS_SELECTOR, f'[class="i-h rw-sh fp_row"]')[0]
expanded = row_element.get_attribute("aria-expanded")
if expanded != "true":
row_element.click()
@ -244,9 +240,8 @@ def all_cards(): # return to the main page and closes all other tabs
custom_sleep(uniform(3, 5))
try:
titre = "Placeholder"
driver.find_element(
By.XPATH,f"/html/body/div/div/div[3]/div[2]/div[1]/div[2]/div/div[{i+1}]/a",
).click()
elm = driver.find_elements(By.CLASS_NAME, 'promo_cont')
elm[i].click()
sleep(1)
titre = driver.title
try_play(titre)
@ -254,51 +249,52 @@ def all_cards(): # return to the main page and closes all other tabs
reset()
printf(f"DailyCard {titre} ok")
except Exception as e:
log_error(f"all_cards card {titre} error ({format_error(e)})")
log_error(f"all_cards card `{titre}` error ({format_error(e)})")
break
try : # devrait renvoyer vrai si la carte i est faite ou pas, a l'aide su symbole en haut a droite de la carte
elm = driver.find_element(By.XPATH, f"/html/body/div/div/div[3]/div[2]/div[1]/div[2]/div/div[{i+1}]/a/div/div[2]/div[1]/div[2]/div")
elm = driver.find_elements(By.CLASS_NAME, 'promo_cont')[i]
if not ("correctCircle" in elm.get_attribute("innerHTML")):
printf(f"missed card {i}")
try_play(titre)
elm.click()
try_play("recovery")
sleep(3)
reset()
else :
printf(f'carte OK')
except Exception as e :
printf(format_error(e) + "probablement ok - check card")
printf(format_error(e) + " probablement ok - check card")
# if it fail, it's probably okay -> when all three card are done, the pannel fold
except Exception as e:
log_error(e)
def weekly_cards():
# make sure that the weekly area is expanded
row_element = driver.find_element(By.XPATH, "/html/body/div/div/div[3]/div[2]/div[2]/div[2]")
row_element = driver.find_elements(By.CSS_SELECTOR, f'[class="i-h rw-sh fp_row"]')[1]
expanded = row_element.get_attribute("aria-expanded")
if expanded != "true":
row_element.click()
for i in range(20): # Should raise an error whene there is no card left
printf("début de l'une des cartes")
driver.find_element(
By.XPATH,
"/html/body/div/div/div[3]/div[2]/div[2]/div[3]/div/div[1]/a/div/div[2]",
).click()
elm = driver.find_elements(By.CLASS_NAME, 'promo_cont')
try :
elm[0].click()
printf(f"Carte {i+1} cliquée.")
except Exception as e :
printf(f"Plus aucune carte.")
break
driver.switch_to.window(driver.window_handles[len(driver.window_handles) - 1])
sleep(1)
titre = driver.title
printf(f"carte {titre} en cours")
titre = driver.title.split(" - Recherche")[0]
printf(f"Carte `{titre}` en cours.")
try_play(titre)
reset(True)
sleep(1)
try:
findall('href="([^<]+)" title=""', driver.page_source)[3] # return error if there is no cards left to do
except:
break
def top_cards():
for _ in range(10):
for _ in range(2):
try :
driver.find_element(By.XPATH, "/html/body/div/div/div[3]/div[1]/div/div[1]/div[2]").click()
driver.find_elements(By.CSS_SELECTOR, '[class="banner_cont single wpoints"]')[0].click()
reset()
except Exception as e:
printf(format_error(e))
@ -322,33 +318,31 @@ def all_cards(): # return to the main page and closes all other tabs
# Find out which type of action to do
def try_play(nom="inconnu"):
rgpd_popup(driver)
printf("try_play en cours")
# rgpd_popup(driver)
def play(number):
if number == 8 or number == 9:
try:
printf(f"\033[96m Quiz 8 detected on {nom} \033[0m")
printf(f"\033[96mQuiz 8 detected on `{nom}` \033[0m")
play_quiz8()
printf(f"\033[92m Quiz 8 succeeded on {nom} \033[0m")
printf(f"\033[92mQuiz 8 succeeded on `{nom}` \033[0m")
custom_sleep(uniform(3, 5))
except Exception as e:
printf(f"fail of PlayQuiz 8. Aborted {e} \033[0m")
elif number == 5 or number == 4:
try:
printf(f"\033[96m Quiz 4 detected on {nom} \033[0m")
printf(f"\033[96mQuiz 4 detected on `{nom}` \033[0m")
play_quiz4()
printf(f"\033[92m Quiz 4 succeeded on {nom} \033[0m")
printf(f"\033[92mQuiz 4 succeeded on `{nom}` \033[0m")
custom_sleep(uniform(3, 5))
except Exception as e:
printf(f"fail of PlayQuiz 4. Aborted {e} \033[0m")
printf(f"Fail of PlayQuiz 4. Aborted {e} \033[0m")
elif number == 3 or number == 2:
try:
printf(f"\033[96m Quiz 2 detected on {nom}\033[0m")
printf(f"\033[96mQuiz 2 detected on `{nom}`\033[0m")
play_quiz2()
printf(f"\033[92m Quiz 2 succeeded on {nom}\033[0m")
printf(f"\033[92mQuiz 2 succeeded on `{nom}`\033[0m")
except Exception as e:
printf(f"fail of PlayQuiz 2. Aborted {e}")
else:
@ -363,7 +357,6 @@ def try_play(nom="inconnu"):
if "bt_PollRadio" in driver.page_source:
try:
printf("Poll detected")
rgpd_popup(driver)
do_poll()
printf("Poll succeeded")
except Exception as e:
@ -379,154 +372,106 @@ def try_play(nom="inconnu"):
elif search("([0-9]) de ([0-9]) finalisée", driver.page_source):
printf("fidélité")
rgpd_popup(driver)
fidelity()
else:
printf(f"rien à faire sur la page {nom}")
rgpd_popup(driver)
custom_sleep(uniform(3, 5))
# login() tries to login to your Microsoft account.
# it uses global variable _mail and _password to login
def login(ldriver):
def pwd_login():
# Login with password or with cookies.
# The driver should be in the same state on both case
def pwd_login(ldriver):
printf("pwd_login : start")
ldriver.get("https://login.live.com")
custom_sleep(2)
wait_until_visible(By.ID, "i0116", browser = ldriver)
mail_elem = ldriver.find_element(By.ID, "i0116")
send_keys_wait(mail_elem, _mail)
send_keys_wait(mail_elem, g._mail)
mail_elem.send_keys(Keys.ENTER)
custom_sleep(2)
wait_until_visible(By.ID, "i0118", browser = ldriver)
pwd_elem = ldriver.find_element(By.ID, "i0118")
send_keys_wait(pwd_elem, _password)
send_keys_wait(pwd_elem, g._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(_otp.now())
a2f_elem.send_keys(g._otp.now())
a2f_elem.send_keys(Keys.ENTER)
except Exception as e :
log_error(e)
custom_sleep(5)
def cookie_login(ldriver):
printf("cookies_login : start")
ldriver.get("https://login.live.com")
try :
load_cookies(ldriver)
except FileNotFoundError :
printf("No cookies file Found.")
return(False)
ldriver.refresh()
return(True)
# Accept all cookies question, and check if the account is locked
def login_part_2(ldriver, cookies = False):
custom_sleep(5)
if ('Abuse' in ldriver.current_url) :
log_error("account suspended")
raise Banned()
save_cookies(driver, _mail)
for id in ["KmsiCheckboxField","iLooksGood", "idSIButton9", "iCancel"]:
if cookies:
save_cookies(ldriver)
for id in ["KmsiCheckboxField", "id__0", "iLooksGood", "idSIButton9", "iCancel"]:
if get_domain(ldriver) == "account.microsoft.com":
break
try:
ldriver.find_element(By.ID, id).click()
restart = True
except Exception as e:
pass
wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 20, ldriver)
ldriver.get("https://www.bing.com")
rgpd_popup(ldriver)
ldriver.refresh()
rgpd_popup(ldriver)
ldriver.get("https://account.microsoft.com/")
if wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 30, ldriver) :
return(True) #the account logging was successful
else :
log_error("Error during login. Trying to refresh")
ldriver.refresh()
return(wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 30, ldriver))
try :
body_elem = ldriver.find_element(By.TAG_NAME, "body") # in case of any random popup
body_elem.send_keys(Keys.ENTER)
except :
pass
printf("login completed - going to MsRewards")
custom_sleep(uniform(3,5))
#going to MsRewards
def go_to_msrewards(ldriver):
for i in ["[h='ID=RewardsFlyout,2.1']", f'[title="Rejoindre maintenant"]', f'[title="Rejoindre"]', f'[title="Join now"]'] :
ldriver.get("https://www.bing.com/rewardsapp/flyout")
custom_sleep(uniform(3,5))
for i in [f'[title="Rejoindre maintenant"]', f'[title="Rejoindre"]', f'[title="Join now"]'] :
if ('>Tableau de bord' in ldriver.page_source) :
printf('On MsRewards flyout')
return(True)
try:
ldriver.find_element(By.CSS_SELECTOR, i).click() # depend of the language of the page
except:
printf(f"element {i} not found")
rgpd_popup(ldriver)
custom_sleep(uniform(3,5))
ldriver.get("https://www.bing.com/rewardsapp/flyout")
try:
ldriver.find_element(By.CSS_SELECTOR, '[title="Rejoindre maintenant"]').click() # depend of the language of the page
except:
printf(f"unlock test: fail, probably normal")
printf('on MsRewards')
def cookie_login():
ldriver.get("https://login.live.com")
# login() tries to login to your Microsoft account.
# it uses global variable g._mail and g._password to login
def login(ldriver):
try :
load_cookies(ldriver, _mail)
except FileNotFoundError :
printf("Creating cookies file")
return(False)
try :
ldriver.refresh()
except WebDriverException as e: # This error occurs at random time. Don't really know why
if "Reached error page: about:neterror?e=netTimeout" in str(e):
printf("Timeout error occurred. \"normal\"....., maybe because of mismatch date ? ")
log_error("Timeout error occurred. \"normal\"....., maybe because of mismatch date ?", ldriver, True) # TODO check this hypothesis
else:
log_error(e)
custom_sleep(20) # TODO : remplacer par un wait_element
if ("account.microsoft.com" in ldriver.current_url) :
ldriver.get("https://bing.com")
custom_sleep(5)
ldriver.refresh()
rgpd_popup(ldriver)
ldriver.get("https://www.bing.com/rewardsapp/flyout")
if not('>Tableau de bord' in ldriver.page_source):
try :
ldriver.find_element(By.CSS_SELECTOR, "[h='ID=RewardsFlyout,2.1']").click()
custom_sleep(5)
if "bing.com" in ldriver.current_url :
rgpd_popup(ldriver)
ldriver.get("https://www.bing.com/rewardsapp/flyout")
if ('>Tableau de bord' in ldriver.page_source) :
return(True)
else :
printf("error during the connection. Trying something else")
except Exception as e:
log_error(f"not connected 5 - error {e}", ldriver)
if not('>Tableau de bord' in ldriver.page_source):
try :
ldriver.find_element(By.XPATH, "/html/body/div/div/div/div/div[2]/a").click()
custom_sleep(5)
except Exception as e:
log_error(f"erreur not connected 6{e}", ldriver)
return(False)
if "bing.com" in ldriver.current_url :
rgpd_popup(ldriver)
ldriver.get("https://www.bing.com/rewardsapp/flyout")
if ('>Tableau de bord' in ldriver.page_source) :
return(True)
else :
log_error("not connected 6", ldriver)
return(False)
return(True)
if ('account.live.com' in ldriver.current_url):
log_error("error 1", ldriver, True)
ldriver.refresh()
log_error("error 2", ldriver, True)
ldriver.get("https://bing.com")
ldriver.refresh()
rgpd_popup(ldriver)
log_error("error 3", ldriver, True)
sleep(5)
return(True)
printf("cookies plus valides ?")
return(False)
try :
if cookie_login():
return (ldriver.current_window_handle)
pwd_login() #mobile login in never called. TODO : check if it's bad.
return(ldriver.current_window_handle)
success_cookies = cookie_login(ldriver)
if not success_cookies:
pwd_login(ldriver)
login_part_2(ldriver, not success_cookies)
go_to_msrewards(ldriver)
except Banned:
raise Banned()
except Exception as e:
log_error(e)
ldriver.quit()
return(False)
# Makes 30 search as PC Edge
@ -552,9 +497,7 @@ def bing_pc_search(override=randint(35, 40)):
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(5, 20))
custom_sleep(uniform(3, 7))
try:
driver.find_element(By.ID, "sb_form_q").clear()
except Exception as e:
@ -566,7 +509,6 @@ def bing_pc_search(override=randint(35, 40)):
log_error(f"clear la barre de recherche - {format_error(e)}")
# Unban an account, called with -u parameter. You will need a phone number
def unban() -> None:
driver.find_element(By.ID, "StartAction").click()
@ -600,23 +542,24 @@ def unban() -> None:
# Sends points to database, discord and whatever service you want
def log_points(account="unknown"):
def get_points():
driver.get("https://www.bing.com/rewardsapp/flyout")
regex1 = '<a href="https://rewards\.bing\.com/" title="((.{1,3}),(.{1,3})) points" target="_blank"'
driver.get("https://rewards.bing.com")
custom_sleep(1)
if "/proofs/" in driver.current_url:
for id in ["KmsiCheckboxField","iLooksGood", "idSIButton9", "iCancel"]:
try:
point = search(regex1, driver.page_source)[1].replace(",", "")
driver.find_element(By.ID, id).click()
restart = True
except Exception as e:
elem = driver.find_element(By.CSS_SELECTOR, '[title="Microsoft Rewards"]')
elem.click()
custom_sleep(5)
driver.switch_to.window(driver.window_handles[len(driver.window_handles) - 1])
custom_sleep(uniform(5,7))
pass
wait_until_visible(By.CSS_SELECTOR, 'span[mee-element-ready="$ctrl.loadCounterAnimation()"]', browser=driver)
try :
point = search('availablePoints":([\d]+)', driver.page_source)[1]
except :
point = search('availablePoints\":([\d]+)', driver.page_source)[1]
except Exception as e:
sleep(5)
log_error(f"Dev error, checking why it doesn't work (waited a bit, is this still white ?) {format_error(e)}", driver, True)
driver.refresh()
sleep(5)
point = search('availablePoints":([\d]+)', driver.page_source)[1]
point = search('availablePoints\":([\d]+)', driver.page_source)[1]
return(point)
for _ in range (3):
@ -665,22 +608,23 @@ def fidelity():
fidelity_link = fidelity_link_page.content.decode("UTF-8")
if (fidelity_link.split(":")[0] == "https") or (fidelity_link.split(":")[0] == "http") :
driver.get(fidelity_link)
wait_until_visible(By.CSS_SELECTOR, 'div[class="pull-left spacer-48-bottom punchcard-row"]', browser=driver)
try :
choix = driver.find_element(By.CSS_SELECTOR, 'div[class="pull-left spacer-48-bottom punchcard-row"]') # pull-left spacer-48-bottom punchcard-row? USELESS ?
except : # tentative de fix
driver.refresh()
driver.execute_script("location.reload(true);")
wait_until_visible(By.CSS_SELECTOR, 'div[class="pull-left spacer-48-bottom punchcard-row"]', browser=driver)
choix = driver.find_element(By.CSS_SELECTOR, 'div[class="pull-left spacer-48-bottom punchcard-row"]')
answer_number = search("([0-9]) of ([0-9]) completed", 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 = search("([0-9])&nbsp;défi\(s\) terminé\(s\) sur ([0-9])", 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)
@ -712,60 +656,6 @@ def fidelity():
log_error(e)
def mobile_login_pwd(error):
try:
# TODO
# seems fine, check if there are no issues NO
mot = choice(Liste_de_mot).replace(" ","+")
mobile_driver.get(f"https://www.bing.com/search?q={mot}")
rgpd_popup(mobile_driver)
printf("start of Mobile login")
try :
mobile_driver.find_element(By.ID, "mHamburger").click()
except Exception as e :
elm = mobile_driver.find_element(By.ID, "mHamburger")
mobile_driver.execute_script("arguments[0].scrollIntoView();", elm)
mobile_driver.find_element(By.ID, "mHamburger").click()
wait_until_visible(By.ID, "hb_s", browser=mobile_driver)
mobile_driver.find_element(By.ID, "hb_s").click()
wait_until_visible(By.ID, "i0116", browser=mobile_driver)
mail_elem = mobile_driver.find_element(By.ID, "i0116")
send_keys_wait(mail_elem, _mail)
mail_elem.send_keys(Keys.ENTER)
wait_until_visible(By.ID, "i0118", browser=mobile_driver)
pwd_elem = mobile_driver.find_element(By.ID, "i0118")
send_keys_wait(pwd_elem, _password)
pwd_elem.send_keys(Keys.ENTER)
custom_sleep(uniform(1, 2))
if "Entrez le code de sécurité" in driver.page_source :
try :
a2f_elem = mobile_driver.find_element(By.ID, "idTxtBx_SAOTCC_OTC")
a2f_elem.send_keys(_otp.now())
a2f_elem.send_keys(Keys.ENTER)
except Exception as e :
log_error(e)
custom_sleep(uniform(1, 2))
for i in ["KmsiCheckboxField", "iLooksGood", "idSIButton9"]:
try:
mobile_driver.find_element(By.ID,i ).click()
except Exception as e:
pass
printf("end of Mobile login")
except Exception as e:
error += 1
if error <= 3:
printf(f"failure on mobile_login. Retrying({error}/3), {e}")
custom_sleep(uniform(5, 10))
mobile_login_pwd(error)
else:
log_error(f"login impossible 3 fois de suite. {e}", mobile_driver)
mobile_driver.quit()
return(True)
def mobile_alert_popup():
try:
alert = mobile_driver.switch_to.alert
@ -791,7 +681,7 @@ def bing_mobile_search(override=randint(22, 25)):
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(5, 20))
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 e:
@ -836,20 +726,20 @@ def daily_routine(custom = False):
try:
log_points(_mail)
log_points(g._mail)
except Exception as e:
log_error(e)
def dev():
pass
input("paused")
def CustomStart(Credentials):
global START_TIME
if not LINUX_HOST :
raise NameError('You need to be on linux to do that, due to the utilisation of a module named enquieries, sorry.')
global driver, _mail, _password, p, _otp
global driver, p
system("clear") # clear from previous command to allow a clean choice
actions = ["tout", "daily", "pc", "mobile", "log_points","fidelity", "dev"]
@ -858,10 +748,10 @@ def CustomStart(Credentials):
START_TIME = time() # Reset timer to the start of the actions
for cred in liste:
_mail = cred[0]
_password = cred[1]
g._mail = cred[0]
g._password = cred[1]
if len(cred) == 3:
_otp = TOTP(cred[2])
g._otp = TOTP(cred[2])
driver = firefox_driver()
driver.implicitly_wait(3)
@ -897,13 +787,12 @@ def CustomStart(Credentials):
break
if not "tout" in Actions:
try:
log_points(_mail)
log_points(g._mail)
except Exception as e:
printf(f"CustomStart {e}")
driver.close()
if VNC_ENABLED :
display = SmartDisplay(backend="xvnc", size=(2160, 2160), rfbport=VNC_PORT, color_depth=24)
else :
@ -914,7 +803,7 @@ display.start()
if CUSTOM_START:
CustomStart(Credentials)
elif UNBAN:
_mail, _password = select_accounts(False)[0]
g._mail, g._password = select_accounts(False)[0]
driver = firefox_driver()
try :
login(driver)
@ -925,17 +814,18 @@ elif UNBAN:
elif POINTS_FILE != "":
save_points_from_file(POINTS_FILE)
else:
if UPDATE_VERSION != "None":
if DISCORD_ENABLED_ERROR:
webhookFailure.send(f"Updated to {UPDATE_VERSION}", username="UPDATE", avatar_url="https://cdn-icons-png.flaticon.com/512/1688/1688988.png")
for cred in Credentials:
_mail = cred[0]
_password = cred[1]
g._mail = cred[0]
g._password = cred[1]
if len(cred) == 3:
_otp = TOTP(cred[2])
printf("\n\n")
printf(_mail)
g._otp = TOTP(cred[2])
custom_sleep(1)
printf("début du driver")
printf("Début du driver.")
driver = firefox_driver()
printf("driver demarré")
printf("Driver demarré.")
driver.implicitly_wait(3)
try:
daily_routine()
@ -944,11 +834,11 @@ else:
printf(f"finis. attente de {round(attente/60)}min")
custom_sleep(attente)
except KeyboardInterrupt:
printf("canceled. Closing driver and display.")
printf("Canceled. Closing driver and display.")
driver.quit()
display.stop()
except Exception as e:
printf(f"error not catched. skipping this account. {e}")
printf(f"Error not catched. Skipping this account. {e}")
driver.quit()
display.stop()

View File

@ -10,9 +10,16 @@ parser.add_argument(
help="Choose a file",
type=argparse.FileType('r')
)
parser.add_argument(
"-m",
"--manual",
help="add point manually do database",
dest="manual",
action="store_true"
)
args = parser.parse_args()
MANUAL = args.manual
config_path = "./user_data/config.cfg"
config = configparser.ConfigParser()
@ -47,10 +54,10 @@ def ban_account(name: str, pts = 0):
def update_pts(name: str, pts = 0):
pass
print("ajouter un compte : 1\nban un compte : 2")
i = input()
if i == "1":
if not MANUAL :
print("ajouter un compte : 1\nban un compte : 2")
i = input()
if i == "1":
if args.file :
l =[x.split(",")[0].split("@")[0] for x in args.file.readlines()]
endroit = input("ou est le bot ? ")
@ -62,11 +69,24 @@ if i == "1":
endroit = input("ou est le bot ? ")
proprio = input("qui est le proprio ? ")
add_account(name, endroit, proprio)
elif i == '2':
elif i == '2':
name = input("quel est le compte qui a été ban ? ")
pts = input("il avait combien de points ? ")
ban_account(name, pts)
mydb.commit()
mycursor.close()
mydb.close()
mydb.commit()
mycursor.close()
mydb.close()
else :
import modules.db as datab
config_path = f"{path.abspath(path.dirname(path.dirname( __file__ )))}/MsRewards/user_data/config.cfg"
print(config_path)
config = configparser.ConfigParser()
config.read(config_path)
sql_usr = config["SQL"]["usr"]
sql_pwd = config["SQL"]["pwd"]
sql_host = config["SQL"]["host"]
sql_database = config["SQL"]["database"]
account_name = input("compte ? ")
points = int(input("points ? "))
datab.add_to_database(account_name, points, sql_host, sql_usr, sql_pwd, sql_database)

44
main.py
View File

@ -1,8 +1,11 @@
#/usr/bin/python3.10
from packaging.version import parse as parse_version
import configparser
import os
import shutil
import requests
import sys
config = configparser.ConfigParser()
@ -16,8 +19,6 @@ except :
config.read(config_path)
def confirm(texte, default = False):
if default :
txt = '[Y/n]'
@ -41,12 +42,12 @@ text = {"fr" : {
"next" : "voulez vous ajouter un compte ? ",
"finc" : "comptes en cours d'ajout ",
"ajout" : "comptes ajouté ",
"fidelity" : "avez vous un lien sur lequel le lien vers la page fidelité du mois est le seul contenu de la page ? ",
"fidelity" : "avez vous un lien sur lequel le lien vers la page fidélité du mois est le seul contenu de la page ? ",
"lien" : "entrez le lien ",
"discorde" : "voulez vous envoyer les erreurs sur discord ? ",
"w1" : "entrez le lien du WebHook pour envoyer les points ",
"w2" : "entrez le lien du WebHook pour envoyer les erreurs ",
"msqle" : "voulez vous untiliser une base de donnée ",
"msqle" : "voulez vous utiliser une base de donnée ",
"msqll" : "entrez le lien de la base de donnée ",
"msqlu" : "entrez l'utilisateur de la base de donnée ",
"msqlp" : "entrez le mot de passe de la base de donnée ",
@ -83,8 +84,6 @@ def setup_comptes():
f.write("\n")
f.close()
print(t["ajout"])
#modifie le fichier de configuration
edit_config_txt("logpath",f'{os.getcwd()}/user_data/login.csv')
@ -111,7 +110,7 @@ def setup_settings():
discord()
proxy()
sql()
amazon()
def general():
if confirm(t["fidelity"]):
@ -144,6 +143,7 @@ def sql() :
pwd = input(t["msqlp"])
edit_config_txt("pwd",pwd)
def proxy() :
enabled = confirm(t["proxye"], default = False)
if enabled :
@ -153,13 +153,33 @@ def proxy() :
port = input(t["proxyp"])
edit_config_txt("port",port)
def amazon():
enabled = confirm("claim les recompenses automatiquement sur amazon ?", default = False)
edit_config_txt("claim_amazon",enabled)
def check_update(args):
try :
latest = requests.get("https://api.github.com/repos/piair338/MsRewards/releases").json()[0]["tag_name"]
latest = parse_version(latest)
except Exception as e :
print(e)
return (args)
f = open("./version", 'r')
txt = f.readlines()[0].replace("\n","")
f.close()
cur = parse_version(txt)
if not (cur < latest) :
print("Already up to date.")
return(args)
else :
print(f"updating to {latest}")
os.system("git reset --hard")
os.system("git pull")
os.system("python3 -m pip install -r requirements.txt > update.result")
print(f"updated to {latest}")
return(args + f" --version {latest}")
LogPath = config["PATH"]["logpath"]
if LogPath == "/your/path/to/loginandpass.csv" :
setup()
else :
os.system("python3 V5.py")
args = " ".join(sys.argv[1::])
args = check_update(args)
os.system("python3 V5.py " + args)

View File

@ -81,6 +81,12 @@ parser.add_argument(
default="None"
)
parser.add_argument(
"--version",
help="display a message on discord to tell that the bot have been updated",
dest="update_version",
default="None"
)
args = parser.parse_args()
CUSTOM_START = args.override
@ -93,7 +99,7 @@ if CUSTOM_START :
VNC_ENABLED = args.vnc != "None"
VNC_PORT = args.vnc
POINTS_FILE = args.points_file
UPDATE_VERSION = args.update_version
# global variables used later in the code
LINUX_HOST = platform == "linux" # if the computer running this program is Linux, it allow more things
START_TIME = time()
@ -125,6 +131,10 @@ DISCORD_SUCCESS_LINK = config["DISCORD"]["successlink"]
DISCORD_ERROR_LINK = config["DISCORD"]["errorlink"]
DISCORD_ENABLED_ERROR = config["DISCORD"]["DiscordErrorEnabled"] == "True"
DISCORD_ENABLED_SUCCESS = config["DISCORD"]["DiscordSuccessEnabled"]== "True"
try :
AVATAR_URL = config["OTHER"]["avatar"]== "True"
except :
AVATAR_URL = "https://cdn.discordapp.com/icons/793934298977009674/d8055bccef6eca4855c349e808d0d788.webp"
if DISCORD_ENABLED_ERROR:
webhookFailure = Webhook.from_url(DISCORD_ERROR_LINK, adapter=RequestsWebhookAdapter())

View File

@ -1,6 +1,6 @@
from modules.imports import *
from modules.config import *
import modules.globals as g
def setup_proxy(ip, port, options, socks=False) :
PROXY = f"{ip}:{port}"
@ -25,12 +25,12 @@ def rgpd_popup(driver) -> None:
pass
# save webdriver cookies
def save_cookies(driver, _mail):
pickle.dump(driver.get_cookies(), open(f"{'/'.join(__file__.split('/')[:-2])}/user_data/cookies/{_mail}.pkl", "wb"))
def save_cookies(driver):
pickle.dump(driver.get_cookies(), open(f"{'/'.join(__file__.split('/')[:-2])}/user_data/cookies/{g._mail}.pkl", "wb"))
# load cookies previously saved to the driver
def load_cookies(driver, _mail):
cookies = pickle.load(open(f"{'/'.join(__file__.split('/')[:-2])}/user_data/cookies/{_mail}.pkl", "rb"))
def load_cookies(driver):
cookies = pickle.load(open(f"{'/'.join(__file__.split('/')[:-2])}/user_data/cookies/{g._mail}.pkl", "rb"))
for cookie in cookies:
driver.add_cookie(cookie)
@ -52,6 +52,8 @@ def send_keys_wait(element, keys):
def wait_until_visible(search_by: str, identifier: str, timeout = 20, browser = None) -> None:
try :
WebDriverWait(browser, timeout).until(EC.visibility_of_element_located((search_by,identifier)), "element not found")
return(True)
except TimeoutException as e:
print(f"element not found after {timeout}s")
return(False)

5
modules/globals.py Normal file
View File

@ -0,0 +1,5 @@
driver = None
_mail = '_mail temp'
_password = '_password temp'
_otp = '_otp temp'
display = None

View File

@ -1,18 +1,22 @@
from modules.imports import *
from modules.config import *
import modules.globals as g
# add the time arround the text given in [text]&
def Timer(text: str, mail: str) -> str:
return(f"[{mail} - {datetime.today().strftime('%d-%m-%Y')} - {timedelta(seconds = round(float(time() - START_TIME)))}] " + str(text))
def Timer(text: str) -> str:
return(f"[{g._mail.split('@')[0]} - {datetime.today().strftime('%d/%m')} - {timedelta(seconds = round(float(time() - START_TIME)))}] " + str(text))
# replace the function print, with more options
# [txt] : string, [driver] : selenium webdriver
def printf2(txt, mail, LOG = LOG):
print(Timer(txt, mail))
def printf(txt):
print(Timer(txt))
# return current page domain
def get_domain(driver):
return(driver.current_url.split("/")[2])
# check if the user is using IPV4 using ipify.org
# [driver] : selenium webdriver
@ -26,7 +30,6 @@ def check_ipv4(driver):
return False
def custom_sleep(temps):
try :
if FAST and temps > 50:

View File

@ -9,3 +9,4 @@ pyvirtualdisplay
pillow
EasyProcess
pyotp
packaging

View File

@ -31,5 +31,5 @@ usr = root
pwd = password
[OTHER]
avatar = https://cdn.discordapp.com/icons/793934298977009674/d8055bccef6eca4855c349e808d0d788.webp
ipv6 = False

1
version Normal file
View File

@ -0,0 +1 @@
v5.7.1