Esempio n. 1
0
    def handle(self, *args, **options):
        if options['clear-all']:
            if options['force'] or query_yes_no(self.CONFIRMATION_PROMPT_CLEAR,
                                                default="no"):
                logging.info("Removing all libraries from the index")
                ContentLibraryIndexer.remove_all_items()
                LibraryBlockIndexer.remove_all_items()
            return

        if options['all']:
            if options['force'] or query_yes_no(self.CONFIRMATION_PROMPT_ALL,
                                                default="no"):
                logging.info("Indexing all libraries")
                library_keys = [
                    library.library_key
                    for library in ContentLibrary.objects.all()
                ]
            else:
                return
        else:
            logging.info("Indexing libraries: {}".format(
                options['library_ids']))
            library_keys = list(
                map(LibraryLocatorV2.from_string, options['library_ids']))

        ContentLibraryIndexer.index_items(library_keys)

        for library_key in library_keys:
            ref = ContentLibrary.objects.get_by_key(library_key)
            lib_bundle = LibraryBundle(library_key,
                                       ref.bundle_uuid,
                                       draft_name=DRAFT_NAME)
            LibraryBlockIndexer.index_items(lib_bundle.get_all_usages())
Esempio n. 2
0
def get_library_blocks(library_key, text_search=None, block_types=None):
    """
    Get the list of top-level XBlocks in the specified library.

    Returns a list of LibraryXBlockMetadata objects
    """
    metadata = None
    if LibraryBlockIndexer.indexing_is_enabled():
        try:
            filter_terms = {
                'library_key': [str(library_key)],
                'is_child': [False],
            }
            if block_types:
                filter_terms['block_type'] = block_types
            metadata = [
                {
                    **item,
                    "id": LibraryUsageLocatorV2.from_string(item['id']),
                }
                for item in LibraryBlockIndexer.get_items(filter_terms=filter_terms, text_search=text_search)
                if item is not None
            ]
        except ElasticConnectionError as e:
            log.exception(e)

    # If indexing is disabled, or connection to elastic failed
    if metadata is None:
        metadata = []
        ref = ContentLibrary.objects.get_by_key(library_key)
        lib_bundle = LibraryBundle(library_key, ref.bundle_uuid, draft_name=DRAFT_NAME)
        usages = lib_bundle.get_top_level_usages()

        for usage_key in usages:
            # For top-level definitions, we can go from definition key to usage key using the following, but this would
            # not work for non-top-level blocks as they may have multiple usages. Top level blocks are guaranteed to
            # have only a single usage in the library, which is part of the definition of top level block.
            def_key = lib_bundle.definition_for_usage(usage_key)
            display_name = get_block_display_name(def_key)
            text_match = (text_search is None or
                          text_search.lower() in display_name.lower() or
                          text_search.lower() in str(usage_key).lower())
            type_match = (block_types is None or usage_key.block_type in block_types)
            if text_match and type_match:
                metadata.append({
                    "id": usage_key,
                    "def_key": def_key,
                    "display_name": display_name,
                    "has_unpublished_changes": lib_bundle.does_definition_have_unpublished_changes(def_key),
                })

    return [
        LibraryXBlockMetadata(
            usage_key=item['id'],
            def_key=item['def_key'],
            display_name=item['display_name'],
            has_unpublished_changes=item['has_unpublished_changes'],
        )
        for item in metadata
    ]
    def test_remove_all_items(self):
        """
        Test if remove_all_items() deletes all libraries
        """
        lib1 = self._create_library(slug="test-lib-rm-all", title="Title 1", description="Description")
        self._add_block_to_library(lib1['id'], "problem", "problem1")
        self._add_block_to_library(lib1['id'], "problem", "problem2")
        self.assertEqual(len(LibraryBlockIndexer.get_items()), 2)

        LibraryBlockIndexer.remove_all_items()
        self.assertEqual(len(LibraryBlockIndexer.get_items()), 0)
    def test_schema_updates(self):
        """
        Test that outdated indexes aren't retrieved
        """
        lib = self._create_library(slug="test-lib--block-schemaupdates-1", title="Title 1", description="Description")
        with patch("openedx.core.djangoapps.content_libraries.libraries_index.LibraryBlockIndexer.SCHEMA_VERSION",
                   new=0):
            block = self._add_block_to_library(lib['id'], "problem", "problem1")
            self.assertEqual(len(LibraryBlockIndexer.get_items([block['id']])), 1)

        with patch("openedx.core.djangoapps.content_libraries.libraries_index.LibraryBlockIndexer.SCHEMA_VERSION",
                   new=1):
            self.assertEqual(len(LibraryBlockIndexer.get_items([block['id']])), 0)

            call_command("reindex_content_library", all=True, force=True)

            self.assertEqual(len(LibraryBlockIndexer.get_items([block['id']])), 1)
    def test_index_block(self):
        """
        Test if libraries are being indexed correctly
        """
        lib = self._create_library(slug="test-lib-index-1", title="Title 1", description="Description")
        block1 = self._add_block_to_library(lib['id'], "problem", "problem1")
        block2 = self._add_block_to_library(lib['id'], "problem", "problem2")

        self.assertEqual(len(LibraryBlockIndexer.get_items()), 2)

        for block in [block1, block2]:
            usage_key = LibraryUsageLocatorV2.from_string(block['id'])
            response = LibraryBlockIndexer.get_items([usage_key])[0]

            self.assertEqual(response['id'], block['id'])
            self.assertEqual(response['def_key'], block['def_key'])
            self.assertEqual(response['block_type'], block['block_type'])
            self.assertEqual(response['display_name'], block['display_name'])
            self.assertEqual(response['has_unpublished_changes'], block['has_unpublished_changes'])
Esempio n. 6
0
    def test_crud_block(self):
        """
        Test that CRUD operations on blocks are reflected in the index
        """
        lib = self._create_library(slug="test-lib-crud-block",
                                   title="Title",
                                   description="Description")
        block = self._add_block_to_library(lib['id'], "problem", "problem1")

        # Update OLX, verify updates in index
        self._set_library_block_olx(block["id"],
                                    '<problem display_name="new_name"/>')
        response = LibraryBlockIndexer.get_items([block['id']])[0]
        assert response['display_name'] == 'new_name'
        assert response['has_unpublished_changes'] is True

        # Verify has_unpublished_changes after committing library
        self._commit_library_changes(lib['id'])
        response = LibraryBlockIndexer.get_items([block['id']])[0]
        assert response['has_unpublished_changes'] is False

        # Verify has_unpublished_changes after reverting library
        self._set_library_block_asset(block["id"], "whatever.png", b"data")
        response = LibraryBlockIndexer.get_items([block['id']])[0]
        assert response['has_unpublished_changes'] is True

        self._revert_library_changes(lib['id'])
        response = LibraryBlockIndexer.get_items([block['id']])[0]
        assert response['has_unpublished_changes'] is False

        # Verify that deleting block removes it from index
        self._delete_library_block(block['id'])
        assert LibraryBlockIndexer.get_items([block['id']]) == []

        # Verify that deleting a library removes its blocks from index too
        self._add_block_to_library(lib['id'], "problem", "problem1")
        LibraryBlockIndexer.get_items([block['id']])
        self._delete_library(lib['id'])
        assert LibraryBlockIndexer.get_items([block['id']]) == []
Esempio n. 7
0
 def setUp(self):
     super().setUp()
     if settings.ENABLE_ELASTICSEARCH_FOR_TESTS:
         ContentLibraryIndexer.remove_all_items()
         LibraryBlockIndexer.remove_all_items()
Esempio n. 8
0
 def setUp(self):
     super().setUp()
     ContentLibraryIndexer.remove_all_items()
     LibraryBlockIndexer.remove_all_items()
     self.searcher = SearchEngine.get_search_engine(
         LibraryBlockIndexer.INDEX_NAME)