api: add roles to user endpoint; add post_id to mark/review/collection/note
This commit is contained in:
parent
ffcf33fb3b
commit
c186d7d6ed
9 changed files with 70 additions and 23 deletions
|
@ -6,12 +6,34 @@ from django.http import HttpResponse
|
|||
from django.utils import timezone
|
||||
from ninja import Schema
|
||||
|
||||
from common.api import *
|
||||
from common.api import RedirectedResult, Result, api
|
||||
|
||||
from .common import *
|
||||
from .models import *
|
||||
from .common import SiteManager
|
||||
from .models import (
|
||||
Album,
|
||||
AlbumSchema,
|
||||
Edition,
|
||||
EditionSchema,
|
||||
Game,
|
||||
GameSchema,
|
||||
Item,
|
||||
ItemSchema,
|
||||
Movie,
|
||||
MovieSchema,
|
||||
Performance,
|
||||
PerformanceProduction,
|
||||
PerformanceProductionSchema,
|
||||
PerformanceSchema,
|
||||
Podcast,
|
||||
PodcastSchema,
|
||||
TVEpisode,
|
||||
TVEpisodeSchema,
|
||||
TVSeason,
|
||||
TVSeasonSchema,
|
||||
TVShow,
|
||||
TVShowSchema,
|
||||
)
|
||||
from .search.models import enqueue_fetch, get_fetch_lock, query_index
|
||||
from .sites import *
|
||||
|
||||
|
||||
class SearchResult(Schema):
|
|
@ -7,7 +7,7 @@ class CatalogConfig(AppConfig):
|
|||
|
||||
def ready(self):
|
||||
# load key modules in proper order, make sure class inject and signal works as expected
|
||||
from catalog import api, models, sites # noqa
|
||||
from catalog import apis, models, sites # noqa
|
||||
from catalog.models import init_catalog_audit_log, init_catalog_search_models
|
||||
from journal import models as journal_models # noqa
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ from ..models import Collection
|
|||
class CollectionSchema(Schema):
|
||||
uuid: str
|
||||
url: str
|
||||
|
||||
visibility: int = Field(ge=0, le=2)
|
||||
post_id: int | None = Field(alias="latest_post_id")
|
||||
created_time: datetime
|
||||
title: str
|
||||
brief: str
|
||||
|
|
|
@ -12,6 +12,7 @@ from ..models import Note
|
|||
|
||||
class NoteSchema(Schema):
|
||||
uuid: str
|
||||
post_id: int | None = Field(alias="latest_post_id")
|
||||
item: ItemSchema
|
||||
title: str
|
||||
content: str
|
||||
|
|
|
@ -16,8 +16,8 @@ from ..models import (
|
|||
|
||||
class ReviewSchema(Schema):
|
||||
url: str
|
||||
|
||||
visibility: int = Field(ge=0, le=2)
|
||||
post_id: int | None = Field(alias="latest_post_id")
|
||||
item: ItemSchema
|
||||
created_time: datetime
|
||||
title: str
|
||||
|
|
|
@ -9,6 +9,7 @@ from ninja.pagination import paginate
|
|||
from catalog.common.models import AvailableItemCategory, Item, ItemCategory, ItemSchema
|
||||
from common.api import PageNumberPagination, Result, api
|
||||
from journal.models.common import q_owned_piece_visible_to_user
|
||||
from journal.models.shelf import ShelfMember
|
||||
from users.models.apidentity import APIdentity
|
||||
|
||||
from ..models import (
|
||||
|
@ -21,7 +22,7 @@ from ..models import (
|
|||
class MarkSchema(Schema):
|
||||
shelf_type: ShelfType
|
||||
visibility: int = Field(ge=0, le=2)
|
||||
|
||||
post_id: int | None = Field(alias="latest_post_id")
|
||||
item: ItemSchema
|
||||
created_time: datetime
|
||||
comment_text: str | None
|
||||
|
@ -40,9 +41,9 @@ class MarkInSchema(Schema):
|
|||
|
||||
|
||||
@api.get(
|
||||
"/user/{username}/shelf/{type}",
|
||||
response={200: List[MarkSchema], 401: Result, 403: Result},
|
||||
tags=["mark"],
|
||||
"/user/{handle}/shelf/{type}",
|
||||
response={200: List[MarkSchema], 401: Result, 403: Result, 404: Result},
|
||||
tags=["shelf"],
|
||||
)
|
||||
@paginate(PageNumberPagination)
|
||||
def list_marks_on_user_shelf(
|
||||
|
@ -57,13 +58,18 @@ def list_marks_on_user_shelf(
|
|||
Shelf's `type` should be one of `wishlist` / `progress` / `complete` / `dropped`;
|
||||
`category` is optional, marks for all categories will be returned if not specified.
|
||||
"""
|
||||
target = APIdentity.get_by_handle(handle)
|
||||
try:
|
||||
target = APIdentity.get_by_handle(handle)
|
||||
except APIdentity.DoesNotExist:
|
||||
return ShelfMember.objects.none()
|
||||
viewer = request.user.identity
|
||||
if target.is_blocking(viewer) or target.is_blocked_by(viewer):
|
||||
return 403, {"message": "unavailable"}
|
||||
return ShelfMember.objects.none()
|
||||
qv = q_owned_piece_visible_to_user(request.user, target)
|
||||
queryset = (
|
||||
target.shelf_manager.get_latest_members(type, ItemCategory(category))
|
||||
target.shelf_manager.get_latest_members(
|
||||
type, ItemCategory(category) if category else None
|
||||
)
|
||||
.filter(qv)
|
||||
.prefetch_related("item")
|
||||
)
|
||||
|
@ -73,7 +79,7 @@ def list_marks_on_user_shelf(
|
|||
@api.get(
|
||||
"/me/shelf/{type}",
|
||||
response={200: List[MarkSchema], 401: Result, 403: Result},
|
||||
tags=["mark"],
|
||||
tags=["shelf"],
|
||||
)
|
||||
@paginate(PageNumberPagination)
|
||||
def list_marks_on_shelf(
|
||||
|
@ -94,7 +100,7 @@ def list_marks_on_shelf(
|
|||
@api.get(
|
||||
"/me/shelf/item/{item_uuid}",
|
||||
response={200: MarkSchema, 302: Result, 401: Result, 403: Result, 404: Result},
|
||||
tags=["mark"],
|
||||
tags=["shelf"],
|
||||
)
|
||||
def get_mark_by_item(request, item_uuid: str, response: HttpResponse):
|
||||
"""
|
||||
|
@ -115,7 +121,7 @@ def get_mark_by_item(request, item_uuid: str, response: HttpResponse):
|
|||
@api.post(
|
||||
"/me/shelf/item/{item_uuid}",
|
||||
response={200: Result, 401: Result, 403: Result, 404: Result},
|
||||
tags=["mark"],
|
||||
tags=["shelf"],
|
||||
)
|
||||
def mark_item(request, item_uuid: str, mark: MarkInSchema):
|
||||
"""
|
||||
|
@ -147,7 +153,7 @@ def mark_item(request, item_uuid: str, mark: MarkInSchema):
|
|||
@api.delete(
|
||||
"/me/shelf/item/{item_uuid}",
|
||||
response={200: Result, 401: Result, 403: Result, 404: Result},
|
||||
tags=["mark"],
|
||||
tags=["shelf"],
|
||||
)
|
||||
def delete_mark(request, item_uuid: str):
|
||||
"""
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
from typing import Literal
|
||||
|
||||
from django.conf import settings
|
||||
from ninja import Schema
|
||||
from ninja.schema import Field
|
||||
|
||||
from common.api import *
|
||||
from mastodon.models.common import SocialAccount
|
||||
from common.api import NOT_FOUND, Result, api
|
||||
from mastodon.models import SocialAccount
|
||||
from users.models import APIdentity
|
||||
|
||||
|
||||
class ExternalAccountSchema(Schema):
|
||||
|
@ -18,6 +22,7 @@ class UserSchema(Schema):
|
|||
display_name: str
|
||||
avatar: str
|
||||
username: str
|
||||
roles: list[Literal["admin", "staff"]]
|
||||
|
||||
|
||||
@api.get(
|
||||
|
@ -37,12 +42,13 @@ def me(request):
|
|||
"external_accounts": accts,
|
||||
"display_name": request.user.display_name,
|
||||
"avatar": request.user.avatar,
|
||||
"roles": request.user.get_roles(),
|
||||
}
|
||||
|
||||
|
||||
@api.get(
|
||||
"/user/{handle}",
|
||||
response={200: UserSchema, 401: Result, 403: Result},
|
||||
response={200: UserSchema, 401: Result, 403: Result, 404: Result},
|
||||
tags=["user"],
|
||||
)
|
||||
def user(request, handle: str):
|
||||
|
@ -51,7 +57,10 @@ def user(request, handle: str):
|
|||
|
||||
More detailed info can be fetched from Mastodon API
|
||||
"""
|
||||
target = APIdentity.get_by_handle(handle)
|
||||
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"}
|
||||
|
@ -62,4 +71,5 @@ def user(request, handle: str):
|
|||
"external_accounts": [],
|
||||
"display_name": target.display_name,
|
||||
"avatar": target.avatar,
|
||||
"roles": target.user.get_roles() if target.local else [],
|
||||
}
|
|
@ -5,7 +5,7 @@ class UsersConfig(AppConfig):
|
|||
name = "users"
|
||||
|
||||
def ready(self):
|
||||
from . import api # noqa
|
||||
from . import apis # noqa
|
||||
|
||||
# register cron jobs
|
||||
from users.jobs import MastodonUserSync # noqa
|
||||
|
|
|
@ -171,6 +171,14 @@ class User(AbstractUser):
|
|||
def __str__(self):
|
||||
return f"{self.pk}:{self.username or '<missing>'}"
|
||||
|
||||
def get_roles(self):
|
||||
roles = []
|
||||
if self.is_staff:
|
||||
roles.append("staff")
|
||||
if self.is_superuser:
|
||||
roles.append("admin")
|
||||
return roles
|
||||
|
||||
@property
|
||||
def registration_complete(self):
|
||||
return self.username is not None
|
||||
|
|
Loading…
Add table
Reference in a new issue