mirror of
https://github.com/minetest/contentdb.git
synced 2024-11-09 17:13:45 +01:00
Add ability for moderators to delete comments
This commit is contained in:
parent
a4dd4f0429
commit
31b8a7931b
@ -16,15 +16,22 @@
|
||||
|
||||
|
||||
from flask import Blueprint, render_template, redirect, url_for
|
||||
from flask_user import current_user, login_required
|
||||
from flask_user import current_user
|
||||
from app.models import db, AuditLogEntry, UserRank
|
||||
from app.utils import rank_required
|
||||
|
||||
from . import bp
|
||||
|
||||
|
||||
@bp.route("/admin/audit/")
|
||||
@login_required
|
||||
@rank_required(UserRank.MODERATOR)
|
||||
def audit():
|
||||
log = AuditLogEntry.query.order_by(db.desc(AuditLogEntry.created_at)).all()
|
||||
return render_template("admin/audit.html", log=log)
|
||||
|
||||
|
||||
@bp.route("/admin/audit/<int:id>/")
|
||||
@rank_required(UserRank.MODERATOR)
|
||||
def audit_view(id):
|
||||
entry = AuditLogEntry.query.get(id)
|
||||
return render_template("admin/audit_view.html", entry=entry)
|
||||
|
@ -107,6 +107,40 @@ def set_lock(id):
|
||||
return redirect(thread.getViewURL())
|
||||
|
||||
|
||||
@bp.route("/threads/<int:id>/delete/", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def delete_reply(id):
|
||||
thread = Thread.query.get(id)
|
||||
if thread is None:
|
||||
abort(404)
|
||||
|
||||
reply_id = request.args.get("reply")
|
||||
if reply_id is None:
|
||||
abort(404)
|
||||
|
||||
reply = ThreadReply.query.get(reply_id)
|
||||
if reply is None or reply.thread != thread:
|
||||
abort(404)
|
||||
|
||||
if thread.replies[0] == reply:
|
||||
flash("Cannot delete thread opening post!", "danger")
|
||||
return redirect(thread.getViewURL())
|
||||
|
||||
if not thread.checkPerm(current_user, Permission.DELETE_REPLY):
|
||||
abort(403)
|
||||
|
||||
if request.method == "GET":
|
||||
return render_template("threads/delete_reply.html", thread=thread, reply=reply)
|
||||
|
||||
msg = "Deleted reply by {}".format(reply.author.display_name)
|
||||
addAuditLog(AuditSeverity.MODERATION, current_user, msg, thread.getViewURL(), thread.package, reply.comment)
|
||||
|
||||
db.session.delete(reply)
|
||||
db.session.commit()
|
||||
|
||||
return redirect(thread.getViewURL())
|
||||
|
||||
|
||||
@bp.route("/threads/<int:id>/", methods=["GET", "POST"])
|
||||
def view(id):
|
||||
thread = Thread.query.get(id)
|
||||
@ -152,6 +186,7 @@ class ThreadForm(FlaskForm):
|
||||
private = BooleanField("Private")
|
||||
submit = SubmitField("Open Thread")
|
||||
|
||||
|
||||
@bp.route("/threads/new/", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def new():
|
||||
|
@ -92,6 +92,7 @@ class Permission(enum.Enum):
|
||||
CREATE_THREAD = "CREATE_THREAD"
|
||||
COMMENT_THREAD = "COMMENT_THREAD"
|
||||
LOCK_THREAD = "LOCK_THREAD"
|
||||
DELETE_REPLY = "DELETE_REPLY"
|
||||
UNAPPROVE_PACKAGE = "UNAPPROVE_PACKAGE"
|
||||
TOPIC_DISCARD = "TOPIC_DISCARD"
|
||||
CREATE_TOKEN = "CREATE_TOKEN"
|
||||
@ -1123,7 +1124,7 @@ class Thread(db.Model):
|
||||
elif perm == Permission.COMMENT_THREAD:
|
||||
return canSee and (not self.locked or user.rank.atLeast(UserRank.MODERATOR))
|
||||
|
||||
elif perm == Permission.LOCK_THREAD:
|
||||
elif perm == Permission.LOCK_THREAD or perm == Permission.DELETE_REPLY:
|
||||
return user.rank.atLeast(UserRank.MODERATOR)
|
||||
|
||||
else:
|
||||
@ -1201,7 +1202,9 @@ class AuditLogEntry(db.Model):
|
||||
package_id = db.Column(db.Integer, db.ForeignKey("package.id"), nullable=True)
|
||||
package = db.relationship("Package", foreign_keys=[package_id])
|
||||
|
||||
def __init__(self, causer, severity, title, url, package=None):
|
||||
description = db.Column(db.Text, nullable=True, default=None)
|
||||
|
||||
def __init__(self, causer, severity, title, url, package=None, description=None):
|
||||
if len(title) > 100:
|
||||
title = title[:99] + "…"
|
||||
|
||||
@ -1210,6 +1213,7 @@ class AuditLogEntry(db.Model):
|
||||
self.title = title
|
||||
self.url = url
|
||||
self.package = package
|
||||
self.description = description
|
||||
|
||||
|
||||
|
||||
|
@ -9,7 +9,13 @@ Audit Log
|
||||
|
||||
<div class="list-group mt-3">
|
||||
{% for entry in log %}
|
||||
<a class="list-group-item list-group-item-action" href="{{ entry.url }}">
|
||||
<a class="list-group-item list-group-item-action"
|
||||
{% if entry.description %}
|
||||
href="{{ url_for('admin.audit_view', id=entry.id) }}">
|
||||
{% else %}
|
||||
href="{{ entry.url }}">
|
||||
{% endif %}
|
||||
|
||||
<div class="row {% if entry.severity == entry.severity.NORMAL %}text-muted{% endif %}">
|
||||
<div class="col-sm-auto text-center" style="width: 50px;">
|
||||
{% if entry.severity == entry.severity.MODERATION %}
|
||||
@ -30,6 +36,10 @@ Audit Log
|
||||
|
||||
<div class="col-sm">
|
||||
{{ entry.title}}
|
||||
|
||||
{% if entry.description %}
|
||||
<i class="fas fa-paperclip ml-3"></i>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if entry.package %}
|
||||
@ -54,5 +64,5 @@ Audit Log
|
||||
{% else %}
|
||||
<p class="list-group-item"><i>No audit log entires.</i></p>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
19
app/templates/admin/audit_view.html
Normal file
19
app/templates/admin/audit_view.html
Normal file
@ -0,0 +1,19 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}
|
||||
{{ entry.title }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if entry.url %}
|
||||
<a class="float-right btn btn-primary" href="{{ entry.url }}">View</a>
|
||||
{% endif %}
|
||||
|
||||
<h1>{{ entry.title }}</h1>
|
||||
<p class="text-muted mb-4">
|
||||
{{ _("Caused by %(author)s.", author=entry.causer.display_name) }}
|
||||
</p>
|
||||
|
||||
<pre><code>{{ entry.description }}</code></pre>
|
||||
|
||||
{% endblock %}
|
@ -22,6 +22,13 @@
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
{% if r != thread.replies[0] and thread.checkPerm(current_user, "DELETE_REPLY") %}
|
||||
<a class="float-right btn btn-secondary btn-sm"
|
||||
href="{{ url_for('threads.delete_reply', id=thread.id, reply=r.id) }}">
|
||||
<i class="fas fa-trash"></i>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{{ r.comment | markdown }}
|
||||
</div>
|
||||
</div>
|
||||
|
22
app/templates/threads/delete_reply.html
Normal file
22
app/templates/threads/delete_reply.html
Normal file
@ -0,0 +1,22 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}
|
||||
Delete reply in {{ thread.title }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="POST" action="" class="card box_grey">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
|
||||
<h3 class="card-header">Delete reply by {{ reply.author.display_name }}</h3>
|
||||
<div class="card-body">
|
||||
{{ reply.comment | markdown }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Deleting is permanent</p>
|
||||
|
||||
<a class="btn btn-secondary mr-3" href="{{ thread.getViewURL() }}">Cancel</a>
|
||||
<input type="submit" value="Delete" class="btn btn-danger" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
@ -204,8 +204,8 @@ def addNotification(target, causer, title, url, package=None):
|
||||
db.session.add(notif)
|
||||
|
||||
|
||||
def addAuditLog(severity, causer, title, url, package=None):
|
||||
entry = AuditLogEntry(causer, severity, title, url, package)
|
||||
def addAuditLog(severity, causer, title, url, package=None, description=None):
|
||||
entry = AuditLogEntry(causer, severity, title, url, package, description)
|
||||
db.session.add(entry)
|
||||
|
||||
|
||||
|
28
migrations/versions/86512692b770_.py
Normal file
28
migrations/versions/86512692b770_.py
Normal file
@ -0,0 +1,28 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 86512692b770
|
||||
Revises: ba730ce1dc3e
|
||||
Create Date: 2020-07-11 01:56:28.634661
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '86512692b770'
|
||||
down_revision = 'ba730ce1dc3e'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('audit_log_entry', sa.Column('description', sa.Text, nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('audit_log_entry', 'description')
|
||||
# ### end Alembic commands ###
|
Loading…
Reference in New Issue
Block a user