aboutsummaryrefslogtreecommitdiffstats
path: root/pysite/views/staff/jams/teams/view.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/teams/view.py
parent[Wiki] Quick-fix for broken editor (diff)
Backend for team assignment
Diffstat (limited to 'pysite/views/staff/jams/teams/view.py')
-rw-r--r--pysite/views/staff/jams/teams/view.py106
1 files changed, 106 insertions, 0 deletions
diff --git a/pysite/views/staff/jams/teams/view.py b/pysite/views/staff/jams/teams/view.py
new file mode 100644
index 00000000..c68da63e
--- /dev/null
+++ b/pysite/views/staff/jams/teams/view.py
@@ -0,0 +1,106 @@
+from rethinkdb import ReqlNonExistenceError
+from werkzeug.exceptions import NotFound
+
+from pysite.base_route import RouteView
+from pysite.constants import ALL_STAFF_ROLES
+from pysite.decorators import require_roles
+from pysite.mixins import DBMixin
+
+REQUIRED_KEYS = ("title", "date_start", "date_end")
+
+
+class StaffView(RouteView, DBMixin):
+ path = "/jams/teams/<int:jam>"
+ name = "jams.teams"
+
+ table_name = "code_jam_teams"
+
+ forms_table = "code_jam_forms"
+ jams_table = "code_jams"
+ participants_table = "code_jam_participants"
+ questions_table = "code_jam_questions"
+ responses_table = "code_jam_responses"
+ users_table = "users"
+
+ @require_roles(*ALL_STAFF_ROLES)
+ def get(self, jam: int):
+ try:
+ query = self.db.query(self.jams_table).get(jam).merge(
+ # Merge the jam document with a custom document defined below
+ lambda jam_obj: { # The lambda lets us manipulate the jam document server-side
+ "participants":
+ # Query the responses table
+ self.db.query(self.responses_table)
+ # Filter: approved responses for this jam only # noqa: E131
+ .filter({"jam": jam_obj["number"], "approved": True})
+ # Join each response document with documents from the user table that match the user that
+ # created this response - this is the efficient way to do things, inner/outer joins
+ # are slower as they only support explicit predicates
+ .eq_join("snowflake", self.db.query(self.users_table))
+ # Remove the user ID from the left side (the response document)
+ .without({"left": ["snowflake"]})
+ .zip() # Combine the left and right documents together
+ .order_by("username") # Reorder the documents by username
+ .coerce_to("array"), # Coerce the document stream into an array
+ "profiles":
+ # Query the responses table (again)
+ # We do this because RethinkDB just returns empty lists if you join on another join
+ self.db.query(self.responses_table)
+ # Filter: approved responses for this jam only # noqa: E131
+ .filter({"jam": jam_obj["number"], "approved": True})
+ # Join each response document with documents from the participant profiles table
+ # this time
+ .eq_join("snowflake", self.db.query(self.participants_table))
+ # Remove the user ID and answers from the left side (the response document)
+ .without({"left": ["snowflake", "answers"]})
+ .zip() # Combine the left and right documents together
+ .order_by("username") # Reorder the documents by username
+ .coerce_to("array"), # Coerce the document stream into an array
+ "form": self.db.query(self.forms_table).get(jam), # Just get the correct form object
+ "teams":
+ # Query the teams table
+ self.db.query(self.table_name)
+ # Join the teams table against the jams table, to find all of the teams for this
+ # specific jam - we can't simply filter because of the one-to-many relationship,
+ # so we must use an inner join with a predicate function. This function is still
+ # run on the server, however
+ .inner_join(self.db.query(self.jams_table),
+ lambda team_row, jams_row: jams_row["teams"].contains(team_row["id"]))
+ # Only take the ID, name and members of each team, discard everything else
+ .pluck({"left": ["id", "name", "members"]})
+ .zip() # Combine the left and right documents together
+ .coerce_to("array") # Coerce the document stream into an array
+ }
+ )
+
+ jam_data = self.db.run(query)
+ except ReqlNonExistenceError:
+ raise NotFound()
+
+ questions = {}
+
+ for question in jam_data["form"]["questions"]:
+ questions[question] = self.db.get(self.questions_table, question)
+
+ teams = {}
+ participants = {}
+ assigned = []
+
+ for team in jam_data["teams"]:
+ teams[team["id"]] = team
+
+ for member in team["members"]:
+ assigned.append(member)
+
+ for user in jam_data["participants"]:
+ participants[user["user_id"]] = user
+
+ for profile in jam_data["profiles"]:
+ participants[profile["id"]]["profile"] = profile
+
+ return self.render(
+ "staff/jams/teams/view.html",
+ jam=jam_data, teams=teams,
+ participants=participants, assigned=assigned,
+ questions=questions
+ )