Example #1
0
def create_schema_blocks_for_atomic_schema(schema):
    """
    Atomic schemas are a short cut around making an typical metaschemas by being totally explict about the schemablocks
    being created.
    """

    from osf.models import RegistrationSchemaBlock
    current_group_key = None
    grouped_block_types = RegistrationSchemaBlock.INPUT_BLOCK_TYPES.union(
        {'select-input-option', 'select-input-other'})

    for index, block in enumerate(schema.schema['blocks']):
        # Not all block types use all '*_text' fields, so provide an easy default
        for optional_text_field in [
                'display_text', 'help_text', 'example_text'
        ]:
            block[optional_text_field] = block.get(optional_text_field, '')

        block_type = block['block_type']

        # Each 'question-label' generates a 'schema_block_group_key' that is inherited
        # By all input and input-option blocks until the next question-label appears
        if block_type == 'question-label':
            current_group_key = generate_object_id()
            block['schema_block_group_key'] = current_group_key
        elif block_type in grouped_block_types:
            block['schema_block_group_key'] = current_group_key
        else:
            block['schema_block_group_key'] = ''

        # Input blocks define a 'registration_response_key', while it is NULL for all other blocks
        # Either honor a provided key or auto-generate one based on the block's index
        if block_type in RegistrationSchemaBlock.INPUT_BLOCK_TYPES:
            if not block.get('registration_response_key'):
                block['registration_response_key'] = f'{schema.id}-{index}'
        else:  # Ignore any improperly-supplied registration_response_key
            block['registration_response_key'] = None

        RegistrationSchemaBlock.objects.create(schema_id=schema.id, **block)
def create_schema_blocks_for_question(state, rs, question, sub=False):
    """
    For mapping schemas to schema blocks:
    Split the original question from the schema into multiple schema blocks, all of
    which have the same schema_block_group_key, to link them.
    """
    # If there are subquestions, recurse and format subquestions
    properties = question.get('properties')
    if properties:
        first_subquestion = properties[0]
        first_subq_text = first_subquestion.get('title') or first_subquestion.get('description', '')

        if first_subq_text:
            # the first subquestion has text, so this seems like an actual [sub]section
            create_schema_block(
                state,
                rs.id,
                block_type='subsection-heading' if sub else 'section-heading',
                display_text=question.get('title', '') or question.get('description', ''),
            )
        else:
            # the first subquestion has no text, so the "section" heading is better interpreted as a question label
            first_subquestion['title'] = question.get('title', '')
            first_subquestion['description'] = question.get('description', '')
            if not first_subquestion.get('help'):
                first_subquestion['help'] = question.get('help', '')

        for subquestion in properties:
            subquestion['qid'] = get_subquestion_qid(question, subquestion)
            create_schema_blocks_for_question(state, rs, subquestion, sub=True)
    else:
        # All schema blocks related to a particular question share the same schema_block_group_key.
        schema_block_group_key = generate_object_id()
        title, description, help, example = find_title_description_help_example(rs, question)

        # Creates question title block
        create_schema_block(
            state,
            rs.id,
            block_type='question-label',
            display_text=title,
            help_text='' if description else help,
            example_text=example,
            schema_block_group_key=schema_block_group_key
        )

        # Creates paragraph block (question description)
        if description:
            create_schema_block(
                state,
                rs.id,
                block_type='paragraph',
                display_text=description,
                help_text=help,
                schema_block_group_key=schema_block_group_key,
            )

        # Creates question input block - this block will correspond to an answer
        # Map the original schema section format to the new block_type, and create a schema block
        block_type = FORMAT_TYPE_TO_TYPE_MAP[(question.get('format'), question.get('type'))]
        create_schema_block(
            state,
            rs.id,
            block_type,
            required=question.get('required', False),
            schema_block_group_key=schema_block_group_key,
            registration_response_key=get_registration_response_key(question)
        )

        # If there are multiple choice answers, create blocks for these as well.
        split_options_into_blocks(state, rs, question, schema_block_group_key)