csvs.py 2.75 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
"""
Student and course analytics.

Format and create csv responses
"""

import csv
from django.http import HttpResponse


def create_csv_response(filename, header, datarows):
    """
    Create an HttpResponse with an attached .csv file

    header   e.g. ['Name', 'Email']
    datarows e.g. [['Jim', 'jim@edy.org'], ['Jake', 'jake@edy.org'], ...]
    """
    response = HttpResponse(mimetype='text/csv')
19 20 21 22 23 24 25 26
    response['Content-Disposition'] = 'attachment; filename={0}'\
        .format(filename)
    csvwriter = csv.writer(
        response,
        dialect='excel',
        quotechar='"',
        quoting=csv.QUOTE_ALL)

27 28 29 30 31 32 33
    csvwriter.writerow(header)
    for datarow in datarows:
        encoded_row = [unicode(s).encode('utf-8') for s in datarow]
        csvwriter.writerow(encoded_row)
    return response


34
def format_dictlist(dictlist, features):
35
    """
36 37 38 39 40 41 42 43
    Convert a list of dictionaries to be compatible with create_csv_response

    `dictlist` is a list of dictionaries
        all dictionaries should have keys from features
    `features` is a list of features

    example code:
    dictlist = [
44
        {
Miles Steele committed
45 46 47 48
            'label1': 'value-1,1',
            'label2': 'value-1,2',
            'label3': 'value-1,3',
            'label4': 'value-1,4',
49 50
        },
        {
Miles Steele committed
51 52 53 54
            'label1': 'value-2,1',
            'label2': 'value-2,2',
            'label3': 'value-2,3',
            'label4': 'value-2,4',
55 56 57
        }
    ]

58
    header, datarows = format_dictlist(dictlist, ['label1', 'label4'])
59

60 61 62 63 64
    # results in
    header = ['label1', 'label4']
    datarows = [['value-1,1', 'value-1,4'],
                ['value-2,1', 'value-2,4']]
    }
65 66
    """

67
    def dict_to_entry(dct):
68 69 70
        """ Convert dictionary to a list for a csv row """
        relevant_items = [(k, v) for (k, v) in dct.items() if k in features]
        ordered = sorted(relevant_items, key=lambda (k, v): header.index(k))
71
        vals = [v for (_, v) in ordered]
72 73
        return vals

74
    header = features
75 76
    datarows = map(dict_to_entry, dictlist)

77
    return header, datarows
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97


def format_instances(instances, features):
    """
    Convert a list of instances into a header list and datarows list.

    `header` is just `features` e.g. ['username', 'email']
    `datarows` is a list of lists, each sublist representing a row in a table
        e.g. [['username1', 'email1@email.com'], ['username2', 'email2@email.com']]
        for `instances` of length 2.

    `instances` is a list of instances, e.g. list of User's
    `features` is a list of features
        a feature is a string for which getattr(obj, feature) is valid

    Returns header and datarows, formatted for input in create_csv_response
    """
    header = features
    datarows = [[getattr(x, f) for f in features] for x in instances]
    return header, datarows