Esempio n. 1
0
    def test_inherited_field(self):
        kvs = InheritanceKeyValueStore(
            initial_values={}, inherited_settings={'showanswer': 'inherited'})
        model_data = KvsFieldData(kvs)
        descriptor = self.get_descriptor(model_data)
        editable_fields = descriptor.editable_metadata_fields
        self.assert_field_values(editable_fields,
                                 'showanswer',
                                 InheritanceMixin.showanswer,
                                 explicitly_set=False,
                                 value='inherited',
                                 default_value='inherited')

        # Mimic the case where display_name WOULD have been inherited, except we explicitly set it.
        kvs = InheritanceKeyValueStore(
            initial_values={'showanswer': 'explicit'},
            inherited_settings={'showanswer': 'inheritable value'})
        model_data = KvsFieldData(kvs)
        descriptor = self.get_descriptor(model_data)
        editable_fields = descriptor.editable_metadata_fields
        self.assert_field_values(editable_fields,
                                 'showanswer',
                                 InheritanceMixin.showanswer,
                                 explicitly_set=True,
                                 value='explicit',
                                 default_value='inheritable value')
Esempio n. 2
0
 def from_xml(cls, xml_data, system, id_generator):
     """
     Creates an instance of this descriptor from the supplied xml_data.
     This may be overridden by subclasses
     xml_data: A string of xml that will be translated into data and children for
         this module
     system: A DescriptorSystem for interacting with external resources
     id_generator is used to generate course-specific urls and identifiers
     """
     xml_object = etree.fromstring(xml_data)
     url_name = xml_object.get('url_name', xml_object.get('slug'))
     block_type = 'video'
     definition_id = id_generator.create_definition(block_type, url_name)
     usage_id = id_generator.create_usage(definition_id)
     if is_pointer_tag(xml_object):
         filepath = cls._format_filepath(xml_object.tag, name_to_pathname(url_name))
         xml_object = cls.load_file(filepath, system.resources_fs, usage_id)
         system.parse_asides(xml_object, definition_id, usage_id, id_generator)
     field_data = cls._parse_video_xml(xml_object, id_generator)
     kvs = InheritanceKeyValueStore(initial_values=field_data)
     field_data = KvsFieldData(kvs)
     video = system.construct_xblock_from_class(
         cls,
         # We're loading a descriptor, so student_id is meaningless
         # We also don't have separate notions of definition and usage ids yet,
         # so we use the location for both
         ScopeIds(None, block_type, definition_id, usage_id),
         field_data,
     )
     return video
Esempio n. 3
0
    def from_xml(cls, xml_data, system, org=None, course=None):
        """
        Creates an instance of this descriptor from the supplied xml_data.
        This may be overridden by subclasses

        xml_data: A string of xml that will be translated into data and children for
            this module
        system: A DescriptorSystem for interacting with external resources
        org and course are optional strings that will be used in the generated modules
            url identifiers
        """
        xml_object = etree.fromstring(xml_data)
        url_name = xml_object.get('url_name', xml_object.get('slug'))
        location = Location('i4x', org, course, 'video', url_name)
        if is_pointer_tag(xml_object):
            filepath = cls._format_filepath(xml_object.tag,
                                            name_to_pathname(url_name))
            xml_data = etree.tostring(
                cls.load_file(filepath, system.resources_fs, location))
        field_data = cls._parse_video_xml(xml_data)
        field_data['location'] = location
        kvs = InheritanceKeyValueStore(initial_values=field_data)
        field_data = DbModel(kvs)
        video = system.construct_xblock_from_class(
            cls,
            # We're loading a descriptor, so student_id is meaningless
            # We also don't have separate notions of definition and usage ids yet,
            # so we use the location for both
            ScopeIds(None, location.category, location, location),
            field_data,
        )
        return video
Esempio n. 4
0
    def from_xml(cls, xml_data, system, org=None, course=None):
        """
        Creates an instance of this descriptor from the supplied xml_data.
        This may be overridden by subclasses

        xml_data: A string of xml that will be translated into data and children for
            this module
        system: A DescriptorSystem for interacting with external resources
        org and course are optional strings that will be used in the generated modules
            url identifiers
        """

        xml_object = etree.fromstring(xml_data)
        # VS[compat] -- just have the url_name lookup, once translation is done
        url_name = xml_object.get('url_name', xml_object.get('slug'))
        location = Location('i4x', org, course, xml_object.tag, url_name)

        # VS[compat] -- detect new-style each-in-a-file mode
        if is_pointer_tag(xml_object):
            # new style:
            # read the actual definition file--named using url_name.replace(':','/')
            filepath = cls._format_filepath(xml_object.tag,
                                            name_to_pathname(url_name))
            definition_xml = cls.load_file(filepath, system.resources_fs,
                                           location)
        else:
            definition_xml = xml_object
            filepath = None

        definition, children = cls.load_definition(
            definition_xml, system, location)  # note this removes metadata

        # VS[compat] -- make Ike's github preview links work in both old and
        # new file layouts
        if is_pointer_tag(xml_object):
            # new style -- contents actually at filepath
            definition['filename'] = [filepath, filepath]

        metadata = cls.load_metadata(definition_xml)

        # move definition metadata into dict
        dmdata = definition.get('definition_metadata', '')
        if dmdata:
            metadata['definition_metadata_raw'] = dmdata
            try:
                metadata.update(json.loads(dmdata))
            except Exception as err:
                log.debug('Error %s in loading metadata %s' % (err, dmdata))
                metadata['definition_metadata_err'] = str(err)

        # Set/override any metadata specified by policy
        k = policy_key(location)
        if k in system.policy:
            cls.apply_policy(metadata, system.policy[k])

        field_data = {}
        field_data.update(metadata)
        field_data.update(definition)
        field_data['children'] = children

        field_data['xml_attributes']['filename'] = definition.get(
            'filename', ['', None])  # for git link
        field_data['location'] = location
        field_data['category'] = xml_object.tag
        kvs = InheritanceKeyValueStore(initial_values=field_data)
        field_data = DbModel(kvs)

        return system.construct_xblock_from_class(
            cls,
            # We're loading a descriptor, so student_id is meaningless
            # We also don't have separate notions of definition and usage ids yet,
            # so we use the location for both
            ScopeIds(None, location.category, location, location),
            field_data,
        )
Esempio n. 5
0
    def parse_xml(cls, node, runtime, keys, id_generator):  # pylint: disable=unused-argument
        """
        Use `node` to construct a new block.

        Arguments:
            node (etree.Element): The xml node to parse into an xblock.

            runtime (:class:`.Runtime`): The runtime to use while parsing.

            keys (:class:`.ScopeIds`): The keys identifying where this block
                will store its data.

            id_generator (:class:`.IdGenerator`): An object that will allow the
                runtime to generate correct definition and usage ids for
                children of this block.

        Returns (XBlock): The newly parsed XBlock

        """
        # VS[compat] -- just have the url_name lookup, once translation is done
        url_name = cls._get_url_name(node)
        def_id = id_generator.create_definition(node.tag, url_name)
        usage_id = id_generator.create_usage(def_id)
        aside_children = []

        # VS[compat] -- detect new-style each-in-a-file mode
        if is_pointer_tag(node):
            # new style:
            # read the actual definition file--named using url_name.replace(':','/')
            definition_xml, filepath = cls.load_definition_xml(
                node, runtime, def_id)
            aside_children = runtime.parse_asides(definition_xml, def_id,
                                                  usage_id, id_generator)
        else:
            filepath = None
            definition_xml = node

        # Note: removes metadata.
        definition, children = cls.load_definition(definition_xml, runtime,
                                                   def_id, id_generator)

        # VS[compat] -- make Ike's github preview links work in both old and
        # new file layouts
        if is_pointer_tag(node):
            # new style -- contents actually at filepath
            definition['filename'] = [filepath, filepath]

        metadata = cls.load_metadata(definition_xml)

        # move definition metadata into dict
        dmdata = definition.get('definition_metadata', '')
        if dmdata:
            metadata['definition_metadata_raw'] = dmdata
            try:
                metadata.update(json.loads(dmdata))
            except Exception as err:  # lint-amnesty, pylint: disable=broad-except
                log.debug('Error in loading metadata %r',
                          dmdata,
                          exc_info=True)
                metadata['definition_metadata_err'] = str(err)

        definition_aside_children = definition.pop('aside_children', None)
        if definition_aside_children:
            aside_children.extend(definition_aside_children)

        # Set/override any metadata specified by policy
        cls.apply_policy(metadata, runtime.get_policy(usage_id))

        field_data = {}
        field_data.update(metadata)
        field_data.update(definition)
        field_data['children'] = children

        field_data['xml_attributes']['filename'] = definition.get(
            'filename', ['', None])  # for git link
        kvs = InheritanceKeyValueStore(initial_values=field_data)
        field_data = KvsFieldData(kvs)

        xblock = runtime.construct_xblock_from_class(
            cls,
            # We're loading a descriptor, so student_id is meaningless
            ScopeIds(None, node.tag, def_id, usage_id),
            field_data,
        )

        if aside_children:
            asides_tags = [x.tag for x in aside_children]
            asides = runtime.get_asides(xblock)
            for asd in asides:
                if asd.scope_ids.block_type in asides_tags:
                    xblock.add_aside(asd)

        return xblock
Esempio n. 6
0
    def parse_xml(cls, node, runtime, keys, id_generator):  # pylint: disable=unused-argument
        """
        Use `node` to construct a new block.

        Arguments:
            node (etree.Element): The xml node to parse into an xblock.

            runtime (:class:`.Runtime`): The runtime to use while parsing.

            keys (:class:`.ScopeIds`): The keys identifying where this block
                will store its data.

            id_generator (:class:`.IdGenerator`): An object that will allow the
                runtime to generate correct definition and usage ids for
                children of this block.

        Returns (XBlock): The newly parsed XBlock

        """
        # VS[compat] -- just have the url_name lookup, once translation is done
        url_name = node.get('url_name', node.get('slug'))
        def_id = id_generator.create_definition(node.tag, url_name)
        usage_id = id_generator.create_usage(def_id)

        # VS[compat] -- detect new-style each-in-a-file mode
        if is_pointer_tag(node):
            # new style:
            # read the actual definition file--named using url_name.replace(':','/')
            filepath = cls._format_filepath(node.tag,
                                            name_to_pathname(url_name))
            definition_xml = cls.load_file(filepath, runtime.resources_fs,
                                           def_id)
            runtime.parse_asides(definition_xml, def_id, usage_id,
                                 id_generator)
        else:
            filepath = None
            definition_xml = node
            dog_stats_api.increment(
                DEPRECATION_VSCOMPAT_EVENT,
                tags=["location:xmlparser_util_mixin_parse_xml"])

        # Note: removes metadata.
        definition, children = cls.load_definition(definition_xml, runtime,
                                                   def_id, id_generator)

        # VS[compat] -- make Ike's github preview links work in both old and
        # new file layouts
        if is_pointer_tag(node):
            # new style -- contents actually at filepath
            definition['filename'] = [filepath, filepath]

        metadata = cls.load_metadata(definition_xml)

        # move definition metadata into dict
        dmdata = definition.get('definition_metadata', '')
        if dmdata:
            metadata['definition_metadata_raw'] = dmdata
            try:
                metadata.update(json.loads(dmdata))
            except Exception as err:
                log.debug('Error in loading metadata %r',
                          dmdata,
                          exc_info=True)
                metadata['definition_metadata_err'] = str(err)

        # Set/override any metadata specified by policy
        cls.apply_policy(metadata, runtime.get_policy(usage_id))

        field_data = {}
        field_data.update(metadata)
        field_data.update(definition)
        field_data['children'] = children

        field_data['xml_attributes']['filename'] = definition.get(
            'filename', ['', None])  # for git link
        kvs = InheritanceKeyValueStore(initial_values=field_data)
        field_data = KvsFieldData(kvs)

        return runtime.construct_xblock_from_class(
            cls,
            # We're loading a descriptor, so student_id is meaningless
            ScopeIds(None, node.tag, def_id, usage_id),
            field_data,
        )
Esempio n. 7
0
    def from_xml(cls, xml_data, system, id_generator):
        """
        Creates an instance of this descriptor from the supplied xml_data.
        This may be overridden by subclasses

        xml_data: A string of xml that will be translated into data and children for
            this module
        system: A DescriptorSystem for interacting with external resources
        """

        xml_object = etree.fromstring(xml_data)
        # VS[compat] -- just have the url_name lookup, once translation is done
        url_name = xml_object.get('url_name', xml_object.get('slug'))
        def_id = id_generator.create_definition(xml_object.tag, url_name)
        usage_id = id_generator.create_usage(def_id)

        # VS[compat] -- detect new-style each-in-a-file mode
        if is_pointer_tag(xml_object):
            # new style:
            # read the actual definition file--named using url_name.replace(':','/')
            filepath = cls._format_filepath(xml_object.tag,
                                            name_to_pathname(url_name))
            definition_xml = cls.load_file(filepath, system.resources_fs,
                                           def_id)
        else:
            definition_xml = xml_object
            filepath = None

        definition, children = cls.load_definition(
            definition_xml, system, def_id)  # note this removes metadata

        # VS[compat] -- make Ike's github preview links work in both old and
        # new file layouts
        if is_pointer_tag(xml_object):
            # new style -- contents actually at filepath
            definition['filename'] = [filepath, filepath]

        metadata = cls.load_metadata(definition_xml)

        # move definition metadata into dict
        dmdata = definition.get('definition_metadata', '')
        if dmdata:
            metadata['definition_metadata_raw'] = dmdata
            try:
                metadata.update(json.loads(dmdata))
            except Exception as err:
                log.debug('Error in loading metadata %r',
                          dmdata,
                          exc_info=True)
                metadata['definition_metadata_err'] = str(err)

        # Set/override any metadata specified by policy
        cls.apply_policy(metadata, system.get_policy(usage_id))

        field_data = {}
        field_data.update(metadata)
        field_data.update(definition)
        field_data['children'] = children

        field_data['xml_attributes']['filename'] = definition.get(
            'filename', ['', None])  # for git link
        kvs = InheritanceKeyValueStore(initial_values=field_data)
        field_data = KvsFieldData(kvs)

        return system.construct_xblock_from_class(
            cls,
            # We're loading a descriptor, so student_id is meaningless
            ScopeIds(None, xml_object.tag, def_id, usage_id),
            field_data,
        )