mirror of
https://github.com/ae-utbm/sith.git
synced 2024-12-22 07:41:14 +00:00
113 lines
2.9 KiB
Python
113 lines
2.9 KiB
Python
from pathlib import Path
|
|
from typing import Annotated
|
|
|
|
from annotated_types import MinLen
|
|
from django.contrib.staticfiles.storage import staticfiles_storage
|
|
from django.db.models import Q
|
|
from django.urls import reverse
|
|
from django.utils.text import slugify
|
|
from haystack.query import SearchQuerySet
|
|
from ninja import FilterSchema, ModelSchema, Schema
|
|
from pydantic import AliasChoices, Field
|
|
|
|
from core.models import Group, SithFile, User
|
|
|
|
|
|
class SimpleUserSchema(ModelSchema):
|
|
"""A schema with the minimum amount of information to represent a user."""
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = ["id", "nick_name", "first_name", "last_name"]
|
|
|
|
|
|
class UserProfileSchema(ModelSchema):
|
|
"""The necessary information to show a user profile"""
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = ["id", "nick_name", "first_name", "last_name"]
|
|
|
|
display_name: str
|
|
profile_url: str
|
|
profile_pict: str
|
|
|
|
@staticmethod
|
|
def resolve_display_name(obj: User) -> str:
|
|
return obj.get_display_name()
|
|
|
|
@staticmethod
|
|
def resolve_profile_url(obj: User) -> str:
|
|
return reverse("core:user_profile", kwargs={"user_id": obj.pk})
|
|
|
|
@staticmethod
|
|
def resolve_profile_pict(obj: User) -> str:
|
|
if obj.profile_pict_id is None:
|
|
return staticfiles_storage.url("core/img/unknown.jpg")
|
|
return reverse("core:download", kwargs={"file_id": obj.profile_pict_id})
|
|
|
|
|
|
class SithFileSchema(ModelSchema):
|
|
class Meta:
|
|
model = SithFile
|
|
fields = ["id", "name"]
|
|
|
|
path: str
|
|
|
|
@staticmethod
|
|
def resolve_path(obj: SithFile) -> str:
|
|
return str(Path(obj.get_parent_path()) / obj.name)
|
|
|
|
|
|
class GroupSchema(ModelSchema):
|
|
class Meta:
|
|
model = Group
|
|
fields = ["id", "name"]
|
|
|
|
|
|
class UserFilterSchema(FilterSchema):
|
|
search: Annotated[str, MinLen(1)]
|
|
exclude: list[int] | None = Field(
|
|
None, validation_alias=AliasChoices("exclude", "exclude[]")
|
|
)
|
|
|
|
def filter_search(self, value: str | None) -> Q:
|
|
if not value:
|
|
return Q()
|
|
if len(value) < 3:
|
|
# For small queries, full text search isn't necessary
|
|
return (
|
|
Q(first_name__istartswith=value)
|
|
| Q(last_name__istartswith=value)
|
|
| Q(nick_name__istartswith=value)
|
|
)
|
|
return Q(
|
|
id__in=list(
|
|
SearchQuerySet()
|
|
.models(User)
|
|
.autocomplete(auto=slugify(value).replace("-", " "))
|
|
.values_list("pk", flat=True)
|
|
)
|
|
)
|
|
|
|
def filter_exclude(self, value: set[int] | None) -> Q:
|
|
if not value:
|
|
return Q()
|
|
return ~Q(id__in=value)
|
|
|
|
|
|
class MarkdownSchema(Schema):
|
|
text: str
|
|
|
|
|
|
class FamilyGodfatherSchema(Schema):
|
|
godfather: int
|
|
godchild: int
|
|
|
|
|
|
class UserFamilySchema(Schema):
|
|
"""Represent a graph of a user's family"""
|
|
|
|
users: list[UserProfileSchema]
|
|
relationships: list[FamilyGodfatherSchema]
|