basic posting

This commit is contained in:
2026-04-16 00:01:18 +03:00
parent d0daaf4494
commit d6b44da6c2
6 changed files with 64 additions and 8 deletions

View File

@@ -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

View File

@@ -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'

View File

@@ -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('/<slug>/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('/<slug>/feed.atom')
def feed(slug):

View File

@@ -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"

View File

@@ -101,7 +101,7 @@
</span>
<a href="##">babycode help</a>
</span>
<textarea name="babycode-content" class="babycode-editor" placeholder="{{placeholder}}" required>{{ prefill }}</textarea>
<textarea name="babycode_content" class="babycode-editor" placeholder="{{placeholder}}" required>{{ prefill }}</textarea>
{%- endif -%}
{%- endcall -%}
{%- endmacro %}

View File

@@ -14,7 +14,7 @@
</ul>
{%- endwith -%}
{%- else -%}
<form class="horizontal wrap" method="POST" action="{{url_for('users.log_in')}}">
<form class="horizontal wrap" method="POST" action="{{url_for('users.log_in_post')}}">
<input type="hidden" name="return_to" value="{{request.path}}">
<input type="text" placeholder="Username" name="username" autocomplete="username" required>
<input type="password" placeholder="Password" name="password" autocomplete="current-password" required>