basic posting
This commit is contained in:
16
app/auth.py
16
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 .models import Sessions, Users
|
||||||
from argon2 import PasswordHasher
|
from argon2 import PasswordHasher
|
||||||
|
from functools import wraps
|
||||||
import secrets
|
import secrets
|
||||||
import time
|
import time
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ def verify(expected, given):
|
|||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_logged_in():
|
def is_logged_in() -> bool:
|
||||||
if 'pyrom_session_key' not in session:
|
if 'pyrom_session_key' not in session:
|
||||||
return False
|
return False
|
||||||
sess = Sessions.find({'key': session['pyrom_session_key']})
|
sess = Sessions.find({'key': session['pyrom_session_key']})
|
||||||
@@ -28,7 +29,7 @@ def is_logged_in():
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_active_user():
|
def get_active_user() -> Users | None:
|
||||||
if not is_logged_in():
|
if not is_logged_in():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -41,3 +42,12 @@ def create_session(user_id):
|
|||||||
'user_id': user_id,
|
'user_id': user_id,
|
||||||
'expires_at': int(time.time()) + (31 * 24 * 60 * 60),
|
'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
|
||||||
|
|||||||
@@ -267,6 +267,39 @@ class Posts(Model):
|
|||||||
q = f'{self.FULL_POSTS_QUERY} WHERE posts.id = ?'
|
q = f'{self.FULL_POSTS_QUERY} WHERE posts.id = ?'
|
||||||
return db.fetch_one(q, self.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):
|
class PostHistory(Model):
|
||||||
table = 'post_history'
|
table = 'post_history'
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from flask import Blueprint, redirect, url_for, render_template, request, abort
|
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
|
from ..models import Threads, Posts, Topics, Users, Reactions
|
||||||
import math
|
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)
|
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')
|
@bp.post('/<slug>/reply')
|
||||||
|
@login_required
|
||||||
def reply(slug):
|
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')
|
@bp.get('/<slug>/feed.atom')
|
||||||
def feed(slug):
|
def feed(slug):
|
||||||
|
|||||||
@@ -5,8 +5,12 @@ from ..models import Users
|
|||||||
|
|
||||||
bp = Blueprint('users', __name__, url_prefix='/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')
|
@bp.post('/log-in')
|
||||||
def log_in():
|
def log_in_post():
|
||||||
user = Users.find({'username': request.form['username']})
|
user = Users.find({'username': request.form['username']})
|
||||||
if not user:
|
if not user:
|
||||||
return "no user"
|
return "no user"
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<a href="##">babycode help</a>
|
<a href="##">babycode help</a>
|
||||||
</span>
|
</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 -%}
|
{%- endif -%}
|
||||||
{%- endcall -%}
|
{%- endcall -%}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
{%- endwith -%}
|
{%- endwith -%}
|
||||||
{%- else -%}
|
{%- 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="hidden" name="return_to" value="{{request.path}}">
|
||||||
<input type="text" placeholder="Username" name="username" autocomplete="username" required>
|
<input type="text" placeholder="Username" name="username" autocomplete="username" required>
|
||||||
<input type="password" placeholder="Password" name="password" autocomplete="current-password" required>
|
<input type="password" placeholder="Password" name="password" autocomplete="current-password" required>
|
||||||
|
|||||||
Reference in New Issue
Block a user