2
2
3
3
from django .conf import settings
4
4
from django .db .models import Q
5
- from django .utils import timezone
6
5
7
6
import django_filters
8
7
from rest_framework import filters , mixins , viewsets
9
8
from rest_framework .decorators import action
10
9
from rest_framework .response import Response
11
10
from rest_framework .status import HTTP_200_OK , HTTP_400_BAD_REQUEST
12
11
13
- from marsha .core import defaults , permissions as core_permissions
12
+ from marsha .core import defaults , permissions as core_permissions , storage
14
13
from marsha .core .api import APIViewMixin , ObjectPkMixin , ObjectRelatedMixin
15
14
from marsha .core .models import ADMINISTRATOR
16
- from marsha .core .utils .s3_utils import create_presigned_post
17
- from marsha .core .utils .time_utils import to_timestamp
15
+ from marsha .core .utils .time_utils import to_datetime
18
16
from marsha .markdown import permissions as markdown_permissions , serializers
19
17
from marsha .markdown .defaults import LTI_ROUTE
20
18
from marsha .markdown .forms import MarkdownDocumentForm
@@ -333,7 +331,7 @@ def initiate_upload(self, request, *args, pk=None, **kwargs):
333
331
"""Get an upload policy for a Markdown image.
334
332
335
333
Calling the endpoint resets the upload state to `pending` and returns an upload policy to
336
- our AWS S3 source bucket.
334
+ our S3 storage bucket.
337
335
338
336
Parameters
339
337
----------
@@ -345,33 +343,31 @@ def initiate_upload(self, request, *args, pk=None, **kwargs):
345
343
Returns
346
344
-------
347
345
Type[rest_framework.response.Response]
348
- HttpResponse carrying the AWS S3 upload policy as a JSON object.
346
+ HttpResponse carrying the S3 storage upload policy as a JSON object.
349
347
350
348
"""
351
349
markdown_image = self .get_object () # check permissions first
352
350
353
- serializer = serializers .MarkdownImageUploadSerializer (
351
+ serializer = serializers .MarkdownImageInitiateUploadSerializer (
354
352
data = request .data ,
355
353
)
356
354
357
355
if not serializer .is_valid ():
358
356
return Response (serializer .errors , status = HTTP_400_BAD_REQUEST )
359
357
360
- now = timezone .now ()
361
- stamp = to_timestamp (now )
362
-
363
- key = markdown_image .get_source_s3_key (
364
- stamp = stamp ,
365
- extension = serializer .validated_data ["extension" ],
366
- )
367
-
368
- presigned_post = create_presigned_post (
369
- [
370
- ["starts-with" , "$Content-Type" , "image/" ],
371
- ["content-length-range" , 0 , settings .MARKDOWN_IMAGE_SOURCE_MAX_SIZE ],
372
- ],
373
- {},
374
- key ,
358
+ presigned_post = (
359
+ storage .get_initiate_backend ().initiate_markdown_image_storage_upload (
360
+ request ,
361
+ markdown_image ,
362
+ [
363
+ ["starts-with" , "$Content-Type" , "image/" ],
364
+ [
365
+ "content-length-range" ,
366
+ 0 ,
367
+ settings .MARKDOWN_IMAGE_SOURCE_MAX_SIZE ,
368
+ ],
369
+ ],
370
+ )
375
371
)
376
372
377
373
# Reset the upload state of the Markdown image
@@ -381,3 +377,46 @@ def initiate_upload(self, request, *args, pk=None, **kwargs):
381
377
)
382
378
383
379
return Response (presigned_post )
380
+
381
+ @action (methods = ["post" ], detail = True , url_path = "upload-ended" )
382
+ # pylint: disable=unused-argument
383
+ def upload_ended (
384
+ self ,
385
+ request ,
386
+ pk = None ,
387
+ markdown_document_id = None ,
388
+ ):
389
+ """Notify the API that the markdown image upload has ended.
390
+
391
+ Calling the endpoint will update the upload state of the markdown image.
392
+ The request should have a file_key in the body, which is the key of the
393
+ uploaded file.
394
+
395
+ Parameters
396
+ ----------
397
+ request : Type[django.http.request.HttpRequest]
398
+ The request on the API endpoint
399
+ pk: string
400
+ The primary key of the markdown image
401
+
402
+ Returns
403
+ -------
404
+ Type[rest_framework.response.Response]
405
+ HttpResponse with the serialized markdown image.
406
+ """
407
+ markdown_image = self .get_object () # check permissions first
408
+
409
+ serializer = serializers .MarkdownImageUploadEndedSerializer (
410
+ data = request .data , context = {"obj" : markdown_image }
411
+ )
412
+
413
+ serializer .is_valid (raise_exception = True )
414
+
415
+ file_key = serializer .validated_data ["file_key" ]
416
+ # The file_key have the "markdown/{markdown_pk}/markdownimage/{markdownimage}/
417
+ # {stamp}" format
418
+ stamp = file_key .split ("/" )[- 1 ]
419
+
420
+ markdown_image .update_upload_state (defaults .READY , to_datetime (stamp ))
421
+
422
+ return Response (serializer .data )
0 commit comments