aboutsummaryrefslogtreecommitdiffstats
path: root/pysite/views/staff/jams/actions.py
diff options
context:
space:
mode:
authorGravatar Gareth Coles <[email protected]>2018-06-17 21:31:00 +0000
committerGravatar Gareth Coles <[email protected]>2018-06-17 21:31:00 +0000
commitdc2a5013fb93141f50dc92b4b8cc4d6004b8e814 (patch)
tree07a3c381d9b58890c14049f8a23e8154b33e0003 /pysite/views/staff/jams/actions.py
parent[Wiki] Quick-fix for broken editor (diff)
Backend for team assignment
Diffstat (limited to 'pysite/views/staff/jams/actions.py')
-rw-r--r--pysite/views/staff/jams/actions.py229
1 files changed, 222 insertions, 7 deletions
diff --git a/pysite/views/staff/jams/actions.py b/pysite/views/staff/jams/actions.py
index 24b31ce9..3cacbb50 100644
--- a/pysite/views/staff/jams/actions.py
+++ b/pysite/views/staff/jams/actions.py
@@ -1,19 +1,22 @@
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 = [
+GET_ACTIONS = ("questions",)
+POST_ACTIONS = (
"associate_question", "disassociate_question", "infraction", "questions", "state", "approve_application",
- "unapprove_application"
-]
-DELETE_ACTIONS = ["infraction", "question"]
-KEYS = ["action"]
+ "unapprove_application", "create_team", "generate_teams", "set_team_member",
+ "reroll_team"
+)
+DELETE_ACTIONS = ("infraction", "question", "team")
-QUESTION_KEYS = ["optional", "title", "type"]
+KEYS = ("action",)
+QUESTION_KEYS = ("optional", "title", "type")
class ActionView(APIView, DBMixin, RMQMixin):
@@ -25,6 +28,8 @@ class ActionView(APIView, DBMixin, RMQMixin):
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)
@@ -192,6 +197,204 @@ class ActionView(APIView, DBMixin, RMQMixin):
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": []
+ }
+
+ 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)
+ .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 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 == "approve_application":
app = request.form.get("id")
@@ -324,3 +527,15 @@ class ActionView(APIView, DBMixin, RMQMixin):
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"
+ )
+
+ self.db.delete(self.teams_table, team)
+
+ return jsonify({"result": True})