def get_block(self, usage_id, for_parent=None):
        """
        Create an XBlock instance in this runtime.

        The `usage_id` is used to find the XBlock class and data.
        """
        def_id = self.id_reader.get_definition_id(usage_id)
        if def_id is None:
            raise ValueError(
                "Definition not found for usage {}".format(usage_id))
        if not isinstance(def_id, BundleDefinitionLocator):
            raise TypeError(
                "This runtime can only load blocks stored in Blockstore bundles."
            )
        try:
            block_type = self.id_reader.get_block_type(def_id)
        except NoSuchDefinition:
            raise NoSuchUsage(repr(usage_id))
        keys = ScopeIds(self.user_id, block_type, def_id, usage_id)

        if self.system.authored_data_store.has_cached_definition(def_id):
            return self.construct_xblock(block_type,
                                         keys,
                                         for_parent=for_parent)
        else:
            # We need to load this block's field data from its OLX file in blockstore:
            xml_node = xml_for_definition(def_id)
            if xml_node.get("url_name", None):
                log.warning(
                    "XBlock at %s should not specify an old-style url_name attribute.",
                    def_id.olx_path)
            block_class = self.mixologist.mix(self.load_block_type(block_type))
            if hasattr(block_class, 'parse_xml_new_runtime'):
                # This is a (former) XModule with messy XML parsing code; let its parse_xml() method continue to work
                # as it currently does in the old runtime, but let this parse_xml_new_runtime() method parse the XML in
                # a simpler way that's free of tech debt, if defined.
                # In particular, XmlParserMixin doesn't play well with this new runtime, so this is mostly about
                # bypassing that mixin's code.
                # When a former XModule no longer needs to support the old runtime, its parse_xml_new_runtime method
                # should be removed and its parse_xml() method should be simplified to just call the super().parse_xml()
                # plus some minor additional lines of code as needed.
                block = block_class.parse_xml_new_runtime(xml_node,
                                                          runtime=self,
                                                          keys=keys)
            else:
                block = block_class.parse_xml(xml_node,
                                              runtime=self,
                                              keys=keys,
                                              id_generator=None)
            # Update field data with parsed values. We can't call .save() because it will call save_block(), below.
            block.force_save_fields(block._get_fields_to_save())  # pylint: disable=protected-access
            self.system.authored_data_store.cache_fields(block)
            # There is no way to set the parent via parse_xml, so do what
            # HierarchyMixin would do:
            if for_parent is not None:
                block._parent_block = for_parent  # pylint: disable=protected-access
                block._parent_block_id = for_parent.scope_ids.usage_id  # pylint: disable=protected-access
            return block
Exemplo n.º 2
0
    def get_usage_id_from_aside(self, aside_id):
        """
        Extract the usage_id from the aside_id.

        Arguments:
            aside_id: An XBlockAside usage_id
        """
        try:
            return self._aside_usages[aside_id][0]
        except KeyError:
            raise NoSuchUsage(usage_id)
Exemplo n.º 3
0
    def get_aside_type_from_usage(self, usage_id):
        """
        Parse the type of the aside from an XBlockAside usage_id.

        Arguments:
            usage_id: An XBlockAside usage_id.
        """
        try:
            return self._aside_usages[usage_id][1]
        except KeyError:
            raise NoSuchUsage(usage_id)
Exemplo n.º 4
0
    def get_block(self, usage_id, for_parent=None):
        """
        Create an XBlock instance in this runtime.

        The `usage_id` is used to find the XBlock class and data.
        """
        def_id = self.id_reader.get_definition_id(usage_id)
        try:
            block_type = self.id_reader.get_block_type(def_id)
        except NoSuchDefinition:
            raise NoSuchUsage(repr(usage_id))
        keys = ScopeIds(self.user_id, block_type, def_id, usage_id)
        block = self.construct_xblock(block_type, keys, for_parent=for_parent)
        return block
Exemplo n.º 5
0
 def get_definition_id(self, usage_id):
     """Get a definition_id by its usage id."""
     try:
         return self._usages[usage_id]
     except KeyError:
         raise NoSuchUsage(repr(usage_id))