Profile medals: add progressbars, make top packages per type

This commit is contained in:
rubenwardy 2021-07-25 22:44:13 +01:00
parent 4de802c68d
commit e06ac1689c
2 changed files with 51 additions and 32 deletions

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import math
from flask import *
from flask_login import current_user, login_required
@ -64,6 +65,10 @@ def profile(username):
users_by_reviews = db.session.query(User.username, func.count(PackageReview.id).label("count")) \
.select_from(User).join(PackageReview) \
.group_by(User.username).order_by(text("count DESC")).all()
try:
review_boundary = users_by_reviews[math.floor(len(users_by_reviews) * 0.25)][1] + 1
except IndexError:
review_boundary = None
users_by_reviews = [ username for username, _ in users_by_reviews ]
review_idx = None
@ -80,19 +85,26 @@ def profile(username):
.filter(User.id == user.id, Package.state == PackageState.APPROVED).scalar() or 0
all_package_ranks = db.session.query(
Package.type,
Package.author_id,
func.rank().over(order_by=db.desc(Package.score)) \
func.rank().over(order_by=db.desc(Package.score), partition_by=Package.type) \
.label('rank')).order_by(db.asc(text("rank"))) \
.filter_by(state=PackageState.APPROVED).subquery()
user_package_ranks = db.session.query(all_package_ranks) \
.filter_by(author_id=user.id).first()
min_package_rank = user_package_ranks[1] if user_package_ranks else None
min_package_rank = None
min_package_type = None
if user_package_ranks:
min_package_rank = user_package_ranks[2]
min_package_type = PackageType.coerce(user_package_ranks[0]).value
# Process GET or invalid POST
return render_template("users/profile.html", user=user,
packages=packages, maintained_packages=maintained_packages,
total_downloads=total_downloads, min_package_rank=min_package_rank,
review_idx=review_idx, review_percent=review_percent)
total_downloads=total_downloads,
review_idx=review_idx, review_percent=review_percent, review_boundary=review_boundary,
min_package_rank=min_package_rank, min_package_type=min_package_type)
@bp.route("/users/<username>/check/", methods=["POST"])

View File

@ -95,7 +95,8 @@
<a class="btn" href="#reviews">
<i class="fas fa-star-half-alt"></i>
<span class="count">
<strong>{{ user.reviews | length }}</strong>
{% set num_reviews = user.reviews | length %}
<strong>{{ num_reviews }}</strong>
{{ _("reviews") }}
</span>
</a>
@ -175,12 +176,21 @@
</div>
{% elif current_user == user %}
<div class="col-md-4">
<p class="border border-dark rounded p-3 text-muted my-0">
{{ _("Consider writing more reviews to get a badge.") }}
{% if review_idx %}
{{ _("You are in place %(place)s.", place=review_idx + 1) }}
{% endif %}
</p>
<div class="border border-dark rounded p-3 text-muted my-0">
<p>
{{ _("Consider writing more reviews to get a medal.") }}
{% if review_idx %}
{{ _("You are in place %(place)s.", place=review_idx + 1) }}
{% endif %}
</p>
<div class="progress">
<div class="progress-bar" role="progressbar"
style="width: {{ [100 * num_reviews / review_boundary, 100] | min }}%;"
aria-valuenow="{{ num_reviews }}" aria-valuemin="0" aria-valuemax="{{ review_boundary }}">
{{ _("%(value)d / %(target)d", value=num_reviews, target=review_boundary) }}
</div>
</div>
</div>
</div>
{% endif %}
{% if total_downloads >= 50000 %}
@ -219,22 +229,27 @@
</div>
{% elif total_downloads > 0 and current_user == user %}
<div class="col-md-4">
<p class="border border-dark rounded p-3 text-muted my-0">
{{ _("Your packages have %(downloads)d downloads in total.", downloads=total_downloads) }}
{# <div class="progress">#}
{# <div class="progress-bar" role="progressbar"#}
{# style="width: {{ [100 * total_downloads / 50000, 100] | min }}%;"#}
{# aria-valuenow="{{ total_downloads }}" aria-valuemin="0" aria-valuemax="50000"></div>#}
{# </div>#}
</p>
<div class="border border-dark rounded p-3 text-muted my-0">
<p>
{{ _("Your packages have %(downloads)d downloads in total.", downloads=total_downloads) }}
{{ _("First medal is at 50k.") }}
</p>
<div class="progress">
<div class="progress-bar" role="progressbar"
style="width: {{ [100 * total_downloads / 50000, 100] | min }}%;"
aria-valuenow="{{ total_downloads }}" aria-valuemin="0" aria-valuemax="50000">
{{ _("%(value)d / %(target)d", value=total_downloads, target=50000) }}
</div>
</div>
</div>
</div>
{% endif %}
{% if min_package_rank is not none and min_package_rank <= 30 %}
{% if min_package_rank <= 5 %}
{% if min_package_rank is not none and min_package_rank <= 20 %}
{% if min_package_rank == 1 %}
{% set badge_color = "gold" %}
{% elif min_package_rank <= 10 %}
{% elif min_package_rank == 2 %}
{% set badge_color = "#888" %}
{% elif min_package_rank <= 20 %}
{% elif min_package_rank == 3 %}
{% set badge_color = "#cd7f32" %}
{% else %}
{% set badge_color = "white" %}
@ -245,15 +260,7 @@
<i class="fas fa-trophy ml-2 mr-4 text-size" style="font-size: 45px; color: {{ badge_color }};"></i>
<div class="media-body">
<h5 class="mt-0">
{% if min_package_rank <= 5 %}
{{ _("Top 5 package") }}
{% elif min_package_rank <= 10 %}
{{ _("Top 10 package") }}
{% elif min_package_rank <= 20 %}
{{ _("Top 20 package") }}
{% else %}
{{ _("Top 30 package") }}
{% endif %}
{{ _("Top %(place)d %(type)s", place=min_package_rank, type=min_package_type) }}
</h5>
<p class="my-0">
{{ _("%(display_name)s has a package placed at #%(place)d.",