Skip to content

Commit b74337b

Browse files
committed
🚚(back) serve legacy markdown images from Scaleway S3
Markdown images are now served from the aws/ directory in Scaleway S3. They are served using the django-storage already in place. As the newer markdown images are already stored in Scaleway, we do not rename these files and allow them to be served without requiring signed URLs.
1 parent 49a3265 commit b74337b

File tree

5 files changed

+44
-26
lines changed

5 files changed

+44
-26
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Versioning](https://semver.org/spec/v2.0.0.html).
1212

1313
- Serve legacy classroom documents from Scaleway S3 after AWS migration
1414
- Serve legacy videos and related files from Scaleway S3 after AWS migration
15+
- Serve legacy Markdown images from Scaleway S3 after AWS migration
1516

1617
## [5.9.1] - 2025-06-25
1718

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 5.0.9 on 2025-07-09 07:14
2+
3+
from django.db import migrations
4+
5+
from marsha.core.defaults import AWS_S3
6+
7+
8+
def fix_storage_location_to_aws(apps, schema_editor):
9+
"""Fix the storage_location field for existing markdown images on AWS."""
10+
MarkdownImage = apps.get_model("markdown", "MarkdownImage")
11+
MarkdownImage.objects.filter(storage_location="AWS_S3").update(
12+
storage_location=AWS_S3
13+
)
14+
15+
16+
class Migration(migrations.Migration):
17+
dependencies = [
18+
("markdown", "0008_markdownimage_fill_storage_location"),
19+
]
20+
21+
operations = [
22+
migrations.RunPython(fix_storage_location_to_aws, migrations.RunPython.noop),
23+
]

src/backend/marsha/markdown/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from parler.models import TranslatableModelMixin, TranslatedFields
1515

1616
from marsha.core.defaults import (
17+
AWS_STORAGE_BASE_DIRECTORY,
1718
DELETED_STORAGE_BASE_DIRECTORY,
1819
MARKDOWN_DOCUMENT_STORAGE_BASE_DIRECTORY,
1920
SCW_S3,
@@ -240,6 +241,12 @@ def get_storage_key(
240241
stamp = stamp or self.uploaded_on_stamp()
241242

242243
base = base_dir
244+
if base == AWS_STORAGE_BASE_DIRECTORY:
245+
return (
246+
f"{base}/{self.markdown_document.pk}/markdown-image/"
247+
f"{self.pk}/{stamp}.{self.extension.lstrip('.')}"
248+
)
249+
243250
if base == DELETED_STORAGE_BASE_DIRECTORY:
244251
base = f"{base}/{MARKDOWN_DOCUMENT_STORAGE_BASE_DIRECTORY}"
245252

src/backend/marsha/markdown/serializers.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@
99

1010
from rest_framework import serializers
1111

12-
from marsha.core.defaults import MARKDOWN_DOCUMENT_STORAGE_BASE_DIRECTORY, SCW_S3
12+
from marsha.core.defaults import (
13+
AWS_S3,
14+
AWS_STORAGE_BASE_DIRECTORY,
15+
MARKDOWN_DOCUMENT_STORAGE_BASE_DIRECTORY,
16+
)
1317
from marsha.core.serializers import (
1418
BaseInitiateUploadSerializer,
1519
ReadOnlyModelSerializer,
1620
TimestampField,
1721
UploadableFileWithExtensionSerializerMixin,
18-
get_resource_cloudfront_url_params,
1922
)
2023
from marsha.core.serializers.playlist import PlaylistLiteSerializer
2124
from marsha.core.storage.storage_class import file_storage
22-
from marsha.core.utils import cloudfront_utils, time_utils
25+
from marsha.core.utils import time_utils
2326
from marsha.markdown.models import MarkdownDocument, MarkdownImage
2427

2528

@@ -99,23 +102,12 @@ def get_url(self, obj):
99102
if not obj.uploaded_on:
100103
return None
101104

102-
if obj.storage_location == SCW_S3:
105+
if obj.storage_location == AWS_S3:
106+
file_key = obj.get_storage_key(base_dir=AWS_STORAGE_BASE_DIRECTORY)
107+
else:
103108
file_key = obj.get_storage_key()
104109

105-
return file_storage.url(file_key)
106-
107-
base = f"{settings.AWS_S3_URL_PROTOCOL}://{settings.CLOUDFRONT_DOMAIN}"
108-
base = f"{base}/{obj.markdown_document_id}/markdown-image"
109-
stamp = time_utils.to_timestamp(obj.uploaded_on)
110-
url = f"{base}/{obj.pk}/{stamp}.{obj.extension.lstrip('.')}"
111-
112-
if not settings.CLOUDFRONT_SIGNED_URLS_ACTIVE:
113-
return url
114-
115-
params = get_resource_cloudfront_url_params(
116-
"markdown-document", obj.markdown_document_id
117-
)
118-
return cloudfront_utils.build_signed_url(url, params)
110+
return file_storage.url(file_key)
119111

120112

121113
class MarkdownImageInitiateUploadSerializer(BaseInitiateUploadSerializer):

src/backend/marsha/markdown/tests/api/markdown_images/test_retrieve.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ def test_api_markdown_image_instructor_read_detail_in_read_only(self):
7171

7272
self.assertEqual(response.status_code, 403)
7373

74-
@override_settings(CLOUDFRONT_SIGNED_URLS_ACTIVE=False)
7574
def test_api_markdown_image_read_detail_token_user(self):
7675
"""
7776
Instructors should be able to read details of Markdown image
@@ -126,7 +125,6 @@ def test_api_markdown_image_administrator_read_detail_in_read_only(self):
126125

127126
self.assertEqual(response.status_code, 403)
128127

129-
@override_settings(CLOUDFRONT_SIGNED_URLS_ACTIVE=False)
130128
def test_api_markdown_image_read_detail_admin_user(self):
131129
"""
132130
Admin should be able to read details of Markdown image associated
@@ -165,9 +163,7 @@ def test_api_markdown_image_read_detail_admin_user(self):
165163
},
166164
)
167165

168-
@override_settings(
169-
MEDIA_URL="https://abc.svc.edge.scw.cloud/",
170-
)
166+
@override_settings(MEDIA_URL="https://abc.svc.edge.scw.cloud/")
171167
def test_api_markdown_image_read_ready_markdown_image(self):
172168
"""A ready Markdown image on SCW should have computed urls."""
173169
markdown_document = MarkdownDocumentFactory(
@@ -212,6 +208,7 @@ def test_api_markdown_image_read_ready_markdown_image(self):
212208
},
213209
)
214210

211+
@override_settings(MEDIA_URL="https://abc.svc.edge.scw.cloud/")
215212
def test_api_markdown_image_read_ready_markdown_image_aws(self):
216213
"""A ready Markdown image on AWS should have computed urls."""
217214
markdown_document = MarkdownDocumentFactory(
@@ -248,7 +245,7 @@ def test_api_markdown_image_read_ready_markdown_image_aws(self):
248245
"is_ready_to_show": True,
249246
"upload_state": "ready",
250247
"url": (
251-
"https://abc.cloudfront.net/"
248+
"https://abc.svc.edge.scw.cloud/aws/"
252249
"78338c1c-356e-4156-bd95-5bed71ffb655/markdown-image/"
253250
"9ddf9c1f-ec88-4a3a-bfa0-423c4fe89b15/1533686400.gif"
254251
),
@@ -272,7 +269,6 @@ def test_api_markdown_image_read_detail_user_access_token(self):
272269

273270
self.assertEqual(response.status_code, 403)
274271

275-
@override_settings(CLOUDFRONT_SIGNED_URLS_ACTIVE=False)
276272
def test_api_markdown_image_read_detail_user_access_token_organization_admin(self):
277273
"""
278274
An organization administrator should be able to read details of Markdown image
@@ -306,7 +302,6 @@ def test_api_markdown_image_read_detail_user_access_token_organization_admin(sel
306302
},
307303
)
308304

309-
@override_settings(CLOUDFRONT_SIGNED_URLS_ACTIVE=False)
310305
def test_api_markdown_image_read_detail_user_access_token_playlist_admin(self):
311306
"""
312307
A playlist administrator should be able to read details of Markdown image

0 commit comments

Comments
 (0)