pyrom/app/routes/posts.py
2025-07-02 16:22:07 +03:00

100 lines
3.3 KiB
Python

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("/<post_id>/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("/<post_id>/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("/<post_id>/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}'))