aboutsummaryrefslogtreecommitdiffstats
path: root/pysite/views
diff options
context:
space:
mode:
Diffstat (limited to 'pysite/views')
-rw-r--r--pysite/views/api/bot/user.py86
-rw-r--r--pysite/views/main/auth/__init__.py0
-rw-r--r--pysite/views/main/auth/done.py18
-rw-r--r--pysite/views/main/jams/index.py2
-rw-r--r--pysite/views/main/jams/join.py8
-rw-r--r--pysite/views/main/jams/profile.py20
-rw-r--r--pysite/views/main/jams/retract.py83
-rw-r--r--pysite/views/main/logout.py5
-rw-r--r--pysite/views/staff/jams/actions.py1
-rw-r--r--pysite/views/staff/jams/edit_ending.py1
-rw-r--r--pysite/views/staff/jams/edit_info.py1
-rw-r--r--pysite/views/staff/jams/forms/questions_edit.py2
-rw-r--r--pysite/views/staff/render.py1
-rw-r--r--pysite/views/wiki/render.py1
14 files changed, 204 insertions, 25 deletions
diff --git a/pysite/views/api/bot/user.py b/pysite/views/api/bot/user.py
index a353ccfe..8c5d8f77 100644
--- a/pysite/views/api/bot/user.py
+++ b/pysite/views/api/bot/user.py
@@ -26,6 +26,8 @@ DELETE_SCHEMA = Schema([
}
])
+BANNABLE_STATES = ("preparing", "running")
+
class UserView(APIView, DBMixin):
path = "/bot/users"
@@ -33,6 +35,9 @@ class UserView(APIView, DBMixin):
table_name = "users"
oauth_table_name = "oauth_data"
participants_table = "code_jam_participants"
+ infractions_table = "code_jam_infractions"
+ jams_table = "code_jams"
+ responses_table = "code_jam_responses"
@api_key
@api_params(schema=SCHEMA, validation_type=ValidationTypes.json)
@@ -42,6 +47,8 @@ class UserView(APIView, DBMixin):
deletions = 0
oauth_deletions = 0
profile_deletions = 0
+ response_deletions = 0
+ bans = 0
user_ids = [user["user_id"] for user in data]
@@ -56,10 +63,42 @@ class UserView(APIView, DBMixin):
for item in all_oauth_data:
if item["snowflake"] not in user_ids:
- self.db.delete(self.oauth_table_name, item["id"], durability="soft")
- self.db.delete(self.participants_table, item["id"], durability="soft")
- oauth_deletions += 1
- profile_deletions += 1
+ user_id = item["snowflake"]
+
+ oauth_deletions += self.db.delete(
+ self.oauth_table_name, item["id"], durability="soft", return_changes=True
+ ).get("deleted", 0)
+ profile_deletions += self.db.delete(
+ self.participants_table, user_id, durability="soft", return_changes=True
+ ).get("deleted", 0)
+
+ banned = False
+ responses = self.db.run(
+ self.db.query(self.responses_table).filter({"snowflake": user_id}),
+ coerce=list
+ )
+
+ for response in responses:
+ jam = response["jam"]
+ jam_obj = self.db.get(self.jams_table, jam)
+
+ if jam_obj:
+ if jam_obj["state"] in BANNABLE_STATES:
+ banned = True
+
+ self.db.delete(self.responses_table, response["id"], durability="soft")
+ response_deletions += 1
+
+ if banned:
+ self.db.insert(
+ self.infractions_table, {
+ "participant": user_id,
+ "reason": "Automatic ban: Removed jammer profile in the middle of a code jam",
+ "number": -1,
+ "decremented_for": []
+ }, durability="soft"
+ )
+ bans += 1
del user_ids
@@ -69,11 +108,17 @@ class UserView(APIView, DBMixin):
durability="soft"
)
+ self.db.sync(self.infractions_table)
+ self.db.sync(self.oauth_table_name)
+ self.db.sync(self.participants_table)
+ self.db.sync(self.responses_table)
self.db.sync(self.table_name)
changes["deleted"] = deletions
changes["deleted_oauth"] = oauth_deletions
changes["deleted_jam_profiles"] = profile_deletions
+ changes["deleted_responses"] = response_deletions
+ changes["jam_bans"] = bans
return jsonify(changes) # pragma: no cover
@@ -108,9 +153,40 @@ class UserView(APIView, DBMixin):
self.db.query(self.participants_table)
.get_all(*user_ids)
.delete()
- )
+ ).get("deleted", 0)
+
+ bans = 0
+ response_deletions = 0
+
+ for user_id in user_ids:
+ banned = False
+ responses = self.db.run(self.db.query(self.responses_table).filter({"snowflake": user_id}), coerce=list)
+
+ for response in responses:
+ jam = response["jam"]
+ jam_obj = self.db.get(self.jams_table, jam)
+
+ if jam_obj:
+ if jam_obj["state"] in BANNABLE_STATES:
+ banned = True
+
+ self.db.delete(self.responses_table, response["id"])
+ response_deletions += 1
+
+ if banned:
+ self.db.insert(
+ self.infractions_table, {
+ "participant": user_id,
+ "reason": "Automatic ban: Removed jammer profile in the middle of a code jam",
+ "number": -1,
+ "decremented_for": []
+ }
+ )
+ bans += 1
changes["deleted_oauth"] = oauth_deletions
changes["deleted_jam_profiles"] = profile_deletions
+ changes["deleted_responses"] = response_deletions
+ changes["jam_bans"] = bans
return jsonify(changes) # pragma: no cover
diff --git a/pysite/views/main/auth/__init__.py b/pysite/views/main/auth/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/pysite/views/main/auth/__init__.py
diff --git a/pysite/views/main/auth/done.py b/pysite/views/main/auth/done.py
new file mode 100644
index 00000000..6e892906
--- /dev/null
+++ b/pysite/views/main/auth/done.py
@@ -0,0 +1,18 @@
+from flask import redirect, session, url_for
+
+from pysite.base_route import RouteView
+
+
+class AuthDoneView(RouteView):
+ path = "/auth/done"
+ name = "auth.done"
+
+ def get(self):
+ if self.logged_in:
+ target = session.get("redirect_target")
+
+ if target:
+ del session["redirect_target"]
+ return redirect(url_for(target["url"], **target.get("kwargs", {})))
+
+ return redirect(url_for("main.index"))
diff --git a/pysite/views/main/jams/index.py b/pysite/views/main/jams/index.py
index 6d066117..8d34fa50 100644
--- a/pysite/views/main/jams/index.py
+++ b/pysite/views/main/jams/index.py
@@ -16,6 +16,6 @@ class JamsIndexView(RouteView, DBMixin):
.order_by(rethinkdb.desc("number"))
.limit(5)
)
+
jams = self.db.run(query, coerce=list)
- print(jams)
return self.render("main/jams/index.html", jams=jams)
diff --git a/pysite/views/main/jams/join.py b/pysite/views/main/jams/join.py
index 24931f72..c4011170 100644
--- a/pysite/views/main/jams/join.py
+++ b/pysite/views/main/jams/join.py
@@ -5,10 +5,10 @@ from werkzeug.exceptions import BadRequest, NotFound
from pysite.base_route import RouteView
from pysite.decorators import csrf
-from pysite.mixins import DBMixin, OauthMixin
+from pysite.mixins import DBMixin, OAuthMixin
-class JamsJoinView(RouteView, DBMixin, OauthMixin):
+class JamsJoinView(RouteView, DBMixin, OAuthMixin):
path = "/jams/join/<int:jam>"
name = "jams.join"
@@ -26,7 +26,7 @@ class JamsJoinView(RouteView, DBMixin, OauthMixin):
return NotFound()
if not self.user_data:
- return redirect(url_for("discord.login"))
+ return self.redirect_login(jam=jam)
infractions = self.get_infractions(self.user_data["user_id"])
@@ -76,7 +76,7 @@ class JamsJoinView(RouteView, DBMixin, OauthMixin):
return NotFound()
if not self.user_data:
- return redirect(url_for("discord.login"))
+ return self.redirect_login(jam=jam)
infractions = self.get_infractions(self.user_data["user_id"])
diff --git a/pysite/views/main/jams/profile.py b/pysite/views/main/jams/profile.py
index ce8dfdf1..d8a663f7 100644
--- a/pysite/views/main/jams/profile.py
+++ b/pysite/views/main/jams/profile.py
@@ -5,10 +5,10 @@ from werkzeug.exceptions import BadRequest
from pysite.base_route import RouteView
from pysite.decorators import csrf
-from pysite.mixins import DBMixin, OauthMixin
+from pysite.mixins import DBMixin, OAuthMixin
-class JamsProfileView(RouteView, DBMixin, OauthMixin):
+class JamsProfileView(RouteView, DBMixin, OAuthMixin):
path = "/jams/profile"
name = "jams.profile"
@@ -16,12 +16,14 @@ class JamsProfileView(RouteView, DBMixin, OauthMixin):
def get(self):
if not self.user_data:
- return redirect(url_for("discord.login"))
+ return self.redirect_login()
participant = self.db.get(self.table_name, self.user_data["user_id"])
+ existing = True
if not participant:
participant = {"id": self.user_data["user_id"]}
+ existing = False
form = request.args.get("form")
@@ -32,13 +34,13 @@ class JamsProfileView(RouteView, DBMixin, OauthMixin):
pass # Someone trying to have some fun I guess
return self.render(
- "main/jams/profile.html", participant=participant, form=form
+ "main/jams/profile.html", participant=participant, form=form, existing=existing
)
@csrf
def post(self):
if not self.user_data:
- return redirect(url_for("discord.login"))
+ return self.redirect_login()
participant = self.db.get(self.table_name, self.user_data["user_id"])
@@ -56,6 +58,12 @@ class JamsProfileView(RouteView, DBMixin, OauthMixin):
dob = datetime.datetime.strptime(dob, "%Y-%m-%d")
dob = dob.replace(tzinfo=datetime.timezone.utc)
+ now = datetime.datetime.now(tz=datetime.timezone.utc)
+ then = now.replace(year=now.year - 13)
+
+ if then < dob:
+ raise BadRequest() # They're too young, but this is validated on the form
+
participant["dob"] = dob
participant["github_username"] = github_username
participant["timezone"] = timezone
@@ -73,5 +81,5 @@ class JamsProfileView(RouteView, DBMixin, OauthMixin):
return redirect(url_for("main.jams.join", jam=form))
return self.render(
- "main/jams/profile.html", participant=participant, done=True
+ "main/jams/profile.html", participant=participant, done=True, existing=True
)
diff --git a/pysite/views/main/jams/retract.py b/pysite/views/main/jams/retract.py
new file mode 100644
index 00000000..277426b5
--- /dev/null
+++ b/pysite/views/main/jams/retract.py
@@ -0,0 +1,83 @@
+from werkzeug.exceptions import BadRequest
+
+from pysite.base_route import RouteView
+from pysite.decorators import csrf
+from pysite.mixins import DBMixin, OAuthMixin
+
+BANNABLE_STATES = ("preparing", "running")
+
+
+class JamsProfileView(RouteView, DBMixin, OAuthMixin):
+ path = "/jams/retract"
+ name = "jams.retract"
+
+ table_name = "code_jam_participants"
+ infractions_table = "code_jam_infractions"
+ jams_table = "code_jams"
+ responses_table = "code_jam_responses"
+
+ def get(self):
+ if not self.user_data:
+ return self.redirect_login()
+
+ user_id = self.user_data["user_id"]
+ participant = self.db.get(self.table_name, user_id)
+
+ banned = False
+
+ if participant:
+ responses = self.db.run(self.db.query(self.responses_table).filter({"snowflake": user_id}), coerce=list)
+
+ for response in responses:
+ jam = response["jam"]
+ jam_obj = self.db.get(self.jams_table, jam)
+
+ if jam_obj:
+ if jam_obj["state"] in BANNABLE_STATES:
+ banned = True
+ break
+
+ return self.render(
+ "main/jams/retract.html", participant=participant, banned=banned
+ )
+
+ @csrf
+ def post(self):
+ if not self.user_data:
+ return self.redirect_login()
+
+ user_id = self.user_data["user_id"]
+ participant = self.db.get(self.table_name, user_id)
+
+ if not participant:
+ return BadRequest()
+
+ banned = False
+
+ responses = self.db.run(self.db.query(self.responses_table).filter({"snowflake": user_id}), coerce=list)
+
+ for response in responses:
+ jam = response["jam"]
+ jam_obj = self.db.get(self.jams_table, jam)
+
+ if jam_obj:
+ if jam_obj["state"] in BANNABLE_STATES:
+ banned = True
+
+ self.db.delete(self.responses_table, response["id"])
+
+ self.db.delete(self.table_name, participant["id"])
+
+ if banned:
+ self.db.insert(
+ self.infractions_table, {
+ "participant": user_id,
+ "reason": "Automatic ban: Removed jammer profile in the middle of a code jam",
+ "number": -1,
+ "decremented_for": []
+ }
+ )
+
+ return self.render(
+ "main/jams/retracted.html", participant=participant, banned=banned
+ )
diff --git a/pysite/views/main/logout.py b/pysite/views/main/logout.py
index 2461450d..64326371 100644
--- a/pysite/views/main/logout.py
+++ b/pysite/views/main/logout.py
@@ -1,4 +1,4 @@
-from flask import redirect, session
+from flask import redirect, session, url_for
from pysite.base_route import RouteView
@@ -12,4 +12,5 @@ class LogoutView(RouteView):
# remove user's session
del session["session_id"]
self.oauth.logout()
- return redirect("/")
+
+ return redirect(url_for("main.index"))
diff --git a/pysite/views/staff/jams/actions.py b/pysite/views/staff/jams/actions.py
index 1af215a5..059f8969 100644
--- a/pysite/views/staff/jams/actions.py
+++ b/pysite/views/staff/jams/actions.py
@@ -33,7 +33,6 @@ class ActionView(APIView, DBMixin):
if action == "questions":
questions = self.db.get_all(self.questions_table)
- print(questions)
return jsonify({"questions": questions})
@csrf
diff --git a/pysite/views/staff/jams/edit_ending.py b/pysite/views/staff/jams/edit_ending.py
index c4dcfcb3..43a36ebc 100644
--- a/pysite/views/staff/jams/edit_ending.py
+++ b/pysite/views/staff/jams/edit_ending.py
@@ -39,7 +39,6 @@ class StaffView(RouteView, DBMixin):
if not jam_obj["state"] in ALLOWED_STATES:
return BadRequest()
- print(request.form)
for key in REQUIRED_KEYS:
arg = request.form.get(key)
diff --git a/pysite/views/staff/jams/edit_info.py b/pysite/views/staff/jams/edit_info.py
index 7d4401f0..ad0d3d41 100644
--- a/pysite/views/staff/jams/edit_info.py
+++ b/pysite/views/staff/jams/edit_info.py
@@ -39,7 +39,6 @@ class StaffView(RouteView, DBMixin):
if not jam_obj["state"] in ALLOWED_STATES:
return BadRequest()
- print(request.form)
for key in REQUIRED_KEYS:
arg = request.form.get(key)
diff --git a/pysite/views/staff/jams/forms/questions_edit.py b/pysite/views/staff/jams/forms/questions_edit.py
index 4de06793..d46c4ef3 100644
--- a/pysite/views/staff/jams/forms/questions_edit.py
+++ b/pysite/views/staff/jams/forms/questions_edit.py
@@ -42,8 +42,6 @@ class StaffView(RouteView, DBMixin):
optional = request.form.get("optional")
question_type = request.form.get("type")
- print(question_type)
-
if not title or not optional or not question_type:
return BadRequest()
diff --git a/pysite/views/staff/render.py b/pysite/views/staff/render.py
index 00c9a9f3..0152e568 100644
--- a/pysite/views/staff/render.py
+++ b/pysite/views/staff/render.py
@@ -57,7 +57,6 @@ class RenderView(APIView):
}
)
- print(data)
return jsonify(data)
except Exception as e:
return jsonify({"error": str(e)})
diff --git a/pysite/views/wiki/render.py b/pysite/views/wiki/render.py
index b08f54dd..40e5d3f4 100644
--- a/pysite/views/wiki/render.py
+++ b/pysite/views/wiki/render.py
@@ -57,7 +57,6 @@ class RenderView(APIView):
}
)
- print(data)
return jsonify(data)
except Exception as e:
return jsonify({"error": str(e)})