195 lines
6.2 KiB
Python
195 lines
6.2 KiB
Python
from app import app, db
|
|
from app.models.attachment import Attachment
|
|
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, flash
|
|
from flask_login import login_required, current_user
|
|
from sqlalchemy import text
|
|
|
|
@app.route('/post/editer/<int:postid>', methods=['GET','POST'])
|
|
@login_required
|
|
def edit_post(postid):
|
|
# TODO: Maybe not safe
|
|
referrer = urlparse(request.args.get('r', default = '/', type = str)).path
|
|
print(referrer)
|
|
|
|
p = Post.query.filter_by(id=postid).first_or_404()
|
|
|
|
# Check permissions
|
|
if not current_user.can_edit_post(p):
|
|
abort(403)
|
|
|
|
if isinstance(p, Comment):
|
|
base = CommentEditForm
|
|
comment = p
|
|
elif isinstance(p, Topic):
|
|
base = TopicEditForm
|
|
comment = p.thread.top_comment
|
|
else:
|
|
abort(404)
|
|
|
|
class TheForm(base):
|
|
pass
|
|
for a in comment.attachments:
|
|
setattr(TheForm, f'a{a.id}', BooleanField(f'a{a.id}'))
|
|
setattr(TheForm, 'attachment_list',
|
|
{ f'a{a.id}': a for a in comment.attachments })
|
|
form = TheForm()
|
|
|
|
if isinstance(p, Topic):
|
|
forums = sorted(Forum.query.all(), key=lambda f: f.url)
|
|
forums = [f for f in forums if current_user.can_post_in_forum(f)]
|
|
form.forum.choices = [(f.url, f"{f.url}: {f.name}") for f in forums]
|
|
|
|
if form.validate_on_submit():
|
|
comment.text = form.message.data
|
|
|
|
# Remove attachments
|
|
for id, a in form.attachment_list.items():
|
|
if form[id].data:
|
|
a.delete()
|
|
|
|
# Add new attachments
|
|
attachments = []
|
|
for file in form.attachments.data:
|
|
if file.filename != "":
|
|
a = Attachment(file, comment)
|
|
attachments.append((a, file))
|
|
db.session.add(a)
|
|
|
|
comment.touch()
|
|
db.session.add(comment)
|
|
|
|
if isinstance(p, Topic):
|
|
p.title = form.title.data
|
|
f = Forum.query.filter_by(url=form.forum.data).first_or_404()
|
|
if current_user.can_post_in_forum(f):
|
|
p.forum = f
|
|
db.session.merge(p)
|
|
|
|
db.session.commit()
|
|
|
|
for a, file in attachments:
|
|
a.set_file(file)
|
|
|
|
# Determine topic URL now, in case forum was changed
|
|
if isinstance(p, Topic):
|
|
return redirect(url_for('forum_topic', f=p.forum, page=(p,1)))
|
|
else:
|
|
return redirect(referrer)
|
|
|
|
# Non-submitted form
|
|
if isinstance(p, Comment):
|
|
form.message.data = p.text
|
|
return render('forum/edit_comment.html', comment=p, form=form)
|
|
elif isinstance(p, Topic):
|
|
form.message.data = p.thread.top_comment.text
|
|
form.title.data = p.title
|
|
form.forum.data = p.forum.url
|
|
return render('forum/edit_topic.html', t=p, form=form)
|
|
|
|
@app.route('/post/supprimer/<int:postid>', methods=['GET','POST'])
|
|
@login_required
|
|
@check_csrf
|
|
def delete_post(postid):
|
|
next_page = request.referrer
|
|
p = Post.query.filter_by(id=postid).first_or_404()
|
|
xp = -1
|
|
|
|
if not current_user.can_delete_post(p):
|
|
abort(403)
|
|
|
|
# Users who need to have their trophies updated
|
|
authors = set()
|
|
|
|
# When deleting topics, return to forum page
|
|
if isinstance(p, Topic):
|
|
next_page = url_for('forum_page', f=p.forum)
|
|
xp = -2
|
|
|
|
for comment in p.thread.comments:
|
|
if isinstance(comment.author, Member):
|
|
comment.author.add_xp(-1)
|
|
db.session.merge(comment.author)
|
|
authors.add(comment.author)
|
|
|
|
if isinstance(p.author, Member):
|
|
factor = 3 if request.args.get('penalty') == 'True' else 1
|
|
p.author.add_xp(xp * factor)
|
|
db.session.merge(p.author)
|
|
authors.add(p.author)
|
|
|
|
p.delete()
|
|
db.session.commit()
|
|
|
|
for author in authors:
|
|
author.update_trophies("new-post")
|
|
|
|
return redirect(next_page)
|
|
|
|
@app.route('/post/entete/<int:postid>', methods=['GET'])
|
|
@login_required
|
|
@check_csrf
|
|
def set_post_topcomment(postid):
|
|
comment = Post.query.filter_by(id=postid).first_or_404()
|
|
|
|
if current_user.can_set_topcomment(comment):
|
|
comment.thread.top_comment = comment
|
|
db.session.add(comment.thread)
|
|
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)
|