Example #1
0
def get_library(library_key):
    """
    Get the library with the specified key. Does not check permissions.
    returns a ContentLibraryMetadata instance.

    Raises ContentLibraryNotFound if the library doesn't exist.
    """
    assert isinstance(library_key, LibraryLocatorV2)
    ref = ContentLibrary.objects.get_by_key(library_key)
    bundle_metadata = get_bundle(ref.bundle_uuid)
    lib_bundle = LibraryBundle(library_key,
                               ref.bundle_uuid,
                               draft_name=DRAFT_NAME)
    num_blocks = len(lib_bundle.get_top_level_usages())
    last_published = lib_bundle.get_last_published_time()
    (has_unpublished_changes,
     has_unpublished_deletes) = lib_bundle.has_changes()
    return ContentLibraryMetadata(
        key=library_key,
        bundle_uuid=ref.bundle_uuid,
        title=bundle_metadata.title,
        description=bundle_metadata.description,
        num_blocks=num_blocks,
        version=bundle_metadata.latest_version,
        last_published=last_published,
        allow_public_learning=ref.allow_public_learning,
        allow_public_read=ref.allow_public_read,
        has_unpublished_changes=has_unpublished_changes,
        has_unpublished_deletes=has_unpublished_deletes,
    )
Example #2
0
    def get_item_definition(cls, item):
        ref = ContentLibrary.objects.get_by_key(item)
        lib_bundle = LibraryBundle(item,
                                   ref.bundle_uuid,
                                   draft_name=DRAFT_NAME)
        num_blocks = len(lib_bundle.get_top_level_usages())
        last_published = lib_bundle.get_last_published_time()
        last_published_str = None
        if last_published:
            last_published_str = last_published.strftime('%Y-%m-%dT%H:%M:%SZ')
        (has_unpublished_changes,
         has_unpublished_deletes) = lib_bundle.has_changes()

        bundle_metadata = get_bundle(ref.bundle_uuid)

        # NOTE: Increment ContentLibraryIndexer.SCHEMA_VERSION if the following schema is updated to avoid dealing
        # with outdated indexes which might cause errors due to missing/invalid attributes.
        return {
            "schema_version": ContentLibraryIndexer.SCHEMA_VERSION,
            "id": str(item),
            "uuid": str(bundle_metadata.uuid),
            "title": bundle_metadata.title,
            "description": bundle_metadata.description,
            "num_blocks": num_blocks,
            "version": bundle_metadata.latest_version,
            "last_published": last_published_str,
            "has_unpublished_changes": has_unpublished_changes,
            "has_unpublished_deletes": has_unpublished_deletes,
            # only 'content' field is analyzed by elastisearch, and allows text-search
            "content": {
                "id": str(item),
                "title": bundle_metadata.title,
                "description": bundle_metadata.description,
            },
        }
Example #3
0
    def index_libraries(cls, library_keys):
        """
        Index the specified libraries. If they already exist, replace them with new ones.
        """
        searcher = SearchEngine.get_search_engine(cls.INDEX_NAME)

        library_dicts = []

        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)
            num_blocks = len(lib_bundle.get_top_level_usages())
            last_published = lib_bundle.get_last_published_time()
            last_published_str = None
            if last_published:
                last_published_str = last_published.strftime(
                    '%Y-%m-%dT%H:%M:%SZ')
            (has_unpublished_changes,
             has_unpublished_deletes) = lib_bundle.has_changes()

            bundle_metadata = get_bundle(ref.bundle_uuid)

            # NOTE: Increment ContentLibraryIndexer.SCHEMA_VERSION if the following schema is updated to avoid dealing
            # with outdated indexes which might cause errors due to missing/invalid attributes.
            library_dict = {
                "schema_version": ContentLibraryIndexer.SCHEMA_VERSION,
                "id": str(library_key),
                "uuid": str(bundle_metadata.uuid),
                "title": bundle_metadata.title,
                "description": bundle_metadata.description,
                "num_blocks": num_blocks,
                "version": bundle_metadata.latest_version,
                "last_published": last_published_str,
                "has_unpublished_changes": has_unpublished_changes,
                "has_unpublished_deletes": has_unpublished_deletes,
            }
            library_dicts.append(library_dict)

        return searcher.index(cls.LIBRARY_DOCUMENT_TYPE, library_dicts)
Example #4
0
def get_library(library_key):
    """
    Get the library with the specified key. Does not check permissions.
    returns a ContentLibraryMetadata instance.

    Raises ContentLibraryNotFound if the library doesn't exist.
    """
    assert isinstance(library_key, LibraryLocatorV2)
    ref = ContentLibrary.objects.get_by_key(library_key)
    bundle_metadata = get_bundle(ref.bundle_uuid)
    lib_bundle = LibraryBundle(library_key, ref.bundle_uuid, draft_name=DRAFT_NAME)
    (has_unpublished_changes, has_unpublished_deletes) = lib_bundle.has_changes()
    return ContentLibraryMetadata(
        key=library_key,
        bundle_uuid=ref.bundle_uuid,
        title=bundle_metadata.title,
        description=bundle_metadata.description,
        version=bundle_metadata.latest_version,
        has_unpublished_changes=has_unpublished_changes,
        has_unpublished_deletes=has_unpublished_deletes,
    )
Example #5
0
def update_library(
    library_key,
    title=None,
    description=None,
    allow_public_learning=None,
    allow_public_read=None,
    library_type=None,
    library_license=None,
):
    """
    Update a library's metadata
    (Slug cannot be changed as it would break IDs throughout the system.)

    A value of None means "don't change".
    """
    ref = ContentLibrary.objects.get_by_key(library_key)

    # Update MySQL model:
    changed = False
    if allow_public_learning is not None:
        ref.allow_public_learning = allow_public_learning
        changed = True
    if allow_public_read is not None:
        ref.allow_public_read = allow_public_read
        changed = True
    if library_type is not None:
        if library_type not in (COMPLEX, ref.type):
            lib_bundle = LibraryBundle(library_key,
                                       ref.bundle_uuid,
                                       draft_name=DRAFT_NAME)
            (has_unpublished_changes,
             has_unpublished_deletes) = lib_bundle.has_changes()
            if has_unpublished_changes or has_unpublished_deletes:
                raise IncompatibleTypesError(
                    _('You may not change a library\'s type to {library_type} if it still has unpublished changes.'
                      ).format(library_type=library_type))
            for block in get_library_blocks(library_key):
                if block.usage_key.block_type != library_type:
                    raise IncompatibleTypesError(
                        _('You can only set a library to {library_type} if all existing blocks are of that type. '
                          'Found incompatible block {block_id} with type {block_type}.'
                          ).format(
                              library_type=library_type,
                              block_type=block.usage_key.block_type,
                              block_id=block.usage_key.block_id,
                          ), )
        ref.type = library_type

        changed = True
    if library_license is not None:
        ref.license = library_license
        changed = True
    if changed:
        ref.save()
    # Update Blockstore:
    fields = {
        # We don't ever read the "slug" value from the Blockstore bundle, but
        # we might as well always do our best to keep it in sync with the "slug"
        # value in the LMS that we do use.
        "slug": ref.slug,
    }
    if title is not None:
        assert isinstance(title, str)
        fields["title"] = title
    if description is not None:
        assert isinstance(description, str)
        fields["description"] = description
    update_bundle(ref.bundle_uuid, **fields)
    CONTENT_LIBRARY_UPDATED.send(sender=None, library_key=ref.library_key)