from flask import ( Blueprint, render_template, request, redirect, url_for ) from .users import login_required, mod_only, get_active_user, is_logged_in from ..db import db from ..models import Threads, Topics, Posts, Subscriptions from .posts import create_post from slugify import slugify import math import time bp = Blueprint("threads", __name__, url_prefix = "/threads/") @bp.get("/") def thread(slug): POSTS_PER_PAGE = 10 thread = Threads.find({"slug": slug}) if not thread: return "no" post_count = Posts.count({"thread_id": thread.id}) page_count = max(math.ceil(post_count / POSTS_PER_PAGE), 1) page = 1 after = request.args.get("after", default=None) if after is not None: after_id = int(after) post_position = Posts.count([ ("thread_id", "=", thread.id), ("id", "<=", after_id), ]) print(post_position) page = math.ceil((post_position) / POSTS_PER_PAGE) else: page = max(1, min(page_count, int(request.args.get("page", default = 1)))) posts = thread.get_posts(POSTS_PER_PAGE, (page - 1) * POSTS_PER_PAGE) topic = Topics.find({"id": thread.topic_id}) other_topics = Topics.select() is_subscribed = False if is_logged_in(): subscription = Subscriptions.find({ 'thread_id': thread.id, 'user_id': get_active_user().id, }) if subscription: subscription.update({ 'last_seen': int(time.time()) }) is_subscribed = True return render_template( "threads/thread.html", thread = thread, current_page = page, page_count = page_count, posts = posts, topic = topic, topics = other_topics, is_subscribed = is_subscribed, ) @bp.post("/") @login_required def reply(slug): thread = Threads.find({"slug": slug}) if not thread: return "no" user = get_active_user() if user.is_guest(): return "no" if thread.locked() and not user.is_mod(): return "no" post_content = request.form['post_content'] post = create_post(thread.id, user.id, post_content) return redirect(url_for(".thread", slug=slug, after=post.id, _anchor="latest-post")) @bp.get("/create") @login_required def create(): all_topics = Topics.select() return render_template("threads/create.html", all_topics = all_topics) @bp.post("/create") @login_required def create_form(): topic = Topics.find({"id": request.form['topic_id']}) user = get_active_user() if not topic: return "no" if topic.is_locked and not get_active_user().is_mod(): return "no" title = request.form['title'].strip() now = int(time.time()) slug = f"{slugify(title)}-{now}" post_content = request.form['initial_post'] thread = Threads.create({ "topic_id": topic.id, "user_id": user.id, "title": title, "slug": slug, "created_at": now, }) post = create_post(thread.id, user.id, post_content) return redirect(url_for(".thread", slug = thread.slug)) @bp.post("//lock") @login_required def lock(slug): pass @bp.post("//sticky") @login_required @mod_only(".thread", slug = lambda slug: slug) def sticky(slug): pass @bp.post("//move") @login_required @mod_only(".thread", slug = lambda slug: slug) def move(slug): pass @bp.post("//subscribe") @login_required def subscribe(slug): user = get_active_user() thread = Threads.find({'slug': slug}) if not thread: return 'no' subscription = Subscriptions.find({ 'user_id': user.id, 'thread_id': thread.id, }) if request.form['subscribe'] == 'subscribe': if subscription: subscription.delete() Subscriptions.create({ 'user_id': user.id, 'thread_id': thread.id, 'last_seen': int(time.time()), }) elif request.form['subscribe'] == 'unsubscribe': if not subscription: return 'no' subscription.delete() elif request.form['subscribe'] == 'read': if not subscription: return 'no' subscription.update({ 'last_seen': int(time.time()) }) last_visible_post = request.form.get('last_visible_post', default=None) if last_visible_post is not None: return redirect(url_for('.thread', slug=thread.slug, after=last_visible_post)) else: return redirect(url_for('users.inbox', username=user.username))