human
Solve the following python programming problem given the following code:
@set_database
def annotate_content_models(channel='khan', language='en', ids=None, iterator_content_items=iterator_content_items, **kwargs):
assistant
#Here is the Python program you requested.

    """Annotate content models that have the ids specified in a list.
    Our ids can be duplicated at the moment, so this may be several content items per id.
    When a content item has been updated, propagate availability up the topic tree.
    :param channel: Channel to update.
    :param language: Language of channel to update.
    :param ids: List of content ids to find content models for annotation.
    :param iterator_content_items: Generator function to use to yield paths and updates.
    """
    db = kwargs.get('db')
    if db:
        content_models = iterator_content_items(ids=ids, channel=channel, language=language)
        with db.atomic() as transaction:
            def update_parent_annotation(parent):
                children = list(Item.select(Item.available, Item.total_files, Item.files_complete, Item.remote_size, Item.size_on_disk).where((Item.parent == parent.pk)))
                available = any((child.available for child in children))
                total_files = sum((child.total_files for child in children))
                files_complete = sum((child.files_complete for child in children))
                child_remote = sum((child.remote_size for child in children if (((not child.available) and (child.kind != 'Topic')) or (child.kind == 'Topic'))))
                child_on_disk = sum((child.size_on_disk for child in children))
                files_complete = min(total_files, files_complete)
                if (parent.available != available):
                    parent.available = available
                if (parent.files_complete != files_complete):
                    parent.files_complete = files_complete
                if (parent.remote_size != child_remote):
                    parent.remote_size = child_remote
                if (parent.size_on_disk != child_on_disk):
                    parent.size_on_disk = child_on_disk
                if parent.is_dirty():
                    parent.save()
                    return True
                else:
                    return False
            parents_to_update = {}
            for (path, update) in content_models:
                if update:
                    item = Item.get((Item.path == path))
                    if (item.kind != 'Topic'):
                        item_data = unparse_model_data(model_to_dict(item, recurse=False))
                        item_data.update(update)
                        item_data = parse_model_data(item_data)
                        for (attr, val) in item_data.iteritems():
                  ...