Files
pyrom/app/routes/api.py
2026-06-07 23:01:58 +03:00

90 lines
2.7 KiB
Python

from flask import Blueprint, request
from ..auth import is_logged_in, hard_login_required, get_active_user
from ..lib.babycode import babycode_to_html
from ..models import APIRateLimits, Posts, Threads, Reactions
from ..constants import REACTION_EMOJI
bp = Blueprint('api', __name__, url_prefix='/api/')
@bp.before_request
def ensure_json():
if request.method == 'POST':
if not request.is_json:
return {'error': 'unsupported media type'}, 415
elif not request.content_length:
return {'error': 'body expected'}, 400
elif not isinstance(request.json, dict):
return {'error': 'body must be an object'}, 400
@bp.post('/babycode-preview/')
@hard_login_required
def babycode_preview():
user = get_active_user()
if not APIRateLimits.is_allowed(user.id, 'babycode_preview', 5):
return {'error': 'too many requests'}, 429
markup = str(request.json.get('markup', ''))
if not markup:
return {'error': 'markup field missing or invalid type'}, 400
banned_tags = request.json.get('banned_tags', [])
if not isinstance(banned_tags, list):
return {'error': 'banned_tags field is invalid type'}, 400
rendered = babycode_to_html(markup, banned_tags).result
return {'html': rendered}
@bp.get('/whoami/')
def whoami():
user = get_active_user()
if not user:
return {}
return {
'id': user.id,
'username': user.username,
'display_name': user.display_name,
}
@bp.post('/toggle-reaction/')
@hard_login_required
def toggle_reaction():
user = get_active_user()
emoji = request.json.get('reaction')
if emoji not in REACTION_EMOJI:
return {'error': f'invalid reaction string, given: {emoji}'}, 400
post_id = request.json.get('post', -1)
post = Posts.find({'id': post_id})
if not post:
return {'error': 'post not found'}, 404
thread = Threads.find({'id': post.thread_id})
if not user.can_post_to_thread_or_topic(thread):
return {'error': 'thread is locked'}, 403
reaction_obj = {
'user_id': int(user.id),
'post_id': int(post_id),
'reaction_text': emoji,
}
r = Reactions.find(reaction_obj)
if r:
# remove
r.delete()
return {'status': 'ok', 'added': False}
else:
# add
r = Reactions.create(reaction_obj)
return {'status': 'ok', 'added': True}
@bp.get('/thread-permission/<int:thread_id>')
def thread_permission(thread_id):
user = get_active_user()
if not user:
return {'can_post': False}
thread = Threads.find({'id': thread_id})
if not thread:
return {'can_post': False}
return {'can_post': user.can_post_to_thread_or_topic(thread)}