75
76
ctx['semesters'].append((semester, offerings))
79
def format_submission_principal(user, principal):
80
"""Render a list of users to fit in the offering project listing.
82
Given a user and a list of submitters, returns 'solo' if the
83
only submitter is the user, or a string of the form
84
'with A, B and C' if there are any other submitters.
86
If submitters is None, we assume that the list of members could
87
not be determined, so we just return 'group'.
95
display_names = sorted(
96
member.display_name for member in principal.members
97
if member is not user)
99
if len(display_names) == 0:
100
return 'solo (%s)' % principal.name
101
elif len(display_names) == 1:
102
return 'with %s (%s)' % (display_names[0], principal.name)
103
elif len(display_names) > 5:
104
return 'with %d others (%s)' % (len(display_names), principal.name)
106
return 'with %s and %s (%s)' % (', '.join(display_names[:-1]),
107
display_names[-1], principal.name)
110
class OfferingView(XHTMLView):
111
"""The home page of an offering."""
112
template = 'templates/offering.html'
116
def populate(self, req, ctx):
117
# Need the worksheet result styles.
118
self.plugin_styles[TutorialPlugin] = ['tutorial.css']
119
ctx['context'] = self.context
121
ctx['permissions'] = self.context.get_permissions(req.user)
122
ctx['format_submission_principal'] = format_submission_principal
123
ctx['format_datetime'] = ivle.date.make_date_nice
124
ctx['format_datetime_short'] = ivle.date.format_datetime_for_paragraph
126
# As we go, calculate the total score for this subject
127
# (Assessable worksheets only, mandatory problems only)
129
ctx['worksheets'], problems_total, problems_done = (
130
ivle.worksheet.utils.create_list_of_fake_worksheets_and_stats(
131
req.store, req.user, self.context))
133
ctx['exercises_total'] = problems_total
134
ctx['exercises_done'] = problems_done
135
if problems_total > 0:
136
if problems_done >= problems_total:
137
ctx['worksheets_complete_class'] = "complete"
138
elif problems_done > 0:
139
ctx['worksheets_complete_class'] = "semicomplete"
141
ctx['worksheets_complete_class'] = "incomplete"
142
# Calculate the final percentage and mark for the subject
143
(ctx['exercises_pct'], ctx['worksheet_mark'],
144
ctx['worksheet_max_mark']) = (
145
ivle.worksheet.utils.calculate_mark(
146
problems_done, problems_total))
78
149
class UserValidator(formencode.FancyValidator):
79
150
"""A FormEncode validator that turns a username into a user.
245
316
reverse_routes = (subject_url, offering_url, projectset_url, project_url)
247
318
views = [(ApplicationRoot, ('subjects', '+index'), SubjectsView),
319
(Offering, '+index', OfferingView),
248
320
(Offering, ('+enrolments', '+index'), EnrolmentsView),
249
321
(Offering, ('+enrolments', '+new'), EnrolView),
250
322
(Offering, ('+projects', '+index'), OfferingProjectsView),