from pandas import read_csv from functools import wraps from app.config import Config from flask_migrate import Migrate from flask_sqlalchemy import SQLAlchemy from flask_simplelogin import SimpleLogin from werkzeug.utils import secure_filename from flask_simplelogin import is_logged_in from flask import ( Flask, render_template_string, render_template, request, redirect, url_for, Response, get_template_attribute, ) app = Flask(__name__) app.config.from_object(Config) db = SQLAlchemy(app) migrate = Migrate(app, db) SimpleLogin(app) from app.controller import Session # noqa: E402 g = Session() @app.route("/", methods=["GET"]) def home(): return render_template("index.j2", url_for=url_for) @app.route("/control", methods=["GET"]) def get_controls(): return render_template("controls.j2", courts=g.courts.all()) @app.route("/players", methods=["GET"]) def get_list_of_players(): return render_template( "players.j2", regulars=g.players.regulars(), guests=g.players.guests(), url_for=url_for, ) @app.route("/courts", methods=["GET"]) def get_list_of_courts(): return render_template("courts.j2", courts=g.courts.all()) def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): if not is_logged_in(): response = Response("User isn't logged in!") response.headers["HX-Redirect"] = url_for("simplelogin.login") return response return f(*args, **kwargs) return decorated_function @app.route("/propose", methods=["POST"]) @login_required def get_random_games(): g.levels = int(request.form["levels"].split()[0]) g.teams = request.form["team"] == "Teams" return render_template("games.j2", games=g.propose(), title="Proposal") @app.route("/confirm", methods=["POST"]) @login_required def confirm_games(): return render_template("games.j2", games=g.confirm(), title=f"Round: {g.round()}") @app.route("/clear", methods=["POST"]) def clear_games(): return render_template( "games.j2", games=g.current_round(), title=f"Round: {g.round()}" ) @app.route("/reset", methods=["POST"]) @login_required def reset_games(): return render_template("games.j2", games=g.reset(), title=f"Round: {g.round()}") @app.route("/player-toggle/", methods=["POST"]) @login_required def toggle_player(player_request): id = int(player_request) player = g.players.toggle(id) button = get_template_attribute("macros.j2", "player_button") return render_template_string("{{button(player)}}", player=player, button=button) @app.route("/reset_players", methods=["POST"]) @login_required def reset_all_players(): g.players.reset() return redirect(url_for("players")) @app.route("/update_players", methods=["POST"]) @login_required def update_all_players(): file = request.files.get("players") response = Response("File name or data has issues!", 400) response.headers["HX-Refresh"] = "true" if file is None: return response elif file.filename is None: return response file_name = secure_filename(file.filename) try: data = read_csv(file_name) required_columns = ["id", "first_name", "last_name", "level", "team"] if not all([item in data.columns for item in required_columns]): raise ImportError("All columns aren't available in the data.") except: # noqa: E722 return response g.players.update(data) return redirect(url_for("players")) @app.route("/court-toggle/", methods=["POST"]) @login_required def toggle_court(court_number): id = int(court_number) court = g.courts.toggle(id) button = get_template_attribute("macros.j2", "court_button") return render_template_string("{{button(court)}}", court=court, button=button)