diff --git a/openedx/core/djangoapps/content_libraries/api/containers.py b/openedx/core/djangoapps/content_libraries/api/containers.py index 3a0a89550cc4..393755ed1c91 100644 --- a/openedx/core/djangoapps/content_libraries/api/containers.py +++ b/openedx/core/djangoapps/content_libraries/api/containers.py @@ -60,7 +60,47 @@ class ContainerType(Enum): + """ + The container types supported by content_libraries, and logic to map them to OLX. + """ Unit = "unit" + Subsection = "subsection" + Section = "section" + + @property + def olx_tag(self) -> str: + """ + Canonical XML tag to use when representing this container as OLX. + + For example, Units are encoded as .... + + These tag names are historical. We keep them around for the backwards compatibility of OLX + and for easier interaction with legacy modulestore-powered structural XBlocks + (e.g., copy-paste of Units between courses and V2 libraries). + """ + match self: + case self.Unit: + return "vertical" + case self.Subsection: + return "sequential" + case self.Section: + return "chapter" + raise TypeError(f"unexpected ContainerType: {self!r}") + + @classmethod + def from_source_olx_tag(cls, olx_tag: str) -> 'ContainerType': + """ + Get the ContainerType that this OLX tag maps to. + """ + if olx_tag == "unit": + # There is an alternative implementation to VerticalBlock called UnitBlock whose + # OLX tag is . When converting from OLX, we want to handle both + # and as Unit containers, although the canonical serialization is still . + return cls.Unit + try: + return next(ct for ct in cls if olx_tag == ct.olx_tag) + except StopIteration: + raise ValueError(f"no container_type for XML tag: <{olx_tag}>") from None @dataclass(frozen=True, kw_only=True) @@ -83,7 +123,6 @@ def from_container(cls, library_key, container: Container, associated_collection container=container, ) container_type = ContainerType(container_key.container_type) - published_by = "" if last_publish_log and last_publish_log.published_by: published_by = last_publish_log.published_by.username @@ -209,7 +248,7 @@ def create_container( created_by=user_id, ) case _: - raise ValueError(f"Invalid container type: {container_type}") + raise NotImplementedError(f"Library support for {container_type} is in progress") LIBRARY_CONTAINER_CREATED.send_event( library_container=LibraryContainerData(