add mentions
This commit is contained in:
@@ -41,7 +41,7 @@ def babycode_preview():
|
||||
if not markup or not isinstance(markup, str):
|
||||
return {'error': 'markup field missing or invalid type'}, 400
|
||||
banned_tags = request.json.get('banned_tags', [])
|
||||
rendered = babycode_to_html(markup, banned_tags)
|
||||
rendered = babycode_to_html(markup, banned_tags).result
|
||||
return {'html': rendered}
|
||||
|
||||
|
||||
@@ -213,3 +213,16 @@ def bookmark_thread(thread_id):
|
||||
return {'error': 'bad request'}, 400
|
||||
|
||||
return {'status': 'ok'}, 200
|
||||
|
||||
@bp.get('/current-user')
|
||||
def get_current_user_info():
|
||||
if not is_logged_in():
|
||||
return {'user': null}
|
||||
|
||||
user = get_active_user()
|
||||
return {
|
||||
'user': {
|
||||
'username': user.username,
|
||||
'display_name': user.display_name,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ def motd_editor_form():
|
||||
data = {
|
||||
'title': title,
|
||||
'body_original_markup': orig_body,
|
||||
'body_rendered': babycode_to_html(orig_body, banned_tags=MOTD_BANNED_TAGS),
|
||||
'body_rendered': babycode_to_html(orig_body, banned_tags=MOTD_BANNED_TAGS).result,
|
||||
'format_version': BABYCODE_VERSION,
|
||||
'edited_at': int(time.time()),
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ from .users import login_required, get_active_user
|
||||
from ..lib.babycode import babycode_to_html, BABYCODE_VERSION
|
||||
from ..constants import InfoboxKind
|
||||
from ..db import db
|
||||
from ..models import Posts, PostHistory, Threads, Topics
|
||||
from ..models import Posts, PostHistory, Threads, Topics, Mentions
|
||||
|
||||
bp = Blueprint("posts", __name__, url_prefix = "/post")
|
||||
|
||||
@@ -21,13 +21,22 @@ def create_post(thread_id, user_id, content, markup_language="babycode"):
|
||||
|
||||
revision = PostHistory.create({
|
||||
"post_id": post.id,
|
||||
"content": parsed_content,
|
||||
"content": parsed_content.result,
|
||||
"is_initial_revision": True,
|
||||
"original_markup": content,
|
||||
"markup_language": markup_language,
|
||||
"format_version": BABYCODE_VERSION,
|
||||
})
|
||||
|
||||
for mention in parsed_content.mentions:
|
||||
Mentions.create({
|
||||
'revision_id': revision.id,
|
||||
'mentioned_user_id': mention['mentioned_user_id'],
|
||||
'original_mention_text': mention['mention_text'],
|
||||
'start_index': mention['start'],
|
||||
'end_index': mention['end'],
|
||||
})
|
||||
|
||||
post.update({"current_revision_id": revision.id})
|
||||
return post
|
||||
|
||||
@@ -38,13 +47,22 @@ def update_post(post_id, new_content, markup_language='babycode'):
|
||||
post = Posts.find({'id': post_id})
|
||||
new_revision = PostHistory.create({
|
||||
'post_id': post.id,
|
||||
'content': parsed_content,
|
||||
'content': parsed_content.result,
|
||||
'is_initial_revision': False,
|
||||
'original_markup': new_content,
|
||||
'markup_language': markup_language,
|
||||
'format_version': BABYCODE_VERSION,
|
||||
})
|
||||
|
||||
for mention in parsed_content.mentions:
|
||||
Mentions.create({
|
||||
'revision_id': new_revision.id,
|
||||
'mentioned_user_id': mention['mentioned_user_id'],
|
||||
'original_mention_text': mention['mention_text'],
|
||||
'start_index': mention['start'],
|
||||
'end_index': mention['end'],
|
||||
})
|
||||
|
||||
post.update({'current_revision_id': new_revision.id})
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ def thread(slug):
|
||||
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()
|
||||
|
||||
@@ -4,7 +4,7 @@ from flask import (
|
||||
from functools import wraps
|
||||
from ..db import db
|
||||
from ..lib.babycode import babycode_to_html, BABYCODE_VERSION
|
||||
from ..models import Users, Sessions, Subscriptions, Avatars, PasswordResetLinks, InviteKeys, BookmarkCollections, BookmarkedThreads
|
||||
from ..models import Users, Sessions, Subscriptions, Avatars, PasswordResetLinks, InviteKeys, BookmarkCollections, BookmarkedThreads, Mentions, PostHistory
|
||||
from ..constants import InfoboxKind, PermissionLevel
|
||||
from ..auth import digest, verify
|
||||
from wand.image import Image
|
||||
@@ -90,6 +90,15 @@ def validate_username(username):
|
||||
return bool(re.fullmatch(pattern, username))
|
||||
|
||||
|
||||
def validate_display_name(display_name):
|
||||
if not display_name:
|
||||
return True
|
||||
|
||||
pattern = r'^[\w!#$%^*\(\)\-_=+\[\]\{\}\|;:,.?\s]{3,50}$'
|
||||
display_name = display_name.replace('@', '_')
|
||||
return bool(re.fullmatch(pattern, display_name))
|
||||
|
||||
|
||||
def redirect_if_logged_in(*args, **kwargs):
|
||||
def decorator(view_func):
|
||||
@wraps(view_func)
|
||||
@@ -184,7 +193,7 @@ def log_in():
|
||||
@redirect_if_logged_in(".page", username = lambda: get_active_user().username)
|
||||
def log_in_post():
|
||||
target_user = Users.find({
|
||||
"username": request.form['username']
|
||||
"username": request.form['username'].lower()
|
||||
})
|
||||
if not target_user:
|
||||
flash("Incorrect username or password.", InfoboxKind.ERROR)
|
||||
@@ -239,7 +248,7 @@ def sign_up_post():
|
||||
flash("Invalid username.", InfoboxKind.ERROR)
|
||||
return redirect(url_for("users.sign_up", key=key))
|
||||
|
||||
user_exists = Users.count({"username": username}) > 0
|
||||
user_exists = Users.count({"username": username.lower()}) > 0
|
||||
if user_exists:
|
||||
flash(f"Username '{username}' is already taken.", InfoboxKind.ERROR)
|
||||
return redirect(url_for("users.sign_up", key=key))
|
||||
@@ -254,8 +263,14 @@ def sign_up_post():
|
||||
|
||||
hashed = digest(password)
|
||||
|
||||
if username.lower() != username:
|
||||
display_name = username
|
||||
else:
|
||||
display_name = ''
|
||||
|
||||
new_user = Users.create({
|
||||
"username": username,
|
||||
'display_name': display_name,
|
||||
"password_hash": hashed,
|
||||
"permission": PermissionLevel.GUEST.value,
|
||||
})
|
||||
@@ -279,14 +294,14 @@ def sign_up_post():
|
||||
|
||||
@bp.get("/<username>")
|
||||
def page(username):
|
||||
target_user = Users.find({"username": username})
|
||||
target_user = Users.find({"username": username.lower()})
|
||||
return render_template("users/user.html", target_user = target_user)
|
||||
|
||||
|
||||
@bp.get("/<username>/settings")
|
||||
@login_required
|
||||
def settings(username):
|
||||
target_user = Users.find({'username': username})
|
||||
target_user = Users.find({'username': username.lower()})
|
||||
if target_user.id != get_active_user().id:
|
||||
return redirect('.settings', username = get_active_user().username)
|
||||
|
||||
@@ -311,10 +326,16 @@ def settings_form(username):
|
||||
status = request.form.get('status', default="")[:100]
|
||||
original_sig = request.form.get('signature', default='').strip()
|
||||
if original_sig:
|
||||
rendered_sig = babycode_to_html(original_sig)
|
||||
rendered_sig = babycode_to_html(original_sig).result
|
||||
else:
|
||||
rendered_sig = ''
|
||||
session['subscribe_by_default'] = request.form.get('subscribe_by_default', default='off') == 'on'
|
||||
display_name = request.form.get('display_name', default='')
|
||||
if not validate_display_name(display_name):
|
||||
flash('Invalid display name.', InfoboxKind.ERROR)
|
||||
return redirect('.settings', username=user.username)
|
||||
|
||||
old_dn = user.display_name
|
||||
|
||||
user.update({
|
||||
'status': status,
|
||||
@@ -322,7 +343,22 @@ def settings_form(username):
|
||||
'signature_rendered': rendered_sig,
|
||||
'signature_format_version': BABYCODE_VERSION,
|
||||
'signature_markup_language': 'babycode',
|
||||
'display_name': display_name,
|
||||
})
|
||||
|
||||
if old_dn != display_name:
|
||||
# re-parse mentions
|
||||
q = """SELECT DISTINCT m.revision_id FROM mentions m
|
||||
JOIN post_history ph ON m.revision_id = ph.id
|
||||
JOIN posts p ON p.current_revision_id = ph.id
|
||||
WHERE m.mentioned_user_id = ?"""
|
||||
mentions = db.query(q, int(user.id))
|
||||
with db.transaction():
|
||||
for mention in mentions:
|
||||
rev = PostHistory.find({'id': int(mention['revision_id'])})
|
||||
parsed_content = babycode_to_html(rev.original_markup).result
|
||||
rev.update({'content': parsed_content})
|
||||
|
||||
flash('Settings updated.', InfoboxKind.INFO)
|
||||
return redirect(url_for('.settings', username=user.username))
|
||||
|
||||
@@ -488,7 +524,7 @@ def guest_user(user_id):
|
||||
@login_required
|
||||
def inbox(username):
|
||||
user = get_active_user()
|
||||
if username != user.username:
|
||||
if username.lower() != user.username:
|
||||
return redirect(url_for(".inbox", username = user.username))
|
||||
|
||||
new_posts = []
|
||||
@@ -630,7 +666,7 @@ def reset_link_login_form(key):
|
||||
@login_required
|
||||
def invite_links(username):
|
||||
target_user = Users.find({
|
||||
'username': username
|
||||
'username': username.lower()
|
||||
})
|
||||
if not target_user or not target_user.can_invite():
|
||||
return redirect(url_for('.page', username=username))
|
||||
@@ -649,10 +685,10 @@ def invite_links(username):
|
||||
@login_required
|
||||
def create_invite_link(username):
|
||||
target_user = Users.find({
|
||||
'username': username
|
||||
'username': username.lower()
|
||||
})
|
||||
if not target_user or not target_user.can_invite():
|
||||
return redirect(url_for('.page', username=username))
|
||||
return redirect(url_for('.page', username=username.lower()))
|
||||
|
||||
if target_user.username != get_active_user().username:
|
||||
return redirect(url_for('.invite_links', username=target_user.username))
|
||||
@@ -669,10 +705,10 @@ def create_invite_link(username):
|
||||
@login_required
|
||||
def revoke_invite_link(username):
|
||||
target_user = Users.find({
|
||||
'username': username
|
||||
'username': username.lower()
|
||||
})
|
||||
if not target_user or not target_user.can_invite():
|
||||
return redirect(url_for('.page', username=username))
|
||||
return redirect(url_for('.page', username=username.lower()))
|
||||
|
||||
if target_user.username != get_active_user().username:
|
||||
return redirect(url_for('.invite_links', username=target_user.username))
|
||||
@@ -695,7 +731,7 @@ def revoke_invite_link(username):
|
||||
@bp.get('/<username>/bookmarks')
|
||||
@login_required
|
||||
def bookmarks(username):
|
||||
target_user = Users.find({'username': username})
|
||||
target_user = Users.find({'username': username.lower()})
|
||||
if not target_user or target_user.username != get_active_user().username:
|
||||
return redirect(url_for('.bookmarks', username=get_active_user().username))
|
||||
|
||||
@@ -707,7 +743,7 @@ def bookmarks(username):
|
||||
@bp.get('/<username>/bookmarks/collections')
|
||||
@login_required
|
||||
def bookmark_collections(username):
|
||||
target_user = Users.find({'username': username})
|
||||
target_user = Users.find({'username': username.lower()})
|
||||
if not target_user or target_user.username != get_active_user().username:
|
||||
return redirect(url_for('.bookmark_collections', username=get_active_user().username))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user