9
9
from rest_framework .decorators import action
10
10
from rest_framework .response import Response
11
11
12
- from marsha .core import defaults , permissions as core_permissions
12
+ from marsha .core import defaults , permissions as core_permissions , storage
13
13
from marsha .core .api import APIViewMixin , ObjectPkMixin , ObjectRelatedMixin
14
14
from marsha .core .models import ADMINISTRATOR , LTI_ROLES , STUDENT
15
- from marsha .core .utils .s3_utils import create_presigned_post
16
- from marsha .core .utils .time_utils import to_timestamp
15
+ from marsha .core .utils .time_utils import to_datetime , to_timestamp
17
16
from marsha .deposit import permissions , serializers
18
17
from marsha .deposit .defaults import LTI_ROUTE
19
18
from marsha .deposit .forms import FileDepositoryForm
@@ -301,20 +300,20 @@ def initiate_upload(
301
300
):
302
301
"""Get an upload policy for a deposited file.
303
302
304
- Calling the endpoint resets the upload state to `pending` and returns an upload policy to
305
- our AWS S3 source bucket.
303
+ Calling the endpoint resets the upload state to `pending` and returns an upload
304
+ policy to our S3 storage bucket.
306
305
307
306
Parameters
308
307
----------
309
308
request : Type[django.http.request.HttpRequest]
310
309
The request on the API endpoint
311
310
pk: string
312
- The primary key of the shared live media
311
+ The primary key of the deposited file
313
312
314
313
Returns
315
314
-------
316
315
Type[rest_framework.response.Response]
317
- HttpResponse carrying the AWS S3 upload policy as a JSON object.
316
+ HttpResponse carrying the S3 storage upload policy as a JSON object.
318
317
319
318
"""
320
319
deposited_file = self .get_object () # check permissions first
@@ -326,20 +325,26 @@ def initiate_upload(
326
325
if serializer .is_valid () is not True :
327
326
return Response (serializer .errors , status = 400 )
328
327
329
- now = timezone .now ()
330
- stamp = to_timestamp (now )
331
-
332
- key = deposited_file .get_source_s3_key (
333
- stamp = stamp , extension = serializer .validated_data ["extension" ]
334
- )
335
-
336
- presigned_post = create_presigned_post (
337
- [
338
- ["eq" , "$Content-Type" , serializer .validated_data ["mimetype" ]],
339
- ["content-length-range" , 0 , settings .DEPOSITED_FILE_SOURCE_MAX_SIZE ],
340
- ],
341
- {},
342
- key ,
328
+ filename = serializer .validated_data ["filename" ]
329
+ extension = serializer .validated_data ["extension" ]
330
+
331
+ if not filename .endswith (extension ):
332
+ filename = f"{ filename } { extension } "
333
+
334
+ presigned_post = (
335
+ storage .get_initiate_backend ().initiate_deposited_file_storage_upload (
336
+ request ,
337
+ deposited_file ,
338
+ filename ,
339
+ [
340
+ ["eq" , "$Content-Type" , serializer .validated_data ["mimetype" ]],
341
+ [
342
+ "content-length-range" ,
343
+ 0 ,
344
+ settings .DEPOSITED_FILE_SOURCE_MAX_SIZE ,
345
+ ],
346
+ ],
347
+ )
343
348
)
344
349
345
350
# Reset the upload state of the deposited file
@@ -349,3 +354,44 @@ def initiate_upload(
349
354
)
350
355
351
356
return Response (presigned_post )
357
+
358
+ @action (methods = ["post" ], detail = True , url_path = "upload-ended" )
359
+ # pylint: disable=unused-argument
360
+ def upload_ended (
361
+ self ,
362
+ request ,
363
+ pk = None ,
364
+ filedepository_id = None ,
365
+ ):
366
+ """Notify the API that the deposited file upload has ended.
367
+
368
+ Calling the endpoint will update the upload state of the deposited file.
369
+ The request should have a file_key in the body, which is the key of the
370
+ uploaded file.
371
+
372
+ Parameters
373
+ ----------
374
+ request : Type[django.http.request.HttpRequest]
375
+ The request on the API endpoint
376
+ pk: string
377
+ The primary key of the deposited file
378
+
379
+ Returns
380
+ -------
381
+ Type[rest_framework.response.Response]
382
+ HttpResponse with the serialized deposited file.
383
+ """
384
+ deposited_file = self .get_object () # check permissions first
385
+
386
+ serializer = serializers .DepositedFileUploadEndedSerializer (
387
+ data = request .data , context = {"obj" : deposited_file }
388
+ )
389
+
390
+ serializer .is_valid (raise_exception = True )
391
+
392
+ now = timezone .now ()
393
+ stamp = to_timestamp (now )
394
+
395
+ deposited_file .update_upload_state (defaults .READY , to_datetime (stamp ))
396
+
397
+ return Response (serializer .data )
0 commit comments