From 63d344c2d0165e78c2989913c50095c2153738bc Mon Sep 17 00:00:00 2001 From: TLSM <104547575+TLSM@users.noreply.github.com> Date: Mon, 2 May 2022 14:14:06 -0400 Subject: [PATCH] Add badge quantity and rarity to /badges. (#238) Implements feature request to know how many of each badge exists and to have a 'rarity', a la Steam or PSN badges, relative to number of non-lurker users. Because Postgres `COUNT()`s are notoriously costly, /badges has been memoized for 1hr to avoid a DOS target. --- files/routes/static.py | 13 +++++++++++-- files/templates/badges.html | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/files/routes/static.py b/files/routes/static.py index c93ae729e..8b6097ef4 100644 --- a/files/routes/static.py +++ b/files/routes/static.py @@ -496,10 +496,19 @@ def robots_txt(): @app.get("/badges") @auth_required +@cache.memoize(timeout=3600) def badges(v): - badges = g.db.query(BadgeDef).order_by(BadgeDef.id).all() + nonlurk_truecoins = 100 - return render_template("badges.html", v=v, badges=badges) + badges = g.db.query(BadgeDef).order_by(BadgeDef.id).all() + counts_raw = g.db.query(Badge.badge_id, func.count()).group_by(Badge.badge_id).all() + users_nonlurk = g.db.query(User.id).filter(User.truecoins >= nonlurk_truecoins).count() + + counts = {} + for c in counts_raw: + counts[c[0]] = (c[1], float(c[1]) * 100 / max(users_nonlurk, 1)) + + return render_template("badges.html", v=v, badges=badges, counts=counts, nonlurk=users_nonlurk, nonlurk_tc=nonlurk_truecoins) @app.get("/blocks") @auth_required diff --git a/files/templates/badges.html b/files/templates/badges.html index 52a7f69b4..8b2802abb 100644 --- a/files/templates/badges.html +++ b/files/templates/badges.html @@ -6,6 +6,7 @@

User Badges

This page describes the requirements for obtaining all profile badges.
+
Rarity is the ratio of badge quantity to the number of non-lurkers (truescore ≥ {{ nonlurk_tc }}): {{ nonlurk }}.
 
 
@@ -17,6 +18,8 @@
 		Name
 		Image
 		Description
+		#
+		Rarity
 	
 
 {% for badge in badges %}
@@ -25,6 +28,9 @@
 		{{badge.name}}
 		{{badge.name}}
 		{{badge.description}}
+		{%- set ct = counts[badge.id] if badge.id in counts else (0, 0) %}
+		{{ ct[0] }}
+		{{ "{:0.3f}".format(ct[1]) }}%
 	
 {% endfor %}