コード例 #1
0
ファイル: test_plugin.py プロジェクト: Randomwak/XBlock
def test_ambiguous_plugins():
    # We can load ok blocks even if there are bad blocks.
    cls = XBlock.load_class("good_block")
    assert_is(cls, UnambiguousBlock)

    # Trying to load bad blocks raises an exception.
    expected_msg = (
        "Ambiguous entry points for bad_block: "
        "xblock.test.test_plugin.AmbiguousBlock1, "
        "xblock.test.test_plugin.AmbiguousBlock2"
    )
    with assert_raises_regexp(AmbiguousPluginError, expected_msg):
        XBlock.load_class("bad_block")

    # We can use our own function as the select function.
    class MyOwnException(Exception):
        """We'll raise this from `boom`."""
        pass

    def boom(identifier, entry_points):
        """A select function to prove user-defined functions are called."""
        assert len(entry_points) == 2
        assert identifier == "bad_block"
        raise MyOwnException("This is boom")

    with assert_raises_regexp(MyOwnException, "This is boom"):
        XBlock.load_class("bad_block", select=boom)
コード例 #2
0
ファイル: test_plugin.py プロジェクト: Randomwak/XBlock
def test_nosuch_plugin():
    # We can provide a default class to return for missing plugins.
    cls = XBlock.load_class("nosuch_block", default=UnambiguousBlock)
    assert_is(cls, UnambiguousBlock)

    # If we don't provide a default class, an exception is raised.
    with assert_raises_regexp(PluginMissingError, "nosuch_block"):
        XBlock.load_class("nosuch_block")
コード例 #3
0
ファイル: test_plugin.py プロジェクト: edx/XBlock
def test_nosuch_plugin():
    # We can provide a default class to return for missing plugins.
    cls = XBlock.load_class("nosuch_block", default=UnambiguousBlock)
    assert cls is UnambiguousBlock

    # If we don't provide a default class, an exception is raised.
    with pytest.raises(PluginMissingError, match="nosuch_block"):
        XBlock.load_class("nosuch_block")
コード例 #4
0
ファイル: test_plugin.py プロジェクト: Randomwak/XBlock
def test_plugin_caching():
    plugin.PLUGIN_CACHE = {}
    assert_equals(_num_plugins_cached(), 0)

    XBlock.load_class("thumbs")
    assert_equals(_num_plugins_cached(), 1)

    XBlock.load_class("thumbs")
    assert_equals(_num_plugins_cached(), 1)
コード例 #5
0
ファイル: test_plugin.py プロジェクト: edx/XBlock
def test_plugin_caching():
    plugin.PLUGIN_CACHE = {}
    assert _num_plugins_cached() == 0

    XBlock.load_class("thumbs")
    assert _num_plugins_cached() == 1

    XBlock.load_class("thumbs")
    assert _num_plugins_cached() == 1
コード例 #6
0
ファイル: xb_scorm.py プロジェクト: dadasoz/tincan-xblock
    def __init__(self, *args, **kwargs):
        try:

            XBlock.__init__(self, *args, **kwargs)

            # FIXME: technically, we're not supposed to provide __init__. This
            # works for now, though...
            self.scorm_path = DEFAULT_SCORM_PATH
            if self.override_scorm_path:
                self.scorm_path = self.override_scorm_path
        except:
            pass
コード例 #7
0
ファイル: test_core.py プロジェクト: edx/XBlock
def test_handle_shortcut():
    runtime = Mock(spec=["handle"])
    scope_ids = Mock(spec=[])
    request = Mock(spec=[])
    block = XBlock(runtime, None, scope_ids)

    block.handle("handler_name", request)
    runtime.handle.assert_called_with(block, "handler_name", request, "")

    runtime.handle.reset_mock()
    block.handle("handler_name", request, "suffix")
    runtime.handle.assert_called_with(block, "handler_name", request, "suffix")
コード例 #8
0
ファイル: test_core.py プロジェクト: Keeward/XBlock
def test_handle_shortcut():
    runtime = Mock(spec=['handle'])
    scope_ids = Mock(spec=[])
    request = Mock(spec=[])
    block = XBlock(runtime, None, scope_ids)

    block.handle('handler_name', request)
    runtime.handle.assert_called_with(block, 'handler_name', request, '')

    runtime.handle.reset_mock()
    block.handle('handler_name', request, 'suffix')
    runtime.handle.assert_called_with(block, 'handler_name', request, 'suffix')
コード例 #9
0
ファイル: test_scenarios.py プロジェクト: agamdua/XBlock
def test_all_scenarios():
    """Load the home page, get every URL, make a test from it."""
    client = Client()
    response = client.get("/")
    assert response.status_code == 200
    html = lxml.html.fromstring(response.content)
    a_tags = list(html.xpath('//a'))
    for a_tag in a_tags:
        yield try_scenario, a_tag.get('href'), a_tag.text

    # Load the scenarios from the classes.
    scenarios = []
    for _, cls in XBlock.load_classes():
        if hasattr(cls, "workbench_scenarios"):
            for _, xml in cls.workbench_scenarios():
                scenarios.append(xml)

    # We should have an <a> tag for each scenario.
    assert_equals(len(a_tags), len(scenarios))

    # We should have at least one scenario with a vertical tag, since we use
    # empty verticals as our canary in the coal mine that something has gone
    # horribly wrong with loading the scenarios.
    assert any("<vertical>" in xml for xml in scenarios)

    # Since we are claiming in try_scenario that no vertical is empty, let's
    # eliminate the possibility that a scenario has an actual empty vertical.
    assert all("<vertical></vertical>" not in xml for xml in scenarios)
    assert all("<vertical/>" not in xml for xml in scenarios)
コード例 #10
0
def xblock_type_display_name(xblock, default_display_name=None):
    """
    Returns the display name for the specified type of xblock. Note that an instance can be passed in
    for context dependent names, e.g. a vertical beneath a sequential is a Unit.
    :param xblock: An xblock instance or the type of xblock.
    :param default_display_name: The default value to return if no display name can be found.
    :return:
    """

    if hasattr(xblock, 'category'):
        category = xblock.category
        if category == 'vertical' and not is_unit(xblock):
            return _('Vertical')
    else:
        category = xblock
    if category == 'chapter':
        return _('Section')
    elif category == 'sequential':
        return _('Subsection')
    elif category == 'vertical':
        return _('Unit')
    component_class = XBlock.load_class(category,
                                        select=settings.XBLOCK_SELECT_FUNCTION)
    if hasattr(component_class,
               'display_name') and component_class.display_name.default:
        return _(component_class.display_name.default)
    else:
        return default_display_name
コード例 #11
0
ファイル: api.py プロジェクト: sliva/edx-platform
def get_allowed_block_types(library_key):  # pylint: disable=unused-argument
    """
    Get a list of XBlock types that can be added to the specified content
    library.
    """
    # This import breaks in the LMS so keep it here. The LMS doesn't generally
    # use content libraries APIs directly but some tests may want to use them to
    # create libraries and then test library learning or course-library integration.
    from cms.djangoapps.contentstore.views.helpers import xblock_type_display_name
    # TODO: return support status and template options
    # See cms/djangoapps/contentstore/views/component.py
    block_types = sorted(name for name, class_ in XBlock.load_classes())
    lib = get_library(library_key)
    if lib.type != COMPLEX:
        # Problem and Video libraries only permit XBlocks of the same name.
        block_types = (name for name in block_types if name == lib.type)
    info = []
    for block_type in block_types:
        display_name = xblock_type_display_name(block_type, None)
        # For now as a crude heuristic, we exclude blocks that don't have a display_name
        if display_name:
            info.append(
                LibraryXBlockType(block_type=block_type,
                                  display_name=display_name))
    return info
コード例 #12
0
def _load_mixed_class(category):
    """
    Load an XBlock by category name, and apply all defined mixins
    """
    component_class = XBlock.load_class(category, select=settings.XBLOCK_SELECT_FUNCTION)
    mixologist = Mixologist(settings.XBLOCK_MIXINS)
    return mixologist.mix(component_class)
コード例 #13
0
    def setUp(self):
        super(TestCourseDetailSerializer, self).setUp()

        # update the expected_data to include the 'overview' data.
        about_descriptor = XBlock.load_class('about')
        overview_template = about_descriptor.get_template('overview.yaml')
        self.expected_data['overview'] = overview_template.get('data')
コード例 #14
0
ファイル: test_crud.py プロジェクト: rayhooker/edx-platform
    def load_from_json(json_data, system, default_class=None, parent_xblock=None):
        """
        This method instantiates the correct subclass of XModuleDescriptor based
        on the contents of json_data. It does not persist it and can create one which
        has no usage id.

        parent_xblock is used to compute inherited metadata as well as to append the new xblock.

        json_data:
        - 'location' : must have this field
        - 'category': the xmodule category (required or location must be a Location)
        - 'metadata': a dict of locally set metadata (not inherited)
        - 'children': a list of children's usage_ids w/in this course
        - 'definition':
        - '_id' (optional): the usage_id of this. Will generate one if not given one.
        """
        class_ = XBlock.load_class(
            json_data.get('category', json_data.get('location', {}).get('category')),
            default_class,
            select=prefer_xmodules
        )
        usage_id = json_data.get('_id', None)
        if not '_inherited_settings' in json_data and parent_xblock is not None:
            json_data['_inherited_settings'] = parent_xblock.xblock_kvs.inherited_settings.copy()
            json_fields = json_data.get('fields', {})
            for field_name in inheritance.InheritanceMixin.fields:
                if field_name in json_fields:
                    json_data['_inherited_settings'][field_name] = json_fields[field_name]

        new_block = system.xblock_from_json(class_, usage_id, json_data)
        if parent_xblock is not None:
            parent_xblock.children.append(new_block.scope_ids.usage_id)
            # decache pending children field settings
            parent_xblock.save()
        return new_block
コード例 #15
0
    def load_from_json(json_data, system, default_class=None, parent_xblock=None):
        """
        This method instantiates the correct subclass of XModuleDescriptor based
        on the contents of json_data. It does not persist it and can create one which
        has no usage id.

        parent_xblock is used to compute inherited metadata as well as to append the new xblock.

        json_data:
        - 'location' : must have this field
        - 'category': the xmodule category (required or location must be a Location)
        - 'metadata': a dict of locally set metadata (not inherited)
        - 'children': a list of children's usage_ids w/in this course
        - 'definition':
        - '_id' (optional): the usage_id of this. Will generate one if not given one.
        """
        class_ = XBlock.load_class(
            json_data.get("category", json_data.get("location", {}).get("category")),
            default_class,
            select=settings.XBLOCK_SELECT_FUNCTION,
        )
        usage_id = json_data.get("_id", None)
        if not "_inherited_settings" in json_data and parent_xblock is not None:
            json_data["_inherited_settings"] = parent_xblock.xblock_kvs.inherited_settings.copy()
            json_fields = json_data.get("fields", {})
            for field_name in inheritance.InheritanceMixin.fields:
                if field_name in json_fields:
                    json_data["_inherited_settings"][field_name] = json_fields[field_name]

        new_block = system.xblock_from_json(class_, usage_id, json_data)
        if parent_xblock is not None:
            parent_xblock.children.append(new_block.scope_ids.usage_id)
            # decache pending children field settings
            parent_xblock.save()
        return new_block
コード例 #16
0
 def test_all_blocks_excluded_from_completion(self, blockclass):
     xblock = XBlock.load_class(blockclass)
     self.assertEqual(
         XBlockCompletionMode.get_mode(xblock),
         XBlockCompletionMode.EXCLUDED,
         "Block {!r} did not have completion mode 'excluded'".format(xblock),
     )
コード例 #17
0
ファイル: runtime.py プロジェクト: qvin/XBlock
 def construct_xblock(self, plugin_name, field_data, scope_ids, default_class=None, *args, **kwargs):
     """
     Construct a new xblock of the type identified by plugin_name,
     passing *args and **kwargs into __init__
     """
     block_class = XBlock.load_class(plugin_name, default_class)
     return self.construct_xblock_from_class(cls=block_class, field_data=field_data, scope_ids=scope_ids, *args, **kwargs)
コード例 #18
0
ファイル: component.py プロジェクト: PaoloC68/edx-platform
def _load_mixed_class(category):
    """
    Load an XBlock by category name, and apply all defined mixins
    """
    component_class = XBlock.load_class(category, select=settings.XBLOCK_SELECT_FUNCTION)
    mixologist = Mixologist(settings.XBLOCK_MIXINS)
    return mixologist.mix(component_class)
コード例 #19
0
ファイル: scenarios.py プロジェクト: renzo-orsini/XBlock
def _do_once():
    """
    Called once when the module is imported to create the global scenarios.
    """
    # Get all the XBlock classes, and add their scenarios.
    for class_name, cls in XBlock.load_classes():
        add_class_scenarios(class_name, cls)
コード例 #20
0
ファイル: test_serializers.py プロジェクト: edx/edx-platform
    def setUp(self):
        super(TestCourseDetailSerializer, self).setUp()

        # update the expected_data to include the 'overview' data.
        about_descriptor = XBlock.load_class('about')
        overview_template = about_descriptor.get_template('overview.yaml')
        self.expected_data['overview'] = overview_template.get('data')
コード例 #21
0
ファイル: helpers.py プロジェクト: AdityaKashyap/edx-platform
def xblock_type_display_name(xblock, default_display_name=None):
    """
    Returns the display name for the specified type of xblock. Note that an instance can be passed in
    for context dependent names, e.g. a vertical beneath a sequential is a Unit.

    :param xblock: An xblock instance or the type of xblock.
    :param default_display_name: The default value to return if no display name can be found.
    :return:
    """

    if hasattr(xblock, "category"):
        category = xblock.category
        if category == "vertical" and not is_unit(xblock):
            return _("Vertical")
    else:
        category = xblock
    if category == "chapter":
        return _("Section")
    elif category == "sequential":
        return _("Subsection")
    elif category == "vertical":
        return _("Unit")
    component_class = XBlock.load_class(category, select=settings.XBLOCK_SELECT_FUNCTION)
    if hasattr(component_class, "display_name") and component_class.display_name.default:
        return _(component_class.display_name.default)
    else:
        return default_display_name
コード例 #22
0
ファイル: xml.py プロジェクト: SnowGeekOrg/edx-platform
def create_block_from_xml(xml_data, system, org=None, course=None, default_class=None):
    """
    Create an XBlock instance from XML data.

    `xml_data' is a string containing valid xml.

    `system` is an XMLParsingSystem.

    `org` and `course` are optional strings that will be used in the generated
    block's url identifiers.

    `default_class` is the class to instantiate of the XML indicates a class
    that can't be loaded.

    Returns the fully instantiated XBlock.

    """
    node = etree.fromstring(xml_data)
    raw_class = XBlock.load_class(node.tag, default_class, select=prefer_xmodules)
    xblock_class = system.mixologist.mix(raw_class)

    # leave next line commented out - useful for low-level debugging
    # log.debug('[create_block_from_xml] tag=%s, class=%s' % (node.tag, xblock_class))

    url_name = node.get('url_name', node.get('slug'))
    location = Location('i4x', org, course, node.tag, url_name)

    scope_ids = ScopeIds(None, location.category, location, location)
    xblock = xblock_class.parse_xml(node, system, scope_ids)
    return xblock
コード例 #23
0
ファイル: helpers.py プロジェクト: Lektorium-LLC/edx-platform
def xblock_type_display_name(xblock, default_display_name=None):
    """
    Returns the display name for the specified type of xblock. Note that an instance can be passed in
    for context dependent names, e.g. a vertical beneath a sequential is a Unit.

    :param xblock: An xblock instance or the type of xblock.
    :param default_display_name: The default value to return if no display name can be found.
    :return:
    """

    if hasattr(xblock, 'category'):
        category = xblock.category
        if category == 'vertical' and not is_unit(xblock):
            return _('Vertical')
    else:
        category = xblock
    if category == 'chapter':
        return _('Section')
    elif category == 'sequential':
        return _('Subsection')
    elif category == 'vertical':
        return _('Unit')
    component_class = XBlock.load_class(category, select=settings.XBLOCK_SELECT_FUNCTION)
    if hasattr(component_class, 'display_name') and component_class.display_name.default:
        return _(component_class.display_name.default)    # pylint: disable=translation-of-non-string
    else:
        return default_display_name
コード例 #24
0
ファイル: test_services.py プロジェクト: stvstnfrd/completion
    def test_blocks_to_mark_complete_on_view(self):

        completable_block_1 = XBlock(Mock(), scope_ids=Mock(spec=ScopeIds))
        usage_id_1 = UsageKey.from_string("i4x://edX/100/a/1").replace(
            course_key=self.course_key)
        completable_block_1.scope_ids.usage_id = usage_id_1
        completable_block_2 = XBlock(Mock(), scope_ids=Mock(spec=ScopeIds))
        usage_id_2 = UsageKey.from_string("i4x://edX/100/a/2").replace(
            course_key=self.course_key)
        completable_block_2.scope_ids.usage_id = usage_id_2
        aggregator_block = XBlock(Mock(), scope_ids=Mock(spec=ScopeIds))
        usage_id_3 = UsageKey.from_string("i4x://edX/100/a/3").replace(
            course_key=self.course_key)
        aggregator_block.scope_ids.usage_id = usage_id_3
        aggregator_block.completion_mode = XBlockCompletionMode.AGGREGATOR

        self.assertEqual(
            self.completion_service.blocks_to_mark_complete_on_view([]), [])

        self.assertEqual(
            self.completion_service.blocks_to_mark_complete_on_view(
                [aggregator_block]), [])

        self.assertEqual(
            self.completion_service.blocks_to_mark_complete_on_view(
                [completable_block_1, completable_block_2, aggregator_block]),
            [completable_block_1, completable_block_2])

        BlockCompletion.objects.submit_completion(
            user=self.user,
            block_key=completable_block_2.scope_ids.usage_id,
            completion=1.0)

        self.assertEqual(
            self.completion_service.blocks_to_mark_complete_on_view(
                [completable_block_1, completable_block_2, aggregator_block]),
            [completable_block_1])

        BlockCompletion.objects.submit_completion(
            user=self.user,
            block_key=completable_block_1.scope_ids.usage_id,
            completion=1.0)

        self.assertEqual(
            self.completion_service.blocks_to_mark_complete_on_view(
                [completable_block_1, completable_block_2, aggregator_block]),
            [])
コード例 #25
0
def create_library_block(library_key, block_type, definition_id):
    """
    Create a new XBlock in this library of the specified type (e.g. "html").

    The 'definition_id' value (which should be a string like "problem1") will be
    used as both the definition_id and the usage_id.
    """
    assert isinstance(library_key, LibraryLocatorV2)
    ref = ContentLibrary.objects.get_by_key(library_key)
    lib_bundle = LibraryBundle(library_key,
                               ref.bundle_uuid,
                               draft_name=DRAFT_NAME)
    # Total number of blocks should not exceed the maximum allowed
    total_blocks = len(lib_bundle.get_top_level_usages())
    if total_blocks + 1 > settings.MAX_BLOCKS_PER_CONTENT_LIBRARY:
        raise BlockLimitReachedError(
            _(u"Library cannot have more than {} XBlocks").format(
                settings.MAX_BLOCKS_PER_CONTENT_LIBRARY))
    # Make sure the proposed ID will be valid:
    validate_unicode_slug(definition_id)
    # Ensure the XBlock type is valid and installed:
    XBlock.load_class(block_type)  # Will raise an exception if invalid
    # Make sure the new ID is not taken already:
    new_usage_id = definition_id  # Since this is a top level XBlock, usage_id == definition_id
    usage_key = LibraryUsageLocatorV2(
        lib_key=library_key,
        block_type=block_type,
        usage_id=new_usage_id,
    )
    library_context = get_learning_context_impl(usage_key)
    if library_context.definition_for_usage(usage_key) is not None:
        raise LibraryBlockAlreadyExists(
            "An XBlock with ID '{}' already exists".format(new_usage_id))

    new_definition_xml = '<{}/>'.format(
        block_type)  # xss-lint: disable=python-wrap-html
    path = "{}/{}/definition.xml".format(block_type, definition_id)
    # Write the new XML/OLX file into the library bundle's draft
    draft = get_or_create_bundle_draft(ref.bundle_uuid, DRAFT_NAME)
    write_draft_file(draft.uuid, path, new_definition_xml.encode('utf-8'))
    # Clear the bundle cache so everyone sees the new block immediately:
    BundleCache(ref.bundle_uuid, draft_name=DRAFT_NAME).clear()
    # Now return the metadata about the new block:
    LIBRARY_BLOCK_CREATED.send(sender=None,
                               library_key=ref.library_key,
                               usage_key=usage_key)
    return get_library_block(usage_key)
コード例 #26
0
 def test_all_blocks_excluded_from_completion(self, blockclass):
     xblock = XBlock.load_class(blockclass)
     self.assertEqual(
         XBlockCompletionMode.get_mode(xblock),
         XBlockCompletionMode.EXCLUDED,
         "Block {!r} did not have completion mode 'excluded'".format(
             xblock),
     )
コード例 #27
0
ファイル: test_services.py プロジェクト: lxp20201/lxp
    def test_blocks_to_mark_complete_on_view(self):

        completable_block_1 = XBlock(Mock(), scope_ids=Mock(spec=ScopeIds))
        completable_block_1.location = UsageKey.from_string(
            "i4x://edX/100/a/1").replace(course_key=self.course_key)
        completable_block_2 = XBlock(Mock(), scope_ids=Mock(spec=ScopeIds))
        completable_block_2.location = UsageKey.from_string(
            "i4x://edX/100/a/2").replace(course_key=self.course_key)
        aggregator_block = XBlock(Mock(), scope_ids=Mock(spec=ScopeIds))
        aggregator_block.location = UsageKey.from_string(
            "i4x://edX/100/a/3").replace(course_key=self.course_key)
        aggregator_block.completion_mode = XBlockCompletionMode.AGGREGATOR

        self.assertSetEqual(
            self.completion_service.blocks_to_mark_complete_on_view({}), set())

        self.assertSetEqual(
            self.completion_service.blocks_to_mark_complete_on_view(
                {aggregator_block}), set())

        self.assertSetEqual(
            self.completion_service.blocks_to_mark_complete_on_view(
                {completable_block_1, completable_block_2, aggregator_block}),
            {completable_block_1, completable_block_2})

        BlockCompletion.objects.submit_completion(
            user=self.user,
            course_key=self.course_key,
            block_key=completable_block_2.location,
            completion=1.0)

        self.assertSetEqual(
            self.completion_service.blocks_to_mark_complete_on_view(
                {completable_block_1, completable_block_2, aggregator_block}),
            {completable_block_1})

        BlockCompletion.objects.submit_completion(
            user=self.user,
            course_key=self.course_key,
            block_key=completable_block_1.location,
            completion=1.0)

        self.assertSetEqual(
            self.completion_service.blocks_to_mark_complete_on_view(
                {completable_block_1, completable_block_2, aggregator_block}),
            set())
コード例 #28
0
ファイル: parse.py プロジェクト: lapentab/XBlock
def _process_node(node, usage_factory):
    """Give the XBlock classes a chance to manipulate the tree."""
    block_cls = XBlock.load_class(node.block_name)
    node = block_cls.preprocess_input(node, usage_factory)
    kids = [_process_node(kid, usage_factory) for kid in node.children]
    if any(old is not new for old, new in zip(node.children, kids)):
        node = usage_factory(node.block_name, kids, node.initial_state, node.def_id)
    node = block_cls.postprocess_input(node, usage_factory)
    return node
コード例 #29
0
ファイル: parse.py プロジェクト: qvin/XBlock
def _process_node(node, usage_factory):
    """Give the XBlock classes a chance to manipulate the tree."""
    block_cls = XBlock.load_class(node.block_name)
    node = block_cls.preprocess_input(node, usage_factory)
    kids = [_process_node(kid, usage_factory) for kid in node.children]
    if any(old is not new for old, new in zip(node.children, kids)):
        node = usage_factory(node.block_name, kids, node.initial_state, node.def_id)
    node = block_cls.postprocess_input(node, usage_factory)
    return node
コード例 #30
0
ファイル: api.py プロジェクト: cmltaWt0/edx-platform
def xblock_type_display_name(block_type):
    """
    Get the display name for the specified XBlock class.
    """
    block_class = XBlock.load_class(block_type)
    if hasattr(block_class, 'display_name') and block_class.display_name.default:
        return _(block_class.display_name.default)  # pylint: disable=translation-of-non-string
    else:
        return block_type  # Just use the block type as the name
コード例 #31
0
def xblock_specs_from_categories(categories):
    """
    Return NestedXBlockSpecs for available XBlocks from categories.
    """
    return (NestedXBlockSpec(class_,
                             category=category,
                             label=class_.display_name.default)
            for category, class_ in XBlock.load_classes()
            if category in categories)
コード例 #32
0
ファイル: finder.py プロジェクト: Lektorium-LLC/edx-platform
 def __init__(self, *args, **kwargs):
     super(XBlockPipelineFinder, self).__init__(*args, **kwargs)
     xblock_classes = set()
     for __, xblock_class in XBlock.load_classes():
         xblock_classes.add(xblock_class)
     self.package_storages = [
         XBlockPackageStorage(xblock_class.__module__, xblock_class.get_resources_dir())
         for xblock_class in xblock_classes
     ]
コード例 #33
0
ファイル: test_services.py プロジェクト: stvstnfrd/completion
 def test_submit_group_completion(self):
     third_user = UserFactory.create()
     completable_block = XBlock(Mock(), scope_ids=Mock(spec=ScopeIds))
     completable_block.location = UsageKey.from_string(
         "i4x://edX/100/a/1").replace(course_key=self.course_key)
     service = CompletionService(self.user, self.course_key)
     service.submit_group_completion(
         block_key=completable_block.location,
         completion=0.25,
         users=[self.other_user, third_user],
     )
     completions = list(
         BlockCompletion.objects.filter(
             block_key=completable_block.location))
     self.assertEqual(len(completions), 2)
     self.assertTrue(all(bc.completion == 0.25 for bc in completions))
     self.assertEqual({bc.user
                       for bc in completions},
                      {self.other_user, third_user})
コード例 #34
0
def init_scenarios():
    """
    Create all the scenarios declared in all the XBlock classes.
    """
    # Clear any existing scenarios, since this is used repeatedly during testing.
    SCENARIOS.clear()

    # Get all the XBlock classes, and add their scenarios.
    for class_name, cls in XBlock.load_classes():
        add_class_scenarios(class_name, cls)
コード例 #35
0
 def __init__(self, *args, **kwargs):
     super(XBlockPipelineFinder, self).__init__(*args, **kwargs)
     xblock_classes = set()
     for __, xblock_class in XBlock.load_classes():
         xblock_classes.add(xblock_class)
     self.package_storages = [
         XBlockPackageStorage(xblock_class.__module__,
                              xblock_class.get_resources_dir())
         for xblock_class in xblock_classes
     ]
コード例 #36
0
def does_block_type_support_children(block_type):
    """
    Does the specified block type (e.g. "html", "vertical") support child
    blocks?
    """
    try:
        return XBlock.load_class(block_type).has_children
    except PluginMissingError:
        # We don't know if this now-uninstalled block type had children
        # but to be conservative, assume it may have.
        return True
コード例 #37
0
ファイル: runtime.py プロジェクト: komeic/XBlock
def create_xblock(usage, student_id=None):
    """Create an XBlock instance.

    This will be invoked to create new instances for every request.

    """
    block_cls = XBlock.load_class(usage.block_name)
    runtime = WorkbenchRuntime(block_cls, student_id, usage)
    model = DbModel(MEMORY_KVS, block_cls, student_id, usage)
    block = block_cls(runtime, model)
    return block
コード例 #38
0
ファイル: runtime.py プロジェクト: dnsserver/XBlock
def create_xblock(usage, student_id=None):
    """Create an XBlock instance.

    This will be invoked to create new instances for every request.

    """
    block_cls = XBlock.load_class(usage.block_name)
    runtime = WorkbenchRuntime(block_cls, student_id, usage)
    model = DbModel(MEMORY_KVS, block_cls, student_id, usage)
    block = block_cls(runtime, model)
    return block
コード例 #39
0
def all_templates():
    """
    Returns all templates for enabled modules, grouped by descriptor type
    """
    # TODO use memcache to memoize w/ expiration
    templates = defaultdict(list)
    for category, descriptor in XBlock.load_classes():
        if not hasattr(descriptor, 'templates'):
            continue
        templates[category] = descriptor.templates()

    return templates
コード例 #40
0
ファイル: runtime.py プロジェクト: haoyuchen1992/XBlock
 def construct_xblock(self, block_type, scope_ids, field_data=None, default_class=None, *args, **kwargs):
     r"""
     Construct a new xblock of the type identified by block_type,
     passing \*args and \*\*kwargs into `__init__`.
     """
     block_class = XBlock.load_class(block_type, default_class)
     return self.construct_xblock_from_class(
         cls=block_class,
         scope_ids=scope_ids,
         field_data=field_data,
         *args, **kwargs
     )
コード例 #41
0
ファイル: views.py プロジェクト: usernamenumber/xblock-sdk
def package_resource(_request, block_type, resource):
    """
    Wrapper for `pkg_resources` that tries to access a resource and, if it
    is not found, raises an Http404 error.
    """
    try:
        xblock_class = XBlock.load_class(block_type)
        content = xblock_class.open_local_resource(resource)
    except Exception:  # pylint: disable-msg=broad-except
        raise Http404
    mimetype, _ = mimetypes.guess_type(resource)
    return HttpResponse(content, mimetype=mimetype)
コード例 #42
0
def block_types_possibly_scored():
    """
    Returns the block types that could have a score.

    Something might be a scored item if it is capable of storing a score
    (has_score=True). We also have to include anything that can have children,
    since those children might have scores. We can avoid things like Videos,
    which have state but cannot ever impact someone's grade.
    """
    return frozenset(cat for (cat, xblock_class) in XBlock.load_classes()
                     if (getattr(xblock_class, 'has_score', False)
                         or getattr(xblock_class, 'has_children', False)))
コード例 #43
0
ファイル: views.py プロジェクト: JAAkana/XBlock
def package_resource(_request, block_type, resource):
    """
    Wrapper for `pkg_resources` that tries to access a resource and, if it
    is not found, raises an Http404 error.
    """
    try:
        xblock_class = XBlock.load_class(block_type)
        content = xblock_class.open_local_resource(resource)
    except Exception:  # pylint: disable-msg=broad-except
        raise Http404
    mimetype, _ = mimetypes.guess_type(resource)
    return HttpResponse(content, mimetype=mimetype)
コード例 #44
0
 def __call__(self, view):
     """
     Add mobile support if the feature flag is enabled.
     """
     try:
         if self.is_mobile_support_enabled:
             return XBlock.supports('multi_device')(view)
     except ImportError:
         # Openedx libraries are not available in testing
         # environment.
         pass
     return view
コード例 #45
0
 def apply_mock(self, mocked_objects):
     """
     Save state of default transcripts related entities before mocks are applied.
     """
     player = XBlock.load_class('youtube')
     mocked_objects.append({
         'obj': player,
         'attrs': ['fetch_default_transcripts_languages'],
         'value': [player.fetch_default_transcripts_languages, ]
     })
     player.fetch_default_transcripts_languages = self.fetch_default_transcripts_languages()
     return mocked_objects
コード例 #46
0
    def get(self, block_type, resource):
        xblock_class = XBlock.load_class(block_type)

        mimetype = mimetypes.guess_type(resource)[0]
        if mimetype is None:
            mimetype = 'application/octet-stream'

        self.response.status = 200
        self.response.headers['Content-Type'] = mimetype
        self.response.cache_control.no_cache = None
        self.response.cache_control.public = 'public'
        self.response.cache_control.max_age = 600
        self.response.write(xblock_class.open_local_resource(resource).read())
コード例 #47
0
def is_aggregation_name(category):
    """
    Return True if the named category is a valid aggregation name.

    Currently, valid aggregators comprise the list of block types that have
    a completion_mode of XBlockCompletionMode.AGGREGATOR, but this may be
    expanded in the future.
    """
    try:
        cls = XBlock.load_class(category)
    except PluginMissingError:
        return False

    return get_completion_mode(cls) == XBlockCompletionMode.AGGREGATOR
コード例 #48
0
ファイル: grades.py プロジェクト: marcore/edx-platform
def block_types_with_scores():
    """
    Returns the block types that could have a score.

    Something might be a scored item if it is capable of storing a score
    (has_score=True). We also have to include anything that can have children,
    since those children might have scores. We can avoid things like Videos,
    which have state but cannot ever impact someone's grade.
    """
    return frozenset(
        cat for (cat, xblock_class) in XBlock.load_classes() if (
            getattr(xblock_class, 'has_score', False) or getattr(xblock_class, 'has_children', False)
        )
    )
コード例 #49
0
def init_scenarios():
    """
    Create all the scenarios declared in all the XBlock classes.
    """
    # Clear any existing scenarios, since this is used repeatedly during testing.
    SCENARIOS.clear()
    if settings.WORKBENCH['reset_state_on_restart']:
        WORKBENCH_KVS.clear()
    else:
        WORKBENCH_KVS.prep_for_scenario_loading()

    # Get all the XBlock classes, and add their scenarios.
    for class_name, cls in sorted(XBlock.load_classes()):
        add_class_scenarios(class_name, cls)
コード例 #50
0
ファイル: scenarios.py プロジェクト: TimothyHohne/xblock-sdk
def init_scenarios():
    """
    Create all the scenarios declared in all the XBlock classes.
    """
    # Clear any existing scenarios, since this is used repeatedly during testing.
    SCENARIOS.clear()
    if settings.WORKBENCH["reset_state_on_restart"]:
        WORKBENCH_KVS.clear()
    else:
        WORKBENCH_KVS.prep_for_scenario_loading()

    # Get all the XBlock classes, and add their scenarios.
    for class_name, cls in sorted(XBlock.load_classes(fail_silently=False)):
        add_class_scenarios(class_name, cls, fail_silently=False)
コード例 #51
0
ファイル: __init__.py プロジェクト: AsylumCorp/edx-platform
    def partition_fields_by_scope(self, category, fields):
        """
        Return dictionary of {scope: {field1: val, ..}..} for the fields of this potential xblock

        :param category: the xblock category
        :param fields: the dictionary of {fieldname: value}
        """
        if fields is None:
            return {}
        cls = self.mixologist.mix(XBlock.load_class(category, select=prefer_xmodules))
        result = collections.defaultdict(dict)
        for field_name, value in fields.iteritems():
            field = getattr(cls, field_name)
            result[field.scope][field_name] = value
        return result
コード例 #52
0
ファイル: test_plugin.py プロジェクト: ffedoroff/XBlock
def test_ambiguous_plugins():
    # We can load ok blocks even if there are bad blocks.
    cls = XBlock.load_class("good_block")
    assert cls is UnambiguousBlock

    # Trying to load bad blocks raises an exception.
    expected_msg = ("Ambiguous entry points for bad_block: "
                    "xblock.test.test_plugin.AmbiguousBlock1, "
                    "xblock.test.test_plugin.AmbiguousBlock2")
    with pytest.raises(AmbiguousPluginError, match=expected_msg):
        XBlock.load_class("bad_block")

    # We can use our own function as the select function.
    class MyOwnException(Exception):
        """We'll raise this from `boom`."""

    def boom(identifier, entry_points):
        """A select function to prove user-defined functions are called."""
        assert len(entry_points) == 2
        assert identifier == "bad_block"
        raise MyOwnException("This is boom")

    with pytest.raises(MyOwnException, match="This is boom"):
        XBlock.load_class("bad_block", select=boom)
コード例 #53
0
ファイル: module_render.py プロジェクト: ropock/edx-platform
def xblock_resource(request, block_type, uri):  # pylint: disable=unused-argument
    """
    Return a package resource for the specified XBlock.
    """
    try:
        xblock_class = XBlock.load_class(block_type, select=settings.XBLOCK_SELECT_FUNCTION)
        content = xblock_class.open_local_resource(uri)
    except IOError:
        log.info('Failed to load xblock resource', exc_info=True)
        raise Http404
    except Exception:  # pylint: disable=broad-except
        log.error('Failed to load xblock resource', exc_info=True)
        raise Http404
    mimetype, _ = mimetypes.guess_type(uri)
    return HttpResponse(content, mimetype=mimetype)
コード例 #54
0
ファイル: __init__.py プロジェクト: priceamanda1/edx-platform
    def partition_fields_by_scope(self, category, fields):
        """
        Return dictionary of {scope: {field1: val, ..}..} for the fields of this potential xblock

        :param category: the xblock category
        :param fields: the dictionary of {fieldname: value}
        """
        result = collections.defaultdict(dict)
        if fields is None:
            return result
        cls = self.mixologist.mix(XBlock.load_class(category, select=prefer_xmodules))
        for field_name, value in fields.iteritems():
            field = getattr(cls, field_name)
            result[field.scope][field_name] = value
        return result
コード例 #55
0
ファイル: test_plugin.py プロジェクト: plounze/XBlock
def test_ambiguous_plugins():
    # We can load ok blocks even if there are bad blocks.
    cls = XBlock.load_class("good_block")
    assert_is(cls, UnambiguousBlock)

    # Trying to load bad blocks raises an exception.
    expected_msg = ("Ambiguous entry points for bad_block: "
                    "xblock.test.test_plugin.AmbiguousBlock1, "
                    "xblock.test.test_plugin.AmbiguousBlock2")
    with assert_raises_regexp(AmbiguousPluginError, expected_msg):
        XBlock.load_class("bad_block")

    # We can use our own function as the select function.
    class MyOwnException(Exception):
        """We'll raise this from `boom`."""
        pass

    def boom(entry_points):
        """A select function to prove user-defined functions are called."""
        assert len(entry_points) == 2
        raise MyOwnException("This is boom")

    with assert_raises_regexp(MyOwnException, "This is boom"):
        XBlock.load_class("bad_block", select=boom)
コード例 #56
0
def test_services_decorators():
    # pylint: disable=E1101
    # A default XBlock has requested no services
    xblock = XBlock(None, None, None)
    assert_equals(XBlock._services_requested, {})
    assert_equals(xblock._services_requested, {})

    @XBlock.needs("n")
    @XBlock.wants("w")
    class ServiceUsingBlock(XBlock):
        """XBlock using some services."""
        pass

    service_using_block = ServiceUsingBlock(None, scope_ids=None)
    assert_equals(ServiceUsingBlock._services_requested, {'n': 'need', 'w': 'want'})
    assert_equals(service_using_block._services_requested, {'n': 'need', 'w': 'want'})