diff options
| author | 2018-05-19 19:34:44 +0100 | |
|---|---|---|
| committer | 2018-05-19 19:34:44 +0100 | |
| commit | 44453da722f7be76b50e391ca96d0b71a2c49acd (patch) | |
| tree | 0ee508b63e0d1382ee68b30d91605988e9aaf80d /pysite | |
| parent | [Jams] Some amount of public display, but links not ready yet (diff) | |
[Jams] Signups code is more or less done, just a few things left
Diffstat (limited to '')
| -rw-r--r-- | pysite/mixins.py | 3 | ||||
| -rw-r--r-- | pysite/tables.py | 8 | ||||
| -rw-r--r-- | pysite/views/main/jams/join.py | 180 | ||||
| -rw-r--r-- | pysite/views/main/jams/signup.py | 9 | 
4 files changed, 187 insertions, 13 deletions
| diff --git a/pysite/mixins.py b/pysite/mixins.py index a3edc4f2..6e5032ab 100644 --- a/pysite/mixins.py +++ b/pysite/mixins.py @@ -4,6 +4,7 @@ from flask import Blueprint  from rethinkdb.ast import Table  from pysite.database import RethinkDB +from pysite.oauth import OauthBackend  class DBMixin: @@ -98,5 +99,5 @@ class OauthMixin:          return self.oauth.user_data()      @property -    def oauth(self): +    def oauth(self) -> OauthBackend:          return self._oauth() diff --git a/pysite/tables.py b/pysite/tables.py index c180e161..c68feba0 100644 --- a/pysite/tables.py +++ b/pysite/tables.py @@ -79,8 +79,9 @@ TABLES = {          primary_key="id",          keys=sorted([              "id",  # uuid +            "snowflake",  # str              "jam",  # int -            "answers",  # dict {question, answer, metadata} +            "answers",  # list [{question, answer, metadata}]              "approved"  # bool          ])      ), @@ -100,14 +101,15 @@ TABLES = {              "id",  # uuid              "participant",  # str              "reason",  # str -            "number"  # int (optionally -1 for permanent) +            "number",  # int (optionally -1 for permanent) +            "decremented_for"  # list[int]          ])      ),      "code_jam_participants": Table(  # Info for each participant          primary_key="id",          keys=sorted([ -            "snowflake",  # int +            "id",  # str              "skill_level",  # str              "age",  # str              "github_username",  # str diff --git a/pysite/views/main/jams/join.py b/pysite/views/main/jams/join.py new file mode 100644 index 00000000..87a2c4ca --- /dev/null +++ b/pysite/views/main/jams/join.py @@ -0,0 +1,180 @@ +from email.utils import parseaddr + +from flask import request, redirect, url_for +from werkzeug.exceptions import NotFound, BadRequest + +from pysite.base_route import RouteView +from pysite.decorators import csrf +from pysite.mixins import DBMixin, OauthMixin + + +class JamsJoinView(RouteView, DBMixin, OauthMixin): +    path = "/jams/join/<int:jam>" +    name = "jams.join" + +    table_name = "code_jams" +    forms_table = "code_jam_forms" +    questions_table = "code_jam_questions" +    responses_table = "code_jam_responses" +    participants_table = "code_jam_participants" +    infractions_table = "code_jam_infractions" + +    def get(self, jam): +        jam_obj = self.db.get(self.table_name, jam) + +        if not jam_obj: +            return NotFound() + +        if not self.user_data: +            return redirect(url_for("discord.login")) + +        if self.get_response(jam, self.user_data["user_id"]): +            return self.render("main/jams/already.html", jam=jam_obj) + +        infractions = self.get_infractions(self.user_data["user_id"]) + +        for infraction in infractions: +            if infraction["number"] == -1:  # Indefinite ban +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +            if infraction["number"]:  # Got some jams left +                if jam not in infraction["decremented_for"]: +                    # Make sure they haven't already tried to apply for this jam +                    infraction["number"] -= 1 +                    infraction["decremented_for"].append(jam) + +                    self.db.insert(self.infractions_table, infraction, conflict="replace") + +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +            if jam in infraction["decremented_for"]: +                # They already tried to apply for this jam +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +        form_obj = self.db.get(self.forms_table, jam) +        questions = [] + +        if form_obj: +            for question in form_obj["questions"]: +                questions.append(self.db.get(self.questions_table, question)) + +        return self.render( +            "main/jams/join.html", jam=jam_obj, form=form_obj, +            questions=questions, question_ids=[q["id"] for q in questions] +        ) + +    @csrf +    def post(self, jam): +        jam_obj = self.db.get(self.table_name, jam) + +        if not jam_obj: +            return NotFound() + +        if not self.user_data: +            return redirect(url_for("discord.login")) + +        if self.get_response(jam, self.user_data["user_id"]): +            return self.render("main/jams/already.html", jam=jam_obj) + +        infractions = self.get_infractions(self.user_data["user_id"]) + +        for infraction in infractions: +            if infraction["number"] == -1:  # Indefinite ban +                return self.render("main/jams/banned.html", infraction=infraction) + +            if infraction["number"]:  # Got some jams left +                if jam not in infraction["decremented_for"]: +                    # Make sure they haven't already tried to apply for this jam +                    infraction["number"] -= 1 +                    infraction["decremented_for"].append(jam) + +                    self.db.insert(self.infractions_table, infraction, conflict="replace") + +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +            if jam in infraction["decremented_for"]: +                # They already tried to apply for this jam +                return self.render("main/jams/banned.html", infraction=infraction, jam=jam_obj) + +        form_obj = self.db.get(self.forms_table, jam) + +        if not form_obj: +            return NotFound() + +        questions = [] + +        for question in form_obj["questions"]: +            questions.append(self.db.get(self.questions_table, question)) + +        answers = [] + +        for question in questions: +            value = request.form.get(question["id"]) +            answer = {"question": question["id"]} + +            if not question["optional"] and value is None: +                return BadRequest() + +            if question["type"] == "checkbox": +                if value == "on": +                    answer["value"] = True +                elif not question["optional"]: +                    return BadRequest() +                else: +                    answer["value"] = False + +            elif question["type"] == "email": +                if value: +                    address = parseaddr(value) + +                    if address == ("", ""): +                        return BadRequest() + +                answer["value"] = value + +            elif question["type"] in ["number", "range", "slider"]: +                if value is not None: +                    value = int(value) + +                    if value > int(question["data"]["max"]) or value < int(question["data"]["min"]): +                        return BadRequest() + +                answer["value"] = value + +            elif question["type"] == "radio": +                if value: +                    if value not in question["data"]["options"]: +                        return BadRequest() + +                answer["value"] = value + +            elif question["type"] in ["text", "textarea"]: +                answer["value"] = value + +            answers.append(answer) + +        user_id = self.user_data["user_id"] + +        response = { +            "snowflake": user_id, +            "jam": jam, +            "approved": False, +            "answers": answers +        } + +        print(response) +        self.db.insert(self.responses_table, response) +        return self.render("main/jams/thanks.html", jam=jam_obj) + +    def get_response(self, jam, user_id): +        query = self.db.query(self.responses_table).filter({"jam": jam, "snowflake": user_id}) +        result = self.db.run(query, coerce=list) +        print(result) + +        if result: +            return result[0] +        return None + +    def get_infractions(self, user_id): +        query = self.db.query(self.infractions_table).filter({"participant": user_id}) +        return self.db.run(query, coerce=list) diff --git a/pysite/views/main/jams/signup.py b/pysite/views/main/jams/signup.py deleted file mode 100644 index 632da6d6..00000000 --- a/pysite/views/main/jams/signup.py +++ /dev/null @@ -1,9 +0,0 @@ -from pysite.base_route import RouteView - - -class JamsSignupView(RouteView): -    path = "/jams/signup" -    name = "jams.signup" - -    def get(self): -        return self.render("main/jams/signup.html") | 
