From 8f4e214c52beeb400cdddc79d486e1aea3dcc096 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 1 Jan 2022 22:17:39 +0000 Subject: [PATCH] Add review votes page --- app/blueprints/packages/reviews.py | 36 +++++++++- app/templates/packages/review_votes.html | 89 ++++++++++++++++++++++++ app/templates/packages/view.html | 5 ++ 3 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 app/templates/packages/review_votes.html diff --git a/app/blueprints/packages/reviews.py b/app/blueprints/packages/reviews.py index e39da8f..18b4bcf 100644 --- a/app/blueprints/packages/reviews.py +++ b/app/blueprints/packages/reviews.py @@ -13,6 +13,7 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from collections import namedtuple from . import bp @@ -21,8 +22,8 @@ from flask_login import current_user, login_required from flask_wtf import FlaskForm from wtforms import * from wtforms.validators import * -from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package -from app.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url +from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package, UserRank +from app.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url, rank_required from app.tasks.webhooktasks import post_discord_webhook @@ -190,3 +191,34 @@ def review_vote(package, review_id): return redirect(next_url) else: return redirect(review.thread.getViewURL()) + + + +@bp.route("/packages///review-votes/") +@rank_required(UserRank.ADMIN) +@is_package_page +def review_votes(package): + user_biases = {} + for review in package.reviews: + review_sign = 1 if review.recommends else -1 + for vote in review.votes: + user_biases[vote.user.username] = user_biases.get(vote.user.username, [0, 0]) + vote_sign = 1 if vote.is_positive else -1 + vote_bias = review_sign * vote_sign + if vote_bias == 1: + user_biases[vote.user.username][0] += 1 + else: + user_biases[vote.user.username][1] += 1 + + BiasInfo = namedtuple("BiasInfo", "username balance with_ against no_vote perc_with") + user_biases_info = [] + for username, bias in user_biases.items(): + total_votes = bias[0] + bias[1] + balance = bias[0] - bias[1] + perc_with = round((100 * bias[0]) / total_votes) + user_biases_info.append(BiasInfo(username, balance, bias[0], bias[1], len(package.reviews) - total_votes, perc_with)) + + user_biases_info.sort(key=lambda x: -abs(x.balance)) + + return render_template("packages/review_votes.html", form=form, package=package, reviews=package.reviews, + user_biases=user_biases_info) \ No newline at end of file diff --git a/app/templates/packages/review_votes.html b/app/templates/packages/review_votes.html new file mode 100644 index 0000000..13bc62e --- /dev/null +++ b/app/templates/packages/review_votes.html @@ -0,0 +1,89 @@ +{% extends "base.html" %} + +{% block title %} + {{ _("Review Votes") }} +{% endblock %} + +{% block link %} + {{ package.title }} +{% endblock %} + + +{% block content %} +

{{ _("Review votes on %(title)s by %(author)s", title=self.link(), author=package.author.display_name) }}

+ +

Helpful Biases

+ {% set total_reviews = reviews | length %} +

+ This section shows whether users tend vote in a way that agrees or disagrees with a package. + Total reviews: {{ total_reviews }}. +

+ + + + + + + + + + + + {% for info in user_biases %} + {% set total_votes = info.with_ + info.against %} + 3 and total_votes > total_reviews * 0.5 and ((info.balance / total_votes) | abs) > 0.8 %} + style="color: #e74c3c;" + {% elif total_votes > 3 and ((info.balance / total_votes) | abs) > 0.9 %} + style="color: #f39c12;" + {% endif %}> + + + + + + + {% else %} + + {% endfor %} + +
UsernameBalanceWith PkgAgainst PkgNo Vote
{{ info.username }}{{ info.balance }}{{ info.with_ }} ({{ info.perc_with }}%){{ info.against }} ({{ 100 - info.perc_with }}%){{ info.no_vote }}
No votes
+ +

Reviews

+ + {% for review in reviews %} + + + + + + + + {% endfor %} +
+ {% if review.recommends %} + + {% else %} + + {% endif %} + + {{ review.thread.title }} + by {{ review.author.display_name }} +
+ {% for vote in review.votes %} + {% if vote.is_positive %} + + {{ vote.user.username }} + + {% endif %} + {% endfor %} + + {% for vote in review.votes %} + {% if not vote.is_positive %} + + {{ vote.user.username }} + + {% endif %} + {% endfor %} +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/packages/view.html b/app/templates/packages/view.html index 9102c4e..d53692e 100644 --- a/app/templates/packages/view.html +++ b/app/templates/packages/view.html @@ -283,6 +283,11 @@ {% else %} {{ render_review_preview(package) }} {% endif %} + + {% if current_user.is_authenticated and current_user.rank.atLeast(current_user.rank.ADMIN) %} + Review Votes + {% endif %} + {{ render_reviews(package.reviews, current_user) }} {% if packages_uses %}