mirror of
https://github.com/minetest/contentdb.git
synced 2025-01-03 11:47:28 +01:00
Add ability for moderators to convert reviews into threads
This commit is contained in:
parent
3566b030c5
commit
f61112a8d7
@ -24,8 +24,9 @@ from flask_login import current_user, login_required
|
|||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import *
|
from wtforms import *
|
||||||
from wtforms.validators import *
|
from wtforms.validators import *
|
||||||
from app.models import db, PackageReview, Thread, ThreadReply, NotificationType, PackageReviewVote, Package, UserRank
|
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
|
Permission, AuditSeverity
|
||||||
|
from app.utils import is_package_page, addNotification, get_int_or_abort, isYes, is_safe_url, rank_required, addAuditLog
|
||||||
from app.tasks.webhooktasks import post_discord_webhook
|
from app.tasks.webhooktasks import post_discord_webhook
|
||||||
|
|
||||||
|
|
||||||
@ -125,14 +126,19 @@ def review(package):
|
|||||||
form=form, package=package, review=review)
|
form=form, package=package, review=review)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/packages/<author>/<name>/review/delete/", methods=["POST"])
|
@bp.route("/packages/<author>/<name>/reviews/<reviewer>/delete/", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
@is_package_page
|
@is_package_page
|
||||||
def delete_review(package):
|
def delete_review(package, reviewer):
|
||||||
review = PackageReview.query.filter_by(package=package, author=current_user).first()
|
review = PackageReview.query \
|
||||||
|
.filter(PackageReview.package == package, PackageReview.author.has(username=reviewer)) \
|
||||||
|
.first()
|
||||||
if review is None or review.package != package:
|
if review is None or review.package != package:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
if not review.checkPerm(current_user, Permission.DELETE_REVIEW):
|
||||||
|
abort(403)
|
||||||
|
|
||||||
thread = review.thread
|
thread = review.thread
|
||||||
|
|
||||||
reply = ThreadReply()
|
reply = ThreadReply()
|
||||||
@ -143,6 +149,10 @@ def delete_review(package):
|
|||||||
|
|
||||||
thread.review = None
|
thread.review = None
|
||||||
|
|
||||||
|
msg = "Converted review by {} to thread".format(review.author.display_name)
|
||||||
|
addAuditLog(AuditSeverity.MODERATION if current_user.username != reviewer else AuditSeverity.NORMAL,
|
||||||
|
current_user, msg, thread.getViewURL(), thread.package)
|
||||||
|
|
||||||
notif_msg = "Deleted review '{}', comments were kept as a thread".format(thread.title)
|
notif_msg = "Deleted review '{}', comments were kept as a thread".format(thread.title)
|
||||||
addNotification(package.maintainers, current_user, NotificationType.OTHER, notif_msg, url_for("threads.view", id=thread.id), package)
|
addNotification(package.maintainers, current_user, NotificationType.OTHER, notif_msg, url_for("threads.view", id=thread.id), package)
|
||||||
|
|
||||||
@ -224,4 +234,4 @@ def review_votes(package):
|
|||||||
user_biases_info.sort(key=lambda x: -abs(x.balance))
|
user_biases_info.sort(key=lambda x: -abs(x.balance))
|
||||||
|
|
||||||
return render_template("packages/review_votes.html", form=form, package=package, reviews=package.reviews,
|
return render_template("packages/review_votes.html", form=form, package=package, reviews=package.reviews,
|
||||||
user_biases=user_biases_info)
|
user_biases=user_biases_info)
|
||||||
|
@ -200,7 +200,8 @@ class PackageReview(db.Model):
|
|||||||
def getDeleteURL(self):
|
def getDeleteURL(self):
|
||||||
return url_for("packages.delete_review",
|
return url_for("packages.delete_review",
|
||||||
author=self.package.author.username,
|
author=self.package.author.username,
|
||||||
name=self.package.name)
|
name=self.package.name,
|
||||||
|
reviewer=self.author.username)
|
||||||
|
|
||||||
def getVoteUrl(self, next_url=None):
|
def getVoteUrl(self, next_url=None):
|
||||||
return url_for("packages.review_vote",
|
return url_for("packages.review_vote",
|
||||||
@ -213,6 +214,20 @@ class PackageReview(db.Model):
|
|||||||
(pos, neg, _) = self.get_totals()
|
(pos, neg, _) = self.get_totals()
|
||||||
self.score = 3 * (pos - neg) + 1
|
self.score = 3 * (pos - neg) + 1
|
||||||
|
|
||||||
|
def checkPerm(self, user, perm):
|
||||||
|
if not user.is_authenticated:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if type(perm) == str:
|
||||||
|
perm = Permission[perm]
|
||||||
|
elif type(perm) != Permission:
|
||||||
|
raise Exception("Unknown permission given to PackageReview.checkPerm()")
|
||||||
|
|
||||||
|
if perm == Permission.DELETE_REVIEW:
|
||||||
|
return user == self.author or user.rank.atLeast(UserRank.MODERATOR)
|
||||||
|
else:
|
||||||
|
raise Exception("Permission {} is not related to reviews".format(perm.name))
|
||||||
|
|
||||||
|
|
||||||
class PackageReviewVote(db.Model):
|
class PackageReviewVote(db.Model):
|
||||||
review_id = db.Column(db.Integer, db.ForeignKey("package_review.id"), primary_key=True)
|
review_id = db.Column(db.Integer, db.ForeignKey("package_review.id"), primary_key=True)
|
||||||
|
@ -86,6 +86,7 @@ class Permission(enum.Enum):
|
|||||||
TOPIC_DISCARD = "TOPIC_DISCARD"
|
TOPIC_DISCARD = "TOPIC_DISCARD"
|
||||||
CREATE_TOKEN = "CREATE_TOKEN"
|
CREATE_TOKEN = "CREATE_TOKEN"
|
||||||
EDIT_MAINTAINERS = "EDIT_MAINTAINERS"
|
EDIT_MAINTAINERS = "EDIT_MAINTAINERS"
|
||||||
|
DELETE_REVIEW = "DELETE_REVIEW"
|
||||||
CHANGE_PROFILE_URLS = "CHANGE_PROFILE_URLS"
|
CHANGE_PROFILE_URLS = "CHANGE_PROFILE_URLS"
|
||||||
CHANGE_DISPLAY_NAME = "CHANGE_DISPLAY_NAME"
|
CHANGE_DISPLAY_NAME = "CHANGE_DISPLAY_NAME"
|
||||||
|
|
||||||
|
@ -36,10 +36,16 @@
|
|||||||
<input type="submit" class="btn btn-primary" value="{{ _('Subscribe') }}" />
|
<input type="submit" class="btn btn-primary" value="{{ _('Subscribe') }}" />
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if thread and thread.checkPerm(current_user, "DELETE_THREAD") %}
|
{% if thread.checkPerm(current_user, "DELETE_THREAD") %}
|
||||||
<a href="{{ url_for('threads.delete_thread', id=thread.id) }}" class="float-right mr-2 btn btn-danger">{{ _('Delete') }}</a>
|
<a href="{{ url_for('threads.delete_thread', id=thread.id) }}" class="float-right mr-2 btn btn-danger">{{ _('Delete') }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if thread and thread.checkPerm(current_user, "LOCK_THREAD") %}
|
{% if thread.review and thread.review.checkPerm(current_user, "DELETE_REVIEW") and current_user.username != thread.review.author.username %}
|
||||||
|
<form method="post" action="{{ thread.review.getDeleteURL() }}" class="float-right mr-2">
|
||||||
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
|
<input type="submit" class="btn btn-danger" value="{{ _('Convert to Thread') }}" />
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% if thread.checkPerm(current_user, "LOCK_THREAD") %}
|
||||||
{% if thread.locked %}
|
{% if thread.locked %}
|
||||||
<form method="post" action="{{ url_for('threads.set_lock', id=thread.id, lock=0) }}" class="float-right mr-2">
|
<form method="post" action="{{ url_for('threads.set_lock', id=thread.id, lock=0) }}" class="float-right mr-2">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
|
Loading…
Reference in New Issue
Block a user