Esempio n. 1
0
def build_chart_data_for_field(xform,
                               field,
                               language_index=0,
                               choices=None,
                               group_by=None,
                               data_view=None):
    # check if its the special _submission_time META
    if isinstance(field, basestring):
        field_label, field_xpath, field_type = FIELD_DATA_MAP.get(field)
    else:
        # TODO: merge choices with results and set 0's on any missing fields,
        # i.e. they didn't have responses

        field_label = get_field_label(field, language_index)
        field_xpath = field.get_abbreviated_xpath()
        field_type = field.type

    data_type = DATA_TYPE_MAP.get(field_type, 'categorized')
    field_name = field.name if not isinstance(field, basestring) else field

    if group_by:
        group_by_name = group_by.get_abbreviated_xpath() \
            if not isinstance(group_by, basestring) else group_by

        if (field_type == common_tags.SELECT_ONE or
                field_name == common_tags.SUBMITTED_BY) and \
                isinstance(group_by, six.string_types):
            result = get_form_submissions_grouped_by_select_one(
                xform, field_xpath, group_by_name, field_name, data_view)
        elif field_type in common_tags.NUMERIC_LIST and \
                isinstance(group_by, six.string_types):
            result = get_form_submissions_aggregated_by_select_one(
                xform, field_xpath, field_name, group_by_name, data_view)
        elif (field_type == common_tags.SELECT_ONE or
              field_name == common_tags.SUBMITTED_BY) and \
                group_by.type == common_tags.SELECT_ONE:
            result = get_form_submissions_grouped_by_select_one(
                xform, field_xpath, group_by_name, field_name, data_view)

            result = _flatten_multiple_dict_into_one(field_name, group_by_name,
                                                     result)
        elif field_type in common_tags.NUMERIC_LIST \
                and group_by.type == common_tags.SELECT_ONE:
            result = get_form_submissions_aggregated_by_select_one(
                xform, field_xpath, field_name, group_by_name, data_view)
        else:
            raise ParseError(u'Cannot group by %s' % group_by_name)
    else:
        result = get_form_submissions_grouped_by_field(xform, field_xpath,
                                                       field_name, data_view)

    result = _use_labels_from_field_name(field_name,
                                         field,
                                         data_type,
                                         result,
                                         choices=choices)

    if group_by and not isinstance(group_by, six.string_types):
        group_by_data_type = DATA_TYPE_MAP.get(group_by.type, 'categorized')
        grp_choices = get_field_choices(group_by, xform)
        result = _use_labels_from_group_by_name(group_by_name,
                                                group_by,
                                                group_by_data_type,
                                                result,
                                                choices=grp_choices)

    if not group_by:
        result = sorted(result, key=lambda d: d['count'])

    # for date fields, strip out None values
    if data_type == 'time_based':
        result = [r for r in result if r.get(field_name) is not None]
        # for each check if it matches the timezone regexp and convert for js
        for r in result:
            if timezone_re.match(r[field_name]):
                try:
                    r[field_name] = utc_time_string_for_javascript(
                        r[field_name])
                except ValueError:
                    pass

    return {
        'data': result,
        'data_type': data_type,
        'field_label': field_label,
        'field_xpath': field_xpath,
        'field_name': field_name,
        'field_type': field_type,
        'grouped_by': group_by_name if group_by else None
    }
Esempio n. 2
0
def build_chart_data_for_field(xform,
                               field,
                               language_index=0,
                               choices=None,
                               group_by=None,
                               data_view=None):
    # check if its the special _submission_time META
    if isinstance(field, basestring):
        field_label, field_xpath, field_type = FIELD_DATA_MAP.get(field)
    else:
        # TODO: merge choices with results and set 0's on any missing fields,
        # i.e. they didn't have responses

        field_label = get_field_label(field, language_index)
        field_xpath = field.get_abbreviated_xpath()
        field_type = field.type

    data_type = DATA_TYPE_MAP.get(field_type, 'categorized')
    field_name = field.name if not isinstance(field, basestring) else field

    if group_by and isinstance(group_by, list):
        group_by_name = [
            g.get_abbreviated_xpath() if not isinstance(g, basestring) else g
            for g in group_by
        ]
        result = get_form_submissions_aggregated_by_select_one(
            xform, field_xpath, field_name, group_by_name, data_view)
    elif group_by:
        group_by_name = group_by.get_abbreviated_xpath() \
            if not isinstance(group_by, basestring) else group_by

        if (field_type == common_tags.SELECT_ONE or
                field_name == common_tags.SUBMITTED_BY) and \
                isinstance(group_by, six.string_types):
            result = get_form_submissions_grouped_by_select_one(
                xform, field_xpath, group_by_name, field_name, data_view)
        elif field_type in common_tags.NUMERIC_LIST and \
                isinstance(group_by, six.string_types):
            result = get_form_submissions_aggregated_by_select_one(
                xform, field_xpath, field_name, group_by_name, data_view)
        elif (field_type == common_tags.SELECT_ONE or
              field_name == common_tags.SUBMITTED_BY) and \
                group_by.type == common_tags.SELECT_ONE:
            result = get_form_submissions_grouped_by_select_one(
                xform, field_xpath, group_by_name, field_name, data_view)

            result = _flatten_multiple_dict_into_one(field_name, group_by_name,
                                                     result)
        elif field_type in common_tags.NUMERIC_LIST \
                and group_by.type == common_tags.SELECT_ONE:
            result = get_form_submissions_aggregated_by_select_one(
                xform, field_xpath, field_name, group_by_name, data_view)
        else:
            raise ParseError('Cannot group by %s' % group_by_name)
    else:
        result = get_form_submissions_grouped_by_field(xform, field_xpath,
                                                       field_name, data_view)

    result = _use_labels_from_field_name(
        field_name, field, data_type, result, choices=choices)

    if group_by and not isinstance(group_by, six.string_types + (list, )):
        group_by_data_type = DATA_TYPE_MAP.get(group_by.type, 'categorized')
        grp_choices = get_field_choices(group_by, xform)
        result = _use_labels_from_group_by_name(
            group_by_name,
            group_by,
            group_by_data_type,
            result,
            choices=grp_choices)
    elif group_by and isinstance(group_by, list):
        for g in group_by:
            if isinstance(g, six.string_types):
                continue

            group_by_data_type = DATA_TYPE_MAP.get(g.type, 'categorized')
            grp_choices = get_field_choices(g, xform)
            result = _use_labels_from_group_by_name(
                g.get_abbreviated_xpath(),
                g,
                group_by_data_type,
                result,
                choices=grp_choices)

    if not group_by:
        result = sorted(result, key=lambda d: d['count'])

    # for date fields, strip out None values
    if data_type == 'time_based':
        result = [r for r in result if r.get(field_name) is not None]
        # for each check if it matches the timezone regexp and convert for js
        for r in result:
            if timezone_re.match(r[field_name]):
                try:
                    r[field_name] = utc_time_string_for_javascript(
                        r[field_name])
                except ValueError:
                    pass

    return {
        'data': result,
        'data_type': data_type,
        'field_label': field_label,
        'field_xpath': field_xpath,
        'field_name': field_name,
        'field_type': field_type,
        'grouped_by': group_by_name if group_by else None
    }