PCv5/app/routes/posts/edit.py

149 lines
4.6 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.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 wtforms import BooleanField
from urllib.parse import urlparse
from flask import redirect, url_for, abort, request
from flask_login import login_required, current_user
@app.route('/post/<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. TODO: Allow guests to edit their posts
if current_user.is_anonymous or 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)
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 current_user.is_anonymous or 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)