Allow to merge a comment with a comment which was posted later
This commit is contained in:
parent
2801f8c1cd
commit
853193cbd8
|
@ -10,3 +10,8 @@ class MovePost(FlaskForm):
|
|||
class SearchThread(FlaskForm):
|
||||
name = StringField("Nom d'un topic, programme, …")
|
||||
search = SubmitField('Rechercher')
|
||||
|
||||
class MergePost(FlaskForm):
|
||||
# List of posts is generated at runtime
|
||||
post = SelectField('Fusionner avec', coerce=int, validators=[])
|
||||
submit = SubmitField('Fusionner')
|
||||
|
|
|
@ -270,6 +270,11 @@ class Member(User):
|
|||
return False
|
||||
return self.priv("lock.threads")
|
||||
|
||||
def can_merge_post(self, post):
|
||||
"""Whether this member can merge the post"""
|
||||
# NOTE: Might need more check than this
|
||||
return self.can_edit_post(post)
|
||||
|
||||
def can_access_file(self, file):
|
||||
"""Whether this member can access the file."""
|
||||
return self.can_access_post(file.comment)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from app import app, db
|
||||
from app import app, db, V5Config
|
||||
from app.models.attachment import Attachment
|
||||
from app.models.comment import Comment
|
||||
from app.models.forum import Forum
|
||||
|
@ -11,17 +11,18 @@ from app.utils.render import render
|
|||
from app.utils.check_csrf import check_csrf
|
||||
from app.utils.priv_required import priv_required
|
||||
from app.forms.forum import CommentEditForm, AnonymousCommentEditForm, TopicEditForm
|
||||
from app.forms.post import MovePost, SearchThread
|
||||
from app.forms.post import MovePost, SearchThread, MergePost
|
||||
from wtforms import BooleanField
|
||||
from urllib.parse import urlparse
|
||||
from flask import redirect, url_for, abort, request, flash
|
||||
from flask_login import login_required, current_user
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy import text, and_
|
||||
from datetime import timedelta
|
||||
|
||||
@app.route('/post/editer/<int:postid>', methods=['GET','POST'])
|
||||
@login_required
|
||||
def edit_post(postid):
|
||||
# TODO: Maybe not safe
|
||||
# FIXME: Maybe not safe
|
||||
referrer = urlparse(request.args.get('r', default = '/', type = str)).path
|
||||
print(referrer)
|
||||
|
||||
|
@ -244,4 +245,48 @@ def lock_thread(postid):
|
|||
flash(f"Le thread a été déverrouillé", 'ok')
|
||||
app.v5logger.info(f"[admin] <{current_user.name}> has unlocked the thread #{post.thread.id}")
|
||||
|
||||
return redirect(request.referrer)
|
||||
return redirect(request.referrer)
|
||||
|
||||
@app.route('/post/fusionner/<int:postid>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def merge_post(postid):
|
||||
comment = Comment.query.get_or_404(postid)
|
||||
|
||||
# Get the posts from the same user in the same topic that are separated
|
||||
# by less than V5Config.MERGE_AGE_THRESHOLD
|
||||
compatible_comments = Comment.query.filter(and_(
|
||||
Comment.thread_id == comment.thread_id,
|
||||
and_(
|
||||
Post.author_id == comment.author_id,
|
||||
and_(
|
||||
Post.date_created > comment.date_created,
|
||||
Post.date_created <= comment.date_created + timedelta(0, V5Config.MERGE_AGE_THRESHOLD)
|
||||
)
|
||||
)
|
||||
))
|
||||
|
||||
merge_form = MergePost()
|
||||
merge_form.post.choices = [(t.id, f"{t.text[:30]}[…]") for t in list(compatible_comments)]
|
||||
|
||||
if merge_form.validate_on_submit():
|
||||
merge_comment = Comment.query.filter_by(id=merge_form.post.data).first_or_404()
|
||||
|
||||
comment.text += f"\n\n---\n\n{merge_comment.text}"
|
||||
|
||||
# Change the modification date only if the other post is more recent
|
||||
if merge_comment.date_created > comment.date_modified:
|
||||
comment.date_modified = merge_comment.date_created
|
||||
|
||||
if merge_comment.is_top_comment:
|
||||
comment.thread.set_top_comment(comment)
|
||||
|
||||
db.session.add(comment)
|
||||
merge_comment.delete()
|
||||
db.session.commit()
|
||||
|
||||
if isinstance(comment.thread.owner_post, Topic):
|
||||
return redirect(url_for('forum_topic', f=comment.thread.owner_post.forum_id, page=comment.thread_id))
|
||||
elif isinstance(comment.thread.owner_post, Program):
|
||||
return redirect(url_for('program_view', page=[comment.thread.owner_post, -1]))
|
||||
|
||||
return render('post/merge_post.html', comment=comment, merge_form=merge_form)
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
{% extends "base/base.html" %}
|
||||
{% import "widgets/editor.html" as widget_editor %}
|
||||
{% import "widgets/user.html" as widget_user %}
|
||||
|
||||
{% set tabtitle = "Déplacer un commentaire" %}
|
||||
|
||||
{% block title %}
|
||||
<a href='/forum'>Forum de Planète Casio</a> » Fusion de commentaire</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section>
|
||||
<h1>Fusionner deux commentaires</h1>
|
||||
|
||||
<table class="thread comment">
|
||||
<tr>
|
||||
<td class="author">{{ widget_user.profile(comment.author) }}</td>
|
||||
<td><div>{{ comment.text | md }}</div></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<form action="" method="post">
|
||||
<h3></h3>
|
||||
{{ merge_form.hidden_tag() }}
|
||||
|
||||
<div>
|
||||
{{ merge_form.post.label }}
|
||||
{{ merge_form.post }}
|
||||
{% for error in merge_form.post.errors %}
|
||||
<span class="msgerror">{{ error }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div>{{ merge_form.submit(class_='bg-ok') }}</div>
|
||||
</form>
|
||||
</section>
|
||||
{% endblock %}
|
|
@ -13,6 +13,7 @@
|
|||
{% set can_topcomm = auth and current_user.can_set_topcomment(post) %}
|
||||
{% set can_move = auth and current_user.can_edit_post(post) and post.type == "comment" %}
|
||||
{% set can_lock = auth and current_user.can_lock_thread(post) %}
|
||||
{% set can_merge = auth and current_user.can_merge_post(post) %}
|
||||
|
||||
{% if post.type == "topic" %}
|
||||
{% set suffix = " le sujet" %}
|
||||
|
@ -32,6 +33,10 @@
|
|||
<a href="{{ url_for('move_post', postid=post.id) }}">Déplacer</a>
|
||||
{% endif %}
|
||||
|
||||
{% if can_merge %}
|
||||
<a href="{{ url_for('merge_post', postid=post.id) }}">Fusioner</a>
|
||||
{% endif %}
|
||||
|
||||
{% if can_punish and post.author.type == "member"%}
|
||||
<a href="{{ url_for('delete_post', postid=post.id, penalty=False, csrf_token=csrf_token()) }}" onclick="return confirm('Le post sera supprimé.')">Supprimer{{ suffix }} (normal)</a>
|
||||
<a href="{{ url_for('delete_post', postid=post.id, penalty=True, csrf_token=csrf_token()) }}" onclick="return confirm('Le post sera supprimé avec pénalité d\'XP.')">Supprimer{{ suffix }} (pénalité)</a>
|
||||
|
|
|
@ -86,6 +86,9 @@ class DefaultConfig(object):
|
|||
ENABLE_FLASK_DEBUG_TOOLBAR = False
|
||||
# Tab title prefix. Useful to dissociate local/dev/prod tabs
|
||||
TABTITLE_PREFIX = ""
|
||||
# Posts which are separated by more than this value (in seconds)
|
||||
# can't be merged together (I thought that 10 minutes was a good default)
|
||||
MERGE_AGE_THRESHOLD = 600
|
||||
|
||||
@staticmethod
|
||||
def v5logger():
|
||||
|
|
Loading…
Reference in New Issue