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 # redis part for live update redis_client = redis.StrictRedis(host='localhost', port=6379, db=0) pubsub = redis_client.pubsub() pubsub.subscribe('console') def generate_output(): for message in pubsub.listen(): if message['type'] == 'message': yield f"data: {message['data'].decode()}\n\n" @app.route('/stream') def stream(): return Response(generate_output(), content_type='text/event-stream') # 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("/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"] 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(): with open("/app/MsRewards-Reborn/user_data/proxy.json", "r") as inFile: j = json.load(inFile) new_proxy = {"address": "ADDRESS", "port": "PORT", "name":"NAME"} max_index = 0 for i in range(1, 50): try : print(j[str(i)]) except : print(f"found {i - 1} proxys") max_index = i break j[f"{max_index}"] = new_proxy print(j) with open("/app/MsRewards-Reborn/user_data/proxy.json", "w") as outfile: json.dump(j, outfile) 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]} --very-custom \"{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/', 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'])