From d6b44da6c214a717ad79d92ba5ffa618a50ee406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Thu, 16 Apr 2026 00:01:18 +0300 Subject: [PATCH] basic posting --- app/auth.py | 16 +++++++++++++--- app/models.py | 33 ++++++++++++++++++++++++++++++++ app/routes/threads.py | 13 +++++++++++-- app/routes/users.py | 6 +++++- app/templates/common/macros.html | 2 +- app/templates/common/topnav.html | 2 +- 6 files changed, 64 insertions(+), 8 deletions(-) diff --git a/app/auth.py b/app/auth.py index 2e53294..e8fac86 100644 --- a/app/auth.py +++ b/app/auth.py @@ -1,6 +1,7 @@ -from flask import session, flash +from flask import session, flash, redirect, url_for from .models import Sessions, Users from argon2 import PasswordHasher +from functools import wraps import secrets import time @@ -15,7 +16,7 @@ def verify(expected, given): except: return False -def is_logged_in(): +def is_logged_in() -> bool: if 'pyrom_session_key' not in session: return False sess = Sessions.find({'key': session['pyrom_session_key']}) @@ -28,7 +29,7 @@ def is_logged_in(): return False return True -def get_active_user(): +def get_active_user() -> Users | None: if not is_logged_in(): return None @@ -41,3 +42,12 @@ def create_session(user_id): 'user_id': user_id, 'expires_at': int(time.time()) + (31 * 24 * 60 * 60), }) + +# annotations +def login_required(view_func): + @wraps(view_func) + def wrapper(*args, **kwargs): + if not is_logged_in(): + return redirect(url_for('users.log_in_page')) + return view_func(*args, **kwargs) + return wrapper diff --git a/app/models.py b/app/models.py index 875fa8c..b8ebbee 100644 --- a/app/models.py +++ b/app/models.py @@ -267,6 +267,39 @@ class Posts(Model): q = f'{self.FULL_POSTS_QUERY} WHERE posts.id = ?' return db.fetch_one(q, self.id) + @classmethod + def new(cls, user_id: int, thread_id: int, content: str, language: str = 'babycode') -> Posts: + from .lib.babycode import babycode_to_html, babycode_to_rssxml, BABYCODE_VERSION + html_content = babycode_to_html(content) + rssxml_content = babycode_to_rssxml(content) + 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': html_content.result, + 'content_rss': rssxml_content, + 'is_initial_revision': True, + 'original_markup': content, + 'markup_language': language, + 'format_version': BABYCODE_VERSION, + }) + + for mention in html_content.mentions: + Mentions.create({ + 'revision_id': revision.id, + 'mentioned_iser_id': mention['mentioned_iser_id'], + 'start_index': mention['start'], + 'end_index': mention['end'], + }) + + post.update({'current_revision_id': revision.id}) + return post + class PostHistory(Model): table = 'post_history' diff --git a/app/routes/threads.py b/app/routes/threads.py index eeb00a9..066bbec 100644 --- a/app/routes/threads.py +++ b/app/routes/threads.py @@ -1,5 +1,5 @@ from flask import Blueprint, redirect, url_for, render_template, request, abort - +from ..auth import login_required, get_active_user from ..models import Threads, Posts, Topics, Users, Reactions import math @@ -35,8 +35,17 @@ def thread(slug): return render_template('threads/thread.html', thread=thread, posts=thread.get_posts(PER_PAGE, page), page=page, page_count=page_count, topic=topic, started_by=started_by, topics=Topics.get_list(), Reactions=Reactions) @bp.post('//reply') +@login_required def reply(slug): - return 'stub' + user = get_active_user() + thread = Threads.find({'slug': slug}) + if not thread: + abort(404) + if thread.locked() and not user.is_mod(): + # TODO: flash + return redirect(url_for('.thread', slug=slug)) + post = Posts.new(user.id, thread.id, request.form.get('babycode_content')) + return redirect(url_for('.thread', slug=slug, after=post.id, _anchor=f'post-{post.id}')) @bp.get('//feed.atom') def feed(slug): diff --git a/app/routes/users.py b/app/routes/users.py index 05d8e2e..56fc597 100644 --- a/app/routes/users.py +++ b/app/routes/users.py @@ -5,8 +5,12 @@ from ..models import Users bp = Blueprint('users', __name__, url_prefix='/users/') +@bp.get('/log-in') +def log_in_page(): + return 'stub/please log in' + @bp.post('/log-in') -def log_in(): +def log_in_post(): user = Users.find({'username': request.form['username']}) if not user: return "no user" diff --git a/app/templates/common/macros.html b/app/templates/common/macros.html index 8f2fcaf..cdc6d49 100644 --- a/app/templates/common/macros.html +++ b/app/templates/common/macros.html @@ -101,7 +101,7 @@ babycode help - + {%- endif -%} {%- endcall -%} {%- endmacro %} diff --git a/app/templates/common/topnav.html b/app/templates/common/topnav.html index 6c0de4c..2be0154 100644 --- a/app/templates/common/topnav.html +++ b/app/templates/common/topnav.html @@ -14,7 +14,7 @@ {%- endwith -%} {%- else -%} -
+