~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/webapp/tutorial/marks.py

  • Committer: Matt Giuca
  • Date: 2010-02-24 09:21:00 UTC
  • mto: This revision was merged to the branch mainline in revision 1701.
  • Revision ID: matt.giuca@gmail.com-20100224092100-krqcjyobxpgrfwak
Added worksheet marks CSV view, which presents the same table as the worksheet marks table, but as a downloadable CSV file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
"""
24
24
 
25
25
import datetime
 
26
import csv
26
27
 
27
28
import ivle.database
28
29
import ivle.worksheet.utils
 
30
from ivle.webapp.base.views import BaseView
29
31
from ivle.webapp.base.xhtml import XHTMLView
30
32
from ivle.webapp.media import media_url
31
33
 
55
57
        ctx['cutoff'] = cutoff
56
58
        ctx['error'] = error
57
59
 
58
 
        # "worksheets" is a list of worksheet names
 
60
        # "worksheets" is a list of (assessable) worksheet names
59
61
        worksheets = offering.worksheets.find(assessable=True)
60
62
        ctx['worksheets'] = [ws.name for ws in worksheets]
61
63
 
74
76
                                                user, as_of=cutoff)
75
77
            students.append((user, worksheet_pcts, total_pct, mark))
76
78
 
 
79
class WorksheetsMarksCSVView(BaseView):
 
80
    """View for presenting all students' individual marks for worksheets."""
 
81
    permission = 'view_worksheet_marks'
 
82
    template = 'templates/worksheets_marks.html'
 
83
    tab = 'subjects'
 
84
 
 
85
    def render(self, req):
 
86
        offering = self.context
 
87
 
 
88
        # User may supply a "cutoff date" to calculate marks as of that date
 
89
        # Default to current time
 
90
        cutoff = datetime.datetime.now()
 
91
        data = dict(req.get_fieldstorage())
 
92
        if data.get('cutoff') is not None:
 
93
            try:
 
94
                cutoff = datetime.datetime.strptime(data.get('cutoff'),
 
95
                                                    "%Y-%m-%d %H:%M:%S")
 
96
            except ValueError:
 
97
                req.write(
 
98
                    "Invalid date format: '%s' (must be YYYY-MM-DD H:M:S)."
 
99
                        % data.get('cutoff'))
 
100
                return
 
101
 
 
102
        req.content_type = "text/csv"
 
103
        req.headers_out.add('Content-Disposition',
 
104
            "attachment; filename=marks-%s-%ss%s.csv" %
 
105
            (offering.subject.short_name, offering.semester.year,
 
106
             offering.semester.semester))
 
107
 
 
108
        # "worksheets" is a list of (assessable) worksheet names
 
109
        worksheets = offering.worksheets.find(assessable=True)
 
110
 
 
111
        # Start writing the CSV file - header
 
112
        csvfile = csv.writer(req)
 
113
        csvfile.writerow(csv_get_header(worksheets))
 
114
 
 
115
        # Get all users enrolled in this offering
 
116
        users = req.store.find(ivle.database.User,
 
117
                   ivle.database.User.id == ivle.database.Enrolment.user_id,
 
118
                   offering.id == ivle.database.Enrolment.offering).order_by(
 
119
                        ivle.database.User.login)
 
120
        for user in users:
 
121
            csv_writeuser(req, worksheets, user, csvfile, cutoff)
 
122
 
77
123
def get_marks_user(req, worksheets, user, as_of=None):
78
124
    """Gets marks for a particular user for a particular set of worksheets.
79
125
    @param worksheets: List of Worksheet objects to get marks for.
102
148
    percent, mark, _ = (
103
149
        ivle.worksheet.utils.calculate_mark(problems_done, problems_total))
104
150
    return (worksheet_pcts, float(percent)/100, mark)
 
151
 
 
152
def csv_get_userdata(user):
 
153
    """
 
154
    Given a User object, returns a list of strings for the user data which
 
155
    will be part of the output for this user.
 
156
    (This is not marks, it's other user data).
 
157
    """
 
158
    last_login = ("N/A" if user.last_login is None else
 
159
                    user.last_login.strftime("%Y-%m-%d"))
 
160
    return [user.studentid or "N/A", user.login, user.fullname, last_login]
 
161
 
 
162
csv_userdata_header = ["Student ID", "Login", "Full name", "Last login"]
 
163
def csv_get_header(worksheets):
 
164
    """
 
165
    Given a list of Worksheet objects (the assessable worksheets), returns a
 
166
    list of strings -- the column headings for the marks section of the CSV
 
167
    output.
 
168
    """
 
169
    return (csv_userdata_header + [ws.name for ws in worksheets]
 
170
            + ["Total %", "Mark"])
 
171
 
 
172
def csv_writeuser(req, worksheets, user, csvfile, cutoff=None):
 
173
    userdata = csv_get_userdata(user)
 
174
    worksheet_pcts, total_pct, mark = get_marks_user(req, worksheets, user,
 
175
                                                     cutoff)
 
176
    data = userdata + worksheet_pcts + [total_pct, mark]
 
177
    # CSV writer can't handle non-ASCII characters. Encode to UTF-8.
 
178
    data = [unicode(x).encode('utf-8') for x in data]
 
179
    csvfile.writerow(data)