post: add move to another thread operation (#79)

Currently only support forum
This commit is contained in:
Darks 2021-07-14 19:55:16 +02:00
parent d4ceeb2cd1
commit c6ef83d32c
Signed by: Darks
GPG Key ID: 7515644268BE1433
5 changed files with 122 additions and 5 deletions

12
app/forms/post.py Normal file
View File

@ -0,0 +1,12 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SelectField, SubmitField
class MovePost(FlaskForm):
# List of threads is generated at runtime
thread = SelectField('Fil de discussion', coerce=int, validators=[])
submit = SubmitField('Déplacer')
class SearchThread(FlaskForm):
name = StringField("Nom d'un topic, programme, …")
search = SubmitField('Rechercher')

View File

@ -22,6 +22,9 @@ class Comment(Post):
# attachments (relation from Attachment)
@property
def is_top_comment(self):
return self.id == self.thread.top_comment_id
def __init__(self, author, text, thread):
"""

View File

@ -4,17 +4,20 @@ from app.models.comment import Comment
from app.models.forum import Forum
from app.models.post import Post
from app.models.program import Program
from app.models.thread import Thread
from app.models.topic import Topic
from app.models.user import Member
from app.utils.render import render
from app.utils.check_csrf import check_csrf
from app.forms.forum import CommentEditForm, AnonymousCommentEditForm, TopicEditForm
from app.forms.post import MovePost, SearchThread
from wtforms import BooleanField
from urllib.parse import urlparse
from flask import redirect, url_for, abort, request
from flask import redirect, url_for, abort, request, flash
from flask_login import login_required, current_user
from sqlalchemy import text
@app.route('/post/<int:postid>', methods=['GET','POST'])
@app.route('/post/editer/<int:postid>', methods=['GET','POST'])
@login_required
def edit_post(postid):
# TODO: Maybe not safe
@ -23,8 +26,8 @@ def edit_post(postid):
p = Post.query.filter_by(id=postid).first_or_404()
# Check permissions. TODO: Allow guests to edit their posts
if current_user.is_anonymous or not current_user.can_edit_post(p):
# Check permissions. TODO: Allow guests to edit their posts?
if not current_user.can_edit_post(p):
abort(403)
if isinstance(p, Comment):
@ -103,7 +106,7 @@ def delete_post(postid):
p = Post.query.filter_by(id=postid).first_or_404()
xp = -1
if current_user.is_anonymous or not current_user.can_delete_post(p):
if not current_user.can_delete_post(p):
abort(403)
# Users who need to have their trophies updated
@ -146,3 +149,45 @@ def set_post_topcomment(postid):
db.session.commit()
return redirect(request.referrer)
@app.route('/post/deplacer/<int:postid>', methods=['GET', 'POST'])
@login_required
def move_post(postid):
comment = Post.query.filter_by(id=postid).first_or_404()
if not current_user.can_edit_post(comment):
abort(403)
if not isinstance(comment, Comment):
flash("Vous ne pouvez pas déplacer un message principal", 'error')
abort(403)
move_form = MovePost(prefix="move_")
search_form = SearchThread(prefix="thread_")
keyword = search_form.name.data if search_form.validate_on_submit() else ""
# Get 10 last corresponding threads
# TODO: add support for every MainPost
req = text("""SELECT thread.id, topic.title FROM thread
INNER JOIN topic ON topic.thread_id = thread.id
WHERE lower(topic.title) LIKE lower(:keyword)
ORDER BY thread.id DESC LIMIT 10""")
threads = list(db.session.execute(req, {'keyword': '%'+keyword+'%'}))
move_form.thread.choices = [(t[0], f"{t[1]}") for t in threads]
if move_form.validate_on_submit():
thread = Thread.query.get_or_404(move_form.thread.data)
owner_post = thread.owner_post
if isinstance(owner_post, Topic):
t = owner_post
if not current_user.can_access_forum(t.forum):
abort(403)
comment.thread = thread
db.session.add(comment)
db.session.commit()
return redirect(url_for('forum_topic', f=t.forum, page=(t,1)))
return render('post/move_post.html', comment=comment,
search_form=search_form, move_form=move_form)

View File

@ -0,0 +1,52 @@
{% extends "base/base.html" %}
{% import "widgets/editor.html" as widget_editor %}
{% import "widgets/user.html" as widget_user %}
{% block title %}
<a href='/forum'>Forum de Planète Casio</a> » Édition de commentaire</h1>
{% endblock %}
{% block content %}
<section>
<h1>Déplacer un commentaire</h1>
<table class="thread topcomment">
<tr>
<td class="author">{{ widget_user.profile(comment.author) }}</td>
<td><div>{{ comment.text | md }}</div></td>
</tr>
</table>
<div class="form">
<form action="" method="post">
<h3>Chercher un thread</h3>
{{ search_form.hidden_tag() }}
<div>
{{ search_form.name.label }}
{{ search_form.name() }}
{% for error in search_form.name.errors %}
<span class="msgerror">{{ error }}</span>
{% endfor %}
</div>
<div>{{ search_form.search(class_='bg-ok') }}</div>
</form>
<form action="" method="post">
<h3>Nouveau thread</h3>
{{ move_form.hidden_tag() }}
<div>
{{ move_form.thread.label }}
{{ move_form.thread }}
{% for error in move_form.thread.errors %}
<span class="msgerror">{{ error }}</span>
{% endfor %}
</div>
<div>{{ move_form.submit(class_='bg-ok') }}</div>
</form>
</div>
</section>
{% endblock %}

View File

@ -11,6 +11,7 @@
{% set can_delete = auth and current_user.can_delete_post(post) %}
{% set can_punish = auth and current_user.can_punish_post(post) %}
{% 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" %}
{% if post.type == "topic" %}
{% set suffix = " le sujet" %}
@ -26,6 +27,10 @@
<a href="{{ url_for('edit_post', postid=post.id, r=request.path) }}">Modifier{{ suffix }}</a>
{% endif %}
{% if can_move %}
<a href="{{ url_for('move_post', postid=post.id) }}">Déplacer</a>
{% endif %}
{% if can_punish %}
<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>