Skip to content

Commit 4773710

Browse files
committed
Started classroom leaderboard implementation
1 parent 6f4b021 commit 4773710

2 files changed

Lines changed: 53 additions & 23 deletions

File tree

zeeguu/api/endpoints/leaderboards.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
import flask
55
from flask import request
66

7+
from zeeguu.core.leaderboards.leaderboards import cohort_leaderboard_user_ids_subquery
78
from zeeguu.api.utils.abort_handling import make_error
89
from zeeguu.api.utils.json_result import json_result
910
from zeeguu.api.utils.route_wrappers import cross_domain, requires_session
1011
from zeeguu.core.leaderboards.leaderboards import exercise_time_leaderboard, exercises_done_leaderboard, \
11-
read_articles_leaderboard, reading_time_leaderboard, listening_time_leaderboard
12+
read_articles_leaderboard, reading_time_leaderboard, listening_time_leaderboard, \
13+
friend_leaderboard_user_ids_subquery
1214
from . import api
1315

1416
LeaderboardMetric = Callable[[int, int, Optional[datetime], Optional[datetime]], list]
@@ -38,7 +40,36 @@ def friends_leaderboard():
3840
return make_error(400, "Invalid leaderboard metric")
3941

4042
rows = metric(
41-
flask.g.user_id,
43+
friend_leaderboard_user_ids_subquery(flask.g.user_id),
44+
params["limit"],
45+
params["from_date"],
46+
params["to_date"],
47+
)
48+
49+
result = [
50+
_serialize_leaderboard_row(row)
51+
for row in rows
52+
]
53+
54+
return json_result(result)
55+
56+
# ---------------------------------------------------------------------------
57+
@api.route("/cohort_leaderboard/<cohort_id>", methods=["GET"])
58+
# ---------------------------------------------------------------------------
59+
@cross_domain
60+
@requires_session
61+
def cohort_leaderboard(cohort_id: int):
62+
params, error_response = _parse_leaderboard_query_params()
63+
if error_response:
64+
return error_response
65+
66+
metric = LEADERBOARD_METRICS.get(request.args.get("metric"))
67+
68+
if not metric:
69+
return make_error(400, "Invalid leaderboard metric")
70+
71+
rows = metric(
72+
cohort_leaderboard_user_ids_subquery(cohort_id),
4273
params["limit"],
4374
params["from_date"],
4475
params["to_date"],

zeeguu/core/leaderboards/leaderboards.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88

99
def exercise_time_leaderboard(
10-
user_id: int,
10+
user_ids_subquery,
1111
limit: int = 20,
1212
from_date=None,
1313
to_date=None,
@@ -18,8 +18,6 @@ def exercise_time_leaderboard(
1818
"""
1919
from zeeguu.core.model.user_exercise_session import UserExerciseSession
2020

21-
related_user_ids = _friend_leaderboard_user_ids_subquery(user_id)
22-
2321
total_duration = func.coalesce(func.sum(UserExerciseSession.duration), 0)
2422

2523
joins = [
@@ -34,15 +32,15 @@ def exercise_time_leaderboard(
3432
]
3533

3634
return _leaderboard_base(
37-
related_user_ids,
35+
user_ids_subquery,
3836
total_duration,
3937
joins,
4038
limit,
4139
)
4240

4341

4442
def listening_time_leaderboard(
45-
user_id: int,
43+
user_ids_subquery,
4644
limit: int = 20,
4745
from_date=None,
4846
to_date=None,
@@ -53,8 +51,6 @@ def listening_time_leaderboard(
5351
"""
5452
from zeeguu.core.model.user_listening_session import UserListeningSession
5553

56-
related_user_ids = _friend_leaderboard_user_ids_subquery(user_id)
57-
5854
total_duration = func.coalesce(func.sum(UserListeningSession.duration), 0)
5955

6056
joins = [
@@ -69,15 +65,15 @@ def listening_time_leaderboard(
6965
]
7066

7167
return _leaderboard_base(
72-
related_user_ids,
68+
user_ids_subquery,
7369
total_duration,
7470
joins,
7571
limit,
7672
)
7773

7874

7975
def read_articles_leaderboard(
80-
user_id: int,
76+
user_ids_subquery,
8177
limit: int = 20,
8278
from_date=None,
8379
to_date=None,
@@ -88,8 +84,6 @@ def read_articles_leaderboard(
8884
"""
8985
from zeeguu.core.model.user_article import UserArticle
9086

91-
related_user_ids = _friend_leaderboard_user_ids_subquery(user_id)
92-
9387
completed_articles_count = func.count(UserArticle.id)
9488

9589
joins = [
@@ -105,15 +99,15 @@ def read_articles_leaderboard(
10599
]
106100

107101
return _leaderboard_base(
108-
related_user_ids,
102+
user_ids_subquery,
109103
completed_articles_count,
110104
joins,
111105
limit,
112106
)
113107

114108

115109
def reading_time_leaderboard(
116-
user_id: int,
110+
user_ids_subquery,
117111
limit: int = 20,
118112
from_date=None,
119113
to_date=None,
@@ -124,8 +118,6 @@ def reading_time_leaderboard(
124118
"""
125119
from zeeguu.core.model.user_reading_session import UserReadingSession
126120

127-
related_user_ids = _friend_leaderboard_user_ids_subquery(user_id)
128-
129121
total_duration = func.coalesce(func.sum(UserReadingSession.duration), 0)
130122

131123
joins = [
@@ -140,15 +132,15 @@ def reading_time_leaderboard(
140132
]
141133

142134
return _leaderboard_base(
143-
related_user_ids,
135+
user_ids_subquery,
144136
total_duration,
145137
joins,
146138
limit,
147139
)
148140

149141

150142
def exercises_done_leaderboard(
151-
user_id: int,
143+
user_ids_subquery,
152144
limit: int = 20,
153145
from_date=None,
154146
to_date=None,
@@ -167,8 +159,6 @@ def exercises_done_leaderboard(
167159
*ExerciseOutcome.correct_after_translation
168160
]
169161

170-
related_user_ids = _friend_leaderboard_user_ids_subquery(user_id)
171-
172162
exercises_done_count = func.coalesce(
173163
func.sum(
174164
case(
@@ -193,14 +183,14 @@ def exercises_done_leaderboard(
193183
]
194184

195185
return _leaderboard_base(
196-
related_user_ids,
186+
user_ids_subquery,
197187
exercises_done_count,
198188
joins,
199189
limit,
200190
)
201191

202192

203-
def _friend_leaderboard_user_ids_subquery(user_id: int):
193+
def friend_leaderboard_user_ids_subquery(user_id: int):
204194
# For each friendship row touching this user, select "the other user".
205195
return (
206196
db.session.query(
@@ -216,6 +206,15 @@ def _friend_leaderboard_user_ids_subquery(user_id: int):
216206
.subquery()
217207
)
218208

209+
def cohort_leaderboard_user_ids_subquery(cohort_id: int):
210+
from zeeguu.core.model.user_cohort_map import UserCohortMap
211+
212+
return (
213+
db.session.query(UserCohortMap.user_id.label("user_id"))
214+
.filter(UserCohortMap.cohort_id == cohort_id)
215+
.subquery()
216+
)
217+
219218

220219
def _leaderboard_base(
221220
user_ids_subquery,

0 commit comments

Comments
 (0)