Compare commits

..

703 Commits

Author SHA1 Message Date
augustin64 d3137f858a Mise en forme des codes ANSI dans les logs 2024-03-25 10:41:34 +01:00
piair d2ad467d4e Oops, pas push le bon fichier 2024-03-24 20:30:09 +01:00
piair b45e9e549f mise à jour automatique de chrome 2024-03-24 20:27:40 +01:00
piair 200b0d8a86 Trying to fix an issue when an account fail 2024-03-05 21:18:39 +01:00
piair 4a5af6455d Fixed 2FA issue + added better logs 2024-03-01 17:29:15 +01:00
piair 49b691d736 not tested enough apparently 2024-02-28 18:22:15 +01:00
piair 9549a6dea3 not tested enough apparently 2024-02-28 18:12:32 +01:00
piair 8c224793b0 resize terminal on animation end 2024-02-28 15:04:19 +01:00
piair 36fd92f71c fix json start 2024-02-28 14:44:11 +01:00
piair 0a02eb2033 fix json start 2024-02-28 14:44:01 +01:00
piair 6122d9ee13 fix json start + improve logs 2024-02-28 14:40:12 +01:00
piair a590d0f1b5 fix json start 2024-02-28 14:29:21 +01:00
piair 64a018044c event on resize 2024-02-28 14:26:25 +01:00
piair 91e7f31bac size issues 2024-02-28 14:17:55 +01:00
piair 295f6d114d size issues 2024-02-28 14:14:29 +01:00
piair 49e0d1b599 the issue seemed to be linked to the use of table instead of div 2024-02-28 14:13:19 +01:00
piair 83eea03c73 the issue seemed to be linked to the use of table instead of div 2024-02-28 14:13:16 +01:00
piair 3d096ec34c close to working 2024-02-28 12:09:32 +01:00
piair 7bdf229fa8 je connais pas le js moi 2024-02-28 12:02:41 +01:00
piair 0abb8a3494 weird errors 2024-02-28 12:00:19 +01:00
piair 231c3b34e3 better terminal 2024-02-28 11:55:55 +01:00
piair c72aaf3fcc better terminal 2024-02-28 11:53:23 +01:00
piair 675e67055b better terminal 2024-02-28 11:41:16 +01:00
piair a089fdfdf1 better terminal 2024-02-28 11:41:13 +01:00
piair 0f60d67951 obsolete : module 2024-02-28 11:38:32 +01:00
piair 1c7d1dfcd6 typo 2024-02-28 11:38:21 +01:00
piair 19606e5f4c I'm just a clown, I didn't update... 2024-02-28 11:15:09 +01:00
piair aaafbb2257 some debug don't work at all ? 2024-02-28 11:13:09 +01:00
piair 8d332f1c3c check if discord works 2024-02-28 11:10:48 +01:00
piair ced633dd68 refactored log_points 2024-02-28 10:49:27 +01:00
piair 5fe05712bd refactored all_cards 2024-02-28 00:14:42 +01:00
piair 6ec5300c7b the logger should only log my code now 2024-02-27 23:59:39 +01:00
piair 5ca91a7075 the optimisation wasn't that great 2024-02-27 16:26:29 +01:00
piair d49742646c wrong parameter in rgpd_popup 2024-02-27 16:21:08 +01:00
piair a88ad8dd47 the issue seems to be due to MS 2024-02-27 16:13:01 +01:00
piair d9ebccebb8 well the login works, but it will cause issues later with cookies 2024-02-27 16:09:23 +01:00
piair 40f08b4c86 issue indeed fixed, but still can't log in 2024-02-27 16:05:29 +01:00
piair b072041446 issue indeed fixed, but still can't log in 2024-02-27 16:05:21 +01:00
piair 476f99b931 fix ? 2024-02-27 15:59:23 +01:00
piair 37c5d9cf43 can I go to some website ? 2024-02-27 15:57:25 +01:00
piair 9e274b6d16 weird error 2024-02-27 15:55:37 +01:00
piair 2a3878b919 bump version. Added docker compose 2024-02-27 15:38:19 +01:00
piair 7cc1b415a6 bump version. Added docker compose (thx chatGPT) 2024-02-27 15:35:31 +01:00
piair 6a2d960dd0 bump version. Added docker compose 2024-02-27 15:31:35 +01:00
piair bff43c8207 bump version. 2024-02-27 15:22:51 +01:00
piair 7a47b7ae9d bump version. 2024-02-27 15:21:30 +01:00
piair 346b9acc04 bump version. 2024-02-27 15:19:53 +01:00
piair bc94489ca0 bump version. 2024-02-27 15:18:45 +01:00
piair a601c64feb bump version. 2024-02-27 15:17:11 +01:00
piair af938eb50a bump version. 2024-02-27 15:14:14 +01:00
piair 2ae80e9c53 bump version. 2024-02-27 15:12:30 +01:00
piair 27f08b5a01 bump version. 2024-02-27 15:12:25 +01:00
piair 84ace32977 bump version. 2024-02-27 15:07:42 +01:00
piair da6ca1cdfc bump version. 2024-02-27 15:05:19 +01:00
piair 9857607eb3 implemented classes to remove global file 2024-02-27 14:52:55 +01:00
piair 3c9d20891c Merge branch 'master' of https://gitea.augustin64.fr/piair/MsRewards-Reborn 2024-02-27 11:34:22 +01:00
piair a0a4535c35 updated webUI according to param changes 2024-02-27 11:26:55 +01:00
piair d4920ec322 bump version. this code have not been tested, so DON'T UPDATE. 2024-02-27 01:45:35 +01:00
piair 31e38b7258 small things here and there 2024-02-27 01:41:40 +01:00
piair 2cc1fcbc72 removed a lot of unused command line parameters 2024-02-27 01:41:18 +01:00
piair 35c846e671 removed a log of global variables. This file should disappear. 2024-02-27 01:40:51 +01:00
piair dc3e31d8d5 typo 2024-02-27 01:35:06 +01:00
piair f1cce097ad moved the initialisation to Config.py 2024-02-27 01:34:56 +01:00
piair da707ade5a moved the initialisation to Config.py 2024-02-27 01:34:51 +01:00
piair 6be44e829a improved try_play to use logger and to be a bit faster 2024-02-27 01:03:57 +01:00
piair 76acfb42c4 Updated play_quiz to use logger 2024-02-27 00:48:55 +01:00
piair a47a460a56 removing dev as it's not used anymore 2024-02-27 00:34:54 +01:00
piair 6de49e8874 removing custom_start as it's not useful anymore with the WebUI 2024-02-27 00:34:30 +01:00
piair b89d3036bb implementing UserCredential class 2024-02-27 00:33:48 +01:00
piair cf6905b169 created config management class 2024-02-27 00:33:17 +01:00
piair 962c2eab86 created user management class 2024-02-27 00:33:08 +01:00
piair 26c4869830 reorganized folder struct 2024-02-27 00:32:52 +01:00
piair 2e0f148d0c deleted old V7 2024-02-27 00:32:31 +01:00
piair f0acd9e2f2 deleted old V7 2024-02-27 00:32:25 +01:00
piair fc8e666927 Merge pull request 'Fix multiple crashes' (#7) from augustin64/MsRewards-Reborn:augustin64-patch-1 into master
Tu es dur avec le « multiple crashes »
2024-02-23 20:42:07 +01:00
augustin64 9682b95001 Fix OTP not working in very custom start 2024-02-23 08:49:00 +01:00
augustin64 cc051aea4c Fix error when changing password 2024-02-23 08:46:29 +01:00
piair ef686799a8 small changes, the real fix vas to update chrome and undetected chromedriver 2024-02-22 09:38:17 +01:00
piair e75a28104d Merge remote-tracking branch 'origin/master' 2024-02-22 09:13:56 +01:00
piair 4b5b7f4b67 old V7 stuff. 2024-02-22 09:13:49 +01:00
piair 86093ab975 Update requirements.txt 2024-01-25 21:13:52 +01:00
piair fa7a8376ec Update requirements.txt 2024-01-25 21:10:42 +01:00
piair 59f7f03584 parsing input file 2024-01-18 20:15:58 +01:00
piair cf1dcec704 uéué, si c'est PyCharm qui le dit ca dois être bien 2024-01-18 16:36:15 +01:00
piair 4c376acf17 implémentation de la recherche PC + du VNC + requirement.txt + joli logger + séparation en plus de fichiers 2024-01-18 16:35:17 +01:00
piair 48e201043b je suis ptet en train de tout refaire mais chut 2024-01-17 17:24:25 +01:00
piair d5ec96f1e8 je suis ptet en train de tout refaire mais chut 2024-01-17 17:22:26 +01:00
piair 7d81eb642e Merge pull request 'Add min to grafana dashboard' (#6) from augustin64/MsRewards-Reborn:augustin64-grafana-config-patch-1 into master
a peine 3 semaine pour voir que j'ai qqchose a faire, c'est pas grand chose si ?
2023-12-06 11:05:08 +01:00
augustin64 24e2506e48 Add min to grafana dashboard
get an accurate scale on the grafana dashboard
2023-11-16 11:16:44 +01:00
Pierre Tellier 595d232c88 updated for chrome 118 2023-11-09 19:56:26 +00:00
Pierre Tellier 7b0c82ca14 chrome 119 support, IDK why it is this version and not any other one 2023-11-08 18:15:36 +00:00
piair e32efc1bf7 Update build.sh
pour fix les problèmes de DNS
2023-11-03 19:00:06 +01:00
piair b5050e6bdc Update Dockerfile
je comporend pas pourquoi ca marchais avant en fait
2023-11-03 18:54:57 +01:00
piair b25fa7579b Update Dockerfile
là je suis juste débile
2023-11-03 18:49:25 +01:00
piair 8b7f17f0f2 Update Dockerfile
je suis vramiment pas sur de comprendre
2023-11-03 18:47:50 +01:00
piair 761de5028f Update Dockerfile
-y
2023-11-03 18:45:26 +01:00
piair 4add59f84e Update Dockerfile
je comprend meme pas
2023-11-03 18:44:11 +01:00
piair b0ddab6827 Update Dockerfile 2023-11-03 18:38:18 +01:00
piair 28206865ea Update Dockerfile
uh
2023-11-03 18:36:03 +01:00
piair eca2012ffa Update Dockerfile
pk c'est pt
2023-11-03 18:35:32 +01:00
piair d3f12f2d1b Update Dockerfile
Je suis en train de tout reinstaller, donc le site principalest down pour le moment
2023-11-03 18:06:30 +01:00
piair 59e57bc124 added random time before each account intead of after 2023-10-15 14:31:07 +02:00
piair d4c3e70e5f Merge pull request 'Fix login' (#5) from augustin64/MsRewards-Reborn:augustin64-fix-login into master
Reviewed-on: https://gitea.augustin64.fr/piair/MsRewards-Reborn/pulls/5
2023-10-09 18:50:25 +02:00
augustin64 ccacad3c0c Changer le type de champ à password
Cela permettra à des gestionnaires de mots de passe de le détecter
2023-10-09 16:20:11 +02:00
augustin64 63b40d2228 Actualiser Flask/templates/login.html
Il est actuellement impossible pour moi de me connecter, la requête POST est faite à `/login` qui cause une redirection vers `/login/`(GET) et le serveur ne traite plus la requête POST initiale contenant le mot de passe.
2023-10-09 16:17:26 +02:00
piair 1c9697700d encore des nouveaux truc par la 2023-10-07 11:56:37 +02:00
piair 7c19dcc974 fixing a little bug with daily not starting + trying something to fix another issue when there are a lot of logs 2023-10-05 22:06:52 +02:00
piair 7d79b727a9 bon j'y crois, tout marche 2023-10-04 18:40:49 +02:00
piair 35ae711c45 allez demarre tout seul 2023-10-04 18:06:58 +02:00
piair 34bdad3721 seems fine to me 2023-10-04 18:02:27 +02:00
piair 3bea338652 plus qu'a demarrer a par default et a rendre joli 2023-10-04 17:55:43 +02:00
piair 2038e84654 ahhh 2023-10-03 12:27:04 +02:00
piair 99ccdbef46 c'est ce que hje cherchais nan ? 2023-10-03 12:24:39 +02:00
piair ab74f5b642 non. 2023-10-03 12:08:02 +02:00
piair 29fce1215d je tente des truc mais on a jamais été si proche 2023-10-03 12:01:59 +02:00
piair 26faab4133 tout casser 2023-10-03 00:58:56 +02:00
piair 9586df7ce7 ahhhhhjh 2023-10-03 00:54:56 +02:00
piair fe35650452 je vais regarder a quoi ca sert yield 2023-10-03 00:32:59 +02:00
piair e181bd1ba4 je devienne fou 2023-10-03 00:30:20 +02:00
piair 8991e4f4c8 please 2023-10-03 00:23:06 +02:00
piair 291b7332bc pouquoi il ne me le pull pas 2023-10-03 00:18:00 +02:00
piair 2639e5ef53 aled je suis en train de tout casser 2023-10-03 00:17:20 +02:00
piair d381c5e113 pourquoi ? 2023-10-02 23:19:22 +02:00
piair 6d91b6e491 je comprend pas pk ca marche pas 2023-10-02 23:19:17 +02:00
piair 1e7f283e80 c'est une bien meilleure manière de faire. 2023-10-02 21:55:56 +02:00
piair e2ab390b01 mis dans le js + fix quelques problemes 2023-09-30 19:30:42 +02:00
piair 43188f65ac names are back 2023-09-30 19:26:17 +02:00
piair 7b1a4cae2c pas besoin d'afficher a chaque fois l'intégralité des mots de passe dans les logs (qui sont plus ou moins public par ailleurs) 2023-09-30 18:36:20 +02:00
piair 213b62712a hmm chelou cette affaire 2023-09-30 18:32:02 +02:00
piair 1bcf53b4af autoconnect test + issue with stop 2023-09-30 18:29:47 +02:00
piair f9d7da64c9 LET'S GO CA MARCHE (il y a plus qu'a rendre tout ca joli + faire en sorte que le vnc se connecte tout seul et c'est une dinguerie) 2023-09-30 18:22:56 +02:00
piair 7860cfdf04 les problemes d'indices .... 2023-09-30 18:16:47 +02:00
piair e89368a5f4 ca marche presque, c'est une dingerue 2023-09-30 18:12:26 +02:00
piair 7c0ed44e17 one tab away 2023-09-30 18:04:16 +02:00
piair 642c93de86 une dingerie cette up^date en vré 2023-09-30 18:02:14 +02:00
piair 56234f2420 on en est a deux dois la. par contre tu immagine a quoi va ressembler la 1.33 sur minecraft ? je suis hype de fou 2023-09-30 18:00:43 +02:00
piair 1e576edc51 fin bon ca va la 2023-09-30 17:56:08 +02:00
piair e13c4ee429 j'y crois tellement que je push 2023-09-30 17:53:16 +02:00
piair 8ec5aa52ba il commence a y avoir beaucoup de modifs 2023-09-30 17:41:46 +02:00
piair 90a87d19c7 2ème problème (je ne vais commit que les modifs sur le app.py) 2023-09-30 17:33:39 +02:00
piair 294ad75aa0 1er probleme 2023-09-30 17:31:19 +02:00
piair e21ee8b5a4 faire git pull = être un gros fou, j'ai rien tester 2023-09-30 17:23:37 +02:00
piair 92ee7da9a4 ouais je pense que tu vois la ou je veux en venir 2023-09-30 16:29:50 +02:00
piair a7b42ab3a1 bon au moins j'ai compris le problème 2023-09-28 15:29:55 +02:00
piair 72a9da6cac ... 2023-09-28 15:11:37 +02:00
piair afb93f1693 je comprend rien 2023-09-28 15:10:40 +02:00
piair 67ac18349b WTF 2023-09-28 15:08:38 +02:00
piair e5183d30a6 je comprend plus rien 2023-09-28 15:08:16 +02:00
piair e10c933994 mais QUOI ?????????? 2023-09-28 15:07:27 +02:00
piair a07a07a0a2 pouquoi ca marche plus je comprend rien 2023-09-28 15:06:47 +02:00
piair 48abf0874c ca avance 2023-09-28 15:03:08 +02:00
piair 5d8ebc379b g tout peter mais c'est fait exprès 2023-09-27 20:20:09 +02:00
piair b5abd589ba on avance 2023-09-27 20:12:29 +02:00
piair 4c78ec150b bah voila a quoi ca sert 2023-09-27 20:05:39 +02:00
piair 11d30491c6 normalement ca marche 2023-09-27 19:59:48 +02:00
piair e6f3d66f7b le test a pas vraiment marché 2023-09-27 19:58:41 +02:00
piair a7e6a73ba5 test pour que ce soit plus joli 2023-09-27 19:57:11 +02:00
piair e7d8e8afa4 en vrai il y a eu d'autres tests 2023-09-27 19:55:43 +02:00
piair 3199db3874 pas mal la 1.16 (je sais pas pk c'est cassé) 2023-09-27 19:47:08 +02:00
piair 98bb9ad6d0 Pourquoi ca descend pas ? 2023-09-27 19:38:21 +02:00
piair 72504e5cab oué ca update 2023-09-27 19:26:44 +02:00
piair 8813542cfc PTDR je modifie le mauvais fichier depuis tout a l'heure 2023-09-27 12:15:08 +02:00
piair 942bda3a29 ca va faire plus de version que minecraft a ce rythme 2023-09-27 12:11:58 +02:00
piair e5d8551aab oops 2023-09-27 12:04:38 +02:00
piair 8934568b84 hmmm 2023-09-27 12:02:19 +02:00
piair 07c37b9ae9 oh bordel qu'es ce que je fous 2023-09-27 11:58:39 +02:00
piair 7e6062ca1c ce serait très frole si ca marche 2023-09-27 11:51:38 +02:00
piair 1710ade2c1 j'aime toujours pas le js mais ca commence a marcher 2023-09-27 11:43:00 +02:00
piair e0b4560988 déjà skip la v6.6.6 ;( 2023-09-27 11:34:58 +02:00
piair 45db9eb67c déjà skip la 6.6.6 ;( 2023-09-27 11:34:47 +02:00
piair dc2a9e20df OMG VERSION DE FOU 2023-09-27 11:30:50 +02:00
piair 6bc4451684 je sais toujours pas comment marche le js mais bon 2023-09-27 11:27:58 +02:00
piair fb71cf7f41 je suis pas sur de savoir pourquoi ca casse, mais ce'est comme avant 2023-09-27 11:17:17 +02:00
piair f727c3ef86 the logs bug seems to be an iPad browser issue, but it sould be fixed now 2023-09-27 10:36:41 +02:00
piair e88a9e22f2 vraiment bizarre cet page de logs 2023-09-27 10:25:54 +02:00
piair 315bf4b150 uh ca marche pas depuis quand ca ? 2023-09-27 10:19:01 +02:00
piair 6fe3f16ead trying something 2023-09-27 10:13:47 +02:00
piair 6e930d5241 euh wé 2023-09-25 19:19:22 +02:00
piair 767d790344 ca a l'air ok, mais ily a toujours des prbls 2023-09-24 22:28:51 +02:00
piair 7a02560473 c'est ptet un fix, mais encore une fois je sais pas pk 2023-09-24 22:26:03 +02:00
piair 1a44c60202 je comprend plus rien 2023-09-24 22:23:52 +02:00
piair e03ef1759c meh wtf 2023-09-24 22:16:06 +02:00
piair 1d4021edb0 where are you ? 2023-09-24 22:13:40 +02:00
piair 799f8d0b43 hmmmmmmmm 2023-09-24 22:10:23 +02:00
piair 611c114881 bon... 2023-09-24 21:48:35 +02:00
piair b5468c9ff2 related to login ? 2023-09-24 21:45:35 +02:00
piair c34a82639c vraiment chelou cette affaire, a la main, il n'y a pas de problèmes 2023-09-24 21:42:27 +02:00
piair 07f6ff9c3c trying to fix that card error + fix config (merci) 2023-09-24 21:19:02 +02:00
piair 424798c7f6 OMG C'est trop bie 2023-09-20 13:13:41 +02:00
piair f0447b2d1d push 2023-09-20 13:05:13 +02:00
piair 9316317d2b push 2023-09-20 13:00:48 +02:00
piair 2c05937663 updated 2023-09-20 12:58:33 +02:00
piair d166b164e6 des ptit problèmes par ci par la 2023-09-20 11:54:43 +02:00
piair 7a59891f37 ofc j'ai oublier ca 2023-09-20 11:48:37 +02:00
piair 192be842a3 et le app.py 2023-09-20 11:48:03 +02:00
piair 15823c850f bump 2023-09-20 11:46:56 +02:00
piair a07b55fab7 euh ouais j'ai ptet rajouter un VNC, bref on verra 2023-09-20 11:46:35 +02:00
piair 58ab110d55 aucune idée pourquoi ca a fix mais bon, fine ? 2023-09-10 11:04:28 +02:00
piair 5a1a5b880b hmmm 2023-09-10 11:03:05 +02:00
piair e7f74e6882 mais quoi ?? 2023-09-10 11:02:15 +02:00
piair 01f678a216 hmm why doesn't this work ? 2023-09-10 10:56:04 +02:00
piair defbc63a65 fixed error 2023-09-06 16:04:42 +02:00
piair ae6707ef53 whoops, btw, clicking again on stats open grafana 2023-08-29 19:34:52 +02:00
piair efd53fb5d9 comeback, version number 2023-08-29 19:31:29 +02:00
piair 10e8fe1dd0 yeah i even consider that as a big update 2023-08-29 19:28:13 +02:00
piair fd3da49694 c'est ok ca marche, et c'est presque joli 2023-08-29 19:04:34 +02:00
piair bd0cb71bba whoops 2023-08-29 18:53:57 +02:00
piair fa45d97576 should be embeded now 2023-08-29 18:53:06 +02:00
piair 74ea8ee854 bah tu étais passé ou toi ? 2023-08-29 18:36:22 +02:00
piair 15103b7905 okay normalement le numero de version marche 2023-08-29 18:34:19 +02:00
piair 2433609cd8 Merge pull request 'Ajout d'un bouton pour activer/désactiver le panneau latéral' (#2) from augustin64/MsRewards-Reborn:master into master
Reviewed-on: https://gitea.augustin64.fr/piair/MsRewards-Reborn/pulls/2
2023-08-29 18:26:36 +02:00
augustin64 d06d925e27 Fix: remove version number 2023-08-29 18:24:06 +02:00
augustin64 221921e3f3 Add sidebar toggling 2023-08-29 15:30:03 +02:00
augustin64 fcc7f4d46e css: use variables for colors 2023-08-29 15:21:44 +02:00
piair 7f21301da0 Merge pull request 'fix: impossible d'afficher des logs quand une seule config existe' (#1) from augustin64/MsRewards-Reborn:patch-logs into master
Reviewed-on: https://gitea.augustin64.fr/piair/MsRewards-Reborn/pulls/1
2023-08-29 11:37:48 +02:00
augustin64 211dcecd23 fix: impossible d'afficher des logs quand une seule config existe 2023-08-29 10:54:58 +02:00
piair c072a71c83 pas mal le version control : 6.2.0 -> 6.2.10 2023-08-26 13:17:57 +02:00
piair fd8f972cf8 let's go ca marche je pense 2023-08-26 13:14:32 +02:00
piair 6e25dcd115 ah la ca semble bien 2023-08-26 13:12:25 +02:00
piair c25a744a5c still testing 2023-08-26 13:10:57 +02:00
piair 83a2b8f33e hmm test 2023-08-26 13:08:18 +02:00
piair 96cb82aac4 testfix + logs style 2023-08-26 12:55:46 +02:00
piair cd39f7109e unrecognized token: "{" 2023-08-26 09:11:26 +02:00
piair 217f385725 no such column: nom 2023-08-25 20:43:37 +02:00
piair 6efc77c512 fixed things, like auto adding account to database 2023-08-25 19:40:39 +02:00
piair 820efd8126 uéuéué j'ai oublier quoi ? 2023-08-25 16:25:17 +02:00
piair b0b537968c omg ca marche ? 2023-08-25 15:49:37 +02:00
piair f7d6b19fc6 still improving 2023-08-25 15:25:32 +02:00
piair 4757a2957d improvement 2023-08-25 15:23:33 +02:00
piair f548c3030a that's what i call progress 2023-08-25 15:12:31 +02:00
piair c712395d39 fixed stuff 2023-08-25 14:50:38 +02:00
piair 8acdcae7de pouyrquoi ca marche pas ? 2023-08-25 14:41:39 +02:00
piair 33cb90f110 hmmmm 2023-08-25 14:39:13 +02:00
piair 0516296499 okay 2023-08-25 14:06:03 +02:00
piair 534b8f3367 BON.... 2023-08-25 13:25:02 +02:00
piair 2d70f00c0f je devrais pas 2023-08-25 13:21:33 +02:00
piair d16715dbf5 uéuéué ca test des trucs (un viewer de logs) 2023-08-25 13:20:51 +02:00
piair 466ab6d880 euh en gros :
- j'ai bougé plus de JS dans le fichier main.js
- j'ai changé le css pour que les listes soient joli
2023-08-25 12:06:52 +02:00
piair 6fb0698d18 adding js to a separate file 2023-08-25 11:54:14 +02:00
piair f05d695ddb je suis désolé, c'est plus simple de commit pour voir ce que ca donne en vrai 2023-08-25 11:47:31 +02:00
piair 79e6d9053e déja ca a fix le problème de lancement je pense 2023-08-25 11:43:09 +02:00
piair bfab01a1a3 Delete dev_build.sh
it's a dev file, so shouldn't be there
2023-08-24 21:22:01 +02:00
piair 5c2fa42f51 removed database configuration page, using instead SQlite, and integrated grafana interface 2023-08-24 21:18:36 +02:00
piair 1befff788d bon, j'ai le droit d'être débile aussi 2023-08-24 14:39:15 +02:00
piair a3d7a49197 added stats link 2023-08-24 14:36:24 +02:00
piair ff9edc2631 ptet que j'ai fix le probleme de multiple execution au passage 2023-08-24 14:31:45 +02:00
piair 24df044e1f bon la ca marche 100% 2023-08-24 14:28:49 +02:00
piair 2f2b4f9905 what is started????????? 2023-08-24 14:24:52 +02:00
piair 0fa8149953 grafana only works 30sec after start 2023-08-24 14:21:51 +02:00
piair f6b43a9ce4 OMG CA MARCHE ? 2023-08-24 14:13:25 +02:00
piair 11b13842dd je veuc comprendre 2023-08-24 14:09:51 +02:00
piair 2938b83217 grzejlh 2023-08-24 14:06:53 +02:00
piair d3496c2fba mais qUQOIUJF OIGEZQHGIHEBOIF HBNEUHb 2023-08-24 14:04:42 +02:00
piair 58b4b26c37 pls explain 2023-08-24 14:01:48 +02:00
piair b227f47953 hmmmm 2023-08-24 13:58:53 +02:00
piair 718fd1643d pls ? 2023-08-24 13:53:51 +02:00
piair ab629d8dd2 meh ? 2023-08-24 13:50:37 +02:00
piair 48225a0455 c'est un peu plus joli, et en plus ca marche (ptet?) 2023-08-24 13:45:58 +02:00
piair e28efad8de ca a l'air 2023-08-24 13:40:46 +02:00
piair 1f73f6fdce c'est pas beau mais si ca marche, ... 2023-08-24 13:38:34 +02:00
piair 74f9c5b496 pourquoi ca marche pas ? 2023-08-24 13:35:53 +02:00
piair 2bc388e61f oops 2023-08-24 13:30:07 +02:00
piair 55a1677fb4 c'est bon ? 2023-08-24 13:28:49 +02:00
piair 864bf95138 need to fix api calls to grafana daashbord 2023-08-24 13:09:36 +02:00
piair 661c76b9f7 test ou on demarre bien tout les services 2023-08-24 13:05:44 +02:00
piair 9810381f8d ca marchera mieux si c'est au bon endroit 2023-08-24 12:38:41 +02:00
piair d6c49168e5 bon je sais toujours pas ce que j'ai fait mais ptet que ca marche mieux qu'avant 2023-08-24 12:37:33 +02:00
piair a9674a5b0a bon normalement ca marche, sauf que grafana et nginx ne se lancent pas auto 2023-08-22 16:32:37 +02:00
piair a426e787e3 aaaa 2023-08-22 13:35:45 +02:00
piair 49f157436b ofc i need to commit 2023-08-22 13:33:43 +02:00
piair 6b8f2f0cbc que suis-je en train de faire ? 2023-08-22 11:47:36 +02:00
piair 36f8938f0f ah ? 2023-08-22 11:24:50 +02:00
piair bc2725a7b9 aa 2023-08-22 11:23:59 +02:00
piair 551c2f18c9 bon 2023-08-22 11:22:50 +02:00
piair adbb33aa0c oulah qu'ai-je fait 2023-08-22 11:21:42 +02:00
piair e896d4b949 New feature : you can import and export configs 2023-08-21 21:38:27 +02:00
piair 3132795c5e oui ca marche 2023-08-21 21:36:14 +02:00
piair b80d82d112 a* 2023-08-21 21:34:55 +02:00
piair 18cc9f902c ? 2023-08-21 21:31:51 +02:00
piair c997dc5ebe F le JS 2023-08-21 21:29:23 +02:00
piair 38de2f040d quoi que j'avais dit 2023-08-21 21:28:18 +02:00
piair aeb93e8a55 hmm? 2023-08-21 21:26:21 +02:00
piair b3f13399a4 aucune idée de ce que je fais 2023-08-21 21:25:05 +02:00
piair e099f705c8 oh bordel je connais pas le js moi 2023-08-21 21:18:24 +02:00
piair 41f4059996 euh ué? 2023-08-21 21:16:59 +02:00
piair 2b0e99031e on fait des tests écoute 2023-08-21 21:10:55 +02:00
piair 02f835e755 oui 2023-08-21 21:07:54 +02:00
piair 16f907d0db close to work 2023-08-21 21:05:49 +02:00
piair 7b4250d444 uéuéuéuéuéué 2023-08-21 21:03:26 +02:00
piair bd70557062 nearly good 2023-08-21 21:00:03 +02:00
piair 8d7a474c69 much better 2023-08-21 20:58:26 +02:00
piair 9b411fe54e okok 2023-08-21 20:57:26 +02:00
piair 18f0f3ec02 j'avais pas de name je suis débile 2023-08-21 20:55:29 +02:00
piair 21599e5db5 "" 2023-08-21 20:54:39 +02:00
piair b6560982e6 okay cla ca marcje 2023-08-21 20:53:59 +02:00
piair 597840d132 ... 2023-08-21 20:53:07 +02:00
piair 259a3ad713 yeah i mean... 2023-08-21 20:51:29 +02:00
piair e668d312b6 as the example shows 2023-08-21 20:50:38 +02:00
piair 60734a373e c'est quoi ca encore ? 2023-08-21 20:48:51 +02:00
piair 1ca5ff2ec1 maintenant 2023-08-21 20:47:02 +02:00
piair 494a58593b plus de redirect débiles 2023-08-21 20:46:09 +02:00
piair 8f5a1ac705 logik en fait 2023-08-21 20:44:48 +02:00
piair 8444fdbb2d chelou cette affaire 2023-08-21 20:43:55 +02:00
piair 280d4c79c3 meh ? 2023-08-21 20:42:16 +02:00
piair 8e9824b3d7 send files 2023-08-21 20:39:45 +02:00
piair f076eafec9 download files 2023-08-21 20:36:32 +02:00
piair d2741e8c7a still about the file backup 2023-08-21 19:59:49 +02:00
piair 84b9c02a72 created a backup 2023-08-21 19:51:29 +02:00
piair f1d74b9921 tests 2023-08-21 19:46:57 +02:00
piair e2f47432c4 a 2023-08-21 19:43:15 +02:00
piair 08dde1f6d2 test 2023-08-21 19:41:50 +02:00
piair 37249ec654 test 2023-08-21 19:40:51 +02:00
piair 2be6348273 a 2023-08-21 19:38:27 +02:00
piair bab3a86624 test 2023-08-21 19:37:21 +02:00
piair a3e993a091 a 2023-08-21 19:35:57 +02:00
piair 5b2f882e56 a 2023-08-21 19:35:27 +02:00
piair 0665ba2808 a 2023-08-21 19:34:04 +02:00
piair f65aa23021 aa 2023-08-21 19:32:02 +02:00
piair ca4f97c07b fix 2023-08-13 20:37:21 +02:00
piair 659e7d3664 auto reload. added back mobile search. 2023-07-03 21:29:26 +02:00
piair 5c23097873 fixed some issues preventing the programm to start (...) 2023-07-03 11:43:57 +02:00
piair 11a7d6c23c whoopps 2023-07-02 19:46:37 +02:00
piair 3a8ccb2e92 a 2023-07-02 19:45:20 +02:00
piair 77a2ba9c65 whoops 2023-07-02 19:36:14 +02:00
piair 835aac046f test 2023-07-02 19:34:56 +02:00
piair ad80de0c04 toujours pas stable 2023-07-02 19:26:24 +02:00
piair a9dcb7726c style update 2023-07-01 16:24:39 +02:00
piair 55b5cff24b style update 2023-07-01 16:21:51 +02:00
piair 49045f54a7 a 2023-07-01 14:41:07 +02:00
piair 61eb6dfe6e aaaaaaaa 2023-07-01 14:35:33 +02:00
piair 0d9c128a2c a 2023-07-01 14:28:04 +02:00
piair 2253506f80 a 2023-07-01 14:22:46 +02:00
piair 2d5cb19896 a 2023-07-01 14:16:43 +02:00
piair a5421f6ae4 y 2023-07-01 14:14:41 +02:00
piair 524e412b40 tests 2023-07-01 14:06:48 +02:00
piair cf88ede967 dev test 2023-07-01 13:51:48 +02:00
piair 5e2e7f9f14 Add 'user_data/logs/.gitignore' 2023-07-01 13:43:51 +02:00
piair fe218a1d21 Delete 'user_data/logs' 2023-07-01 13:43:34 +02:00
piair 68d09d29af Add 'user_data/logs' 2023-07-01 13:42:31 +02:00
piair 3c9472fe2e add logs 2023-07-01 13:41:17 +02:00
piair 9082f9b87c auto update ? 2023-06-29 11:55:49 +02:00
piair b64339bdab si ca marche c'est trop bien 2023-06-26 21:51:47 +02:00
piair 33eadaa405 still looks like beta to me 2023-06-26 21:49:30 +02:00
piair ca7f49e6a6 meh 2023-06-25 10:49:25 +02:00
piair 027ca5dbdb OUI 2023-06-25 10:28:06 +02:00
piair 5b558285af ? 2023-06-25 10:24:03 +02:00
piair fabd826aa8 2 or 3 changes before tomorrows exams 2023-06-25 09:56:14 +02:00
piair 1e22cfcb4a test 2023-06-25 09:22:22 +02:00
piair 4b0f33ae26 stable 2023-06-24 16:39:42 +02:00
piair f098f13242 small fix 2023-06-24 14:04:44 +02:00
piair 51edb0c0fd yeah 2023-06-22 22:27:41 +02:00
piair d96ec5891f HOW TO ENABLE MOBILE PLS 2023-06-22 19:20:32 +02:00
piair 8694c4d30b ignore pls 2023-06-21 21:30:07 +02:00
piair fb6bdf385e uéué 2023-06-21 21:25:36 +02:00
piair 0281bb946d uéuéué 2023-06-21 21:24:30 +02:00
piair ed828e4ea0 ouo 2023-06-19 20:53:13 +02:00
piair 54d728364e Update 'user_data/settings.json' 2023-06-19 20:37:47 +02:00
piair 0d9366c801 default files 2023-06-18 22:22:53 +02:00
piair 6e55189c5d meh ? 2023-06-18 22:12:35 +02:00
piair 9bfbd744e4 ?# 2023-06-18 22:10:42 +02:00
piair 70696ee91b some fixes 2023-06-18 22:08:16 +02:00
piair 9b237c7ebf maybe the last update 2023-06-18 19:21:02 +02:00
piair 4e939bec2f YEAH 2023-06-18 18:32:06 +02:00
piair 08b593eeb9 oh boy 2023-06-18 17:40:59 +02:00
piair b201c68aa9 gitea test 2 2023-06-18 15:58:22 +02:00
piair 171fa2fc77 gitea test 2023-06-18 15:57:41 +02:00
piair 2b849ca0ca implemented different secret and password for each instances 2023-06-18 15:55:45 +02:00
piair d49c8031a1 de toute facon il est useless 2023-06-17 17:03:49 +02:00
piair 1042fcf3cc bruh ? 2023-06-17 16:52:47 +02:00
piair 550e36b954 less errors 2023-05-31 10:52:45 +02:00
piair 4814dfed46 hotfix, but a nice one 2023-05-30 20:21:25 +02:00
piair 67aad7921f useful untested update 2023-05-12 14:53:52 +02:00
piair ecd5a9f204 small fixes, testing tomorrow then releasing 2023-05-09 13:09:14 +02:00
piair338 2b1c7b985e
Create CODE_OF_CONDUCT.md 2023-05-08 21:17:23 +02:00
piair c9c93e9828 Merge branch 'master' of https://github.com/piair338/MsRewards
what am i breaking ?
2023-05-08 20:58:58 +02:00
piair 1a4ed4f4e7 lang + small error fix 2023-05-08 20:56:55 +02:00
piair338 0ba92798ad
Update README.md
A better installation tutorial ?
2023-05-08 20:44:51 +02:00
piair 4aef2bf948 added switches 2023-05-07 23:26:27 +02:00
piair 68395f4314 new handeling method for fidelity. Need deeper testing, but should be fine. 2023-05-07 12:51:38 +02:00
piair 2ca2779ec9 fixed a rare error occuring when the cookie creation isn't successful 2023-05-05 11:56:26 +02:00
piair 5ef8d8b7ca some fixes. I believe it's stable. New release tomorrow 2023-05-05 11:40:38 +02:00
piair f2d08e9137 still dont know 2023-05-04 20:32:19 +02:00
piair d946298a38 don't know 2023-05-04 17:49:51 +02:00
piair ed1e91b304 ptite update 2023-04-25 21:56:29 +02:00
piair 710c272659 better logs 2023-04-17 22:28:26 +02:00
piair 6f325c5a6a small fix 2023-04-17 22:00:46 +02:00
piair 3b82419d4d fixed fidelity, but a new version may come sooner or later 2023-04-15 13:10:14 +02:00
piair 9e0514a902 only the number of the config 2023-04-15 11:18:55 +02:00
piair 5c8730dc26 only the number of the config 2023-04-15 11:18:36 +02:00
piair d11ae4055c euh ué 2023-04-15 11:04:23 +02:00
piair 2dc8cda167 euh ué 2023-04-15 11:03:47 +02:00
piair fbb2feae31 small but infinite error 2023-04-14 10:31:12 +02:00
piair 8d53a2b30b ok 2023-04-13 22:38:27 +02:00
piair f8f3ff2382 uéuéué 2023-04-13 22:22:06 +02:00
piair 024b556f5e bruh 2023-04-13 09:11:12 +02:00
piair b4c9204bf2 oh gosh 2023-04-12 18:25:12 +02:00
piair f810f0ee3c test 2023-04-12 14:40:32 +02:00
piair afac7e9539 bump 2023-04-12 13:29:40 +02:00
piair ae12c18270 not stable either, but something need to change 2023-04-12 13:29:06 +02:00
piair dfd51bc040 uéuéué faster, more reliable, ... 2023-04-12 00:01:24 +02:00
piair 12a6968ee0 well, SadPanda is still here ;( 2023-04-09 23:41:31 +02:00
piair 8726785dc8 random test 2023-04-08 12:08:26 +02:00
piair e9f629dee4 sadpanda + typo 2023-04-08 11:51:27 +02:00
piair c9a838d368 faster overall + better discord error + better login 2023-04-07 23:28:48 +02:00
piair 808916ddd3 testing is everything 2023-04-07 10:04:59 +02:00
piair 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
piair a22d1e6ddb you can manually add points to database 2023-04-07 09:53:11 +02:00
piair 93bb634f7c some fixes here and there 2023-04-06 23:41:11 +02:00
piair 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
piair f862af8699 version control 2023-04-04 21:27:02 +02:00
piair 78e7342acf last update of the night ? 2023-04-04 21:26:40 +02:00
piair 4d8157ba1e better stronger faster 2023-04-04 21:18:09 +02:00
piair 661566aade no clue if that's better 2023-04-04 21:07:12 +02:00
piair eb2b9dc2d3 you should now start using main : it can finally pass args 2023-04-04 20:59:45 +02:00
piair 3385540350 better way if manually updated 2023-04-04 20:50:56 +02:00
piair 0588180dda should be good for now 2023-04-04 20:46:10 +02:00
piair 9995bc8e25 Auto Updates ? 2023-04-04 20:37:48 +02:00
piair 98ff0a183a always more stable (no) 2023-04-04 12:55:00 +02:00
piair d579a2c160 once again, should be fairly stable 2023-04-02 12:32:21 +02:00
piair ccf284f6e2 typo + better logic + WTF everything has failed today 2023-04-02 11:02:37 +02:00
piair f30832d8cd OMG finally stable ? 2023-04-01 09:51:53 +02:00
piair 799d3d67d5 may even be stable wtf 2023-03-31 10:00:45 +02:00
piair f10cd8d226 still testing, but on a good way 2023-03-30 09:05:45 +02:00
piair e41d28c142 normalement c'est insane. Il faut juste gérer le problème de login sur le mobile. 2023-03-30 08:03:49 +02:00
piair b0c6a93951 bizarre l'id 2023-03-29 23:24:14 +02:00
piair 012e923ab5 better stronger (no) 2023-03-29 23:19:57 +02:00
piair 0cb0521da6 Don't update yet 2023-03-29 23:09:16 +02:00
piair c5beafe036 test 2023-03-29 14:08:44 +02:00
piair 098b934e96 told ya 2023-03-27 22:47:29 +02:00
piair 339775bdf4 cf previous commit 2023-03-27 22:25:35 +02:00
piair a2b07b9fcd well don't update till tomorrow I guess 2023-03-27 22:20:54 +02:00
piair d5bacd99a1 2023-03-27 16:11:17 +02:00
piair 43035e115d sorry for the pings, 2023-03-26 23:24:59 +02:00
piair c1bbb26c26 no clue why this need to be addressed 2023-03-26 22:56:57 +02:00
piair 95156bacd8 wtf was that 2023-03-26 19:47:13 +02:00
piair f7c6d3f65e just for me 2023-03-26 10:10:08 +02:00
piair338 4ab2530f98
Update Dockerfile 2023-03-25 18:40:17 +01:00
piair338 3ca16d1f37
Update README.md 2023-03-25 18:39:42 +01:00
piair db4ab3bf90 OMG I tested before commiting. (btw cookies login is now implemented) 2023-03-25 18:14:41 +01:00
piair338 6fefaca00a
Create .gitignore 2023-03-25 16:34:49 +01:00
piair338 a2328c2ca7
Delete temp 2023-03-25 16:33:12 +01:00
piair338 37f002049a
how to only create an empty folder ? 2023-03-25 16:32:48 +01:00
piair 8f655a04fb well, as usual, .. 2023-03-24 20:45:13 +01:00
piair 860c7b536a -f 2023-03-24 18:02:47 +01:00
piair e93d4f0baf remove some thing 2023-03-19 18:50:29 +01:00
piair338 a72c74ec05
Update README.md
ptdr not on a raspberrypi anymore
2023-03-19 12:23:42 +01:00
piair 5282b4b434 apparently, no 2023-03-19 12:21:57 +01:00
piair 0263f2e4c1 j'arriverais jamais a faire un truc sans 14 commits ou quoi ? 2023-03-19 10:44:00 +01:00
piair 3324fa478d oui 2023-03-19 10:17:28 +01:00
piair d14e0efad9 fix ? 2023-03-18 19:43:54 +01:00
piair 16ddd7aae9 see previous commit for explaination 2023-03-18 19:26:00 +01:00
piair 66de4dbbd2 oh, f*ck, what have I done 2023-03-18 19:12:27 +01:00
piair 27237354b2 didn't even worked 2023-03-18 14:21:27 +01:00
piair 484a9692cf told you 2023-03-18 14:11:51 +01:00
piair ebb1847a51 maybe better, as usual, probaly don't work, wait tomorrow 2023-03-17 22:37:35 +01:00
piair 80f6cbc919 ofc I broke something 2023-03-15 10:34:59 +01:00
piair dff47887bc cleaned up under the hood (better error logic) 2023-03-14 19:54:12 +01:00
piair d0c78d7db1 don't know 2023-03-14 16:52:46 +01:00
piair ebd22102ef auto remove email part 2023-03-14 16:33:44 +01:00
piair 6ce85286dd V5 2023-03-13 13:42:40 +01:00
piair db557c2e3c V4 now work again. You should still switch to v5 2023-03-13 07:29:34 +01:00
piair 2888f1d761 TODO update 2023-03-12 15:33:35 +01:00
piair 84898cee76 fixed PlayQuizz8 (most likely ?) 2023-03-12 11:22:49 +01:00
piair cef0204868 removed Auto Claim feature because of ban 2023-03-12 10:59:36 +01:00
piair338 93600dd78a
Merge pull request #13 from augustin64/patch-1 2023-03-09 14:30:55 +01:00
Augustin 7e64604e9f
Update Dockerfile
Fix dependencies
2023-03-09 14:30:29 +01:00
piair c28c2c573d was once again broken 2023-02-27 18:31:31 +01:00
piair 1a4cd03ae1 some error fix 2023-02-27 13:41:54 +01:00
piair 87195de1e5 oui 2023-02-27 13:19:46 +01:00
piair 4631a6608c oui 2023-02-27 13:19:12 +01:00
piair 904ad83f36 test 2023-02-27 13:16:55 +01:00
piair338 cd5ce0f6c1
Update requirements.txt 2023-02-27 13:09:01 +01:00
piair338 e28660ea7d
Update requirements.txt 2023-02-27 13:08:14 +01:00
piair bad8be5d1f bon bah je sais pas me servir de finally 2023-02-26 12:50:23 +01:00
piair 87b47e97fd oui 2023-02-25 19:05:47 +01:00
piair338 442dbb08d9
Merge pull request #12 from augustin64/patch-3 2023-02-13 21:03:55 +01:00
Augustin 05b88945ed
Update db.py
Just making sure points is not `None` (when it is not possible to get the number of points for example)
2023-02-13 19:29:54 +01:00
piair 3770fa6451 oui:/ 2023-02-12 13:44:57 +01:00
piair338 cfbe5d7af8
Update README.md 2023-02-11 22:55:23 +01:00
piair 510c7f7251 idk 2023-02-08 15:14:13 +01:00
piair 5b95893bf0 oops 2023-01-30 07:32:29 +01:00
piair 5e3282f873 euh oui 2023-01-29 00:51:30 +01:00
piair deb77cd3d3 now it work 2023-01-14 18:04:55 +01:00
piair dda61eaef9 RP support 2023-01-14 17:53:58 +01:00
piair 8943c0e15d claim multiple things ? 2023-01-14 17:36:28 +01:00
piair 90bcd29d36 works now 2023-01-14 17:19:52 +01:00
piair bb5dbb3cbd --claim amazon 2023-01-14 16:56:33 +01:00
piair ab8ac50fb2 finally working 2023-01-14 15:40:07 +01:00
piair338 994302d28d
Update main.py 2022-12-30 16:02:48 +01:00
piair338 4723049615
Update main.py 2022-12-30 16:02:03 +01:00
piair dd7b62dc92 maybe better ? 2022-12-29 18:25:06 +01:00
piair 992465c562 ok. 2022-12-29 17:56:42 +01:00
piair fbc8dac0e9 ya ? 2022-12-29 17:54:37 +01:00
piair ecfda92584 no ? 2022-12-29 17:53:45 +01:00
piair e4f6677da8 Please 2022-12-29 17:31:45 +01:00
piair 9f3ccafee8 typo 2022-12-29 16:56:29 +01:00
piair 5d64ebdb29 more logical amazon claim logic 2022-12-20 12:42:00 +01:00
piair 45cd381c3a some things 2022-12-17 18:04:49 +01:00
piair ed47bae6b6 fix today's disaster 2022-12-17 17:39:48 +01:00
piair e7f375650d pui 2022-12-15 19:16:25 +01:00
piair ad513bfe9c fix languagee popup error 2022-12-11 17:15:57 +01:00
piair fe772048de fiexed invisible error 2022-12-11 17:04:40 +01:00
piair 08c069ca1e je suis un pro des regexp mdrr 2022-12-03 06:33:27 +01:00
piair 141e896cab WHY MS 2022-12-01 13:46:12 +01:00
piair 05013cea75 fixing issues in fidelité 2022-11-26 15:07:32 +01:00
piair338 26c83c38c6
Update README.md 2022-11-26 13:18:22 +01:00
piair 347ba86a87 pixel 2022-11-23 22:43:29 +01:00
piair 24b2af9d10 euh uéuéué 2022-11-20 16:21:45 +01:00
piair dd38060253 fiexed 2022-11-19 18:11:23 +01:00
piair b0cdc9b779 what isn't it working 2022-11-19 18:06:19 +01:00
piair338 31ec4a1200
Update requirements.txt 2022-11-19 17:16:25 +01:00
piair338 48b4128632
Update Dockerfile 2022-11-19 17:02:28 +01:00
piair b9adb9c59c error handeling 2022-11-18 17:20:57 +01:00
piair338 ca0ae8917a
Merge pull request #11 from augustin64/patch-2 2022-11-16 18:15:27 +01:00
Augustin 80286b6a05
Update db.py 2022-11-16 18:13:36 +01:00
Augustin ebb1a8e48f
Update config.py 2022-11-16 18:12:43 +01:00
Augustin f4ebb39fdf
Update V4.py 2022-11-16 18:11:18 +01:00
piair da5e60f8b7 Please enter the commit message for your changes. Lines starting 2022-11-16 13:42:20 +01:00
piair338 0552338c22
Merge pull request #10 from augustin64/patch-1
Reset Progress
2022-11-14 22:44:34 +01:00
Augustin 0aa7fd3ec0
Reset Progress
- Reset progress when "starting" an already completed task
- Reset START_TIME if override option was used
2022-11-14 22:36:56 +01:00
piair 1be75f1987 easier to copy on discord 2022-11-14 22:21:35 +01:00
piair 5d4dd859bd only start countdown after login (1 min later) 2022-11-12 23:48:54 +01:00
piair 4f21ef22d4 remove some errors 2022-11-12 23:46:12 +01:00
piair a19e40b7e5 fixed 2022-11-12 23:31:58 +01:00
piair 81dc0f7310 ok it's fixed 2022-11-12 23:07:51 +01:00
piair 437afdcce4 ff override is broken don't update 2022-11-12 23:04:38 +01:00
piair decd289994 a tester encore un peu, mais devrais marcher 2022-11-12 23:00:45 +01:00
piair 3c5fb6e702 SPACES 2022-11-12 21:09:07 +01:00
piair 2f6b7f2ab9 useless 2022-11-12 17:40:03 +01:00
piair 741a136b12 . 2022-11-11 11:29:32 +01:00
piair 24849a9418 finally fixed 2022-11-09 22:59:12 +01:00
piair eae66cb163 great idee Augustin64 2022-11-09 22:54:55 +01:00
piair c3fc698e55 FAST DUDE 2022-11-09 19:36:22 +01:00
piair 35db54edfc better unban 2022-11-07 22:45:26 +01:00
piair338 2fdfdb7410
Update README.md 2022-11-06 18:11:50 +01:00
piair338 368523135a
Update Dockerfile 2022-11-06 18:10:44 +01:00
piair338 3189359b81
Update Dockerfile
test (wasn't really working )
2022-11-06 18:09:15 +01:00
piair338 bf675f8c96
Update Dockerfile
not useful
2022-11-06 17:57:02 +01:00
piair e7584702a7 test 2022-11-06 17:47:02 +01:00
piair c651950e7c wasn't working 2022-11-06 17:47:01 +01:00
piair338 7ad71a1cf9
Update README.md 2022-11-06 17:36:25 +01:00
piair 8d15a555e8 should be useful 2022-11-06 13:37:12 +01:00
piair afec68a23e ptit truc par ci par la 2022-11-06 13:29:55 +01:00
piair 545eea48cc better handeling of mobile login 2022-11-06 13:09:02 +01:00
piair f668c49e09 better 2022-11-05 15:32:13 +01:00
piair338 11eaa5189a
Update README.md 2022-11-04 23:11:05 +01:00
piair338 d84ae8dd57 k 2022-11-01 10:09:12 +00:00
piair338 c9aa75e61c custom error + better code + some things 2022-10-31 14:32:39 +00:00
piair338 945497c1d4 didn't push mb 2022-10-30 11:12:00 +00:00
piair338 7882e1dbb3 finally it work again 2022-10-25 17:47:05 +00:00
piair338 92aa56aae0 some tests 2022-10-25 17:44:33 +00:00
piair338 4a434533a7 ptet que c'est utile je sais pas 2022-10-25 17:27:54 +00:00
piair338 c665144b28 I need a better solution 2022-10-25 08:03:24 +00:00
piair338 0af267e628 i was right nothing was,working as intended 2022-10-25 07:48:34 +00:00
piair338 2709d7058a OOPS 2022-10-24 19:44:32 +00:00
piair338 b28119baec kinda work, when we ignore mobile search 2022-10-24 19:35:31 +00:00
piair338 3155b545dc oh boy i probably just broke everything 2022-10-24 18:08:33 +00:00
piair338 f8e9daaedd well, not working at all is faster than working right ? 2022-10-24 08:38:11 +00:00
piair338 c71aad15df login should be two time faster 2022-10-23 17:25:04 +00:00
piair338 a7d32b6064 for me and for you (no just kidding only for me) 2022-10-22 16:15:04 +00:00
piair338 941656100c not much change, look at the code 2022-10-20 20:15:08 +00:00
piair338 170627f5a7 well user_data is made for tha 2022-10-18 14:30:27 +00:00
piair338 6796e71c5b wtf is this error 2022-10-18 10:51:55 +00:00
piair338 1505e7b756 don't send my log 2022-10-17 14:10:59 +00:00
piair338 7c4de0ff5d ouio# Please enter the commit message for your changes. Lines starting 2022-10-16 17:39:38 +00:00
piair338 8ab6c41200
Update README.md 2022-10-16 15:57:02 +02:00
piair338 ecd695f45c
Update README.md 2022-10-16 15:47:58 +02:00
piair338 ac737cd048 changed name 2022-10-16 13:25:19 +00:00
piair338 48a1ca4617 forget to delete that 2022-10-16 13:21:26 +00:00
piair338 b882d0deba oui 2022-10-16 13:20:57 +00:00
piair338 ae3a89802b Merge remote-tracking branch 'refs/remotes/origin/master' 2022-10-16 13:15:29 +00:00
piair338 7137448f65 allow multiple config 2022-10-16 13:15:00 +00:00
piair338 cd94f65045
Update requirements.txt 2022-10-16 15:04:24 +02:00
piair338 a8dacf85d1 why 2022-10-16 12:57:38 +00:00
piair338 d157423bf7
Create config.default 2022-10-16 14:56:20 +02:00
piair338 fd69c86a86 test 2022-10-16 12:55:31 +00:00
piair338 e2a917925e some test as usual 2022-10-16 12:54:59 +00:00
piair338 f1b6232841
Rename config.cfg to config.default 2022-10-16 14:49:10 +02:00
piair338 6526d83e27
Rename config.cfg to user_data/config.cfg 2022-10-16 14:20:19 +02:00
piair338 14d15c4dea new structure 2022-10-16 12:19:18 +00:00
piair338 677b80f521 rename 2022-10-16 12:11:06 +00:00
piair338 65f2705726
Rename config to config.cfg
so gitignore work
2022-10-16 14:10:18 +02:00
piair338 09fd450c59 test 2022-10-16 12:08:30 +00:00
piair338 fdcc34c054 some space 2022-10-16 12:00:35 +00:00
piair338 db5973cf87 small fix, i really should make some tests 2022-10-16 11:49:06 +00:00
piair cec5505f3c test ? 2022-10-15 16:17:21 +02:00
piair ada8b95259 too fast dude 2022-10-13 07:18:08 +02:00
piair 62f9410373 it wasn't working ? 2022-10-12 14:50:38 +02:00
piair 23a7131792 yup 2022-10-11 21:45:47 +02:00
piair 49cf33c780 a lot easier to edit after. 2022-10-11 21:40:41 +02:00
piair 9f5e722a9c some space 2022-10-11 21:30:17 +02:00
piair 6290fde32e didn't I already changed that ? 2022-10-11 21:14:53 +02:00
piair 3d90fa64bb sometime it's in english for whatever reason 2022-10-11 13:00:44 +02:00
piair 1e54e8af9a int_of_string points 2022-10-10 16:27:14 +02:00
piair 43356e032a Merge branch 'master' of https://github.com/piair338/MsRewards 2022-10-10 13:37:44 +02:00
piair f357623a03 nice 2022-10-10 13:37:31 +02:00
piair 4d907ba81b ofc nop 2022-10-09 13:42:45 +02:00
piair 950f8835c3 ofc not 2022-10-09 13:36:08 +02:00
piair fd7feebca5 work first try ? POG 2022-10-09 13:33:13 +02:00
piair338 b8690dfd05
Check ipv6 at first start 2022-10-06 17:55:45 +02:00
piair 7789c89d64 and functions can't be empty 2022-10-04 22:11:25 +02:00
piair dff9af6125 return stop function piair ... 2022-10-04 22:09:51 +02:00
piair 6d73ba94e0 ok. 2022-09-30 16:13:36 +02:00
piair dac3977c71 uéuéué t'est content agustin64 2022-09-30 16:09:11 +02:00
piair 42ad01e493 ofc 2022-09-30 15:17:29 +02:00
piair d4d3213db1 BON 2022-09-30 15:07:34 +02:00
piair a1933447f0 no 2022-09-30 15:05:58 +02:00
piair 20f6eb6796 prevent double logpoints 2022-09-30 15:05:18 +02:00
piair 43e970a1aa better ? 2022-09-30 14:59:54 +02:00
piair 994af56880 i don't know what I am doing 2022-09-30 14:45:53 +02:00
piair 712cc14368 added a risky mode, way faster 2022-09-30 14:34:50 +02:00
piair a1969a3e2e removed discord requirement 2022-09-30 14:26:34 +02:00
piair da33edb381 Merge branch 'master' of https://github.com/piair338/MsReward 2022-09-28 15:04:10 +02:00
piair dea767a392 some typo 2022-09-28 15:04:07 +02:00
piair338 da2471f304
Merge pull request #9 from augustin64/patch-1
Fix constant name
2022-09-25 15:37:57 +02:00
augustin64 b6e30888bb
Update V4.py
Fix constant name (introduced in [this commit](5b3b7c8aec))
2022-09-25 15:32:34 +02:00
piair338 d2cc6891ed
Update README.md 2022-09-23 16:41:32 +02:00
piair 556e89e2b4 finally a docker support 2022-09-23 16:34:01 +02:00
piair 5b3b7c8aec better global constant name 2022-09-23 15:13:14 +02:00
piair338 088861e65d
Update requirements.txt 2022-09-04 14:35:49 +02:00
piair338 8c1de642df
Update requirements.txt 2022-09-04 14:12:37 +02:00
piair338 a4a1cb3b81
Update requirements.txt 2022-09-04 13:56:47 +02:00
piair 2d1cc9e1c0 some tests 2022-08-30 12:00:30 +02:00
piair 2dffe6851a date + more sleep 2022-08-30 11:28:02 +02:00
piair 5c368ce0d0 test 2022-08-30 11:17:56 +02:00
piair 64d70afdd5 yeah 2022-08-29 11:48:05 +02:00
piair c3d49cd093 fixed double login issue 2022-08-29 11:44:35 +02:00
piair 593ddbf4fc idk anymore 2022-08-29 11:36:08 +02:00
piair 1e33769c0d wtf 2022-08-29 11:22:45 +02:00
piair a3adff8130 updated to fix some things 2022-08-29 10:44:57 +02:00
piair 2dffc31d90 accent terms 2022-08-22 11:03:20 +02:00
piair 76c6d84105 Merge branch 'master' of https://github.com/piair338/MsReward 2022-06-28 12:27:24 +02:00
piair 590ac8885e new user agent 2022-06-28 12:27:22 +02:00
piair b5e52591dd ah 2022-06-23 13:40:01 +02:00
piair ef5cdab883 p 2022-06-23 13:26:31 +02:00
piair 38c24ce143 oui 2022-06-22 21:18:08 +02:00
piair cbdc6c9935 mistake 2022-06-22 20:22:52 +02:00
piair 05c9d505eb test do allow docker run 2022-06-22 20:16:04 +02:00
piair eb3c510f82 better path handeling 2022-06-22 18:58:28 +02:00
piair f0f8fc324c k 2022-06-22 12:31:00 +02:00
piair 212b92f937 yeah 2022-06-22 12:30:08 +02:00
piair b562930583 comming soon ® 2022-06-22 12:26:50 +02:00
piair 776da465aa fix som issues in quiz8, where element is not found 2022-06-21 17:36:18 +02:00
piair a3dcf15f7d you can now cancel sleep 2022-06-21 17:22:44 +02:00
piair 3376eaf8ac better fulllog logic 2022-06-20 18:24:29 +02:00
piair 1eb606a62c cleander Logs 2022-06-20 18:16:15 +02:00
piair 66d5354ac2 Check if ipv4 is used 2022-06-17 07:22:37 +02:00
piair ba70727b02 test smth 2022-06-17 07:10:32 +02:00
piair 0f5c64f9d3 comments 2022-06-17 07:05:46 +02:00
piair fbed3ae854 not usefull messages 2022-06-16 08:21:09 +02:00
piair 8f6f2ab5df oui. 2022-06-10 14:15:42 +02:00
piair a9bd8ecf9b well 2022-06-10 12:39:18 +02:00
piair bcb7511ecf Merge branch 'master' of https://github.com/piair338/MsReward 2022-06-10 07:07:50 +02:00
piair 4fa9339632 reenable binmobilesearch for every computer 2022-06-10 07:07:46 +02:00
piair338 a57383b4c9
Update README.md 2022-06-09 16:35:00 +02:00
piair 491891f4de type error 2022-06-09 16:28:30 +02:00
piair 4f29e876b1 update point 2022-06-09 16:23:13 +02:00
piair b7f3bd053a fallback fidelité 2022-06-09 14:36:51 +02:00
piair 5614a06f38 unused import + fallback logpoint 2022-06-09 14:34:02 +02:00
piair 69e8916a05 updated login to have a fallback 2022-06-09 14:19:34 +02:00
piair fd22c9e176 small changes 2022-06-06 12:32:37 +02:00
piair fe8c1addaa oui 2022-06-02 12:39:30 +02:00
piair d4fcc7f769 re disabled mobile search for proxy 2022-06-02 12:29:17 +02:00
piair b459129d66 renabled mobile search with proxy 2022-05-31 21:33:25 +02:00
piair c0d2ea29c7 ... 2022-05-31 21:25:17 +02:00
piair c7da397f28 ? 2022-05-31 21:22:37 +02:00
piair e1a166ed6e some test about the proxy 2022-05-29 21:42:11 +02:00
piair 9684a98fb3 oui 2022-05-28 11:50:45 +02:00
piair f5d332c26e added more delay during logging 2022-05-28 08:18:21 +02:00
piair bc665819e8 workarroud for now on bingMobileSearch not working with a proxy 2022-05-27 15:36:59 +02:00
piair e93dd60da0 still test 2022-05-27 15:28:41 +02:00
piair f9c5e30856 test 2022-05-27 15:26:16 +02:00
piair 36a7fec15c oui 2022-05-27 14:54:21 +02:00
piair 25da67077b push 2022-05-27 14:52:29 +02:00
piair dd0b280b28 oui 2022-05-27 14:49:25 +02:00
piair 4dacc7b61c test 2022-05-27 14:46:23 +02:00
piair a85ff49f25 updated mobile login 2022-05-27 14:42:28 +02:00
piair e9c2ee6f95 revert modif made to mobile search 2022-05-27 14:10:29 +02:00
piair 2bba6d8235 erreur dans la partie fidélité si le lien étais pas bon 2022-05-27 14:07:52 +02:00
piair cfb26f6732 test 2022-05-27 10:07:19 +02:00
piair e4ad601317 mobile search wtf 2022-05-27 09:50:21 +02:00
piair 9032f56d99 test 2022-05-27 09:40:54 +02:00
piair b26f0c1130 test 2022-05-27 09:37:34 +02:00
piair 365df0abcd update mobile login 2022-05-27 09:28:31 +02:00
piair338 13ab9b1acf
Update README.md 2022-05-26 08:55:24 +02:00
piair338 9155fbead0
Create LICENSE 2022-05-26 08:40:03 +02:00
piair338 078bf45e67
Update issue templates 2022-05-26 08:30:50 +02:00
piair338 ac34baf215
Update README.md 2022-05-26 08:27:07 +02:00
piair338 06e65222db
Updated from downloaded world list to default one 2022-05-26 08:24:36 +02:00
piair e5cce67a76 Merge branch 'master' of https://github.com/piair338/MsReward 2022-05-26 08:20:05 +02:00
piair 4e4461f7f8 enable default linux worldlist support 2022-05-26 08:20:02 +02:00
piair338 54aa973d46
Defaulted to Linux default world list
You can get then with the command apt-get install wfrench
2022-05-26 07:57:53 +02:00
piair df0ea09662 remove trailing spaces + added some comments + dealed with error with some popus + some little things 2022-05-26 07:47:29 +02:00
piair338 5f554cc9b2
Merge pull request #8 from augustin64/patch-3
Update V4.py
2022-05-25 07:16:05 +02:00
piair 5406b5538b may be ok 2022-05-24 22:53:02 +02:00
piair 7e2e5cf0c2 Merge branch 'master' of https://github.com/piair338/MsReward 2022-05-24 22:43:02 +02:00
piair 20efc9f3f6 s 2022-05-24 22:43:01 +02:00
piair338 d2ed535bf2
Update .gitignore 2022-05-24 22:42:05 +02:00
piair338 d959594e71
Create requirements.txt 2022-05-24 22:41:44 +02:00
piair 66c979c624 STILL 2022-05-24 22:39:18 +02:00
piair 3bebee9c13 AS WELL 2022-05-24 22:38:23 +02:00
piair fa8d27db0f STILL BUGGED 2022-05-24 22:38:13 +02:00
piair d0f76720f6 WARNING this has not beeing tested yet 2022-05-24 22:32:38 +02:00
74 changed files with 5225 additions and 1080 deletions

View File

@ -1,8 +1,32 @@
if you have a rare bug, i'll not fix it. If you have a reccurent bug, send : ---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
| python version | ---
| --- |
| page.html | **Describe the bug**
screenshot of error A clear and concise description of what the bug is.
---
and i may try to fix it. **To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem, and the html file if there is an error.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

19
.gitignore vendored
View File

@ -1,9 +1,20 @@
/old dev_build.sh
geckodriver.log geckodriver.log
config .vscode/
.vscode/settings.json .idea
update.sh venv
/Git /Git
page.html page.html
screenshot.png screenshot.png
login.csv login.csv
data
**/__pycache__
user_data/*
install.sh
nohup.out
points.csv
file.png
user_data/configs.json
*.ts
LICENSE
README.md

22
Dockerfile Normal file
View File

@ -0,0 +1,22 @@
FROM python:3.10
ENV DEBIAN_FRONTEND noninteractive
WORKDIR /app/
RUN apt update \
&& wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.0g-2ubuntu4_amd64.deb \
&& dpkg -i libssl1.1_1.1.0g-2ubuntu4_amd64.deb \
&& apt install redis libgtk-4-1 libvulkan1 libxdamage1 -y \
&& curl -sSLO https://nc.piair.xyz/s/BKLsBWoZkTdYjfq/download/chrome.deb \
&& ln -fs /usr/share/zoneinfo/Europe/Paris /etc/localtime \
&& git clone https://gitea.augustin64.fr/piair/MsRewards-Reborn \
&& python3 -m pip install -r MsRewards-Reborn/requirements.txt \
&& wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key \
&& curl -fsSL https://packages.redis.io/gpg | gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee -a /etc/apt/sources.list.d/grafana.list \
&& apt update \
&& apt install novnc websockify grafana xvfb nginx nano tzdata sqlite3 apt-transport-https software-properties-common wget wfrench tigervnc-standalone-server libasound2 libatk-bridge2.0-0 libnss3 libnspr4 xvfb libgbm1 libatk1.0-0 libu2f-udev libatspi2.0-0 libcups2 libxkbcommon0 libxrandr2 libdbus-1-3 xdg-utils fonts-liberation libdrm2 -y \
&& bash MsRewards-Reborn/config/config.sh \
&& dpkg -i chrome.deb
ENV TZ="Europe/Paris"
WORKDIR /app/MsRewards-Reborn/Flask/
CMD bash start.sh

442
Flask/app.py Normal file
View File

@ -0,0 +1,442 @@
import gevent.monkey
gevent.monkey.patch_all()
from time import sleep
import subprocess
import os
from flask import Flask, Response, redirect, url_for, request, session, abort, render_template, send_from_directory
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
from flask_login import LoginManager, UserMixin, login_required, login_user, logout_user
from werkzeug.utils import secure_filename
import json
import re
from requests import get
import redis
# redis part for live update
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.Redis(connection_pool=pool)
def generate_output():
pubsub = r.pubsub()
pubsub.subscribe('console')
try :
for message in pubsub.listen():
if message['type'] == 'message':
print(message)
yield f"data: {message['data'].decode()}\n\n"
except Exception as e:
print(f"ya eu une erreur sad {e}")
# the end
global password
with open("/app/MsRewards-Reborn/user_data/flask.json", "r") as inFile:
data = json.load(inFile)
password = data["password"]
secret = data["secret"]
if secret == "":
import secrets
secret = secrets.token_hex()
with open("/app/MsRewards-Reborn/user_data/flask.json", "w") as inFile:
data = {
"password": password,
"secret": secret
}
json.dump(data, inFile)
"""
#Automatic start of MsRewards
"""
def daily_command():
subprocess.Popen(["git",'pull'])
subprocess.Popen(["pkill","-9","chrome"])
subprocess.Popen(["pkill","-9","Xvfb"])
subprocess.Popen(["pkill","-9","Xvnc"])
subprocess.Popen(["pkill","-9", "undetected_chromedriver"])
scheduler = BackgroundScheduler()
scheduler.start()
scheduler.add_job( # on relance le job
daily_command, # ---
trigger=CronTrigger(
year="*", month="*", day="*", hour="0", minute="0", second="0"
), # ---
name="Daily refresh", # ---
id="99" # ---
)
def start_ms(i):
print("\033[32m" + f"Starting config {i}" + "\033[0m")
log = open(f"/app/MsRewards-Reborn/Flask/static/logs/{i}.txt", 'a') # so that data written to it will be appended
subprocess.Popen([f"python3 -u /app/MsRewards-Reborn/V6.py -c {i}"], stdout=log, stderr=log, shell=True)
log.close()
TriggerDict = {}
def update_jobs():
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
for i in configs:
try :
h, m = configs[i]["time"].split(":")
print("\033[36m" + f"config {i} : {h}:{m}" + "\033[0m")
TriggerDict[i] = CronTrigger(
year="*", month="*", day="*", hour=h, minute=m, second="0"
)
if configs[i]["enabled"]:
try :
scheduler.remove_job(i) # on reset le job
except Exception as e:
print(f"\033[33merror with deleting config {i} : {e}\033[0m")
try :
scheduler.add_job( # on relance le job
start_ms, # ---
trigger=TriggerDict[i], # ---
args=[i], # ---
name="Daily start", # ---
id=i # ---
)
print("\033[36m" + f"successfully created config {i}" + "\033[0m")
except Exception as e:
print(f"\033[33merror with creating config {i} : {e}\033[0m")
else :
try :
scheduler.remove_job(i)
except Exception as e :
print(f"\033[33merror with deleting config {i} : {e}\033[0m")
except Exception as e:
print(e)
"""
#Flask app
"""
app = Flask(__name__)
@app.context_processor
def inject_default_variables():
with open("/app/MsRewards-Reborn/version", "r") as f:
version = f.readline().replace("\n", '')
return dict(version=version)
"""
#Login stuff
"""
# config
app.config["TEMPLATES_AUTO_RELOAD"] = True
app.config.update(
SECRET_KEY = secret
)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = "login"
# silly user model
class User(UserMixin):
def __init__(self, id):
self.id = id
self.name = "user" + str(id)
self.password = password
def __repr__(self):
return "%d/%s/%s" % (self.id, self.name, self.password)
users = [User(1)]
@app.route('/stream')
def stream():
return Response(generate_output(), content_type='text/event-stream')
@app.route("/login/", methods=["GET", "POST"])
def login():
if request.method == 'POST':
if request.form['password'] == password:
user = User(id)
login_user(user)
if password == "ChangeMe":
return(redirect('/change_password'))
return(redirect('/schedule'))
else:
return abort(401)
else:
return(render_template("login.html"))
@app.route("/change_password/", methods=["GET", "POST"])
@login_required
def change_password():
global password
if request.method == 'POST':
password = request.form["password"]
subprocess.Popen(["grafana-cli", "admin", "reset-admin-password", password])
with open("/app/MsRewards-Reborn/user_data/flask.json", "w") as inFile:
data = {
"password": password,
"secret": secret
}
json.dump(data, inFile)
return(render_template("change_password.html"))
# handle login failed
@app.errorhandler(401)
def unauthorized(e):
return(redirect("/login"))
# callback to reload the user object
@login_manager.user_loader
def load_user(userid):
return User(userid)
"""
#end of login stuff
"""
@app.route("/")
def main():
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
return(render_template("schedule.html", data=configs))
@app.route("/discord/")
def discord_get():
with open("/app/MsRewards-Reborn/user_data/discord.json", "r") as inFile:
data = json.load(inFile)
return(render_template("discord.html", data=data, len=maxi(data)))
@app.route("/discord/", methods=["post"])
def discord_post():
with open("/app/MsRewards-Reborn/user_data/discord.json", "r") as inFile:
data = json.load(inFile)
action = request.form
if action['DISCORD'] == "delete" :
data.pop(action["select"], None)
else :
config = action["select"]
successL = action["successL"]
try :
a = action["successT"]
successT = "True"
except:
successT = "False"
try :
a = action["errorsT"]
errorsT = "True"
except:
errorsT = "False"
errorsL = action["errorsL"]
name = action["name"] if action["name"] else f"unnamed{action['select']}"
data[config] = {"errorsL" : errorsL, "errorsT": errorsT, "successT": successT, "successL": successL, "name": name}
with open("/app/MsRewards-Reborn/user_data/discord.json", "w") as outFile:
json.dump(data, outFile)
return(render_template("discord.html", data=data, len=maxi(data)))
@app.route("/dev/")
def dev2():
return(render_template("dev.html"))
@app.route("/settings/")
def settings_get():
with open("/app/MsRewards-Reborn/user_data/settings.json", "r") as inFile:
settings = json.load(inFile)
return(render_template("settings.html", data=settings))
@app.route("/settings/", methods=["post"])
def settings_post():
settings = {}
action = request.form
settings['avatarlink'] = action["avatarlink"]
with open("/app/MsRewards-Reborn/user_data/settings.json", "w") as inFile:
json.dump(settings, inFile)
return(render_template("settings.html", data=settings))
@app.route("/proxy/")
def proxy_get():
with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile:
j = json.load(inFile)
return(render_template("proxy.html", data=j, len=maxi(j)))
@app.route("/proxy/", methods=["post"])
def proxy_post():
with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile:
data = json.load(inFile)
action = request.form
print(action)
if action['PROXY'] == "delete" :
print(action)
data.pop(action["select"], None)
else :
try :
config = action["select"]
address = action["address"]
port = action["port"]
name = action["name"] if action["name"] else f"@unnamed{action['select']}"
data[config] = {"address" : address, "port": port, "name": name}
except :
print("error : probably bad config")
with open("/app/MsRewards-Reborn/user_data/proxy.json", "w") as outFile:
json.dump(data, outFile)
return(render_template("proxy.html", data=data, len=maxi(data)))
@app.route("/schedule/")
def schedule_get():
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
return(render_template("schedule.html", data=configs))
@app.route("/schedule/", methods=["post"])
def schedule_post():
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
data = dict(request.form)
for i in configs:
try :
data[f'switch{i}']
except :
data[f'switch{i}'] = "off"
for i in configs:
configs[i]["time"] = data[f"time{i}"]
configs[i]["enabled"] = data[f"switch{i}"] == "on"
with open("/app/MsRewards-Reborn/user_data/configs.json", "w") as inFile:
json.dump(configs, inFile)
update_jobs()
return(render_template("schedule.html", data=configs))
@app.route("/config/")
def config_get():
with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile:
proxys = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/discord.json", "r") as inFile:
discords = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
return(render_template("config.html", data=configs, discords=discords, proxys=proxys, configs=configs, len=maxi(configs)))
@app.route("/config/", methods=["POST"])
def config_post():
action = request.form
with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile:
proxys = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/discord.json", "r") as inFile:
discords = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
if action["data"] == "delete":
print(action["config"])
configs.pop(action["config"])
else :
comptes = {
"1":{"mail": action["mail1"], "pwd": action["pwd1"], "2fa": action["2fa1"]},
"2":{"mail": action["mail2"], "pwd": action["pwd2"], "2fa": action["2fa2"]},
"3":{"mail": action["mail3"], "pwd": action["pwd3"], "2fa": action["2fa3"]},
"4":{"mail": action["mail4"], "pwd": action["pwd4"], "2fa": action["2fa4"]},
"5":{"mail": action["mail5"], "pwd": action["pwd5"], "2fa": action["2fa5"]}
}
configs[action["config"]] = {
"name" : action["name"] if action["name"] != "" else f"unnamed{action['config']}",
"proxy": action["proxy"],
"discord": action["discord"],
"time":"",
"enabled":"False",
"accounts": comptes
}
with open("/app/MsRewards-Reborn/user_data/configs.json", "w") as outFile:
json.dump(configs, outFile)
return(render_template("config.html", data=configs, discords=discords, proxys=proxys, configs=configs, len=maxi(configs)))
@app.route("/logs/", methods=["GET", "POST"])
def logs():
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
print(configs)
return(render_template("logs.html", data=configs))
@app.route("/stats/", methods=["GET", "POST"])
def stats():
return(render_template("stats.html"))
@app.route("/override/", methods=["POST"])
def override_post():
json = request.form.to_dict(flat=False)
log = open(f"/app/MsRewards-Reborn/Flask/static/logs/custom.txt", 'w') # so that data written to it will be appended
subprocess.Popen([f"python3 -u /app/MsRewards-Reborn/V6.py -c {json['config'][0]} --json \"{json}\""], stdout=log, stderr=log, shell=True)
log.close()
return(render_template("vnc_post.html"))
@app.route("/override/", methods=["GET"])
def override_get():
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
return(render_template("vnc_get.html", configs=configs))
@app.route('/download/<path:filename>', methods=['GET', 'POST'])
@login_required
def download(filename):
return send_from_directory(directory='/app/MsRewards-Reborn/user_data/', path=filename, as_attachment=True)
def allowed_file(filename):
ALLOWED_EXTENSIONS = ["json"]
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
@app.route('/upload_file/', methods=['POST'])
@login_required
def upload_file():
print(request.files)
i = 1
while f'file{i}' in request.files :
file = request.files[f'file{i}']
if file.filename == '':
print('end of files')
return redirect(url_for('settings_get'))
elif file and allowed_file(file.filename):
filename = secure_filename(file.filename)
print(os.path.join('/app/MsRewards-Reborn/user_data/', filename))
file.save(os.path.join('/app/MsRewards-Reborn/user_data/', filename))
i += 1
print(i)
print(f'file{i}' in request.files)
print("requete bizarre")
return redirect(url_for('settings_get'))
def maxi(dict):
m = 0
for i in dict :
if int(i) >= m:
m = int(i)
return(m+1)
update_jobs()
subprocess.Popen(["bash",'/app/MsRewards-Reborn/config/request.sh'])

5
Flask/start.sh Normal file
View File

@ -0,0 +1,5 @@
nohup redis-server &> nohup_redis.out &
nohup bash /app/MsRewards-Reborn/sse.sh &> nohup_sse.out &
service grafana-server start
service nginx start
gunicorn --reload --worker-class gevent -b 0.0.0.0:6666 'app:app'

405
Flask/static/css/flask.css Normal file
View File

@ -0,0 +1,405 @@
@import url('https://fonts.googleapis.com/css?family=Montserrat');
/* Colors */
:root {
--color-background0: #212121;
--color-background1: #212121;
--color-background2: dimgray;
--color-border0: #FFFFFF;
--color-border1: grey;
--color-text: #FFFFFF;
--color-green: green;
--color-lime: #BADA55;
--color-red: red;
--color-switch-button: #FFFFFF;
--color-switch-background: grey;
--color-transparent: rgba(0, 0, 0, 0);
}
/* Sidebar size is the left panel size when opened */
:root {
--sidebar-size: max(20vw, 160px);
--sidebar-sz-plus10: calc(var(--sidebar-size) + 10px);
--sidebar-sz-plus30: calc(var(--sidebar-size) + 30px);
}
html {
text-align: center;
font-family: Montserrat;
height: 95%;
}
form {
width: 100%;
}
table {
width: 100%;
height: 100%;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
a {
color: var(--color-text);
}
iframe{
border: none;
}
input[type=text] {
width: 90%;
padding: 12px 20px;
margin: 8px 0;
background-color: var(--color-background1);
border: 2px solid var(--color-border1);
border-radius: 4px;
outline: none;
color: var(--color-text);
text-align: center;
}
input[type=password] {
width: 90%;
padding: 12px 20px;
margin: 8px 0;
text-align: center;
border: 2px solid var(--color-border1);
border-radius: 4px;
outline: none;
color: var(--color-text);
background-color: var(--color-background1);
}
.button{
border-radius: 4px;
border: 2px solid var(--color-border1);
background-color: var(--color-background1);
color: var(--color-text);
padding: 12px 20px;
width: 70%;
margin: 10px;
}
.left-button{
width: 10%;
}
.ban{
border-radius: 4px;
border: 2px solid var(--color-red);
background-size: 200% 100%;
background-image: linear-gradient(to right, var(--color-background1) 50%, var(--color-red) 50%);
-webkit-transition: background-position 0.5s;
-moz-transition: background-position 0.5s;
transition: background-position 0.5s;
color: var(--color-text);
padding: 12px 0px;
width: 70%;
margin: 10px;
}
.ban:hover{
background-position: -100% 0;
}
.confirm{
color: var(--color-text);
padding: 12px 20px;
width: 70%;
margin: 10px;
background-size: 200% 100%;
background-image: linear-gradient(to right, var(--color-background1) 50%, var(--color-green) 50%);
-webkit-transition: background-position 0.5s;
-moz-transition: background-position 0.5s;
transition: background-position 0.5s;
border: 2px solid var(--color-border1);
}
.confirm:hover{
background-position: -100% 0;
}
.confirm{
color: var(--color-text);
padding: 12px 20px;
width: 70%;
margin: 10px;
background-size: 200% 100%;
background-image: linear-gradient(to right, var(--color-background1) 50%, var(--color-green) 50%);
-webkit-transition: background-position 0.5s;
-moz-transition: background-position 0.5s;
transition: background-position 0.5s;
border: 2px solid var(--color-border1);
}
.confirm:hover{
background-position: -100% 0;
}
.unselected{
border-radius: 4px;
border: 2px solid var(--color-border1);
background-color: var(--color-background1);
color: var(--color-text);
padding: 12px 20px;
width: 70%;
margin: 10px;
}
.selected{
border-radius: 4px;
border: 2px solid var(--color-border1);
background-color: var(--color-background2);
color: var(--color-text);
padding: 12px 20px;
width: 70%;
margin: 10px;
}
button:hover{
border: 2px solid var(--color-border0);
cursor: pointer;
}
input:hover{
border: 2px solid var(--color-border0);
}
.submit{
border-radius: 4px;
border: 2px solid var(--color-border1);
background-color: var(--color-background1);
color: var(--color-text);
padding: 12px 20px;
width: 100%;
margin: 10px;
}
body {
background-color: var(--color-background0);
color: var(--color-text);
height: 100%;
}
.left-pannel{
flex: 1;
margin: 20px;
border: 1px solid var(--color-border0);
border-radius: 5px;
padding: 20px;
width: 80%;
height: 90%;
}
.content{
flex: 3;
margin: 20px;
border: 1px solid var(--color-border0);
border-radius: 5px;
padding: 20px;
height: 90%;
}
.content > ul {
display: inline-block;
}
.container {
display: flex;
width: 100%;
height: 100%;
}
.row-item {
margin: 10px 0;
text-align: center;
}
#image img {
display: block;
margin: auto;
width: 20%;
}
.comlumn-name{
width: 20%;
}
/*
For toggle switch
*/
input.toogle[type=checkbox]{
height: 0;
width: 0;
visibility: hidden;
}
label {
padding: 8px;
margin: auto;
cursor: pointer;
text-indent: -9999px;
width: 100px;
height: 50px;
background: var(--color-switch-background);
display: block;
border-radius: 100px;
position: relative;
}
/*
width: height of label /2 ;
height: height of label /2px;
*/
label:after {
content: '';
position: absolute;
top: 5px;
left: 5px;
width: 40px;
height: 40px;
background: var(--color-switch-button);
border-radius: 90px;
transition: 0.3s;
}
input:checked + label {
background: var(--color-lime);
}
input:checked + label:after {
left: calc(100% - 5px);
transform: translateX(-100%);
}
/*changer l'épaisseur du click */
label:active:after {
width: 30px;
}
select {
width: 90%;
/*height: 100%;*/
padding: 12px 20px;
margin: 8px 0;
background-color: var(--color-background1);
border: 2px solid var(--color-border1);
border-radius: 4px;
outline: none;
color: var(--color-text);
text-align: center;
}
select:hover {
border: 2px solid var(--color-border0);
}
input[type="time"] {
width: 70%;
padding: 8px 12px;
margin: 8px 0;
background-color: var(--color-background1);
border: 2px solid var(--color-border1);
border-radius: 4px;
outline: none;
color: var(--color-text);
text-align: center;
}
input[type="time"]::-webkit-calendar-picker-indicator {
filter: invert(1);
opacity: 0.7;
cursor: pointer;
}
input[type="time"]::-webkit-calendar-picker-indicator:hover {
opacity: 1;
}
/** Sidebar stuff */
#slide-sidebar {
display: none;
}
label[for="slide-sidebar"] {
all: initial;
z-index: 1; /* Always on top */
position: absolute;
top: 20px;
left: var(--sidebar-sz-plus30);
-moz-transition: left 0.5s ease;
transition: left 0.5s ease;
background: var(--color-transparent);
}
label[for="slide-sidebar"]:after {
all:unset;
}
input:checked + label[for="slide-sidebar"] {
background: var(--color-transparent);
}
#slide {
border-style: solid;
border-radius: 4px;
border-width: 1px;
border-color: var(--color-border0);
color: var(--color-text);
background-color: var(--color-background0);
padding: 8px 8px 2px 8px;
}
/* When opened behaviour */
.left-pannel {
width: var(--sidebar-size);
position: fixed;
top: 0;
left: 0;
bottom: 0;
}
.content {
position: absolute;
top: 0;
left: var(--sidebar-sz-plus10);
right: 0;
bottom: 0;
-moz-transition: left 0.5s ease;
transition: left 0.5s ease;
padding: 0 25px;
background-color: var(--color-background0); /* we need no transparency when switching */
overflow: hidden;
}
/* When closed behaviour */
input:checked#slide-sidebar~label {
left: 20px;
}
input:checked#slide-sidebar~.left-pannel {
display: none;
transition: display 0s 0.5s;
}
input:checked#slide-sidebar~.content {
left: 0;
}

BIN
Flask/static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 21 0 C 19.355469 0 18 1.355469 18 3 L 18 5 L 10.1875 5 C 10.0625 4.976563 9.9375 4.976563 9.8125 5 L 8 5 C 7.96875 5 7.9375 5 7.90625 5 C 7.355469 5.027344 6.925781 5.496094 6.953125 6.046875 C 6.980469 6.597656 7.449219 7.027344 8 7 L 9.09375 7 L 12.6875 47.5 C 12.8125 48.898438 14.003906 50 15.40625 50 L 34.59375 50 C 35.996094 50 37.1875 48.898438 37.3125 47.5 L 40.90625 7 L 42 7 C 42.359375 7.003906 42.695313 6.816406 42.878906 6.503906 C 43.058594 6.191406 43.058594 5.808594 42.878906 5.496094 C 42.695313 5.183594 42.359375 4.996094 42 5 L 32 5 L 32 3 C 32 1.355469 30.644531 0 29 0 Z M 21 2 L 29 2 C 29.5625 2 30 2.4375 30 3 L 30 5 L 20 5 L 20 3 C 20 2.4375 20.4375 2 21 2 Z M 11.09375 7 L 38.90625 7 L 35.3125 47.34375 C 35.28125 47.691406 34.910156 48 34.59375 48 L 15.40625 48 C 15.089844 48 14.71875 47.691406 14.6875 47.34375 Z M 18.90625 9.96875 C 18.863281 9.976563 18.820313 9.988281 18.78125 10 C 18.316406 10.105469 17.988281 10.523438 18 11 L 18 44 C 17.996094 44.359375 18.183594 44.695313 18.496094 44.878906 C 18.808594 45.058594 19.191406 45.058594 19.503906 44.878906 C 19.816406 44.695313 20.003906 44.359375 20 44 L 20 11 C 20.011719 10.710938 19.894531 10.433594 19.6875 10.238281 C 19.476563 10.039063 19.191406 9.941406 18.90625 9.96875 Z M 24.90625 9.96875 C 24.863281 9.976563 24.820313 9.988281 24.78125 10 C 24.316406 10.105469 23.988281 10.523438 24 11 L 24 44 C 23.996094 44.359375 24.183594 44.695313 24.496094 44.878906 C 24.808594 45.058594 25.191406 45.058594 25.503906 44.878906 C 25.816406 44.695313 26.003906 44.359375 26 44 L 26 11 C 26.011719 10.710938 25.894531 10.433594 25.6875 10.238281 C 25.476563 10.039063 25.191406 9.941406 24.90625 9.96875 Z M 30.90625 9.96875 C 30.863281 9.976563 30.820313 9.988281 30.78125 10 C 30.316406 10.105469 29.988281 10.523438 30 11 L 30 44 C 29.996094 44.359375 30.183594 44.695313 30.496094 44.878906 C 30.808594 45.058594 31.191406 45.058594 31.503906 44.878906 C 31.816406 44.695313 32.003906 44.359375 32 44 L 32 11 C 32.011719 10.710938 31.894531 10.433594 31.6875 10.238281 C 31.476563 10.039063 31.191406 9.941406 30.90625 9.96875 Z"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

102
Flask/static/js/main.js Normal file
View File

@ -0,0 +1,102 @@
function addline(ligne){
var lplus = parseInt(ligne) + 1;
document.getElementById("table").insertRow(lplus).insertCell(0).innerHTML = '<input type="file" id="file' + lplus + '" name="file' + lplus + '" onchange="addline(' + lplus + ')">'
}
function change_discord(value, data, len) {
if (value == len){
document.getElementById("name").value = "";
document.getElementById("submit").value = "Create !";
document.getElementById("successT").checked = false;
document.getElementById("errorsT").checked = false;
document.getElementById("successL").value = "";
document.getElementById("errorsL").value = "";
}
else {
console.log(data[parseInt(value)]["successL"]);
document.getElementById("submit").value = "Update";
document.getElementById("successT").checked = data[parseInt(value)]["successT"] == "True";
document.getElementById("errorsT").checked = data[parseInt(value)]["errorsT"] == "True";
document.getElementById("successL").value = data[parseInt(value)]["successL"];
document.getElementById("errorsL").value = data[parseInt(value)]["errorsL"];
document.getElementById("name").value = data[parseInt(value)]["name"];
}
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function change_config(value, data, len) {
console.log(data[2]);
document.getElementById("delete").style.visibility = "hidden";
if (value == len){
document.getElementById("submit").value = "Create !";
document.getElementById("discord").value = "-1";
document.getElementById("proxy").value = "-1";
document.getElementById("name").value = "";
for (let i = 1; i < 6; i++) {
document.getElementById("mail"+ i).value = "";
document.getElementById("pwd"+ i).value = "" ;
document.getElementById("2fa"+ i).value = "" ;
}
}
else {
document.getElementById("delete").style.visibility = "visible";
document.getElementById("submit").value = "Update !";
document.getElementById("discord").value = data[parseInt(value)]["discord"];
document.getElementById("proxy").value = data[parseInt(value)]["proxy"];
document.getElementById("name").value = data[parseInt(value)]["name"];
for (let i = 1; i < 6; i++) {
document.getElementById("mail"+ i).value = data[parseInt(value)]['accounts'][i]["mail"] ;
document.getElementById("pwd"+ i).value = data[parseInt(value)]['accounts'][i]["pwd"] ;
document.getElementById("2fa"+ i).value = data[parseInt(value)]['accounts'][i]["2fa"] ;
}
}
}
function change_proxy(value, data, len) {
if (value == len){
document.getElementById("submit").value = "Create";
document.getElementById("address").value = "";
document.getElementById("port").value = "";
document.getElementById("name").value = "";
}
else {
document.getElementById("submit").value = "Update";
document.getElementById("address").value = data[parseInt(value)]["address"];
document.getElementById("port").value = data[parseInt(value)]["port"];
document.getElementById("name").value = data[parseInt(value)]["name"];
}
}
function change_override(value, data) {
for (let i = 1; i < 6; i++) {
document.getElementById("compte_"+ i).innerHTML = data[parseInt(value)]['accounts'][i]["mail"];
if (!(data[parseInt(value)]['accounts'][i]["mail"])){
console.log("hiding" + i);
for (let j = 1; j <= 5; j++) {
document.getElementById(i.toString() +j.toString()).style.visibility = "hidden";
}
} else {
console.log("showing" + i);
for (let j = 1; j <= 5; j++) {
console.log("element " + i.toString()+j.toString());
document.getElementById(i.toString()+j.toString()).style.visibility = "visible";
}
}
}
}
function change_logs(value) {
var myIframe = document.getElementById('embed');
myIframe.addEventListener("load", function() {
let doc = myIframe.contentDocument;
doc.body.innerHTML = doc.body.innerHTML + '<style>html{color:white;}</style>';
myIframe.contentWindow.scrollTo(0, myIframe.contentDocument.body.scrollHeight);
});
myIframe.src = "/static/logs/" + value + ".txt";
}

1
Flask/static/logs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.txt

20
Flask/static/node_modules/.package-lock.json generated vendored Normal file
View File

@ -0,0 +1,20 @@
{
"name": "static",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/xterm": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/xterm/-/xterm-5.3.0.tgz",
"integrity": "sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg=="
},
"node_modules/xterm-addon-fit": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
"peerDependencies": {
"xterm": "^5.0.0"
}
}
}
}

View File

@ -0,0 +1,2 @@
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FitAddon=t():e.FitAddon=t()}(self,(()=>(()=>{"use strict";var e={};return(()=>{var t=e;Object.defineProperty(t,"__esModule",{value:!0}),t.FitAddon=void 0,t.FitAddon=class{activate(e){this._terminal=e}dispose(){}fit(){const e=this.proposeDimensions();if(!e||!this._terminal||isNaN(e.cols)||isNaN(e.rows))return;const t=this._terminal._core;this._terminal.rows===e.rows&&this._terminal.cols===e.cols||(t._renderService.clear(),this._terminal.resize(e.cols,e.rows))}proposeDimensions(){if(!this._terminal)return;if(!this._terminal.element||!this._terminal.element.parentElement)return;const e=this._terminal._core,t=e._renderService.dimensions;if(0===t.css.cell.width||0===t.css.cell.height)return;const r=0===this._terminal.options.scrollback?0:e.viewport.scrollBarWidth,i=window.getComputedStyle(this._terminal.element.parentElement),o=parseInt(i.getPropertyValue("height")),s=Math.max(0,parseInt(i.getPropertyValue("width"))),n=window.getComputedStyle(this._terminal.element),l=o-(parseInt(n.getPropertyValue("padding-top"))+parseInt(n.getPropertyValue("padding-bottom"))),a=s-(parseInt(n.getPropertyValue("padding-right"))+parseInt(n.getPropertyValue("padding-left")))-r;return{cols:Math.max(2,Math.floor(a/t.css.cell.width)),rows:Math.max(1,Math.floor(l/t.css.cell.height))}}}})(),e})()));
//# sourceMappingURL=xterm-addon-fit.js.map

File diff suppressed because one or more lines are too long

26
Flask/static/node_modules/xterm-addon-fit/package.json generated vendored Normal file
View File

@ -0,0 +1,26 @@
{
"name": "xterm-addon-fit",
"version": "0.8.0",
"author": {
"name": "The xterm.js authors",
"url": "https://xtermjs.org/"
},
"main": "lib/xterm-addon-fit.js",
"types": "typings/xterm-addon-fit.d.ts",
"repository": "https://github.com/xtermjs/xterm.js",
"license": "MIT",
"keywords": [
"terminal",
"xterm",
"xterm.js"
],
"scripts": {
"build": "../../node_modules/.bin/tsc -p .",
"prepackage": "npm run build",
"package": "../../node_modules/.bin/webpack",
"prepublishOnly": "npm run package"
},
"peerDependencies": {
"xterm": "^5.0.0"
}
}

209
Flask/static/node_modules/xterm/css/xterm.css generated vendored Normal file
View File

@ -0,0 +1,209 @@
/**
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
* https://github.com/chjj/term.js
* @license MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Originally forked from (with the author's permission):
* Fabrice Bellard's javascript vt100 for jslinux:
* http://bellard.org/jslinux/
* Copyright (c) 2011 Fabrice Bellard
* The original design remains. The terminal itself
* has been extended to include xterm CSI codes, among
* other features.
*/
/**
* Default styles for xterm.js
*/
.xterm {
cursor: text;
position: relative;
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
}
.xterm.focus,
.xterm:focus {
outline: none;
}
.xterm .xterm-helpers {
position: absolute;
top: 0;
/**
* The z-index of the helpers must be higher than the canvases in order for
* IMEs to appear on top.
*/
z-index: 5;
}
.xterm .xterm-helper-textarea {
padding: 0;
border: 0;
margin: 0;
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
position: absolute;
opacity: 0;
left: -9999em;
top: 0;
width: 0;
height: 0;
z-index: -5;
/** Prevent wrapping so the IME appears against the textarea at the correct position */
white-space: nowrap;
overflow: hidden;
resize: none;
}
.xterm .composition-view {
/* TODO: Composition position got messed up somewhere */
background: #000;
color: #FFF;
display: none;
position: absolute;
white-space: nowrap;
z-index: 1;
}
.xterm .composition-view.active {
display: block;
}
.xterm .xterm-viewport {
/* On OS X this is required in order for the scroll bar to appear fully opaque */
background-color: #000;
overflow-y: scroll;
cursor: default;
position: absolute;
right: 0;
left: 0;
top: 0;
bottom: 0;
}
.xterm .xterm-screen {
position: relative;
}
.xterm .xterm-screen canvas {
position: absolute;
left: 0;
top: 0;
}
.xterm .xterm-scroll-area {
visibility: hidden;
}
.xterm-char-measure-element {
display: inline-block;
visibility: hidden;
position: absolute;
top: 0;
left: -9999em;
line-height: normal;
}
.xterm.enable-mouse-events {
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
cursor: default;
}
.xterm.xterm-cursor-pointer,
.xterm .xterm-cursor-pointer {
cursor: pointer;
}
.xterm.column-select.focus {
/* Column selection mode */
cursor: crosshair;
}
.xterm .xterm-accessibility,
.xterm .xterm-message {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 10;
color: transparent;
pointer-events: none;
}
.xterm .live-region {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
}
.xterm-dim {
/* Dim should not apply to background, so the opacity of the foreground color is applied
* explicitly in the generated class and reset to 1 here */
opacity: 1 !important;
}
.xterm-underline-1 { text-decoration: underline; }
.xterm-underline-2 { text-decoration: double underline; }
.xterm-underline-3 { text-decoration: wavy underline; }
.xterm-underline-4 { text-decoration: dotted underline; }
.xterm-underline-5 { text-decoration: dashed underline; }
.xterm-overline {
text-decoration: overline;
}
.xterm-overline.xterm-underline-1 { text-decoration: overline underline; }
.xterm-overline.xterm-underline-2 { text-decoration: overline double underline; }
.xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; }
.xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; }
.xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; }
.xterm-strikethrough {
text-decoration: line-through;
}
.xterm-screen .xterm-decoration-container .xterm-decoration {
z-index: 6;
position: absolute;
}
.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer {
z-index: 7;
}
.xterm-decoration-overview-ruler {
z-index: 8;
position: absolute;
top: 0;
right: 0;
pointer-events: none;
}
.xterm-decoration-top {
z-index: 2;
position: relative;
}

2
Flask/static/node_modules/xterm/lib/xterm.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1
Flask/static/node_modules/xterm/lib/xterm.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

100
Flask/static/node_modules/xterm/package.json generated vendored Normal file
View File

@ -0,0 +1,100 @@
{
"name": "xterm",
"description": "Full xterm terminal, in your browser",
"version": "5.3.0",
"main": "lib/xterm.js",
"style": "css/xterm.css",
"types": "typings/xterm.d.ts",
"repository": "https://github.com/xtermjs/xterm.js",
"license": "MIT",
"keywords": [
"cli",
"command-line",
"console",
"pty",
"shell",
"ssh",
"styles",
"terminal-emulator",
"terminal",
"tty",
"vt100",
"webgl",
"xterm"
],
"scripts": {
"prepackage": "npm run build",
"package": "webpack",
"package-headless": "webpack --config ./webpack.config.headless.js",
"postpackage-headless": "node ./bin/package_headless.js",
"start": "node demo/start",
"build-demo": "webpack --config ./demo/webpack.config.js",
"start-debug": "node --inspect-brk demo/start",
"lint": "eslint -c .eslintrc.json --max-warnings 0 --ext .ts src/ addons/",
"lint-api": "eslint --no-eslintrc -c .eslintrc.json.typings --max-warnings 0 --no-ignore --ext .d.ts typings/",
"test": "npm run test-unit",
"posttest": "npm run lint",
"test-api": "npm run test-api-chromium",
"test-api-chromium": "node ./bin/test_api.js --browser=chromium --timeout=20000",
"test-api-firefox": "node ./bin/test_api.js --browser=firefox --timeout=20000",
"test-api-webkit": "node ./bin/test_api.js --browser=webkit --timeout=20000",
"test-playwright": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4",
"test-playwright-chromium": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='Chrome Stable'",
"test-playwright-firefox": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='Firefox Stable'",
"test-playwright-webkit": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='WebKit'",
"test-playwright-debug": "playwright test -c ./out-test/playwright/playwright.config.js --headed --workers 1 --timeout 30000",
"test-unit": "node ./bin/test.js",
"test-unit-coverage": "node ./bin/test.js --coverage",
"test-unit-dev": "cross-env NODE_PATH='./out' mocha",
"build": "tsc -b ./tsconfig.all.json",
"install-addons": "node ./bin/install-addons.js",
"presetup": "npm run install-addons",
"setup": "npm run build",
"prepublishOnly": "npm run package",
"watch": "tsc -b -w ./tsconfig.all.json --preserveWatchOutput",
"benchmark": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json",
"benchmark-baseline": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --baseline out-test/benchmark/test/benchmark/*benchmark.js",
"benchmark-eval": "NODE_PATH=./out xterm-benchmark -r 5 -c test/benchmark/benchmark.json --eval out-test/benchmark/test/benchmark/*benchmark.js",
"clean": "rm -rf lib out addons/*/lib addons/*/out",
"vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts"
},
"devDependencies": {
"@playwright/test": "^1.37.1",
"@types/chai": "^4.2.22",
"@types/debug": "^4.1.7",
"@types/deep-equal": "^1.0.1",
"@types/express": "4",
"@types/express-ws": "^3.0.1",
"@types/glob": "^7.2.0",
"@types/jsdom": "^16.2.13",
"@types/mocha": "^9.0.0",
"@types/node": "^18.16.0",
"@types/utf8": "^3.0.0",
"@types/webpack": "^5.28.0",
"@types/ws": "^8.2.0",
"@typescript-eslint/eslint-plugin": "^6.2.00",
"@typescript-eslint/parser": "^6.2.00",
"chai": "^4.3.4",
"cross-env": "^7.0.3",
"deep-equal": "^2.0.5",
"eslint": "^8.45.0",
"eslint-plugin-jsdoc": "^39.3.6",
"express": "^4.17.1",
"express-ws": "^5.0.2",
"glob": "^7.2.0",
"jsdom": "^18.0.1",
"mocha": "^10.1.0",
"mustache": "^4.2.0",
"node-pty": "^0.10.1",
"nyc": "^15.1.0",
"source-map-loader": "^3.0.0",
"source-map-support": "^0.5.20",
"ts-loader": "^9.3.1",
"typescript": "^5.1.6",
"utf8": "^3.0.0",
"webpack": "^5.61.0",
"webpack-cli": "^4.9.1",
"ws": "^8.2.3",
"xterm-benchmark": "^0.3.1"
}
}

26
Flask/static/package-lock.json generated Normal file
View File

@ -0,0 +1,26 @@
{
"name": "static",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
}
},
"node_modules/xterm": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/xterm/-/xterm-5.3.0.tgz",
"integrity": "sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg=="
},
"node_modules/xterm-addon-fit": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
"integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
"peerDependencies": {
"xterm": "^5.0.0"
}
}
}
}

View File

@ -0,0 +1,6 @@
{
"dependencies": {
"xterm": "^5.3.0",
"xterm-addon-fit": "^0.8.0"
}
}

79
Flask/templates/base.html Normal file
View File

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<meta name="robots" content="noindex, nofollow">
<meta charset="utf-8">
<link rel="icon" type="image/png" href="{{ url_for('static', filename='favicon.ico') }}">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MS Rewards</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/flask.css')}}"/>
<script src="{{ url_for('static', filename='js/main.js')}}"></script>
</head>
<body>
<div class="container">
<input id="slide-sidebar" type="checkbox" role="button"/>
<label for="slide-sidebar">
<div id="slide">
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-menu-2" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
<path d="M4 6l16 0"></path>
<path d="M4 12l16 0"></path>
<path d="M4 18l16 0"></path>
</svg>
</div>
</label>
<div class="left-pannel">
<table>
<tr>
<td>
<button class="unselected" id="sidebar_schedule" onclick="location.href = '/schedule';">schedule</button>
</td>
</tr>
<tr>
<td>
<button class="unselected" id="sidebar_config" onclick="location.href = '/config';">config</button>
</td>
</tr>
<tr>
<td>
<button class="unselected" id="sidebar_discord" onclick="location.href = '/discord';">discord</button>
</td>
</tr>
<tr>
<td>
<button class="unselected" id="sidebar_proxy" onclick="location.href = '/proxy';">proxy</button>
</td>
</tr>
<tr>
<td>
<button class="unselected" id="sidebar_logs" onclick="location.href = '/logs';">logs</button>
</td>
</tr>
<tr>
<td>
<button class="unselected" id="sidebar_stats" onclick="location.href = '/stats';">stats</button>
</td>
</tr>
<tr>
<td>
<button class="unselected" id="sidebar_override" onclick="location.href = '/override';">Override</button>
</td>
</tr>
<tr>
<td>
<button class="unselected" id="sidebar_settings" onclick="location.href = '/settings';">settings</button>
</td>
</tr>
</table>
<script>document.getElementById("sidebar_{% block left_pannel %}{% endblock %}").className = "selected"</script>
</div>
<div class="content">
{% block content %}
{% endblock %}
</div>
</div>
<div class="footer">{{version}}</div>
</body>
</html>

View File

@ -0,0 +1,22 @@
{% extends "base.html" %}
{% block left_pannel %}
{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<h1>Already logged in</h1>
{% else %}
<form method="post" action="/change_password/">
<table>
<tr>
<td class="comlumn-name">Change password</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="NewPassword" value="send" class="button"/></td>
</tr>
</table>
</form>
{% endif %}
{% endblock %}

106
Flask/templates/config.html Normal file
View File

@ -0,0 +1,106 @@
{% extends "base.html" %}
{% block left_pannel %}config{% endblock %}
{% block content %}
<script>data2 = JSON.parse('{{configs|tojson}}'); </script>
{%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<form method="post" action="/config/">
<table>
<tr>
<td style="width: 10%;">config : </td>
<td style="width: 40%;">
<select onchange="change_config(this.value, data2, '{{len}}')" name="config">
<option id="config" value="{{len}}">New config</option>
{% for i in configs %}
<option id="{{configs[i]['name']}}" value="{{i}}">{{configs[i]['name']}}</option>
{% endfor %}
</select>
</td>
<td style="width: 10%;">name : </td>
<td>
<input type="text" id="name" name="name" value = "">
</td>
</tr>
<tr>
<td style="width: 10%;">Proxy : </td>
<td style="width: 40%;">
<select id="proxy" name="proxy">
<option id="" value="-1">No proxy</option>
{% for i in proxys %}
<option id="{{proxys[i]['name']}}" value="{{i}}">{{proxys[i]['name']}}</option>
{% endfor %}
</select>
</td>
<td style="width: 10%;">Discord : </td>
<td>
<select id="discord" name="discord">
<option id="no discord" value="-1">No discord (not sure about the support)</option>
{% for i in discords %}
<option id="{{discords[i]['name']}}" value="{{i}}">{{discords[i]['name']}}</option>
{% endfor %}
</select>
</td>
</tr>
</table>
<br><br>
<table>
<tr>
<td>Mail</td>
<td>Password</td>
<td>2FA</td>
</tr>
<tr>
<td><input type="text" id="mail1" name="mail1" value=""></td>
<td><input type="text" id="pwd1" name="pwd1" value=""></td>
<td><input type="text" id="2fa1" name="2fa1" value=""></td>
<td class="left-button"><button class="ban" name="ban" value="">ban</button></td>
</tr>
<tr>
<td><input type="text" id="mail2" name="mail2" value=""></td>
<td><input type="text" id="pwd2" name="pwd2" value=""></td>
<td><input type="text" id="2fa2" name="2fa2" value=""></td>
<td class="left-button"><button class="ban" name="ban" value="">ban</button></td>
</tr>
<tr>
<td><input type="text" id="mail3" name="mail3" value=""></td>
<td><input type="text" id="pwd3" name="pwd3" value="" ></td>
<td><input type="text" id="2fa3" name="2fa3" value=""></td>
<td class="left-button"><button class="ban" name="ban" value="">ban</button></td>
</tr>
<tr>
<td><input type="text" id="mail4" name="mail4" value=""></td>
<td><input type="text" id="pwd4" name="pwd4" value="" ></td>
<td><input type="text" id="2fa4" name="2fa4" value=""></td>
<td class="left-button"><button class="ban" name="ban" value="">ban</button></td>
</tr>
<tr>
<td><input type="text" id="mail5" name="mail5" value=""></td>
<td><input type="text" id="pwd5" name="pwd5" value=""></td>
<td><input type="text" id="2fa5" name="2fa5" value=""></td>
<td class="left-button"><button class="ban" name="ban" value="">ban</button></td>
</tr>
</table>
<table>
<tr>
<td>
<input type="submit" class="confirm" name="data" id="submit" value="Create !" class="button" style="width:97%;"/>
</td>
<td class="left-button">
<input type="submit" name="data" id="delete" value="delete" class="ban" style="visibility: hidden;"/>
</td>
</tr>
</table>
</form>
{% endif %}
{% endblock %}

31
Flask/templates/dev.html Normal file
View File

@ -0,0 +1,31 @@
{% extends "base.html" %}
{% block left_pannel %}{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<table>
<tr>
<td width="20%" height="90%">
<div id="console"></div>
</td>
</tr>
</table>
<script>
const consoleElement = document.getElementById('console');
const eventSource = new EventSource('/stream');
eventSource.onmessage = (event) => {
console.log("je ne comprend vraiment plus rien, meme git me casse les couilles");
const newOutput = document.createElement('div');
newOutput.textContent = event.data;
consoleElement.appendChild(newOutput);
};
</script>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,56 @@
{% extends "base.html" %}
{% block left_pannel %}discord{% endblock %}
{% block content %}
<script>data = JSON.parse('{{data|tojson}}'); </script>
{%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<form method="post" action="/discord/">
<table>
<tr>
<td></td>
<td>
<select name="select" onchange="change_discord(this.value, data, '{{len}}')">
<option selected id="new" value="{{ len }}">Create new Discord config</option>
{% for i in data %}
<option id="{{data[i]['name']}}" value="{{i}}">{{data[i]['name']}}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td class="comlumn-name">name</td>
<td><input type="text" id="name" name="name" value=""></td>
</tr>
<tr>
<td class="comlumn-name">Send errors</td>
<td><input type="checkbox" id="errorsT" name="errorsT" class="toogle"/><label for="errorsT">Toggle</label></td>
</tr>
<tr>
<td class="comlumn-name">Send success</td>
<td><input type="checkbox" id="successT" name="successT" class="toogle"/><label for="successT">Toggle</label></td>
</tr>
<tr>
<td class="comlumn-name">Success link</td>
<td><input type="text" id="successL" name="successL" value=""></td>
</tr>
<tr>
<td class="comlumn-name">Failure Link</td>
<td><input type="text" id="errorsL" name="errorsL" value=""></td>
</tr>
</table>
<table>
<tr>
<td class="comlumn-name"></td>
<td style="width:60%;"><input type="submit" name="DISCORD" id="submit" value="Create !" class="confirm" style="width:86%;"/></td>
<td style="padding-right: 20px;">
<input type="submit" name="DISCORD" id="submit" value="delete" class="ban" style="width:60%;"/>
</td>
</tr>
</table>
</form>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,23 @@
{% extends "base.html" %}
{% block left_pannel %}login{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<form method="post" action="/login/">
<table>
<tr>
<td class="comlumn-name">password</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" name="DISCORD" value="send" class="button"/></td>
</tr>
</table>
</form>
{% else %}
<h1>Already logged in</h1>
{% endif %}
{% endblock %}

31
Flask/templates/logs.html Normal file
View File

@ -0,0 +1,31 @@
{% extends "base.html" %}
{% block left_pannel %}logs{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<h1>Already logged in</h1>
{% else %}
<select name="select" onchange="change_logs(this.value)">
<option id="null" value="0">Choisir une config</option>
{% for i in data %}
<option id="{{data[i]['name']}}" value="{{i}}">{{data[i]['name']}}</option>
{% endfor %}
</select>
<br><br>
<iframe type="text/html" src="{{url_for('static', filename='logs/1.txt')}}" width="100%" height="85%" id="embed">
<script type="text/javascript">
const subdoc = document.getElementsByTagName("iframe")[0].contentWindow.document;
var script = document.createElement('script');
script.onload = function () {
const ansiOutput = subdoc.getElementsByTagName("body")[0].getElementsByTagName("pre")[0]
const ansi_up = new AnsiUp();
ansiOutput.innerHTML = ansi_up.ansi_to_html(ansiOutput.innerText)
};
script.src = "https://cdn.jsdelivr.net/npm/ansi_up@4.0.4/ansi_up.js";
document.head.appendChild(script);
</script>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,53 @@
{% extends "base.html" %}
{% block left_pannel %}proxy{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<form method="post" action="/proxy/">
<table>
<tr>
<td class="comlumn-name"></td>
<td>
<script>data = JSON.parse('{{data|tojson}}');</script>
<select name="select" onchange="change_proxy(this.value, data, '{{len}}')">
<option selected id="new" value="{{ len }}">Create new proxy</option>
{% for i in data %}
<option id="{{data[i]['name']}}" value="{{i}}">{{data[i]['name']}}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td class="comlumn-name">name : </td>
<td><input type="text" name="name" value="" id="name"></td>
</tr>
<tr>
<td class="comlumn-name">address : </td>
<td><input type="text" name="address" value="" id="address"></td>
</tr>
<tr>
<td class="comlumn-name">port : </td>
<td><input type="text" name="port" value="" id="port"></td>
</tr>
</table>
<table>
<tr>
<td class="comlumn-name"></td>
<td style="width:60%;"><input type="submit" name="PROXY" id="submit" value="Create !" class="confirm" style="width:86%;"/></td>
<td style="padding-right: 20px;"><input type="submit" name="PROXY" id="submit" value="delete" class="ban" style="width:60%;"/></td>
</tr>
</table>
</form>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,35 @@
{% extends "base.html" %}
{% block left_pannel %}schedule{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<form method="post" action="/schedule/">
<table>
{% for i in data %}
<tr>
<td>{{data[i]['name']}}</td>
<td>
<input type="time" id="{{i}}" name="time{{i}}" value="{{data[i]['time']}}" required>
</td>
<td>
<input type="checkbox" class="toogle" id="switch{{i}}" name="switch{{i}}" {{ "checked" if data[i]['enabled'] == True else "" }} />
<label for="switch{{i}}">
Toggle
</label>
</td>
</tr>
{% endfor %}
</table>
<input type="submit" name="data" value="Update" class="button"/>
</form>
{% endif %}
{%endblock %}

View File

@ -0,0 +1,49 @@
{% extends "base.html" %}
{% block left_pannel %}settings{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<form method="post" action="/settings/">
<table>
<tr>
<td class="comlumn-name">avatar url :</td>
<td><input type="text" name="avatarlink" value="{{data['avatarlink']}}"></td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" name="settings" id="submit" value="update" class="button"/>
</td>
</tr>
</table>
</form>
<h2>TODO</h2>
<ul>
<li>ban button</li>
</ul>
<br><br>
<h2>Backup config files</h2>
<ul>
<li><a href="/download/configs.json">download account config</a></li>
<li><a href="/download/discord.json">download discord config</a></li>
<li><a href="/download/flask.json">download flask config</a></li>
<li><a href="/download/proxy.json">download proxy config</a></li>
<li><a href="/download/settings.json">download settings</a></li>
</ul>
<br><br>
<h2>Upload your files</h2>
<form method="POST" action="/upload_file/" enctype=multipart/form-data>
<table id="table">
<tr><td><input type="file" id="file1" name="file1" onchange='addline(0)'></td></tr>
<tr><td><input type="submit" name="settings" id="submit" value="send file" class="button"/></td></tr>
</table>
</form>
{% endif %}
{%endblock %}

View File

@ -0,0 +1,12 @@
{% extends "base.html" %}
{% block left_pannel %}stats{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<iframe src="/grafana?orgId=1&kiosk" width="100%" height="100%" frameborder="0"></iframe>
{% endif %}
{%endblock %}

View File

@ -0,0 +1,45 @@
{% extends "base.html" %}
{% block left_pannel %}override{% endblock %}
{% block content %}
{%if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<script>data = JSON.parse('{{configs|tojson}}'); </script>
<form method="post" action="/override/" height="90%">
<select onchange="change_override(this.value, data)" name="config">
<option id="-1" value="-1" selected>Select a config</option>
{% for i in configs %}
<option id="{{configs[i]['name']}}" value="{{i}}">{{configs[i]['name']}}</option>
{% endfor %}
</select>
<table height="90%" class="lines">
<tr>
<td width="30%">name</td>
<td width="14%">Unban</td>
<td width="14%">tout</td>
<td width="14%">daily</td>
<td width="14%">pc</td>
<td width="14%">mobile</td>
</tr>
{% for i in range(0,5) %}
<tr heigh="15%">
<td id="compte_{{i+1}}"></td>
<td id="{{i+1}}1" style="visibility: hidden;"><input type="checkbox" id="compte_{{i+1}}" value="{{i}}" name="unban"></td>
<td id="{{i+1}}2" style="visibility: hidden;"><input type="checkbox" id="compte_{{i+1}}" value="{{i}}" name="tout"></td>
<td id="{{i+1}}3" style="visibility: hidden;"><input type="checkbox" id="compte_{{i+1}}" value="{{i}}" name="daily"></td>
<td id="{{i+1}}4" style="visibility: hidden;"><input type="checkbox" id="compte_{{i+1}}" value="{{i}}" name="pc"></td>
<td id="{{i+1}}5" style="visibility: hidden;"><input type="checkbox" id="compte_{{i+1}}" value="{{i}}" name="mobile"></td>
</tr>
{% endfor %}
</table>
<input type="submit" name="VNC" id="submit" value="Start" class="confirm" style="width:60%;"/>
</form>
{% endif %}
{%endblock %}

View File

@ -0,0 +1,48 @@
{% extends "base.html" %}
{% block left_pannel %}override{% endblock %}
{% block content %}
{% if not current_user.is_authenticated %}
<button class="unselected" onclick="location.href = '/login';">login</button>
{% else %}
<link rel="stylesheet" href="{{ url_for('static', filename='node_modules/xterm/css/xterm.css') }}"/>
<script src="{{ url_for('static', filename='node_modules/xterm/lib/xterm.js') }}"></script>
<script src="{{ url_for('static', filename='node_modules/xterm-addon-fit/lib/xterm-addon-fit.js') }}"></script>
<script>
document.getElementsByClassName("content")[0].style.padding = "0 0"
</script>
<div style="height: 100%">
<div id="console" style="height: 100%; width: 20%; float:left;"></div>
<div style="height: 100%; width: 80%; float:left;">
<iframe src="/novnc/vnc.html?resize=scale&path=novnc/websockify&autoconnect=true&view_only"
width="100%" height="100%" frameborder="0"></iframe>
</div>
</div>
<script>
var term = new Terminal();
const fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(document.getElementById('console'));
fitAddon.fit()
addEventListener("transitionend", (event) => {
fitAddon.fit()
});
document.getElementById("console").style.textAlign = "left"
const eventSource = new EventSource('/stream');
eventSource.onmessage = (event) => {
term.writeln(event.data)
};
addEventListener("resize", (event) => {
fitAddon.fit()
});
</script>
{% endif %}
{% endblock %}

View File

@ -1,18 +0,0 @@
# MsReward
A Microsoft reward automator, designed to work headless on a raspberry pi. Tested with a pi 3b+ and a pi 4 2Gb .
Using a discord webhook to log everything.
Using Selenium and geckodriver.
You have to fill the config file.
you have to put your credentials in the same folder as the script, in a `.csv` file. You have to put login and password this way :
```
email1,password1
email2,password2
```
You have to put a list with a dictionnary in the same folder as the script, in a `.txt` file. It should have a lot of words, used to make random search on bing, as shown in the example file.
Tou can add a link to a website where content is only the link of the monthly fidelity card
You should limit to 6 account per IP.
![image](https://user-images.githubusercontent.com/74496300/155960737-061229ca-db8c-4e66-9aef-542d9e709bb2.png)

1021
V4.py

File diff suppressed because it is too large Load Diff

783
V6.py Executable file
View File

@ -0,0 +1,783 @@
#!/usr/bin/python3.10
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.cards import *
from modules.config import *
from modules.db import add_to_database
from modules.driver_tools import *
from modules.error import *
# 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 config.proxy.is_enabled():
chrome_options.add_argument(f'--proxy-server={config.proxy.ip}:{config.proxy.port}')
driver = uc.Chrome(options=chrome_options)
set_language(driver)
return driver
# 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 = config.WebDriver.driver
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.")
driver = config.WebDriver.driver
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():
driver = config.WebDriver.driver
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(8):
try:
element = driver.find_element(By.ID, f"rqAnswerOption{i}")
if 'iscorrectoption="True"' in element.get_attribute("outerHTML"):
correct_answers.append(f'rqAnswerOption{i}')
except Exception as e:
warning(f"can't find rqAnswerOption{i}. 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(config)
correct_answers.append(answer_id)
except Exception as e:
log_error(f"{format_error(e)} \n Good answers : {' '.join(correct_answers)}")
raise ValueError(format_error(e))
info("Quiz 8 done.")
custom_sleep(3)
def play_quiz4(override: int = None):
info(f"Starting Quiz 4")
driver = config.WebDriver.driver
if not override:
try: # fidelity quiz are much longer than usual ones
override = int(findall('rqQuestionState([\d]{1,2})"', driver.page_source)[-1])
except Exception as err:
debug(err)
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 4 done.")
custom_sleep(3)
# do_poll() answer a random thing to poll, on of daily activities
def do_poll():
info("Starting poll")
driver = config.WebDriver.driver
try:
answer_elem = driver.find_element(By.ID, f"btoption{choice([0, 1])}")
try:
answer_elem.click()
except exceptions.ElementNotInteractableException:
warning("element not clickable. Waiting a bit and retrying.")
custom_sleep(uniform(2, 2.5))
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
def all_cards():
driver = config.WebDriver.driver
driver.get("https://rewards.bing.com")
wait_until_visible(By.CLASS_NAME, "c-card-content", 10, driver)
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
custom_sleep(2)
try:
promo()
except Exception as e:
debug(e)
info("no promo card")
if len(card_list) < 10: # most likely an error during loading
if "suspendu" in driver.page_source:
raise Banned()
driver.refresh()
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
if len(card_list) < 10:
log_error("Less than 10 cards. Most likely an error with login.")
return "Not enough cards"
for i in range(len(card_list)):
debug(f"carte {i}")
checked = False
try:
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML")
except StaleElementReferenceException:
driver.refresh()
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
warning(f"staled, {len(card_list)}")
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML")
except IndexError:
driver.get("https://rewards.bing.com")
custom_sleep(10)
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
try:
checked = "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML")
except IndexError:
if i == len(card_list) and i > 15:
checked = False
if checked:
custom_sleep(1.5)
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)
close_tab(driver.window_handles[1])
try:
driver.refresh()
card_list = driver.find_elements(By.CLASS_NAME, "c-card-content")
if "mee-icon-AddMedium" in card_list[i].get_attribute("innerHTML"):
driver.execute_script("arguments[0].scrollIntoView();", card_list[i])
card_list[i].click()
driver.switch_to.window(driver.window_handles[1])
custom_sleep(10)
log_error(f"Card {i} Can't be completed. Why MS ?")
try:
try_play(driver.title) # go back to the main page
try:
close_tab(driver.window_handles[1])
except Exception as e:
debug(e)
except Exception as e:
debug(e)
driver.get("https://rewards.bing.com")
except Exception as err:
log_error(err)
custom_sleep(3)
def promo():
driver = config.WebDriver.driver
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("There is more than 3 promo cards, most likely an unskippable one.")
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:
driver.execute_script("arguments[0].click();", elm)
warning(f"that shouldn't be there (promo), but the workaround 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 Exception as e:
warning(f"no new windows {format_error(e)}")
driver.get("https://rewards.bing.com")
driver.refresh()
custom_sleep(3)
# Find out which type of action to do
def try_play(nom="unknown"):
driver = config.WebDriver.driver
rgpd_popup(config)
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(config)
custom_sleep(5)
debug("Detected and fixed connection popup")
if "bt_PollRadio" in driver.page_source:
debug("Poll detected")
do_poll()
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)
elif "rqQuestionState" in driver.page_source:
number = driver.page_source.count("rqAnswerOption")
warning(f"recovery detected. quiz : {number}")
play(number - 1)
else:
info(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():
info("Starting part 1 of login")
driver = config.WebDriver.driver
driver.get("https://login.live.com")
wait_until_visible(By.ID, "i0116", browser=driver)
mail_elem = driver.find_element(By.ID, "i0116")
send_keys_wait(mail_elem, config.UserCredentials.get_mail())
mail_elem.send_keys(Keys.ENTER)
wait_until_visible(By.ID, "i0118", browser=driver)
pwd_elem = driver.find_element(By.ID, "i0118")
send_keys_wait(pwd_elem, config.UserCredentials.get_password())
pwd_elem.send_keys(Keys.ENTER)
custom_sleep(2)
# 2FA
if "Entrez le code de sécurité" in driver.page_source:
try:
a2f_elem = driver.find_element(By.ID, "idTxtBx_SAOTCC_OTC")
a2f_elem.send_keys(config.UserCredentials.get_tfa().now())
a2f_elem.send_keys(Keys.ENTER)
except Exception as err:
log_error(err)
# Accept all cookies question, and check if the account is locked
def login_part_2():
driver = config.WebDriver.driver
custom_sleep(5)
if 'Abuse' in driver.current_url:
raise Banned()
if 'identity' in driver.current_url:
raise Identity()
if 'notice' in driver.current_url:
driver.find_element(By.ID, "id__0").click()
if "proof" in driver.current_url:
driver.find_element(By.ID, "iLooksGood")
for elm_id in ["checkboxField", "KmsiCheckboxField", "acceptButton", "iNext", "id__0", "iLooksGood", "idSIButton9",
"iCancel"]:
if get_domain(driver) == "account.microsoft.com":
break
try:
driver.find_element(By.ID, elm_id).click()
except Exception as e:
debug(e)
wait_until_visible(By.CSS_SELECTOR, '[data-bi-id="sh-sharedshell-home"]', 20, driver)
# login() tries to login to your Microsoft account.
# it uses global variable g._mail and g._password to login
def login():
driver = config.WebDriver.driver
try:
login_part_1()
login_part_2()
driver.get("https://rewards.bing.com/")
except Banned:
raise Banned()
except Identity:
raise Banned()
except Exception as err:
critical("Error not caught during login." + format_error(err))
log_error(err)
driver.quit()
return False
# Makes 30 search as PC Edge
def bing_pc_search(override=randint(35, 40)):
driver = config.WebDriver.driver
driver.get(f"https://www.bing.com/search?q={config.wordlist.get_word().replace(' ', '+')}")
custom_sleep(uniform(1, 2))
rgpd_popup(config)
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 = config.wordlist.get_word()
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 current account's points to database
def log_points():
driver = config.WebDriver.driver
account = config.UserCredentials.get_mail()
driver.get("https://rewards.bing.com")
custom_sleep(1)
wait_until_visible(By.CSS_SELECTOR, 'span[mee-element-ready="$ctrl.loadCounterAnimation()"]', browser=driver)
try:
points = search('availablePoints\":([\d]+)', driver.page_source)[1]
except Exception as err:
log_error(
f"Dev error, checking why it doesn't work (waited a bit, is this still white ?) {format_error(err)}")
error(f"Can't get points. {format_error(err)}")
return -1
custom_sleep(uniform(3, 20))
account_name = account.split("@")[0]
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():
driver = config.WebDriver.driver
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])&nbsp;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]
button_card = driver.find_element(By.XPATH, f'//span[text()="{button_text}"]')
button_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"Fidelity: Multiples error - 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 err:
error(err)
info("fidelity - done")
except Exception as err:
log_error(err)
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"]')
pause.click()
except Exception as e:
error(f"Error while clicking pause. Probably no cards. {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()
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():
driver = config.WebDriver.driver
try:
alert = driver.switch_to.alert
alert.dismiss()
except exceptions.NoAlertPresentException:
pass
except Exception as err:
log_error(err)
# todo: be coherent with pc search regarding error management
def bing_mobile_search(cred: UserCredentials, override=randint(22, 25)):
config.WebDriver.set_mobile_driver(create_driver(mobile=True))
config.WebDriver.switch_to_driver("Mobile")
driver = config.WebDriver.driver
try:
login()
mot = config.wordlist.get_word().replace(" ", "+")
driver.get(f"https://www.bing.com/search?q={mot}")
custom_sleep(uniform(1, 2))
rgpd_popup(config)
custom_sleep(uniform(1, 1.5))
for i in range(override): # 20
try:
mot = config.wordlist.get_word()
send_keys_wait(driver.find_element(By.ID, "sb_form_q"), mot)
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)
driver.find_element(By.ID, "sb_form_q").clear()
except Exception as err:
error(err)
driver.refresh()
custom_sleep(30)
i -= 1
driver.quit()
except Exception as err:
log_error(err)
driver.quit()
finally:
config.WebDriver.switch_to_driver("PC")
def daily_routine(cred: UserCredentials, custom=False):
try:
if not custom: # custom already is logged in
login()
except Banned:
log_error("This account is locked.")
raise Banned()
except Identity:
log_error("This account has an issue.")
return
try:
all_cards()
except Banned:
log_error("banned")
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()
except Exception as err:
log_error(err)
def json_start(json_entry, cred: UserCredentials):
json_entry = json.loads(json_entry)
config.set_display(SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=2345, color_depth=24))
config.display.start()
account_id = 0
while config.UserCredentials.is_valid():
start = False
for action in ["unban", "tout", "pc", "mobile", "daily"]:
try:
if str(account_id) in json_entry[action]:
start = True
info(f"{cred.get_mail()} : {action}")
except KeyError:
pass
if start:
config.WebDriver.set_pc_driver(create_driver())
config.WebDriver.switch_to_driver("PC")
driver = config.WebDriver.driver
try:
if str(account_id) in json_entry["unban"]:
login_part_1()
info("\nGO TO example.com TO PROCEED or wait 1200 secs.")
for _ in range(1200):
sleep(1)
if driver.current_url == "https://example.com/":
info("proceeding")
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"]:
try:
all_cards()
except Exception as e:
log_error(e)
except KeyError:
pass
try:
if str(account_id) in json_entry["pc"]:
try:
bing_pc_search()
except Exception as e:
log_error(e)
except KeyError:
pass
try:
if str(account_id) in json_entry["mobile"]:
try:
bing_mobile_search(cred)
except Exception as e:
log_error(e)
except KeyError:
pass
try:
log_points()
except Exception as e:
error(f"CustomStart {e}")
driver.close()
cred.next_account()
account_id += 1
config.display.stop()
def default_start():
if config.vnc_enabled():
config.set_display(SmartDisplay(backend="xvnc", size=(1920, 1080), rfbport=config.vnc, color_depth=24))
else:
config.set_display(SmartDisplay(size=(1920, 1080)))
config.display.start()
while config.UserCredentials.is_valid():
custom_sleep(1)
info("Starting and configuring driver.")
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)
config.WebDriver.pc_driver.quit()
except KeyboardInterrupt:
critical("Canceled by user. Closing driver and display.")
config.WebDriver.pc_driver.quit()
config.display.stop()
break
except Banned:
warning("this account is banned. Switching to next account")
except Exception as e:
log_error(f"Error not caught. Skipping this account. " + format_error(e))
critical(f"Error not caught. Skipping this account. {e}")
config.WebDriver.pc_driver.quit()
finally:
config.UserCredentials.next_account()
config.display.stop()
def log_error(msg):
DiscordLogger(config).send(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")
if __name__ == "__main__":
config = Config(args)
check_updated()
match config.start:
case "json":
json_start(config.json_entry, config.UserCredentials)
case "default":
default_start()

1
build.sh Executable file
View File

@ -0,0 +1 @@
sudo docker build --no-cache --network host -t msrewards . && sudo docker run -d --restart unless-stopped -p 1234:1234 -p 2345:2345 -ti --shm-size=2gb --name MsRewards msrewards

29
config
View File

@ -1,29 +0,0 @@
[PATH]
motpath = /your/path/to/words_list.txt
logpath = /your/path/to/loginandpass.csv
[SETTINGS]
FidelityLink = Null
embeds = False
Headless = True
[DISCORD]
successlink = https://discord.com/api/webhooks/[put your webhook here]
errorlink =https://discord.com/api/webhooks/[put your webhook here]
[PROXY]
enabled = False
url = Null
port = 0
[DATABASE]
enabled = False
host = Null
database = MsRewards
usr = root
pwd = password

193
config/Stats-dashbord.json Normal file
View File

@ -0,0 +1,193 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": false,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 1,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "frser-sqlite-datasource",
"uid": "bed26262-6b98-4dfc-a95d-f8bd39b5d09c"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"max": 10000,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "dark-red",
"value": null
},
{
"color": "dark-yellow",
"value": 2000
},
{
"color": "green",
"value": 7500
},
{
"color": "blue",
"value": 10000
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 24,
"x": 0,
"y": 0
},
"id": 3,
"options": {
"displayMode": "gradient",
"minVizHeight": 10,
"minVizWidth": 0,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showUnfilled": true,
"valueMode": "color"
},
"pluginVersion": "10.0.3",
"targets": [
{
"datasource": {
"type": "frser-sqlite-datasource",
"uid": "bed26262-6b98-4dfc-a95d-f8bd39b5d09c"
},
"queryText": "SELECT\n unixepoch() as time,\n c.compte,\n c.last_pts as \"\"\nFROM \n comptes c;\n",
"queryType": "time series",
"rawQueryText": "SELECT\n unixepoch() as time,\n c.compte,\n c.last_pts as \"\"\nFROM \n comptes c;\n",
"refId": "A",
"timeColumns": [
"time",
"ts"
]
}
],
"title": "Account points",
"type": "bargauge"
},
{
"datasource": {
"type": "frser-sqlite-datasource",
"uid": "bed26262-6b98-4dfc-a95d-f8bd39b5d09c"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"max": 300,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "dark-red",
"value": null
},
{
"color": "dark-green",
"value": 200
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 11,
"w": 24,
"x": 0,
"y": 11
},
"id": 4,
"options": {
"displayMode": "gradient",
"minVizHeight": 10,
"minVizWidth": 0,
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"showUnfilled": true,
"valueMode": "color"
},
"pluginVersion": "10.0.3",
"targets": [
{
"datasource": {
"type": "frser-sqlite-datasource",
"uid": "bed26262-6b98-4dfc-a95d-f8bd39b5d09c"
},
"queryText": "SELECT\n unixepoch() as time,\n c.compte as metric,\n c.last_pts - d2.points as ''\nFROM \n comptes c \nLEFT OUTER JOIN \n daily d1 \nON \n c.compte = d1.compte \nAND \n d1.date = date() \n LEFT OUTER JOIN daily d2 ON c.compte = d2.compte AND d2.date = DATE('now','-1 day')\nORDER BY d1.points DESC",
"queryType": "time series",
"rawQueryText": "SELECT\n unixepoch() as time,\n c.compte as metric,\n c.last_pts - d2.points as ''\nFROM \n comptes c \nLEFT OUTER JOIN \n daily d1 \nON \n c.compte = d1.compte \nAND \n d1.date = date() \n LEFT OUTER JOIN daily d2 ON c.compte = d2.compte AND d2.date = DATE('now','-1 day')\nORDER BY d1.points DESC",
"refId": "A",
"timeColumns": [
"time",
"ts"
]
}
],
"title": "Daily progress",
"type": "bargauge"
}
],
"refresh": "",
"schemaVersion": 38,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Stats",
"uid": "e70d4980-36d1-4107-90b0-d9164ae8ead4",
"version": 14,
"weekStart": ""
}

66
config/config.sh Normal file
View File

@ -0,0 +1,66 @@
printf "\nsetting up NGINX\n"
rm /etc/nginx/sites-available/default
echo "
map \$http_upgrade \$connection_upgrade {
default upgrade;
'' close;
}
upstream grafana {
server localhost:3000;
}
server {
listen 1234;
server_name localhost;
location /grafana {
proxy_pass http://localhost:3000;
rewrite ^/grafana/(.*) /\$1 break;
proxy_set_header Host \$host;
}
location /grafana/api/live/ {
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection \$connection_upgrade;
proxy_set_header Host \$http_host;
proxy_pass http://grafana;
rewrite ^/grafana/(.*) /\$1 break;
}
location /novnc/ {
proxy_pass http://127.0.0.1:6080/;
}
location /novnc/websockify {
proxy_pass http://127.0.0.1:6080/;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host \$host;
}
location / {
proxy_set_header X-Forwarded-For \$remote_addr;
proxy_set_header Host \$http_host;
proxy_pass "http://127.0.0.1:6666";
chunked_transfer_encoding off;
proxy_buffering off;
}
}
" >> /etc/nginx/sites-available/default
printf "\nNGINX configuration successfull\n"
printf "\ncreating sqlite databases\n"
sqlite3 /app/MsRewards-Reborn/MsRewards.db "CREATE TABLE daily (id INTEGER PRIMARY KEY,compte TEXT,points int,date TEXT);"
sqlite3 /app/MsRewards-Reborn/MsRewards.db "CREATE TABLE comptes (id INTEGER PRIMARY KEY,compte TEXT,last_pts int, banned int);"
printf "\nconfigurating grafana\n"
cp /app/MsRewards-Reborn/config/grafana.ini /etc/grafana/
grafana-cli plugins install frser-sqlite-datasource
printf "setting up default dashboard"
cp /app/MsRewards-Reborn/config/Stats-dashbord.json /usr/share/grafana/public/dashboards/home.json

1469
config/grafana.ini Executable file

File diff suppressed because it is too large Load Diff

19
config/request.sh Normal file
View File

@ -0,0 +1,19 @@
sleep 30
curl -X "POST" "http://localhost:1234/grafana/api/datasources" \
-H "Content-Type: application/json" \
--user admin:admin \
--data-raw $'{"id":1,"uid":"bed26262-6b98-4dfc-a95d-f8bd39b5d09c","orgId":1,"name":"SQLite","type":"frser-sqlite-datasource","typeName":"SQLite","typeLogoUrl":"public/plugins/frser-sqlite-datasource/img/logo.svg","access":"proxy","url":"","user":"","database":"","basicAuth":false,"isDefault":true,"jsonData":{"attachLimit":0,"path":"/app/MsRewards-Reborn/MsRewards.db","pathPefix":"file:"},"readOnly":false}'
curl 'http://localhost:1234/grafana/api/dashboards/import' \
-H 'content-type: application/json' \
-H 'x-grafana-org-id: 1' \
--user admin:admin \
--data-raw $'{"dashboard":{"annotations":{"list":[{"builtIn":1,"datasource":{"type":"grafana","uid":"-- Grafana --"},"enable":true,"hide":true,"iconColor":"rgba(0, 211, 255, 1)","name":"Annotations & Alerts","type":"dashboard"}]},"editable":true,"fiscalYearStartMonth":0,"graphTooltip":0,"id":null,"links":[],"liveNow":false,"panels":[{"datasource":{"type":"frser-sqlite-datasource","uid":"bed26262-6b98-4dfc-a95d-f8bd39b5d09c"},"fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"max":10000,"thresholds":{"mode":"absolute","steps":[{"color":"dark-red","value":null},{"color":"dark-yellow","value":2000},{"color":"green","value":7500},{"color":"blue","value":10000}]}},"overrides":[]},"gridPos":{"h":11,"w":24,"x":0,"y":0},"id":3,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":true,"valueMode":"color"},"pluginVersion":"10.0.3","targets":[{"datasource":{"type":"frser-sqlite-datasource","uid":"bed26262-6b98-4dfc-a95d-f8bd39b5d09c"},"queryText":"SELECT\\n unixepoch() as time,\\n c.compte,\\n c.last_pts as \\"\\"\\nFROM \\n comptes c;\\n","queryType":"time series","rawQueryText":"SELECT\\n unixepoch() as time,\\n c.compte,\\n c.last_pts as \\"\\"\\nFROM \\n comptes c;\\n","refId":"A","timeColumns":["time","ts"]}],"title":"Account points","type":"bargauge"},{"datasource":{"type":"frser-sqlite-datasource","uid":"bed26262-6b98-4dfc-a95d-f8bd39b5d09c"},"fieldConfig":{"defaults":{"color":{"mode":"thresholds"},"mappings":[],"max":300,"thresholds":{"mode":"absolute","steps":[{"color":"dark-red","value":null},{"color":"dark-green","value":200}]}},"overrides":[]},"gridPos":{"h":11,"w":24,"x":0,"y":11},"id":4,"options":{"displayMode":"gradient","minVizHeight":10,"minVizWidth":0,"orientation":"auto","reduceOptions":{"calcs":["lastNotNull"],"fields":"","values":false},"showUnfilled":true,"valueMode":"color"},"pluginVersion":"10.0.3","targets":[{"datasource":{"type":"frser-sqlite-datasource","uid":"bed26262-6b98-4dfc-a95d-f8bd39b5d09c"},"queryText":"SELECT\\n unixepoch() as time,\\n c.compte as metric,\\n c.last_pts - d2.points as \'\'\\nFROM \\n comptes c \\nLEFT OUTER JOIN \\n daily d1 \\nON \\n c.compte = d1.compte \\nAND \\n d1.date = date() \\n LEFT OUTER JOIN daily d2 ON c.compte = d2.compte AND d2.date = DATE(\'now\',\'-1 day\')\\nORDER BY d1.points DESC","queryType":"time series","rawQueryText":"SELECT\\n unixepoch() as time,\\n c.compte as metric,\\n c.last_pts - d2.points as \'\'\\nFROM \\n comptes c \\nLEFT OUTER JOIN \\n daily d1 \\nON \\n c.compte = d1.compte \\nAND \\n d1.date = date() \\n LEFT OUTER JOIN daily d2 ON c.compte = d2.compte AND d2.date = DATE(\'now\',\'-1 day\')\\nORDER BY d1.points DESC","refId":"A","timeColumns":["time","ts"]}],"title":"Daily progress","type":"bargauge"}],"refresh":"","schemaVersion":38,"style":"dark","tags":[],"templating":{"list":[]},"time":{"from":"now-6h","to":"now"},"timepicker":{},"timezone":"","title":"main","uid":"stats","version":14,"weekStart":""},"overwrite":true,"inputs":[],"folderUid":""}' \
--compressed \
--insecure
websockify -D \
--web /usr/share/novnc/ \
6080 \
localhost:2345

19
docker-compose.yml Normal file
View File

@ -0,0 +1,19 @@
version: '3.8'
services:
msrewards:
build:
context: .
dockerfile: Dockerfile
# optional if you have Dockerfile in the same directory
# arguments:
# - ARG_NAME=value # If you have build arguments
image: msrewards
container_name: MsRewards
restart: unless-stopped
ports:
- "1234:1234"
- "2345:2345"
shm_size: 2gb
volumes:
- "./data/:/data"

View File

@ -1 +0,0 @@
you,have,to,add,a,lots,of,words,like,this,separated,with,a,coma

79
modules/Classes/Config.py Normal file
View File

@ -0,0 +1,79 @@
import json
from discord import Webhook, RequestsWebhookAdapter
from modules.Classes.DiscordConfig import DiscordConfig, FakeWebHook
from modules.Classes.Driver import Driver
from modules.Classes.Proxy import Proxy
from modules.Classes.UserCredentials import UserCredentials
from modules.Classes.WordList import WordList
class Config:
def __init__(self, args):
"""
open config file
"""
with open("/app/MsRewards-Reborn/user_data/discord.json", "r") as inFile:
discord = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/settings.json", "r") as inFile:
settings = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile:
proxy = json.load(inFile)
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
config = json.load(inFile)
"""
setup standalone stuff
"""
self.args = args
self.start = "json" if args.json else "default"
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
"""
setup UserCredential
"""
self.UserCredentials = UserCredentials()
with open("/app/MsRewards-Reborn/user_data/configs.json", "r") as inFile:
configs = json.load(inFile)
for i in configs[str(args.config)]["accounts"]:
d = configs[str(args.config)]["accounts"][i]
self.UserCredentials.add(d["mail"], d["pwd"], d["2fa"])
"""
Setup discord
"""
self.discord = DiscordConfig()
self.discord.avatar_url = settings["avatarlink"]
self.discord.wh_link = discord[config[args.config]["discord"]]["errorsL"]
if self.discord.wh_link != "":
self.discord.wh = Webhook.from_url(self.discord.wh_link, adapter=RequestsWebhookAdapter())
else:
self.discord.wh = FakeWebHook()
"""
setup proxy
"""
proxy_conf = config[args.config]["proxy"]
if proxy_conf != "-1":
proxy_address = proxy[config[args.config]["proxy"]]["address"]
proxy_port = proxy[config[args.config]["proxy"]]["port"]
else:
proxy_address = ""
proxy_port = ""
self.proxy = Proxy(proxy_conf, proxy_address, proxy_port)
def vnc_enabled(self):
return self.vnc != "None"
def set_display(self, display):
self.display = display
def has_been_updated(self):
return self.version != "None"

View File

@ -0,0 +1,14 @@
from modules.Tools.logger import debug
class DiscordConfig:
def __init__(self):
self.avatar_url = ""
self.wh_link = None
self.wh = None
class FakeWebHook:
def send(self, *args):
debug(f"Used a webhook call without webhook url with {args}")

View File

@ -0,0 +1,36 @@
from discord import Embed, Colour, File
from modules.Classes.Config import Config
from modules.Tools.logger import error
from modules.Tools.tools import format_error
class DiscordLogger:
def __init__(self, config: Config):
self.config = config
def send(self, message: str):
driver = self.config.WebDriver.driver
if type(message) is not str:
message = format_error(message)
error(message)
with open("page.html", "w") as f:
try:
f.write(driver.page_source)
except Exception as e:
error(e)
f.write("the driver has closed or crashed. Can't access page content")
img = self.config.display.waitgrab()
img.save("screenshot.png")
embed = Embed(
title="An Error has occurred",
description=str(message),
colour=Colour.red(),
)
file = File("screenshot.png")
embed.set_image(url="attachment://screenshot.png")
embed.set_footer(text=self.config.UserCredentials.get_mail() + " - " + self.config.WebDriver.current_driver())
self.config.discord.wh.send(embed=embed, username="error", file=file, avatar_url=self.config.discord.avatar_url)
self.config.discord.wh.send(username="error", file=File("page.html"), avatar_url=self.config.discord.avatar_url)

25
modules/Classes/Driver.py Normal file
View File

@ -0,0 +1,25 @@
class Driver:
def __init__(self):
self.pc_driver = None
self.mobile_driver = None
self.driver = None
def set_pc_driver(self, pc_driver):
self.pc_driver = pc_driver
def set_mobile_driver(self, mobile_driver):
self.mobile_driver = mobile_driver
def switch_to_driver(self, driver: str):
match driver:
case "pc" | "PC" | "Pc":
self.driver = self.pc_driver
case "mobile" | "Mobile":
self.driver = self.mobile_driver
case _:
raise ValueError("The driver must be either pc or mobile")
def current_driver(self):
return "PC" if self.pc_driver == self.driver else "Mobile"

9
modules/Classes/Proxy.py Normal file
View File

@ -0,0 +1,9 @@
class Proxy:
def __init__(self, enabled: str, ip: str = None, port: str = None):
self.ip = ip
self.port = port
self.enabled = enabled != "-1"
def is_enabled(self):
return self.enabled

View File

@ -0,0 +1,44 @@
from pyotp import TOTP
from modules.Tools.logger import debug, warning
class UserCredentials:
def __init__(self):
self.data = {}
self.current = 0
self.total = 0
def add(self, username: str, password: str, tfa: str = None):
debug(
f"adding account with data : Username: {username}, Password: {password}, 2FA: {'None' if tfa == '' else tfa}")
self.data[self.total] = {
"username": username,
"password": password,
"2fa": None if tfa == '' else tfa
}
self.total += 1
def tfa_enable(self):
return self.data[self.current]["2fa"] is not None
def get_mail(self):
return self.data[self.current]["username"]
def get_password(self):
return self.data[self.current]["password"]
def get_tfa(self):
if not self.tfa_enable():
warning("Warning: TFA is not enabled. Calling get_tfa is an expected behaviour.")
return TOTP(self.data[self.current]["2fa"])
def next_account(self):
self.current += 1
if self.is_valid():
debug(f"New credentials: {self.data[self.current]}")
else:
debug("No new credentials.")
def is_valid(self):
return self.current < self.total

View File

@ -0,0 +1,13 @@
import random
class WordList:
def __init__(self, path):
with open(path, "r", encoding="utf-8") as h:
lines = h.readlines()
self.words = [x.replace('\n', "") for x in lines]
random.shuffle(self.words)
def get_word(self):
return self.words.pop(0)

View File

@ -0,0 +1,8 @@
import undetected_chromedriver as uc
from pyvirtualdisplay.smartdisplay import SmartDisplay
display = SmartDisplay(size=(1920, 1080))
display.start()
driver = uc.Chrome()
driver.close()
driver.close()

47
modules/Tools/logger.py Normal file
View File

@ -0,0 +1,47 @@
import logging
# ANSI escape codes for colors
COLOR_CODES = {
'RESET': '\033[0m',
'BOLD': '\033[1m',
'RED': '\033[31m',
'GREEN': '\033[32m',
'YELLOW': '\033[33m',
'BLUE': '\033[34m',
}
# Define colors for each log level
LOG_COLORS = {
'DEBUG': COLOR_CODES['BLUE'],
'INFO': COLOR_CODES['GREEN'],
'WARNING': COLOR_CODES['YELLOW'],
'ERROR': COLOR_CODES['RED'],
'CRITICAL': COLOR_CODES['BOLD'] + COLOR_CODES['RED'],
}
# Create a formatter with colors
class ColoredFormatter(logging.Formatter):
def format(self, record):
log_level = record.levelname
record.levelname = f"{LOG_COLORS.get(log_level, '')}{record.levelname}{COLOR_CODES['RESET']}"
return super().format(record)
# Set up the root logger
root_logger = logging.getLogger(__name__)
root_logger.setLevel(logging.INFO)
# Create a console handler and set the formatter
ch = logging.StreamHandler()
ch.setFormatter(ColoredFormatter('%(levelname)s: %(message)s'))
# Add the console handler to the root logger
root_logger.addHandler(ch)
# Define log level functions
debug = root_logger.debug
info = root_logger.info
warning = root_logger.warning
error = root_logger.error
critical = root_logger.critical

36
modules/Tools/tools.py Normal file
View File

@ -0,0 +1,36 @@
from time import sleep
from modules.Tools.logger import info, error
# return current page domain
def get_domain(driver):
return driver.current_url.split("/")[2]
def custom_sleep(temps):
try:
if False: # todo: change this awful condition
points = ["", "", "", "", "", "", "", ""]
passe = 0
for _ in range(int(temps)):
for i in range(8):
sleep(0.125)
passe += 0.125
print(f"{points[i]} - {round(float(temps) - passe, 3)}", end="\r")
print(" ", end="\r")
else:
sleep(temps)
except KeyboardInterrupt:
info("Wait canceled.")
except Exception as err:
error(err)
def format_error(e) -> str:
tb = e.__traceback__
txt = ""
while tb is not None:
txt = txt + f" -> {tb.tb_frame.f_code.co_name} ({tb.tb_lineno}) "
tb = tb.tb_next
return txt + "\n" + str(e)

View File

@ -0,0 +1,48 @@
import requests
import re
from packaging import version
import subprocess
from logger import critical, info, error
errorMessage = subprocess.run(['python3', '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]+)"
try:
versionN = re.search(versionPattern, errorMessage)[1]
except Exception as e:
critical("Can't get version number from error")
error(e)
exit(0)
info(f"Needed version : '{versionN}'")
downloadUrl = "http://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/"
r = requests.get(downloadUrl)
content = r.text
exactVersionList = re.findall(f"(google-chrome-stable_({versionN}.[0-9.]+)[^<^>^\"]+)", content)
try:
best = exactVersionList[0]
except Exception as e:
critical("No version matches required version")
error(e)
exit(0)
for i in exactVersionList:
if version.parse(i[1]) > version.parse(best[1]):
best = i
chromeDebURL = f"http://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/{best[0]}"
info(f"chrome deb URL : {chromeDebURL}")
info("downloading chrome")
subprocess.call(['wget', "-O", "/tmp/chrome.deb", chromeDebURL])
info("Chrome deb downloaded. Installing chrome")
subprocess.call(["dpkg", "-i", "/tmp/chrome.deb"])
info("Chrome installed")

34
modules/cards.py Normal file
View File

@ -0,0 +1,34 @@
from modules.imports import *
def welcome_tour(elm, driver):
try :
driver.find_element(By.CSS_SELECTOR, '[class="welcome-tour-next-button c-call-to-action c-glyph"]').click()
except :
pass
driver.find_element(By.CSS_SELECTOR, '[class="quiz-link gray-button c-call-to-action c-glyph f-lightweight"]').click()
sleep(5)
driver.find_element(By.CSS_SELECTOR, '[class="c-glyph glyph-cancel"]').click()
elm.click()
driver.find_element(By.CSS_SELECTOR, '[class="quiz-link gray-button c-call-to-action c-glyph f-lightweight"]').click()
sleep(5)
driver.find_element(By.CSS_SELECTOR, '[class="c-glyph glyph-cancel"]').click()
elm.click()
driver.find_element(By.CSS_SELECTOR, '[class="quiz-link gray-button c-call-to-action c-glyph f-lightweight"]').click()
sleep(5)
driver.find_element(By.CSS_SELECTOR, '[class="c-glyph glyph-cancel"]').click()
def welcome_tour_NO(driver):
try :
driver.find_element(By.CSS_SELECTOR, '[class="welcome-tour-next-button c-call-to-action c-glyph"]').click()
except :
pass
driver.find_element(By.CSS_SELECTOR, '[class="c-glyph glyph-cancel"]').click()
sleep(5)
def spotify(driver):
sleep(5)
driver.find_element(By.CSS_SELECTOR, '[data-bi-id="spotify-premium gratuit"]').click()
sleep(5)
close_tab(driver.window_handles[1])

33
modules/config.py Normal file
View File

@ -0,0 +1,33 @@
#!/usr/bin/python3.10
from modules.imports import *
parser = argparse.ArgumentParser()
parser.add_argument(
"-c",
"--config",
help="Choose a specific config file",
default=""
)
parser.add_argument(
"-v",
"--vnc",
help="enable VNC",
dest="vnc"
)
parser.add_argument(
"--version",
help="display a message on discord to tell that the bot have been updated",
dest="update_version",
default="None"
)
parser.add_argument(
"--json",
help="input json to start the bot with custom parameters",
default=""
)
args = parser.parse_args()

66
modules/db.py Normal file
View File

@ -0,0 +1,66 @@
import sqlite3
# Create a new row, for the account [compte] whith [points] points
def add_row(account, points, mycursor, mydb):
sql = "INSERT INTO daily (compte, points, date) VALUES (?, ?, date())"
val = (account, points)
mycursor.execute(sql, val)
mydb.commit()
# printf(mycursor.rowcount, "record created.")
# update the ammount of points for the account [compte]
def update_row(account, points, mycursor, mydb):
sql = f"UPDATE daily SET points = {points} WHERE compte = '{account}' AND date = date() ;"
mycursor.execute(sql)
mydb.commit()
# update the value of last_pts for the table comptes
def update_last(account, points, mycursor, mydb):
sql1 = f"UPDATE comptes SET last_pts = {points} WHERE compte = '{account}';"
sql2 = f"select * from comptes where compte = '{account}'"
sql3 = f"INSERT INTO comptes (compte, last_pts,banned) VALUES ('{account}', {points}, 0)"
cmd = mycursor.execute(sql2)
if len(list(cmd)) == 0:
mycursor.execute(sql3)
else:
mycursor.execute(sql1)
mydb.commit()
# Return if there already is a line in the database for the account [account].
# if same_point is enabled, the line must also have the same number of points
# SQLITE
def get_row(account, points, mycursor, same_points=True):
if same_points:
mycursor.execute(f"SELECT * FROM daily WHERE points = {points} AND compte = '{account}' AND date = date() ;")
else:
mycursor.execute(f"SELECT * FROM daily WHERE compte = '{account}' AND date = date() ;")
myresult = mycursor.fetchall()
return (len(myresult) == 1)
def add_to_database(account, points):
if points is None:
pass
else:
mydb = sqlite3.connect("/app/MsRewards-Reborn/MsRewards.db")
mycursor = mydb.cursor()
if get_row(account, points, mycursor, True):
# check if the row exist with the same amount of points and do nothing if it does
pass
# check if the row exist, but without the same amount of points and update the point account then
elif get_row(account, points, mycursor, False):
update_row(account, points, mycursor, mydb)
else: # if the row don't exist, create it with the good amount of points
add_row(account, points, mycursor, mydb)
if int(points) > 10:
update_last(account, points, mycursor, mydb)
mycursor.close()
mydb.close()

72
modules/driver_tools.py Normal file
View File

@ -0,0 +1,72 @@
from random import uniform
from selenium.common import TimeoutException
from selenium.webdriver import ActionChains, Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from modules.Tools.logger import debug
from modules.Tools.tools import *
def set_language(ldriver):
ldriver.get("chrome://settings/languages")
action = ActionChains(ldriver)
action.reset_actions()
# select language
x_coord = 1200
y_coord = 150
action.move_by_offset(x_coord, y_coord).click().perform()
sleep(0.5)
# scroll down
action.reset_actions()
elm = ldriver.find_element(By.XPATH, "/html/body")
ActionChains(ldriver) \
.send_keys("french") \
.pause(0.5) \
.send_keys(Keys.TAB + Keys.TAB + Keys.ENTER + Keys.TAB + Keys.TAB + Keys.ENTER) \
.perform()
x_coord = 1163
y_coord = 717
action.move_by_offset(x_coord, y_coord).click().perform()
# put to the top
sleep(0.5)
action.reset_actions()
x_coord = 1257
y_coord = 328
action.move_by_offset(x_coord, y_coord).click().perform()
action.click().perform()
# Deal with RGPD popup as well as some random popup like 'are you satisfied' one
def rgpd_popup(config) -> None:
for i in ["bnp_btn_accept", "bnp_hfly_cta2", "bnp_hfly_close"]:
try:
config.WebDriver.driver.find_element(By.ID, i).click()
except Exception as err:
debug(err)
"""
send_keys_wait([selenium element:element, str:keys]) send the different keys to the field element, with a random
time between each press to simulate human action.
keys can be an string, but also selenium keys
"""
def send_keys_wait(element, keys: str) -> None:
for i in keys:
element.send_keys(i)
sleep(uniform(0.1, 0.3))
# Wait for the presence of the element identifier or [timeout]s
def wait_until_visible(search_by: str, identifier: str, timeout: int = 20, browser=None) -> bool:
try:
WebDriverWait(browser, timeout).until(
expected_conditions.visibility_of_element_located((search_by, identifier)), "element not found")
return True
except TimeoutException as e:
error(f"element {identifier} not found after {timeout}s")
return False

10
modules/error.py Normal file
View File

@ -0,0 +1,10 @@
class Banned(Exception):
pass
class NotBanned(Exception):
pass
class Identity(Exception):
pass

36
modules/imports.py Normal file
View File

@ -0,0 +1,36 @@
import argparse
import asyncio
import json
import configparser
import pickle
from csv import reader
from datetime import datetime, timedelta
from os import path, sys, system
from random import choice, randint, shuffle, uniform
from re import findall, search
from sys import platform
from time import sleep, time
from discord import Colour, Embed, File, RequestsWebhookAdapter, Webhook
from pyotp import TOTP
from pyvirtualdisplay import Display
from pyvirtualdisplay.smartdisplay import SmartDisplay
from requests import get
from selenium import webdriver
from selenium.common import exceptions
from selenium.common.exceptions import (ElementClickInterceptedException,
NoSuchElementException,
StaleElementReferenceException,
TimeoutException, WebDriverException)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select, WebDriverWait
from ast import literal_eval
try:
import enquiries
except:
system("") # enable colors in windows cmd
import undetected_chromedriver as uc

17
requirements.txt Normal file
View File

@ -0,0 +1,17 @@
argparse
discord.py==1.7.3
selenium
pillow
pyvirtualdisplay
undetected_chromedriver
requests>=2.31.0
flask
flask_sse
EasyProcess
pyotp
packaging
apscheduler
flask_login
gunicorn
gevent
redis

3
sse.sh Normal file
View File

@ -0,0 +1,3 @@
while IFS= read -r newline; do
redis-cli publish console "$newline"
done < <(tail -f /app/MsRewards-Reborn/Flask/static/logs/custom.txt)

4
user_data/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

1
user_data/configs.json Normal file
View File

@ -0,0 +1 @@
{}

4
user_data/cookies/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

1
user_data/discord.json Normal file
View File

@ -0,0 +1 @@
{}

4
user_data/flask.json Normal file
View File

@ -0,0 +1,4 @@
{
"password": "ChangeMe",
"secret": ""
}

1
user_data/logs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*

View File

1
user_data/proxy.json Normal file
View File

@ -0,0 +1 @@
{}

1
user_data/settings.json Normal file
View File

@ -0,0 +1 @@
{"avatarlink":"https://cdn.discordapp.com/icons/793934298977009674/d8055bccef6eca4855c349e808d0d788.webp"}

1
version Normal file
View File

@ -0,0 +1 @@
v6.8.42