mirror of
https://github.com/ae-utbm/sith.git
synced 2025-03-10 07:17:11 +00:00
Add API endpoint to upload images
This commit is contained in:
parent
6a17e4480e
commit
6ec79966b1
64
core/api.py
64
core/api.py
@ -1,23 +1,30 @@
|
|||||||
|
from io import BytesIO
|
||||||
|
from pathlib import Path
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
import annotated_types
|
import annotated_types
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.core.files.base import ContentFile
|
||||||
|
from django.db import transaction
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from ninja import Query
|
from ninja import Query, UploadedFile
|
||||||
from ninja_extra import ControllerBase, api_controller, paginate, route
|
from ninja_extra import ControllerBase, api_controller, paginate, route
|
||||||
from ninja_extra.exceptions import PermissionDenied
|
from ninja_extra.exceptions import PermissionDenied
|
||||||
from ninja_extra.pagination import PageNumberPaginationExtra
|
from ninja_extra.pagination import PageNumberPaginationExtra
|
||||||
from ninja_extra.schemas import PaginatedResponseSchema
|
from ninja_extra.schemas import PaginatedResponseSchema
|
||||||
|
from PIL import Image, UnidentifiedImageError
|
||||||
|
|
||||||
from club.models import Mailing
|
from club.models import Mailing
|
||||||
from core.auth.api_permissions import CanAccessLookup, CanView
|
from core.auth.api_permissions import CanAccessLookup, CanView, IsOldSubscriber
|
||||||
from core.models import Group, SithFile, User
|
from core.models import Group, SithFile, User
|
||||||
from core.schemas import (
|
from core.schemas import (
|
||||||
FamilyGodfatherSchema,
|
FamilyGodfatherSchema,
|
||||||
GroupSchema,
|
GroupSchema,
|
||||||
MarkdownSchema,
|
MarkdownSchema,
|
||||||
SithFileSchema,
|
SithFileSchema,
|
||||||
|
UploadedFileSchema,
|
||||||
UserFamilySchema,
|
UserFamilySchema,
|
||||||
UserFilterSchema,
|
UserFilterSchema,
|
||||||
UserProfileSchema,
|
UserProfileSchema,
|
||||||
@ -33,6 +40,59 @@ class MarkdownController(ControllerBase):
|
|||||||
return HttpResponse(markdown(body.text), content_type="text/html")
|
return HttpResponse(markdown(body.text), content_type="text/html")
|
||||||
|
|
||||||
|
|
||||||
|
@api_controller("/upload")
|
||||||
|
class UploadController(ControllerBase):
|
||||||
|
@route.post("/images", response=UploadedFileSchema, permissions=[IsOldSubscriber])
|
||||||
|
def upload_assets(self, file: UploadedFile):
|
||||||
|
if file.content_type.split("/")[0] != "image":
|
||||||
|
return self.create_response(
|
||||||
|
message=f"{file.name} isn't a file image", status_code=400
|
||||||
|
)
|
||||||
|
|
||||||
|
def convert_image(file: UploadedFile) -> ContentFile:
|
||||||
|
content = BytesIO()
|
||||||
|
Image.open(BytesIO(file.read())).save(
|
||||||
|
fp=content, format="webp", optimize=True
|
||||||
|
)
|
||||||
|
return ContentFile(content.getvalue())
|
||||||
|
|
||||||
|
try:
|
||||||
|
converted = convert_image(file)
|
||||||
|
except UnidentifiedImageError:
|
||||||
|
return self.create_response(
|
||||||
|
message=f"{file.name} can't be processed", status_code=400
|
||||||
|
)
|
||||||
|
|
||||||
|
with transaction.atomic():
|
||||||
|
parent = SithFile.objects.filter(parent=None, name="upload").first()
|
||||||
|
if parent is None:
|
||||||
|
root = User.objects.get(id=settings.SITH_ROOT_USER_ID)
|
||||||
|
parent = SithFile.objects.create(
|
||||||
|
parent=None,
|
||||||
|
name="upload",
|
||||||
|
owner=root,
|
||||||
|
)
|
||||||
|
image = SithFile(
|
||||||
|
parent=parent,
|
||||||
|
name=f"{Path(file.name).stem}_{uuid4()}.webp",
|
||||||
|
file=converted,
|
||||||
|
owner=self.context.request.user,
|
||||||
|
is_folder=False,
|
||||||
|
mime_type="img/webp",
|
||||||
|
size=converted.size,
|
||||||
|
moderator=self.context.request.user,
|
||||||
|
is_moderated=True,
|
||||||
|
)
|
||||||
|
image.file.name = image.name
|
||||||
|
image.clean()
|
||||||
|
image.save()
|
||||||
|
image.view_groups.add(
|
||||||
|
Group.objects.filter(id=settings.SITH_GROUP_PUBLIC_ID).first()
|
||||||
|
)
|
||||||
|
image.save()
|
||||||
|
return image
|
||||||
|
|
||||||
|
|
||||||
@api_controller("/mailings")
|
@api_controller("/mailings")
|
||||||
class MailingListController(ControllerBase):
|
class MailingListController(ControllerBase):
|
||||||
@route.get("", response=str)
|
@route.get("", response=str)
|
||||||
|
@ -856,6 +856,10 @@ Welcome to the wiki page!
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Upload folder
|
||||||
|
SithFile.objects.create(name="upload", owner=root)
|
||||||
|
(settings.MEDIA_ROOT / "upload").mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
def _create_profile_pict(self, user: User):
|
def _create_profile_pict(self, user: User):
|
||||||
path = self.SAS_FIXTURE_PATH / "Family" / f"{user.username}.jpg"
|
path = self.SAS_FIXTURE_PATH / "Family" / f"{user.username}.jpg"
|
||||||
file = resize_image(Image.open(path), 400, "WEBP")
|
file = resize_image(Image.open(path), 400, "WEBP")
|
||||||
|
@ -9,6 +9,7 @@ from django.utils.text import slugify
|
|||||||
from haystack.query import SearchQuerySet
|
from haystack.query import SearchQuerySet
|
||||||
from ninja import FilterSchema, ModelSchema, Schema
|
from ninja import FilterSchema, ModelSchema, Schema
|
||||||
from pydantic import AliasChoices, Field
|
from pydantic import AliasChoices, Field
|
||||||
|
from pydantic_core import Url
|
||||||
|
|
||||||
from core.models import Group, SithFile, User
|
from core.models import Group, SithFile, User
|
||||||
|
|
||||||
@ -47,6 +48,18 @@ class UserProfileSchema(ModelSchema):
|
|||||||
return reverse("core:download", kwargs={"file_id": obj.profile_pict_id})
|
return reverse("core:download", kwargs={"file_id": obj.profile_pict_id})
|
||||||
|
|
||||||
|
|
||||||
|
class UploadedFileSchema(ModelSchema):
|
||||||
|
class Meta:
|
||||||
|
model = SithFile
|
||||||
|
fields = ["id", "name", "mime_type", "size"]
|
||||||
|
|
||||||
|
href: str
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_href(obj: SithFile) -> Url:
|
||||||
|
return reverse("core:download", kwargs={"file_id": obj.id})
|
||||||
|
|
||||||
|
|
||||||
class SithFileSchema(ModelSchema):
|
class SithFileSchema(ModelSchema):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SithFile
|
model = SithFile
|
||||||
|
Loading…
x
Reference in New Issue
Block a user