diff options
Diffstat (limited to 'pysite/views/staff/jams/actions.py')
-rw-r--r-- | pysite/views/staff/jams/actions.py | 597 |
1 files changed, 0 insertions, 597 deletions
diff --git a/pysite/views/staff/jams/actions.py b/pysite/views/staff/jams/actions.py deleted file mode 100644 index dfcbf2de..00000000 --- a/pysite/views/staff/jams/actions.py +++ /dev/null @@ -1,597 +0,0 @@ -from flask import jsonify, request -from rethinkdb import ReqlNonExistenceError - -from pysite.base_route import APIView -from pysite.constants import ALL_STAFF_ROLES, BotEventTypes, CHANNEL_JAM_LOGS, ErrorCodes, JAMMERS_ROLE -from pysite.decorators import csrf, require_roles -from pysite.mixins import DBMixin, RMQMixin -from pysite.utils.words import get_word_pairs - -GET_ACTIONS = ("questions",) -POST_ACTIONS = ( - "associate_question", "disassociate_question", "infraction", "questions", "state", "approve_application", - "unapprove_application", "create_team", "generate_teams", "set_team_member", - "reroll_team", "set_winning_team", "unset_winning_team" -) -DELETE_ACTIONS = ("infraction", "question", "team") - -KEYS = ("action",) -QUESTION_KEYS = ("optional", "title", "type") - - -class ActionView(APIView, DBMixin, RMQMixin): - path = "/jams/action" - name = "jams.action" - - table_name = "code_jams" - forms_table = "code_jam_forms" - infractions_table = "code_jam_infractions" - questions_table = "code_jam_questions" - responses_table = "code_jam_responses" - teams_table = "code_jam_teams" - users_table = "users" - - @csrf - @require_roles(*ALL_STAFF_ROLES) - def get(self): - action = request.args.get("action") - - if action not in GET_ACTIONS: - return self.error(ErrorCodes.incorrect_parameters) - - if action == "questions": - questions = self.db.get_all(self.questions_table) - - return jsonify({"questions": questions}) - - @csrf - @require_roles(*ALL_STAFF_ROLES) - def post(self): - if request.is_json: - data = request.get_json(force=True) - action = data["action"] if "action" in data else None - else: - action = request.form.get("action") - - if action not in POST_ACTIONS: - return self.error(ErrorCodes.incorrect_parameters) - - if action == "associate_question": - form = int(request.form.get("form")) - question = request.form.get("question") - - form_obj = self.db.get(self.forms_table, form) - - if not form_obj: - return self.error(ErrorCodes.incorrect_parameters, f"Unknown form: {form}") - - question_obj = self.db.get(self.questions_table, question) - - if not question_obj: - return self.error(ErrorCodes.incorrect_parameters, f"Unknown question: {question}") - - if question_obj["id"] not in form_obj["questions"]: - form_obj["questions"].append(question_obj["id"]) - self.db.insert(self.forms_table, form_obj, conflict="replace") - - return jsonify({"question": question_obj}) - else: - return self.error( - ErrorCodes.incorrect_parameters, - f"Question {question} already associated with form {form}" - ) - - if action == "disassociate_question": - form = int(request.form.get("form")) - question = request.form.get("question") - - form_obj = self.db.get(self.forms_table, form) - - if not form_obj: - return self.error(ErrorCodes.incorrect_parameters, f"Unknown form: {form}") - - question_obj = self.db.get(self.questions_table, question) - - if not question_obj: - return self.error(ErrorCodes.incorrect_parameters, f"Unknown question: {question}") - - if question_obj["id"] in form_obj["questions"]: - form_obj["questions"].remove(question_obj["id"]) - self.db.insert(self.forms_table, form_obj, conflict="replace") - - return jsonify({"question": question_obj}) - else: - return self.error( - ErrorCodes.incorrect_parameters, - f"Question {question} not already associated with form {form}" - ) - - if action == "state": - jam = int(request.form.get("jam")) - state = request.form.get("state") - - if not all((jam, state)): - return self.error(ErrorCodes.incorrect_parameters) - - jam_obj = self.db.get(self.table_name, jam) - jam_obj["state"] = state - self.db.insert(self.table_name, jam_obj, conflict="update") - - return jsonify({}) - - if action == "questions": - data = request.get_json(force=True) - - for key in QUESTION_KEYS: - if key not in data: - return self.error(ErrorCodes.incorrect_parameters, f"Missing key: {key}") - - title = data["title"] - optional = data["optional"] - question_type = data["type"] - question_data = data.get("data", {}) - - if question_type in ["number", "range", "slider"]: - if "max" not in question_data or "min" not in question_data: - return self.error( - ErrorCodes.incorrect_parameters, f"{question_type} questions must have both max and min values" - ) - - result = self.db.insert( - self.questions_table, - { - "title": title, - "optional": optional, - "type": question_type, - "data": { - "max": question_data["max"], - "min": question_data["min"] - } - }, - conflict="error" - ) - elif question_type == "radio": - if "options" not in question_data: - return self.error( - ErrorCodes.incorrect_parameters, f"{question_type} questions must have both options" - ) - - result = self.db.insert( - self.questions_table, - { - "title": title, - "optional": optional, - "type": question_type, - "data": { - "options": question_data["options"] - } - }, - conflict="error" - ) - else: - result = self.db.insert( - self.questions_table, - { # No extra data for other types of question - "title": title, - "optional": optional, - "type": question_type - }, - conflict="error" - ) - - return jsonify({"id": result["generated_keys"][0]}) - - if action == "infraction": - participant = request.form.get("participant") - reason = request.form.get("reason") - - if not participant or not reason or "number" not in request.form: - return self.error( - ErrorCodes.incorrect_parameters, "Infractions must have a participant, reason and number" - ) - - number = int(request.form.get("number")) - - result = self.db.insert(self.infractions_table, { - "participant": participant, - "reason": reason, - "number": number, - "decremented_for": [] - }) - - return jsonify({"id": result["generated_keys"][0]}) - - if action == "create_team": - jam = request.form.get("jam", type=int) - - if not jam: - return self.error( - ErrorCodes.incorrect_parameters, "Jam number required" - ) - - jam_data = self.db.get(self.table_name, jam) - - if not jam_data: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown jam number" - ) - - word_pairs = get_word_pairs() - adjective, noun = list(word_pairs)[0] - - team = { - "name": f"{adjective} {noun}".title(), - "members": [], - "jam": jam - } - - result = self.db.insert(self.teams_table, team) - team["id"] = result["generated_keys"][0] - - jam_obj = self.db.get(self.table_name, jam) - jam_obj["teams"].append(team["id"]) - - self.db.insert(self.table_name, jam_obj, conflict="replace") - - return jsonify({"team": team}) - - if action == "generate_teams": - jam = request.form.get("jam", type=int) - - if not jam: - return self.error( - ErrorCodes.incorrect_parameters, "Jam number required" - ) - - try: - query = self.db.query(self.table_name).get(jam).merge( - lambda jam_obj: { - "participants": - self.db.query(self.responses_table) - .filter({"jam": jam_obj["number"], "approved": True}) - .eq_join("snowflake", self.db.query(self.users_table)) - .without({"left": ["snowflake", "answers"]}) - .zip() - .order_by("username") - .coerce_to("array"), - "teams": - self.db.query(self.teams_table) - .outer_join(self.db.query(self.table_name), - lambda team_row, jams_row: jams_row["teams"].contains(team_row["id"])) - .pluck({"left": ["id", "name", "members"]}) - .zip() - .coerce_to("array") - } - ) - - jam_data = self.db.run(query) - except ReqlNonExistenceError: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown jam number" - ) - - if jam_data["teams"]: - return self.error( - ErrorCodes.incorrect_parameters, "Jam already has teams" - ) - - num_participants = len(jam_data["participants"]) - num_teams = num_participants // 3 - - if num_participants % 3: - num_teams += 1 - - word_pairs = get_word_pairs(num_teams) - teams = [] - - for adjective, noun in word_pairs: - team = { - "name": f"{adjective} {noun}".title(), - "members": [] - } - - result = self.db.insert(self.teams_table, team, durability="soft") - team["id"] = result["generated_keys"][0] - teams.append(team) - - self.db.sync(self.teams_table) - - jam_obj = self.db.get(self.table_name, jam) - jam_obj["teams"] = [team["id"] for team in teams] - - self.db.insert(self.table_name, jam_obj, conflict="replace") - - return jsonify({"teams": teams}) - - if action == "set_team_member": - jam = request.form.get("jam", type=int) - member = request.form.get("member") - team = request.form.get("team") - - if not jam: - return self.error( - ErrorCodes.incorrect_parameters, "Jam number required" - ) - - if not member: - return self.error( - ErrorCodes.incorrect_parameters, "Member ID required" - ) - - if not team: - return self.error( - ErrorCodes.incorrect_parameters, "Team ID required" - ) - - try: - query = self.db.query(self.table_name).get(jam).merge( - lambda jam_obj: { - "participants": - self.db.query(self.responses_table) - .filter({"jam": jam_obj["number"], "approved": True}) - .eq_join("snowflake", self.db.query(self.users_table)) - .without({"left": ["snowflake", "answers"]}) - .zip() - .order_by("username") - .coerce_to("array"), - "teams": - self.db.query(self.teams_table) - .filter(lambda team_row: jam_obj["teams"].contains(team_row["id"])) - .pluck(["id", "name", "members", "jam"]) - .coerce_to("array") - } - ) - - jam_data = self.db.run(query) - except ReqlNonExistenceError: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown jam number" - ) - - if not jam_data["teams"]: - return self.error( - ErrorCodes.incorrect_parameters, "Jam has no teams" - ) - - team_obj = self.db.get(self.teams_table, team) - - if not team_obj: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown team ID" - ) - - for jam_team_obj in jam_data["teams"]: - if jam_team_obj["id"] == team: - if member not in jam_team_obj["members"]: - jam_team_obj["members"].append(member) - - self.db.insert(self.teams_table, jam_team_obj, conflict="replace") - else: - if member in jam_team_obj["members"]: - jam_team_obj["members"].remove(member) - - self.db.insert(self.teams_table, jam_team_obj, conflict="replace") - - return jsonify({"result": True}) - - if action == "reroll_team": - team = request.form.get("team") - - if not team: - return self.error( - ErrorCodes.incorrect_parameters, "Team ID required" - ) - - team_obj = self.db.get(self.teams_table, team) - - if not team_obj: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown team ID" - ) - - word_pairs = get_word_pairs() - adjective, noun = list(word_pairs)[0] - - team_obj["name"] = f"{adjective} {noun}".title() - - self.db.insert(self.teams_table, team_obj, conflict="replace") - - return jsonify({"name": team_obj["name"]}) - - if action == "set_winning_team": - team = request.form.get("team") - - if not team: - return self.error( - ErrorCodes.incorrect_parameters, "Team ID required" - ) - - team_obj = self.db.get(self.teams_table, team) - - if not team_obj: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown team ID" - ) - - jam_number = team_obj["jam"] - jam_obj = self.db.get(self.table_name, jam_number) - jam_obj["winning_team"] = team - self.db.insert(self.table_name, jam_obj, conflict="replace") - - return jsonify({"result": "success"}) - - if action == "unset_winning_team": - jam = request.form.get("jam", type=int) - - if not jam: - return self.error( - ErrorCodes.incorrect_parameters, "Jam number required" - ) - - jam_obj = self.db.get(self.table_name, jam) - if not jam_obj: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown jam number" - ) - - jam_obj["winning_team"] = None - self.db.insert(self.table_name, jam_obj, conflict="replace") - - return jsonify({"result": "success"}) - - if action == "approve_application": - app = request.form.get("id") - - if not app: - return self.error( - ErrorCodes.incorrect_parameters, "Application ID required" - ) - - app_obj = self.db.get(self.responses_table, app) - - if not app_obj: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown application ID" - ) - - app_obj["approved"] = True - - self.db.insert(self.responses_table, app_obj, conflict="replace") - - jam_obj = self.db.get(self.table_name, app_obj["jam"]) - - snowflake = app_obj["snowflake"] - participants = jam_obj.get("participants", []) - - if snowflake not in participants: - participants.append(snowflake) - jam_obj["participants"] = participants - self.db.insert(self.table_name, jam_obj, conflict="replace") - - self.rmq_bot_event( - BotEventTypes.add_role, - { - "reason": "Code jam application approved", - "role_id": JAMMERS_ROLE, - "target": snowflake, - } - ) - - self.rmq_bot_event( - BotEventTypes.send_message, - { - "message": f"Congratulations <@{snowflake}> - you've been approved, " - f"and we've assigned you the Jammer role!", - "target": CHANNEL_JAM_LOGS, - } - ) - - return jsonify({"result": "success"}) - - if action == "unapprove_application": - app = request.form.get("id") - - if not app: - return self.error( - ErrorCodes.incorrect_parameters, "Application ID required" - ) - - app_obj = self.db.get(self.responses_table, app) - - if not app_obj: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown application ID" - ) - - app_obj["approved"] = False - - self.db.insert(self.responses_table, app_obj, conflict="replace") - - jam_obj = self.db.get(self.table_name, app_obj["jam"]) - - snowflake = app_obj["snowflake"] - participants = jam_obj.get("participants", []) - - if snowflake in participants: - participants.remove(snowflake) - jam_obj["participants"] = participants - - self.db.insert(self.table_name, jam_obj, conflict="replace") - - self.rmq_bot_event( - BotEventTypes.remove_role, - { - "reason": "Code jam application unapproved", - "role_id": JAMMERS_ROLE, - "target": snowflake, - } - ) - - return jsonify({"result": "success"}) - - @csrf - @require_roles(*ALL_STAFF_ROLES) - def delete(self): - action = request.form.get("action") - - if action not in DELETE_ACTIONS: - return self.error(ErrorCodes.incorrect_parameters) - - if action == "question": - question = request.form.get("id") - - if not question: - return self.error(ErrorCodes.incorrect_parameters, f"Missing key: id") - - question_obj = self.db.get(self.questions_table, question) - - if not question_obj: - return self.error(ErrorCodes.incorrect_parameters, f"Unknown question: {question}") - - self.db.delete(self.questions_table, question) - - for form_obj in self.db.get_all(self.forms_table): - if question in form_obj["questions"]: - form_obj["questions"].remove(question) - self.db.insert(self.forms_table, form_obj, conflict="replace") - - return jsonify({"id": question}) - - if action == "infraction": - infraction = request.form.get("id") - - if not infraction: - return self.error(ErrorCodes.incorrect_parameters, "Missing key id") - - infraction_obj = self.db.get(self.infractions_table, infraction) - - if not infraction_obj: - return self.error(ErrorCodes.incorrect_parameters, f"Unknown infraction: {infraction}") - - self.db.delete(self.infractions_table, infraction) - - return jsonify({"id": infraction_obj["id"]}) - - if action == "team": - team = request.form.get("team") - - if not team: - return self.error( - ErrorCodes.incorrect_parameters, "Team ID required" - ) - - team_obj = self.db.get(self.teams_table, team) - - if not team_obj: - return self.error( - ErrorCodes.incorrect_parameters, "Unknown team ID" - ) - - jam_obj = self.db.get(self.table_name, team_obj["jam"]) - if jam_obj: - jam_obj["teams"].remove(team) - self.db.insert(self.table_name, jam_obj, conflict="update") - - self.db.delete(self.teams_table, team) - - return jsonify({"result": True}) |