Skip to content

Commit

Permalink
feat: handle file content logic when creating next component version
Browse files Browse the repository at this point in the history
  • Loading branch information
Ian2012 committed Oct 25, 2024
1 parent 7e3ad5c commit ff8f794
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
17 changes: 16 additions & 1 deletion openedx_learning/apps/authoring/components/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"""
from __future__ import annotations

import mimetypes
from datetime import datetime, timezone
from enum import StrEnum, auto
from logging import getLogger
Expand Down Expand Up @@ -129,7 +130,7 @@ def create_component_version(
def create_next_component_version(
component_pk: int,
/,
content_to_replace: dict[str, int | None],
content_to_replace: dict[str, int | None | bytes],
created: datetime,
title: str | None = None,
created_by: int | None = None,
Expand Down Expand Up @@ -191,6 +192,20 @@ def create_next_component_version(
# content represented by our key from the next version. Otherwise,
# we add our key->content_pk mapping to the next version.
if content_pk is not None:
if isinstance(content_pk, bytes):
file_path, file_content = key, content_pk
media_type_str, _encoding = mimetypes.guess_type(file_path)
# We use "application/octet-stream" as a generic fallback media type, per
# RFC 2046: https://datatracker.ietf.org/doc/html/rfc2046
media_type_str = media_type_str or "application/octet-stream"
media_type = contents_api.get_or_create_media_type(media_type_str)
content = contents_api.get_or_create_file_content(
component.publishable_entity.learning_package.id,
media_type.id,
data=file_content,
created=created,
)
content_pk = content.pk
ComponentVersionContent.objects.create(
content_id=content_pk,
component_version=component_version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@
This is mostly meant to be a debugging tool to let us to easily load some test
asset data into the system.
"""
import mimetypes
import pathlib
from datetime import datetime, timezone

from django.core.management.base import BaseCommand

from ....components.api import create_component_version_content
from ....contents.api import get_or_create_file_content, get_or_create_media_type
from ....publishing.api import get_learning_package_by_key
from ...api import create_next_component_version, get_component_by_key

Expand Down Expand Up @@ -70,7 +68,7 @@ def handle(self, *args, **options):

created = datetime.now(tz=timezone.utc)
keys_to_remove = set()
local_keys_to_content = {}
local_keys_to_raw_content = {}

for file_mapping in file_mappings:
local_key, file_path = file_mapping.split(":", 1)
Expand All @@ -80,22 +78,14 @@ def handle(self, *args, **options):
keys_to_remove.add(local_key)
continue

media_type_str, _encoding = mimetypes.guess_type(file_path)
media_type = get_or_create_media_type(media_type_str)
content = get_or_create_file_content(
learning_package.id,
media_type.id,
data=pathlib.Path(file_path).read_bytes(),
created=created,
)
local_keys_to_content[local_key] = content.id
local_keys_to_raw_content[local_key] = pathlib.Path(file_path).read_bytes()

next_version = create_next_component_version(
component.pk,
content_to_replace={local_key: None for local_key in keys_to_remove},
created=created,
)
for local_key, content_id in sorted(local_keys_to_content.items()):
for local_key, content_id in sorted(local_keys_to_raw_content.items()):
create_component_version_content(
next_version.pk,
content_id,
Expand Down
7 changes: 4 additions & 3 deletions tests/openedx_learning/apps/authoring/components/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,13 +442,14 @@ def test_multiple_versions(self):
content_to_replace={
"hello.txt": hello_content.pk,
"goodbye.txt": goodbye_content.pk,
"raw.txt": b'raw content',
},
created=self.now,
)
assert version_1.version_num == 1
assert version_1.title == "Problem Version 1"
version_1_contents = list(version_1.contents.all())
assert len(version_1_contents) == 2
assert len(version_1_contents) == 3
assert (
hello_content ==
version_1.contents
Expand All @@ -472,7 +473,7 @@ def test_multiple_versions(self):
created=self.now,
)
assert version_2.version_num == 2
assert version_2.contents.count() == 3
assert version_2.contents.count() == 4
assert (
blank_content ==
version_2.contents
Expand Down Expand Up @@ -503,7 +504,7 @@ def test_multiple_versions(self):
created=self.now,
)
assert version_3.version_num == 3
assert version_3.contents.count() == 1
assert version_3.contents.count() == 2
assert (
hello_content ==
version_3.contents
Expand Down

0 comments on commit ff8f794

Please sign in to comment.