81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
## Copyright © 2026 Olaf Kolkman
|
|
## SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import math
|
|
|
|
from fastapi import APIRouter, Depends, Query
|
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
|
|
from backend.app.core.config import settings
|
|
from backend.app.services.link_service import list_public_links, list_public_users
|
|
from backend.app.services.token_service import validate_token
|
|
from backend.app.services.theme_service import THEMES, get_enabled_themes
|
|
|
|
router = APIRouter()
|
|
optional_bearer = HTTPBearer(auto_error=False)
|
|
|
|
|
|
@router.get('/users')
|
|
def public_users():
|
|
return list_public_users()
|
|
|
|
|
|
@router.get('/themes')
|
|
def public_themes():
|
|
enabled = get_enabled_themes()
|
|
return [{'id': theme, **THEMES[theme]} for theme in enabled]
|
|
|
|
|
|
@router.get('/config')
|
|
def public_config():
|
|
return {'feed_page_sizes': settings.feed_page_sizes, 'default_page_size': settings.feed_page_sizes[0]}
|
|
|
|
|
|
@router.get('/feed')
|
|
@router.get('/feed/{username}')
|
|
def public_feed(
|
|
username: str | None = None,
|
|
tag: str | None = None,
|
|
search: str | None = None,
|
|
sort: str = 'newest',
|
|
page: int = Query(1, ge=1),
|
|
page_size: int | None = Query(None, ge=1),
|
|
credentials: HTTPAuthorizationCredentials | None = Depends(optional_bearer),
|
|
):
|
|
current_user_id = None
|
|
if credentials:
|
|
token_data = validate_token(credentials.credentials)
|
|
if token_data:
|
|
current_user_id = token_data['user_id']
|
|
allowed_sizes = settings.feed_page_sizes
|
|
effective_page_size = page_size if page_size in allowed_sizes else allowed_sizes[0]
|
|
result = list_public_links(username, tag=tag, search=search, sort=sort, page=page, page_size=effective_page_size)
|
|
items = [
|
|
{
|
|
'id': item['id'],
|
|
'title': item['title'],
|
|
'url': item['url'],
|
|
'comment': item['comment'],
|
|
'tags': item['tags'],
|
|
'user': {
|
|
'username': item['username'],
|
|
'avatar_url': item['avatar_url'],
|
|
'bio': item['bio'],
|
|
},
|
|
'is_owner': item['user_id'] == current_user_id,
|
|
'can_edit': item['user_id'] == current_user_id,
|
|
'created_at': item['created_at'],
|
|
'mastodon_posted': bool(item['mastodon_posted']),
|
|
}
|
|
for item in result['items']
|
|
]
|
|
total = result['total']
|
|
total_pages = max(1, math.ceil(total / effective_page_size))
|
|
return {
|
|
'items': items,
|
|
'total': total,
|
|
'page': page,
|
|
'page_size': effective_page_size,
|
|
'total_pages': total_pages,
|
|
}
|