Implement comment locking (#439)

* Implement comment locking

This adds a new flags to torrents, which is only editable by
moderators and admins. If checked, it does not allow unprivileged
users to post, edit or delete comments on that torrent.

* Rename "locked" to "comment_locked".

* Shorter button and additional words on alt text

* Admin log: Change comment locking message

dude I love bikeshedding xd

* Bikeshedding over admin log messages

* >&
Also some bikeshedding
This commit is contained in:
Nicolas F 2018-03-26 02:03:49 +02:00 committed by Arylide
parent 2b5f9922e9
commit 60ce4ec3f1
7 changed files with 48 additions and 5 deletions

View File

@ -218,6 +218,10 @@ def handle_torrent_upload(upload_form, uploading_user=None, fromAPI=False):
# To do, automatically mark trusted if user is trusted unless user specifies otherwise
torrent.trusted = upload_form.is_trusted.data if can_mark_trusted else False
# Only allow mods to upload locked torrents
can_mark_locked = uploading_user and uploading_user.is_moderator
torrent.comment_locked = upload_form.is_comment_locked.data if can_mark_locked else False
# Set category ids
torrent.main_category_id, torrent.sub_category_id = \
upload_form.category.parsed_data.get_category_ids()

View File

@ -263,6 +263,7 @@ class EditForm(FlaskForm):
is_anonymous = BooleanField('Anonymous')
is_complete = BooleanField('Complete')
is_trusted = BooleanField('Trusted')
is_comment_locked = BooleanField('Lock Comments')
information = StringField('Information', [
Length(max=255, message='Information must be at most %(max)d characters long.')
@ -338,6 +339,7 @@ class UploadForm(FlaskForm):
is_anonymous = BooleanField('Anonymous')
is_complete = BooleanField('Complete')
is_trusted = BooleanField('Trusted')
is_comment_locked = BooleanField('Lock Comments')
information = StringField('Information', [
Length(max=255, message='Information must be at most %(max)d characters long.')

View File

@ -100,6 +100,7 @@ class TorrentFlags(IntEnum):
COMPLETE = 16
DELETED = 32
BANNED = 64
COMMENT_LOCKED = 128
class TorrentBase(DeclarativeHelperBase):
@ -259,6 +260,7 @@ class TorrentBase(DeclarativeHelperBase):
trusted = FlagProperty(TorrentFlags.TRUSTED)
remake = FlagProperty(TorrentFlags.REMAKE)
complete = FlagProperty(TorrentFlags.COMPLETE)
comment_locked = FlagProperty(TorrentFlags.COMMENT_LOCKED)
# Class methods

View File

@ -68,6 +68,14 @@
Trusted
</label>
{% endif %}
{% if g.user.is_moderator %}
<label class="btn btn-default {% if torrent.comment_locked %}active{% endif %}" title="Lock comments">
{{ form.is_comment_locked }}
<span class="glyphicon glyphicon-check"></span>
<span class="glyphicon glyphicon-unchecked"></span>
Lock Comments
</label>
{% endif %}
</div>
</div>
</div>

View File

@ -105,7 +105,7 @@
{{ linkable_header("IRC Help Channel Policies", "irchelp") }}
<div>
<p>Our IRC help channel is at Rizon <a href="irc://irc.rizon.net/nyaa-help">#nyaa-help</a>. A webchat link
pre-filled with our channel is available <a href="https://qchat.rizon.net/?channels=nyaa-help&uio=d4">right here</a>.</p>
pre-filled with our channel is available <a href="https://qchat.rizon.net/?channels=nyaa-help">right here</a>.</p>
<b>Read this to avoid getting banned:</b>
<ul>

View File

@ -159,10 +159,10 @@
<small data-timestamp-swap data-timestamp-title data-timestamp="{{ comment.edited_utc_timestamp }}" title="{{ comment.edited_time }}">(edited)</small>
{% endif %}
<div class="comment-actions">
{% if g.user.id == comment.user_id and not comment.editing_limit_exceeded %}
{% if g.user.id == comment.user_id and not comment.editing_limit_exceeded and (not torrent.comment_locked or comment_form) %}
<button class="btn btn-xs edit-comment" title="Edit"{% if config.EDITING_TIME_LIMIT %} data-until="{{ comment.editable_until|int }}"{% endif %}>Edit</button>
{% endif %}
{% if g.user.is_superadmin or g.user.id == comment.user_id %}
{% if g.user.is_superadmin or (g.user.id == comment.user_id and not torrent.comment_locked) %}
<form class="delete-comment-form" action="{{ url_for('torrents.delete_comment', torrent_id=torrent.id, comment_id=comment.id) }}" method="POST">
<button name="submit" type="submit" class="btn btn-danger btn-xs" title="Delete">Delete</button>
</form>
@ -190,6 +190,14 @@
</div>
{% endfor %}
{% if torrent.comment_locked %}
<div class="alert alert-warning">
<p>
<i class="fa fa-lock" aria-hidden="true"></i>
Comments have been locked.
</p>
</div>
{% endif %}
{% if comment_form %}
<form class="comment-box" method="POST">
{{ comment_form.csrf_token }}

View File

@ -33,11 +33,11 @@ def view_torrent(torrent_id):
flask.abort(404)
comment_form = None
if flask.g.user:
if flask.g.user and (not torrent.comment_locked or flask.g.user.is_moderator):
comment_form = forms.CommentForm()
if flask.request.method == 'POST':
if not flask.g.user:
if not comment_form:
flask.abort(403)
if comment_form.validate():
@ -117,6 +117,18 @@ def edit_torrent(torrent_id):
if editor.is_trusted:
torrent.trusted = form.is_trusted.data
if editor.is_moderator:
locked_changed = torrent.comment_locked != form.is_comment_locked.data
torrent.comment_locked = form.is_comment_locked.data
url = flask.url_for('torrents.view', torrent_id=torrent.id)
if editor.is_moderator and locked_changed:
log = "Torrent [#{0}]({1}) marked as {2}".format(
torrent.id, url,
"comments locked" if torrent.comment_locked else "comments unlocked")
adminlog = models.AdminLog(log=log, admin_id=editor.id)
db.session.add(adminlog)
db.session.commit()
flask.flash(flask.Markup(
@ -141,6 +153,7 @@ def edit_torrent(torrent_id):
form.is_complete.data = torrent.complete
form.is_anonymous.data = torrent.anonymous
form.is_trusted.data = torrent.trusted
form.is_comment_locked.data = torrent.comment_locked
ipbanned = None
if editor.is_moderator:
@ -331,6 +344,9 @@ def edit_comment(torrent_id, comment_id):
if not comment.user.id == flask.g.user.id:
flask.abort(403)
if torrent.comment_locked and not flask.g.user.is_moderator:
flask.abort(403)
if comment.editing_limit_exceeded:
flask.abort(flask.make_response(flask.jsonify(
{'error': 'Editing time limit exceeded.'}), 400))
@ -365,6 +381,9 @@ def delete_comment(torrent_id, comment_id):
if torrent_id != comment.torrent_id:
flask.abort(400)
if torrent.comment_locked and not flask.g.user.is_moderator:
flask.abort(403)
db.session.delete(comment)
db.session.flush()
torrent.update_comment_count()