216
216
worksheetdom.getAttribute("assessable") == "true")
217
217
worksheets.append(worksheet)
221
# Now all the errors are out the way, we can begin writing
222
req.title = "Tutorial - %s" % subject
223
req.write_html_head_foot = True
224
req.write('<div id="ivle_padding">\n')
225
req.write("<h1>IVLE Tutorials - %s</h1>\n" % cgi.escape(subject))
226
req.write('<h2>Worksheets</h2>\n<ul id="tutorial-toc">\n')
227
# As we go, calculate the total score for this subject
228
# (Assessable worksheets only, mandatory problems only)
231
for worksheet in worksheets:
232
req.write(' <li><a href="%s">%s</a>'
233
% (urllib.quote(worksheet.id), cgi.escape(worksheet.name)))
235
# If the assessable status of this worksheet has changed,
237
# (Note: This fails the try block if the worksheet is not yet
238
# in the DB, which is fine. The author should visit the
239
# worksheet page to get it into the DB).
240
if (db.worksheet_is_assessable(subject, worksheet.id) !=
241
worksheet.assessable):
242
db.set_worksheet_assessable(subject, worksheet.id,
243
assessable=worksheet.assessable)
244
if worksheet.assessable:
219
# Now all the errors are out the way, we can begin writing
220
req.title = "Tutorial - %s" % subject
221
req.write_html_head_foot = True
222
req.write('<div id="ivle_padding">\n')
223
req.write("<h1>IVLE Tutorials - %s</h1>\n" % cgi.escape(subject))
224
req.write('<h2>Worksheets</h2>\n<ul id="tutorial-toc">\n')
225
# As we go, calculate the total score for this subject
226
# (Assessable worksheets only, mandatory problems only)
229
for worksheet_from_xml in worksheets:
230
worksheet = ivle.database.Worksheet.get_by_name(req.store,
231
subject, worksheet_from_xml.id)
232
# If worksheet is not in database yet, we'll simply not display
233
# data about it yet (it should be added as soon as anyone visits
234
# the worksheet itself).
235
req.write(' <li><a href="%s">%s</a>'
236
% (urllib.quote(worksheet_from_xml.id),
237
cgi.escape(worksheet_from_xml.name)))
238
if worksheet is not None:
239
# If the assessable status of this worksheet has changed,
241
# (Note: This fails the try block if the worksheet is not yet
242
# in the DB, which is fine. The author should visit the
243
# worksheet page to get it into the DB).
244
if worksheet.assessable != worksheet_from_xml.assessable:
245
# XXX If statement to avoid unnecessary database writes.
246
# Is this necessary, or will Storm check for us?
247
worksheet.assessable = worksheet_from_xml.assessable
249
if worksheet.assessable:
250
# XXX Refactor ivle.db
245
253
mand_done, mand_total, opt_done, opt_total = (
246
254
db.calculate_score_worksheet(req.user.login, subject,
249
optional_message = " (excluding optional exercises)"
251
optional_message = ""
252
if mand_done >= mand_total:
253
complete_class = "complete"
255
complete_class = "semicomplete"
257
complete_class = "incomplete"
258
problems_done += mand_done
259
problems_total += mand_total
260
req.write('\n <ul><li class="%s">'
261
'Completed %d/%d%s</li></ul>\n '
262
% (complete_class, mand_done, mand_total,
264
except ivle.db.DBException:
265
# Worksheet is probably not in database yet
269
if problems_total > 0:
270
if problems_done >= problems_total:
271
complete_class = "complete"
272
elif problems_done > 0:
273
complete_class = "semicomplete"
275
complete_class = "incomplete"
276
problems_pct = (100 * problems_done) / problems_total # int
277
req.write('<ul><li class="%s">Total exercises completed: %d/%d '
279
% (complete_class, problems_done, problems_total,
281
# XXX Marks calculation (should be abstracted out of here!)
282
# percent / 16, rounded down, with a maximum mark of 5
284
mark = min(problems_pct / 16, max_mark)
285
req.write('<p style="font-weight: bold">Worksheet mark: %d/%d'
286
'</p>\n' % (mark, max_mark))
287
req.write("</div>\n") # tutorialbody
260
optional_message = " (excluding optional exercises)"
262
optional_message = ""
263
if mand_done >= mand_total:
264
complete_class = "complete"
266
complete_class = "semicomplete"
268
complete_class = "incomplete"
269
problems_done += mand_done
270
problems_total += mand_total
271
req.write('\n <ul><li class="%s">'
272
'Completed %d/%d%s</li></ul>\n '
273
% (complete_class, mand_done, mand_total,
277
if problems_total > 0:
278
if problems_done >= problems_total:
279
complete_class = "complete"
280
elif problems_done > 0:
281
complete_class = "semicomplete"
283
complete_class = "incomplete"
284
problems_pct = (100 * problems_done) / problems_total # int
285
req.write('<ul><li class="%s">Total exercises completed: %d/%d '
287
% (complete_class, problems_done, problems_total,
289
# XXX Marks calculation (should be abstracted out of here!)
290
# percent / 16, rounded down, with a maximum mark of 5
292
mark = min(problems_pct / 16, max_mark)
293
req.write('<p style="font-weight: bold">Worksheet mark: %d/%d'
294
'</p>\n' % (mark, max_mark))
295
req.write("</div>\n") # tutorialbody
291
297
def handle_worksheet(req, subject, worksheet):
292
298
# Subject and worksheet names must be valid identifiers