from typing import Literal from django.conf import settings from ninja import Schema from ninja.schema import Field from common.api import NOT_FOUND, Result, api from mastodon.models import SocialAccount from users.models import APIdentity class ExternalAccountSchema(Schema): platform: str handle: str url: str | None class UserSchema(Schema): url: str external_acct: str | None = Field(deprecated=True) external_accounts: list[ExternalAccountSchema] display_name: str avatar: str username: str roles: list[Literal["admin", "staff"]] class PreferenceSchema(Schema): default_crosspost: bool = Field(alias="mastodon_default_repost") default_visibility: int hidden_categories: list[str] language: str = Field(alias="user.language") @api.get( "/me", response={200: UserSchema, 401: Result}, summary="Get current user's basic info", tags=["user"], ) def me(request): accts = SocialAccount.objects.filter(user=request.user) return 200, { # "id": str(request.user.identity.pk), "username": request.user.username, "url": settings.SITE_INFO["site_url"] + request.user.url, "external_acct": ( request.user.mastodon.handle if request.user.mastodon else None ), "external_accounts": accts, "display_name": request.user.display_name, "avatar": request.user.avatar, "roles": request.user.get_roles(), } @api.get( "/me/preference", response={200: PreferenceSchema, 401: Result}, summary="Get current user's preference", tags=["user"], ) def preference(request): return 200, request.user.preference @api.get( "/user/{handle}", response={200: UserSchema, 401: Result, 403: Result, 404: Result}, tags=["user"], ) def user(request, handle: str): """ Get user's basic info More detailed info can be fetched from Mastodon API """ try: target = APIdentity.get_by_handle(handle) except APIdentity.DoesNotExist: return NOT_FOUND viewer = request.user.identity if target.is_blocking(viewer) or target.is_blocked_by(viewer): return 403, {"message": "unavailable"} return 200, { "username": target.handle, "url": target.url, "external_acct": None, "external_accounts": [], "display_name": target.display_name, "avatar": target.avatar, "roles": target.user.get_roles() if target.local else [], }