46 Commits

Author SHA1 Message Date
5e5f7f7407 Implement "timezonedates" 2024-10-18 13:03:16 +02:00
0cc42823ff Add new cards (election, dictionary) 2024-10-15 11:51:55 +02:00
56c858fa90 Adding new "explore on Bing" cards 2024-10-08 09:07:01 +02:00
adf91ac8f0 Ignoring MS Security activity (it would be better to detect it before clicking) 2024-10-01 09:03:50 +02:00
2721c76686 Fix LegacyKeyValueFormat warning
"ENV key=value" should be used instead of legacy "ENV key value" format
2024-09-19 11:57:25 +02:00
45ea72a354 Merge remote-tracking branch 'origin/master' 2024-09-14 22:57:48 +02:00
18b35f6f68 adding new custom search cards 2024-09-14 22:57:40 +02:00
c53125479e Check if streak protection expired 2024-08-30 21:48:20 +02:00
df256f2405 Update modules/Tools/update_chrome.py
fix auto update breaking due to path error
2024-08-28 15:48:31 +02:00
31b4d5d7da Actualiser V6.py 2024-07-08 10:00:28 +02:00
574fa45813 Update version 2024-07-05 13:47:08 +02:00
3bb49d1618 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	V6.py
2024-07-05 13:46:04 +02:00
e25334f1bd adding new custom search cards 2024-07-05 13:45:26 +02:00
41312b53b9 c'est bon là 2024-06-18 20:50:55 +02:00
1ac98f14c4 wqMerge branch 'fix4' 2024-06-18 20:38:21 +02:00
a197d44768 Added package tracking card 2024-06-18 20:37:14 +02:00
f9a21f5b98 Added package tracking card 2024-06-18 16:54:37 +02:00
82161973a9 Added weather carad 2024-06-18 16:38:29 +02:00
c7e110787b Debugging auto update 2024-05-16 17:52:12 +02:00
1db1de9606 oops, bad syntax 2024-05-15 10:03:01 +02:00
10d75f9d78 version bump 2024-05-15 09:52:56 +02:00
87fb791436 Explore on Bing: solve more challenges 2024-05-15 09:52:39 +02:00
6995bde8a6 Actualiser version 2024-05-12 18:55:51 +02:00
92069a013e Merge pull request 'Handle Streak-Protection Popup' (#12) from streak-protection into master
Reviewed-on: https://gitea.augustin64.fr/piair/MsRewards-Reborn/pulls/12
2024-05-12 18:55:34 +02:00
906d3e7822 catch another exception 2024-05-12 18:16:24 +02:00
778adc67d2 Et si on l'active ? 2024-05-12 18:07:36 +02:00
402b8cd3ef Close streak protection 2024-05-12 17:55:56 +02:00
3c74aa025e trying to fix web start 2024-04-26 16:06:33 +02:00
3123a1dbd0 trying to auto update chrome + fixed web override ? 2024-04-26 15:51:52 +02:00
27d45e88dd added more exploreOnBing 2024-04-26 15:43:23 +02:00
0685a42922 making scripts executables 2024-04-26 15:37:32 +02:00
6729703827 auto update hooks 2024-04-26 15:35:37 +02:00
304a222de1 fixed readlines ? 2024-04-26 14:51:23 +02:00
04d33f4ecd fixed readlines ? 2024-04-26 14:45:41 +02:00
ac22814605 fixed readlines ? 2024-04-26 14:41:00 +02:00
b7a89b56d0 fixed typo 2024-04-26 14:36:04 +02:00
127d16afea Changed version update logik 2024-04-26 14:32:01 +02:00
9bcbc81c2f Changement des musiques pour celles que Bing connais 2024-04-26 14:13:50 +02:00
12eba5cde7 top habitué au JS 2024-04-26 14:00:33 +02:00
22ea727c47 progress 2024-04-26 13:55:20 +02:00
05a1fd8557 pourquoi les custom attributes 2024-04-26 12:12:28 +02:00
39e226b564 pourquoi les custom attributes 2024-04-26 12:06:55 +02:00
cd00c8ca88 detecting which cutom search to do 2024-04-26 12:03:49 +02:00
43793d2c2c detecting which cutom search to do 2024-04-26 11:51:50 +02:00
ee6ec458fc switched to login on custom start 2024-04-26 11:27:16 +02:00
e6e8bdaa06 Trying to find out why the part1 is starting 2024-04-26 11:17:18 +02:00
10 changed files with 307 additions and 100 deletions

1
.gitignore vendored
View File

@ -16,3 +16,4 @@ file.png
*.ts
LICENSE
README.md
venv

View File

@ -1,5 +1,5 @@
FROM python:3.10
ENV DEBIAN_FRONTEND noninteractive
ENV DEBIAN_FRONTEND=noninteractive
WORKDIR /app/
# Initial apt install

228
V6.py
View File

@ -1,16 +1,17 @@
#!/usr/bin/python3
import random
import subprocess
from modules.Classes.Config import Config
from modules.Classes.DiscordLogger import DiscordLogger
from modules.Classes.UserCredentials import UserCredentials
from modules.Tools.logger import warning, critical
from modules.Tools.logger import critical, warning
from modules.cards import *
from modules.config import *
from modules.db import add_to_database
from modules.driver_tools import *
from modules.error import *
import random
# create a webdriver
def create_driver(mobile=False):
@ -199,6 +200,10 @@ def do_poll():
def all_cards():
driver = config.WebDriver.driver
def check_popups() -> bool:
"""
Check various annoying popups
"""
def check_welcome_tour() -> bool:
if "rewards.bing.com/welcometour" not in driver.current_url:
return False
@ -210,7 +215,7 @@ def all_cards():
welcome_tour = driver.find_element(By.ID, "welcome-tour")
interest_button_box = welcome_tour.find_element(By.CLASS_NAME, "interest-buttons")
interests = interest_button_box.find_elements(By.CLASS_NAME, "ng-binding")
debug("Got the following interests: "+str(interests))
debug("Got the following interests: " + str(interests))
random.choice(interests).click() # Choose interest
custom_sleep(1.5)
@ -219,6 +224,43 @@ def all_cards():
custom_sleep(1.5)
return True
def check_streak_protection() -> bool:
"""
Ne perdez plus jamais votre série !
"""
try:
streak_protection_close = driver.find_element(By.ID, "streak-protection-popup-close-cross")
streak_protection_activate = driver.find_elements(By.CLASS_NAME, "earningPagePopUpPopUpSelectButton")
streak_protection_activate[0].click()
info("Popup 'Streak Protection' reçue")
custom_sleep(1.5)
return True
except (exceptions.NoSuchElementException, exceptions.ElementNotInteractableException, IndexError):
# les éléments sont présents dans le DOM même quand la popup n'est pas visible apparemment
return False
def check_streak_protection_expired() -> bool:
"""
Non, vous avez utilisé tous vos jours de protection contre les séries !
"""
try:
streak_protection_close = driver.find_element(By.ID, "streak-protection-popup-close-cross")
ok_sad_button = driver.find_elements(By.CLASS_NAME, "dashboardPopUpPopUpSelectButton")
ok_sad_button[0].click()
info("Popup 'Streak Protection fully used' reçue")
custom_sleep(1.5)
return True
except (exceptions.NoSuchElementException, exceptions.ElementNotInteractableException, IndexError):
return False
return (
check_welcome_tour()
or check_streak_protection()
or check_streak_protection_expired()
)
driver.get("https://rewards.bing.com")
wait_until_visible(By.CLASS_NAME, "c-card-content", 10, driver)
@ -265,15 +307,21 @@ def all_cards():
if not checked:
continue
try:
activity = findall("data-bi-id=\"([^\"]+)\"", card_list[i].get_attribute("innerHTML"))[0]
except Exception as e:
warning("Can't find activity." + str(e))
activity = ""
custom_sleep(1.5)
check_welcome_tour()
check_popups()
driver.execute_script("arguments[0].scrollIntoView();", card_list[i])
custom_sleep(1.5)
card_list[i].click()
if len(driver.window_handles) > 1:
driver.switch_to.window(driver.window_handles[1])
try_play(driver.title)
try_play(driver.title, activity)
close_tab(driver.window_handles[1])
try:
@ -283,7 +331,7 @@ def all_cards():
if "mee-icon-AddMedium" not in card_list[i].get_attribute("innerHTML"):
continue
check_welcome_tour()
check_popups()
driver.execute_script("arguments[0].scrollIntoView();", card_list[i])
card_list[i].click()
@ -340,8 +388,124 @@ def promo():
custom_sleep(3)
def explore_on_bing(activity: str, config: Config):
driver = config.WebDriver.driver
def search_bing(txt):
search_elm = driver.find_element(By.ID, "sb_form_q")
send_keys_wait(search_elm, txt)
send_keys_wait(search_elm, Keys.ENTER)
if "lyrics" in activity:
search_bing(
f"paroles de {['Gata', 'Pyramide', 'Dolce Camara', 'Position', 'Mami Wata'][randint(0, 4)]}") # merci bing copilot pour les titres
elif "flight" in activity:
search_bing(
f"vol {['Paris - New York', 'Londres Amsterdam', 'Bora-Bora Miami', 'Los Angeles Toulouse', 'Rome Dubai'][randint(0, 4)]}")
elif "shopping" in activity:
search_bing(f"idée cadeau {['Noel', 'Anniversaire'][randint(0, 1)]}")
elif "movie" in activity:
search_bing(
f"Distribution {['Code 8 part 2', 'The Hunger Games: The ballad of Songbirds & Snakes', 'Rebel Moon: Part Two', 'Dune II', 'Wonka'][randint(0, 4)]}")
elif "translator" in activity:
search_bing(f"traduction {config.wordlist.get_word()} en anglais")
elif "map" in activity:
search_bing(f"{['Paris', 'Nice', 'Marseille', 'Bordeaux', 'Lyon'][randint(0, 4)]} carte")
elif "restaurant" in activity:
search_bing(random.choice([
"restaurant à proximité",
"restaurant pas loin",
"manger dans le coin"
]))
elif "recipe" in activity:
search_bing("recette de " + random.choice([
"cake aux olives",
"tarte tatin",
"Kouign Amann",
"poulet au Curry",
"lasagnes aux épinards et ricotta",
"Boeuf Bourguignon",
"dessert",
"gateau au chocolat",
"crêpe sucrée"
])) # Merci llama pour les idées
elif "currency" in activity:
currencies = [
"euros",
"dollars canadiens",
"dollars",
"livres",
"francs suisses",
"roubles",
"pesos",
"bitcoin",
"anciens francs"
]
chosen = random.sample(currencies, k=2)
search_bing(f"convertir {random.randint(2, 120)} {chosen[0]} en {chosen[1]}")
elif "weather" in activity:
search_bing(f"météo {['Paris', 'Nice', 'Marseille', 'Bordeaux', 'Lyon'][randint(0, 4)]}")
elif "packagetracking" in activity:
driver.get("https://www.bing.com/?setmkt=en-US&setlang=en-US")
search_bing(f"{['fedex', 'UPS'][randint(0, 1)]} package tracking")
elif "hotel" in activity:
search_bing(f" {['Paris', 'Nice', 'Marseille', 'Bordeaux', 'Lyon'][randint(0, 4)]}")
elif "health" in activity:
search_bing(f"{['toux', 'douleur dos', 'nez qui coule', 'mal au genoux', 'otite'][randint(0, 4)]}")
elif "news" in activity:
search_bing(["actualités", "news"][randint(0, 1)])
elif "jobs" in activity:
search_bing("jobs")
elif "realestate" in activity:
search_bing(f"appartement à louer {['Paris', 'Nice', 'Marseille', 'Bordeaux', 'Lyon'][randint(0, 4)]}")
elif "financemarket" in activity:
search_bing(
f"cours action {['AIR LIQUIDE', 'Airbus', 'BNP Paribas', 'Michelin', 'Stellantis', 'Vinci'][randint(0, 5)]}")
elif "sports" in activity:
equipes = random.sample([
"Toulon", "toulouse",
"stade Rochelais", "castres",
"clermont", "perpignan",
"aviron bayonnais", "vannes"
], k=2)
search_bing(f"{['score', 'résultats'][randint(0, 1)]} rugby {equipes[0]} {equipes[1]}")
elif "videogames" in activity:
search_bing(random.choice([
"Minecraft", "GTA V",
"Tetris", "PUBG",
"Mario Kart 8",
"Red Dead Redemption II",
"Terraria",
"The Witcher",
"Animal Crossing",
"Pokémon rouge & bleu",
"Super Mario Bros",
"The legend of Zelda BOTW",
"Call of Duty Modern Warfare",
"The Witcher III"
]))
elif "dictionary" in activity:
search_bing(f"définition {config.wordlist.get_word()}")
elif "election" in activity or "timezonedates" in activity:
#! I don't understand the name of "timezonedates" but this seems to be the same activity
state = random.choice([
"Alaska", "Alabama", "Arkansas", "American Samoa", "Arizona", "California", "Colorado",
"Connecticut", "District ", "of Columbia", "Delaware", "Florida", "Georgia", "Guam",
"Hawaii", "Iowa", "Idaho", "Illinois", "Indiana", "Kansas", "Kentucky", "Louisiana",
"Massachusetts", "Maryland", "Maine", "Michigan", "Minnesota", "Missouri", "Mississippi",
"Montana", "North Carolina", "North Dakota", "Nebraska", "New Hampshire", "New Jersey",
"New Mexico", "Nevada", "New York", "Ohio", "Oklahoma", "Oregon", "Pennsylvania",
"Puerto Rico", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas",
"Utah", "Virginia", "Virgin Islands", "Vermont", "Washington", "Wisconsin",
"West Virginia", "Wyoming"
])
search_bing(f"governor candidates {state} 2024")
else:
log_error(f"Explore on bing: {activity} not found.")
# Find out which type of action to do
def try_play(nom="unknown"):
def try_play(nom="unknown", activity=""):
driver = config.WebDriver.driver
rgpd_popup(config)
@ -387,7 +551,7 @@ def try_play(nom="unknown"):
info("On fidelity page.")
fidelity()
elif wait_until_visible(By.ID, "rqStartQuiz", 5, driver):
elif wait_until_visible(By.ID, "rqStartQuiz", 5, driver, raise_error=False):
custom_sleep(3)
driver.find_element(By.ID, "rqStartQuiz").click() # start the quiz
answer_number = driver.page_source.count("rqAnswerOption")
@ -397,9 +561,14 @@ def try_play(nom="unknown"):
number = driver.page_source.count("rqAnswerOption")
warning(f"recovery detected. quiz : {number}")
play(number - 1)
elif "exploreonbing" in activity:
info(f"Explore on bing: {activity}")
explore_on_bing(activity, config)
custom_sleep(uniform(3, 5))
elif "Optimisez votre sécurité avec Microsoft" in driver.page_source:
info("Still not paying Office 365 ?")
else:
info(f"Nothing to do on page `{nom}`")
info(f"Nothing obvious to do on page `{nom}`.")
custom_sleep(uniform(3, 5))
@ -409,11 +578,15 @@ def login_part_1():
info("Starting part 1 of login")
driver = config.WebDriver.driver
driver.get("https://login.live.com")
try:
wait_until_visible(By.ID, "i0116", browser=driver)
send_wait_and_confirm(
driver.find_element(By.ID, "i0116"),
config.UserCredentials.get_mail()
)
except exceptions.NoSuchElementException:
info("Unable to find mail input for login, might be semi-logged-in")
wait_until_visible(By.ID, "i0118", browser=driver)
send_wait_and_confirm(
driver.find_element(By.ID, "i0118"),
@ -476,10 +649,12 @@ def login():
def logged_in():
driver.get("https://login.live.com")
custom_sleep(10)
debug(get_domain(driver))
if get_domain(driver) == "account.microsoft.com":
return True
return False
info("Logging in...")
driver = config.WebDriver.driver
try:
if not logged_in():
@ -608,19 +783,23 @@ def fidelity():
pause = driver.find_element(By.CSS_SELECTOR, f'[class="c-action-toggle c-glyph f-toggle glyph-pause"]')
pause.click()
except Exception as e:
error(f"Error while clicking pause. Probably no cards. {e}")
return "no cards"
debug("No pause button.")
cartes = driver.find_elements(By.CSS_SELECTOR, f'[ng-repeat="item in $ctrl.transcludedItems"]')
nb_cartes = len(cartes)
if nb_cartes == 0:
warning("No fidelity cards detected")
return "No cards."
checked_list_all = driver.find_elements(By.CSS_SELECTOR, f'[ng-if="$ctrl.complete"]')
for i in range(nb_cartes):
cartes[i].click()
checked_txt = checked_list_all[i].get_attribute("innerHTML")
ok = checked_txt.count("StatusCircleOuter checkmark")
total = checked_txt.count("StatusCircleOuter")
if (ok != total):
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
# legacy code. Should be removed
if "moviesandtv" not 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()
@ -738,9 +917,8 @@ def json_start(json_entry, cred: UserCredentials):
config.WebDriver.set_pc_driver(create_driver())
config.WebDriver.switch_to_driver("PC")
driver = config.WebDriver.driver
try:
if "unban" in json_entry and str(account_id) in json_entry["unban"]:
login_part_1()
login()
info("\nGO TO example.com TO PROCEED or wait 1200 secs.")
for _ in range(1200):
sleep(1)
@ -749,13 +927,10 @@ def json_start(json_entry, cred: UserCredentials):
break
else:
login()
except KeyError:
login()
try:
if str(account_id) in json_entry["tout"]:
daily_routine(cred, True)
except KeyError:
pass
else:
try:
if str(account_id) in json_entry["daily"]:
@ -781,10 +956,14 @@ def json_start(json_entry, cred: UserCredentials):
log_error(e)
except KeyError:
pass
except KeyError:
pass
try:
log_points()
except Exception as e:
error(f"CustomStart {e}")
driver.close()
cred.next_account()
account_id += 1
@ -801,13 +980,17 @@ def default_start():
while config.UserCredentials.is_valid():
custom_sleep(1)
info("Starting and configuring driver.")
try:
config.WebDriver.set_pc_driver(create_driver())
except:
info("Could not configure driver. Trying to update it.")
subprocess.Popen(["python3", "/app/MsRewards-Reborn/modules/Tools/update_chrome.py"])
config.WebDriver.set_pc_driver(create_driver())
config.WebDriver.switch_to_driver("PC")
info("Driver started.")
config.WebDriver.pc_driver.implicitly_wait(3)
try:
wait_time = uniform(1200, 3600)
wait_time = 10 # the display closes when I ctrl + c
info(f"Waiting for {round(wait_time / 60)}min before starting")
custom_sleep(wait_time)
daily_routine(config.UserCredentials)
@ -835,7 +1018,6 @@ def log_error(msg):
def check_updated():
debug(f"updated: {config.has_been_updated()}")
if config.has_been_updated():
config.discord.wh.send(f"Updated to {config.version}", username="update",
avatar_url="https://cdn-icons-png.flaticon.com/512/1688/1688988.png")

12
hooks/bump.sh Executable file
View File

@ -0,0 +1,12 @@
file=version
if [ "$(git diff HEAD version | wc -w)" -eq 0 ]
then
echo 'updating minor version'
new_path=$(cat $file | awk -F . '{print $1"."$2"."$3+1 }')
echo $new_path > $file
git add version
else
echo 'Version have been updated manually'
fi
echo Version: $(cat $file)

1
hooks/pre-commit Executable file
View File

@ -0,0 +1 @@
sh hooks/bump.sh

View File

@ -22,7 +22,8 @@ class Config:
proxy = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
config = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/version", "r") as inFile:
version = inFile.readline()
"""
setup standalone stuff
"""
@ -31,10 +32,9 @@ class Config:
self.json_entry = args.json.replace("'", "\"")
self.wordlist = WordList("/usr/share/dict/french")
self.vnc = args.vnc
self.version = args.update_version
self.WebDriver = Driver()
self.display = None
self.version = version
"""
setup UserCredential
"""
@ -81,4 +81,11 @@ class Config:
self.display = display
def has_been_updated(self):
return self.version != "None"
with open('/app/MsRewards-Reborn/version', "r") as inFile:
in_file_content = inFile.readlines()
if self.version != in_file_content[0]:
self.version = in_file_content[0]
with open('/app/MsRewards-Reborn/user_data/version', "w") as outFile:
outFile.write(self.version)
return True
return False

View File

@ -5,7 +5,7 @@ import subprocess
from logger import critical, info, error
errorMessage = subprocess.run(['python3', 'generate_error.py'], check=False, stdout=subprocess.PIPE,
errorMessage = subprocess.run(['python3', '/app/MsRewards-Reborn/modules/Tools/generate_error.py'], check=False, stdout=subprocess.PIPE,
stderr=subprocess.PIPE).stderr.decode("utf-8")
versionPattern = "This version of ChromeDriver only supports Chrome version ([0-9]+)"
@ -15,6 +15,8 @@ try:
except Exception as e:
critical("Can't get version number from error")
error(e)
info("error message")
info(errorMessage)
exit(0)
info(f"Needed version : '{versionN}'")

View File

@ -1,9 +1,9 @@
import os
import json
import os
from random import uniform
from selenium.common import TimeoutException
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
@ -14,9 +14,9 @@ from modules.Tools.tools import *
def init_profile(mail, mobile=False):
if not mobile:
chrome_profile_dir = "/app/MsRewards-Reborn/user_data/profile/"+mail
chrome_profile_dir = "/app/MsRewards-Reborn/user_data/profile/" + mail
else:
chrome_profile_dir = "/app/MsRewards-Reborn/user_data/profile/mobile-"+mail
chrome_profile_dir = "/app/MsRewards-Reborn/user_data/profile/mobile-" + mail
os.makedirs(chrome_profile_dir, exist_ok=True)
@ -69,6 +69,7 @@ def send_keys_wait(element, keys: str) -> None:
element.send_keys(i)
sleep(uniform(0.1, 0.3))
def send_wait_and_confirm(element, keys: str) -> None:
send_keys_wait(element, keys)
element.send_keys(Keys.ENTER)
@ -81,6 +82,6 @@ def wait_until_visible(search_by: str, identifier: str, timeout: int = 20, brows
expected_conditions.visibility_of_element_located((search_by, identifier)), "element not found")
return True
except TimeoutException as e:
if raise_error:
error(f"element {identifier} not found after {timeout}s")
f = error if raise_error else debug
f(f"element {identifier} not found after {timeout}s")
return False

1
user_data/version Normal file
View File

@ -0,0 +1 @@
0.0.0

View File

@ -1 +1 @@
v6.8.48
v6.8.65