from flask import ( Blueprint, redirect, url_for, flash, render_template, request ) from .users import login_required, get_active_user from ..lib.babycode import babycode_to_html from ..constants import InfoboxKind from ..db import db from ..models import Posts, PostHistory, Threads bp = Blueprint("posts", __name__, url_prefix = "/post") def create_post(thread_id, user_id, content, markup_language="babycode"): with db.transaction(): post = Posts.create({ "thread_id": thread_id, "user_id": user_id, "current_revision_id": None, }) revision = PostHistory.create({ "post_id": post.id, "content": babycode_to_html(content), "is_initial_revision": True, "original_markup": content, "markup_language": markup_language, }) post.update({"current_revision_id": revision.id}) return post def update_post(post_id, new_content, markup_language='babycode'): with db.transaction(): post = Posts.find({'id': post_id}) new_revision = PostHistory.create({ 'post_id': post.id, 'content': babycode_to_html(new_content), 'is_initial_revision': False, 'original_markup': new_content, 'markup_language': markup_language, }) post.update({'current_revision_id': new_revision.id}) @bp.post("//delete") @login_required def delete(post_id): post = Posts.find({'id': post_id}) thread = Threads.find({'id': post.thread_id}) user = get_active_user() if user.is_mod() or post.user_id == user.id: post.delete() flash("Post deleted.", InfoboxKind.INFO) return redirect(url_for('threads.thread', slug=thread.slug)) @bp.get("//edit") @login_required def edit(post_id): user = get_active_user() q = f"{Posts.FULL_POSTS_QUERY} WHERE posts.id = ?" editing_post = db.fetch_one(q, post_id) if not editing_post: return redirect(url_for('topics.all_topics')) if editing_post['user_id'] != user.id: return redirect(url_for('topics.all_topics')) thread = Threads.find({'id': editing_post['thread_id']}) thread_predicate = f'{Posts.FULL_POSTS_QUERY} WHERE posts.thread_id = ?' context_prev_q = f'{thread_predicate} AND posts.created_at < ? ORDER BY posts.created_at DESC LIMIT 2' context_next_q = f'{thread_predicate} AND posts.created_at > ? ORDER BY posts.created_at ASC LIMIT 2' prev_context = db.query(context_prev_q, thread.id, editing_post['created_at']) next_context = db.query(context_next_q, thread.id, editing_post['created_at']) return render_template('posts/edit.html', editing_post = editing_post, thread = thread, prev_context = prev_context, next_context = next_context, ) @bp.post("//edit") @login_required def edit_form(post_id): user = get_active_user() post = Posts.find({'id': post_id}) if post.user_id != user.id: return redirect(url_for('topics.all_topics')) update_post(post.id, request.form.get('new_content', default='')) thread = Threads.find({'id': post.thread_id}) return redirect(url_for('threads.thread', slug=thread.slug, after=post.id, _anchor=f'post-{post.id}'))