lib.itmens/journal/apis/post.py

147 lines
3.5 KiB
Python
Raw Normal View History

2025-01-22 08:49:43 -05:00
from typing import List, Literal, Union
from ninja import Field, Schema
from catalog.common.models import Item
from common.api import NOT_FOUND, Result, api
from journal.models.index import JournalIndex, JournalQueryParser
class CustomEmoji(Schema):
shortcode: str
url: str
static_url: str
visible_in_picker: bool
category: str
class AccountField(Schema):
name: str
value: str
verified_at: str | None = None
class Account(Schema):
id: str
username: str
acct: str
url: str
display_name: str
note: str
avatar: str
avatar_static: str
2025-02-08 15:20:52 -05:00
header: str
header_static: str
2025-01-22 08:49:43 -05:00
locked: bool
fields: list[AccountField]
emojis: list[CustomEmoji]
bot: bool
group: bool
discoverable: bool
indexable: bool
moved: Union[None, bool, "Account"] = None
suspended: bool = False
limited: bool = False
created_at: str
# last_status_at: str | None = Field(...)
# statuses_count: int | None
# followers_count: int | None
# following_count: int | None
2025-02-04 12:20:08 -05:00
# source: dict | None = None
2025-01-22 08:49:43 -05:00
class MediaAttachment(Schema):
id: str
type: Literal["unknown", "image", "gifv", "video", "audio"]
url: str
preview_url: str
remote_url: str | None = None
meta: dict
description: str | None = None
blurhash: str | None = None
class StatusMention(Schema):
id: str
username: str
url: str
acct: str
class StatusTag(Schema):
name: str
url: str
class Post(Schema):
id: str
uri: str
created_at: str
account: Account
content: str
visibility: Literal["public", "unlisted", "private", "direct"]
sensitive: bool
spoiler_text: str
2025-02-04 12:29:19 -05:00
media_attachments: list[MediaAttachment]
2025-01-22 08:49:43 -05:00
mentions: list[StatusMention]
tags: list[StatusTag]
emojis: list[CustomEmoji]
reblogs_count: int
favourites_count: int
replies_count: int
url: str | None = Field(...)
in_reply_to_id: str | None = Field(...)
in_reply_to_account_id: str | None = Field(...)
# reblog: Optional["Status"] = Field(...)
# poll: Poll | None = Field(...)
# card: None = Field(...)
language: str | None = Field(...)
text: str | None = Field(...)
edited_at: str | None = None
favourited: bool = False
reblogged: bool = False
muted: bool = False
bookmarked: bool = False
pinned: bool = False
ext_neodb: dict | None = None
class PaginatedPostList(Schema):
data: List[Post]
pages: int
count: int
PostTypes = {"mark", "comment", "review", "collection"}
@api.get(
"/item/{item_uuid}/posts/",
response={200: PaginatedPostList, 401: Result, 404: Result},
tags=["catalog"],
)
def list_posts_for_item(request, item_uuid: str, type: str | None = None):
"""
Get posts for an item
`type` is optional, can be a comma separated list of "comment", "review", "collection", "mark"; default is "comment,review"
"""
item = Item.get_by_url(item_uuid)
if not item:
return NOT_FOUND
types = [t for t in (type or "").split(",") if t in PostTypes]
q = "type:" + ",".join(types or ["comment", "review"])
query = JournalQueryParser(q)
2025-02-22 15:35:31 -05:00
query.filter_by_viewer(request.user.identity)
2025-01-22 08:49:43 -05:00
query.filter("item_id", item.pk)
r = JournalIndex.instance().search(query)
result = {
"data": [
p.to_mastodon_json()
for p in r.posts.prefetch_related("attachments", "author")
],
"pages": r.pages,
"count": r.total,
}
return result