Merge lp:~ivle-dev/ivle/late-submit into lp:ivle

Proposed by Matt Giuca
Status: Merged
Merged at revision: 1818
Proposed branch: lp:~ivle-dev/ivle/late-submit
Merge into: lp:ivle
Diff against target: 327 lines (+123/-49)
9 files modified
doc/man/tour.rst (+14/-3)
ivle/database.py (+22/-4)
ivle/webapp/admin/templates/project-export.sh (+2/-1)
ivle/webapp/admin/templates/project.html (+3/-2)
ivle/webapp/coremedia/ivle.css (+5/-2)
ivle/webapp/submit/__init__.py (+42/-32)
ivle/webapp/submit/submit-late.html (+27/-0)
ivle/webapp/submit/submit.html (+5/-3)
ivle/webapp/submit/submitted.html (+3/-2)
To merge this branch: bzr merge lp:~ivle-dev/ivle/late-submit
Reviewer Review Type Date Requested Status
David Coles Approve
William Grant Approve
Review via email: mp+30403@code.launchpad.net

Commit message

Students can now submit projects after the deadline (with a red submission field and warning).
- Submitting late requires an extra confirmation step.
- Lecturer project view clearly shows late submissions, and how many days late.
(LP: #598346)

Description of the change

Everything described in bug #598346:
- Students can now submit projects after the deadline (with a red submission field and warning).
- Submitting late requires an extra confirmation step.
- Lecturer project view clearly shows late submissions, and how many days late.

To post a comment you must log in.
lp:~ivle-dev/ivle/late-submit updated
1821. By Matt Giuca

Merge from trunk.

1822. By Matt Giuca

doc/man/tour: Updated the tour page to discuss late submissions.

Revision history for this message
David Coles (dcoles) wrote :

"The project has not yet been submitted" on the 'Submit project - late' page is slightly confusing if you have already made a submission. I assume you're just trying to warn students that the late screen is not a confirmation screen and they still have to click "Submit Late".

The example would be if you submitted 5 minutes before the deadline and then tried 2 minutes after. You may interpret this line to mean that you have _nothing_ submitted.

Revision history for this message
David Coles (dcoles) wrote :

Is that 'else:' on line #205 of the diff is to only run that code if no exception occurs during submission.

Revision history for this message
David Coles (dcoles) wrote :

Do we want to highlight late submissions more than just a '*'? Put those lines in red perhaps?

Revision history for this message
Matt Giuca (mgiuca) wrote :

> "The project has not yet been submitted" on the 'Submit project - late' page
> is slightly confusing if you have already made a submission. I assume you're
> just trying to warn students that the late screen is not a confirmation screen
> and they still have to click "Submit Late".

I see the confusion. I'll reword the message.

Revision history for this message
Matt Giuca (mgiuca) wrote :

> Is that 'else:' on line #205 of the diff is to only run that code if no
> exception occurs during submission.

Yes. It's a bit unfortunate, but it has to now go in the 'else' clause because if the project is submitted late, it no longer raises an exception, it continues running the code but doesn't follow the same code path.

> Do we want to highlight late submissions more than just a '*'? Put those lines
> in red perhaps?

It is also italicised. Is that sufficient, or should it be changed to red?

Revision history for this message
David Coles (dcoles) wrote :

>
>
> > Do we want to highlight late submissions more than just a '*'? Put those
> lines
> > in red perhaps?
>

I missed the italics since I only had one submission. But I think it would
flow on nicely from the red used for showing late submissions and really
make it stand out.

Revision history for this message
William Grant (wgrant) wrote :

I think the late submission confirmation page is insufficiently clear about the lateness. It should be a lot more obvious.

Also, I am a little suspicious of using '*' in HTML like that. That's a bit too plaintexty for my liking.

Apart from those, it looks good.

review: Approve
lp:~ivle-dev/ivle/late-submit updated
1823. By Matt Giuca

Project page: Late submissions are now shown in red (the whole line, not just the date), rather than italics.
Required a bit of CSS hackery (see comments in coremedia/ivle.css).

1824. By Matt Giuca

Project page: Removed the space before the '*'.

1825. By Matt Giuca

Late submission confirmation: Reworded so it is much clearer that a) the previous submission has not yet been overwritten, b) this is a late submission.
Also use more red/bold as a warning.

Revision history for this message
Matt Giuca (mgiuca) wrote :

> I missed the italics since I only had one submission. But I think it would
> flow on nicely from the red used for showing late submissions and really
> make it stand out.

Done.

> I think the late submission confirmation page is insufficiently clear about
> the lateness. It should be a lot more obvious.

OK I have rewritten it. It now reads:

"<red-bold>This submission has not yet been completed.</red-bold>

You are about to submit *project* for *subject*.

The project deadline has already passed. If you choose to continue, <red-bold>your submission will be considered late</red-bold>. This may incur a late penalty, at the discretion of the subject coordinator, even if you have already submitted on time.

You may resubmit this project again at any time, but a new submission will overwrite any made earlier, and further submissions may incur an increased penalty."

> Also, I am a little suspicious of using '*' in HTML like that. That's a bit
> too plaintexty for my liking.

I tried making it <sup>*</sup>, but it takes up more vertical space which isn't good in a list like that. Think of it as a * on the side of a cereal box.

Revision history for this message
David Coles (dcoles) wrote :

*thumbs up*

review: Approve
Revision history for this message
Matt Giuca (mgiuca) wrote :

Cheers :) But I merged this like 5 hours ago...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/man/tour.rst'
2--- doc/man/tour.rst 2010-07-21 04:33:55 +0000
3+++ doc/man/tour.rst 2010-07-22 01:56:43 +0000
4@@ -93,11 +93,16 @@
5 any submitted project from the subject page.
6
7 If you go into the *Intermediate IVLE ‣ group1* directory, you will be able
8-to make a group submission to Phase 2 (which is a group project). Note that
9-the Phase 3 submission has already closed.
10-Also note that the file here (``phase2.html``) was edited by studenta and
11+to make a group submission to Phase 2 (which is a group project). Also note
12+that the file here (``phase2.html``) was edited by studenta and
13 studentb collaboratively, as you can see in the project's revision log.
14
15+Note that the Phase 3 submission has already closed. You can still make a
16+"late submission" to a project that has closed, but there is an extra
17+confirmation step. Lecturers are given details on late submissions and may
18+deduct marks accordingly.
19+
20+
21 Worksheets
22 ----------
23
24@@ -213,6 +218,12 @@
25
26 This will download the student's work into the current directory, to inspect.
27
28+.. note::
29+ This page shows late submissions in red, with a "*", and the number of
30+ days late, rounded upwards. Therefore, a submission which is 1 second late
31+ is shown with a "(1)", while a submission that is 24 hours and 1 second
32+ late is shown with a "(2)".
33+
34 You can also try to check out the group submission from Phase 2.
35
36 Managing worksheets and exercises
37
38=== modified file 'ivle/database.py'
39--- ivle/database.py 2010-07-20 08:24:32 +0000
40+++ ivle/database.py 2010-07-22 01:56:43 +0000
41@@ -610,11 +610,14 @@
42 return "<%s '%s' in %r>" % (type(self).__name__, self.short_name,
43 self.project_set.offering)
44
45- def can_submit(self, principal, user):
46+ def can_submit(self, principal, user, late=False):
47+ """
48+ @param late: If True, does not take the deadline into account.
49+ """
50 return (self in principal.get_projects() and
51- not self.has_deadline_passed(user))
52+ (late or not self.has_deadline_passed(user)))
53
54- def submit(self, principal, path, revision, who):
55+ def submit(self, principal, path, revision, who, late=False):
56 """Submit a Subversion path and revision to a project.
57
58 @param principal: The owner of the Subversion repository, and the
59@@ -622,9 +625,11 @@
60 @param path: A path within that repository to submit.
61 @param revision: The revision of that path to submit.
62 @param who: The user who is actually making the submission.
63+ @param late: If True, will not raise a DeadlinePassed exception even
64+ after the deadline. (Default False.)
65 """
66
67- if not self.can_submit(principal, who):
68+ if not self.can_submit(principal, who, late=late):
69 raise DeadlinePassed()
70
71 a = Assessed.get(Store.of(self), principal, self)
72@@ -946,6 +951,19 @@
73 raise SubmissionError("Path must not contain '\\n', '[' or ']'")
74 return os.path.normpath(path)
75
76+ @property
77+ def late(self):
78+ """True if the project was submitted late."""
79+ return self.days_late > 0
80+
81+ @property
82+ def days_late(self):
83+ """The number of days the project was submitted late (rounded up), or
84+ 0 if on-time."""
85+ # XXX: Need to respect extensions.
86+ return max(0,
87+ (self.date_submitted - self.assessed.project.deadline).days + 1)
88+
89 # WORKSHEETS AND EXERCISES #
90
91 class Exercise(Storm):
92
93=== modified file 'ivle/webapp/admin/templates/project-export.sh'
94--- ivle/webapp/admin/templates/project-export.sh 2010-07-20 08:31:02 +0000
95+++ ivle/webapp/admin/templates/project-export.sh 2010-07-22 01:56:43 +0000
96@@ -20,9 +20,10 @@
97 # $ ./project-export.sh
98
99 # Submissions: ${project.latest_submissions.count()}/${project.project_set.assigned.count()}
100+# * Late submissions (number of days late)
101
102 {% if project.latest_submissions.count() == 0 %}# There are no submissions.{% end %}{% if project.latest_submissions.count() > 0 %}# Group Submitter Date
103-{% for submission in project.latest_submissions %}# {% choose submission.assessed.principal is submission.submitter %}{% when True %}-{% end %}{% otherwise %}${submission.assessed.principal.short_name}{% end %}{% end %} ${submission.submitter.short_name} ${submission.date_submitted.strftime("%Y-%m-%d %H:%M:%S")}
104+{% for submission in project.latest_submissions %}# {% choose submission.assessed.principal is submission.submitter %}{% when True %}-{% end %}{% otherwise %}${submission.assessed.principal.short_name}{% end %}{% end %} ${submission.submitter.short_name} ${submission.date_submitted.strftime("%Y-%m-%d %H:%M:%S")}{% if submission.late %}* (${submission.days_late}){% end %}
105 ${submission.get_svn_export_command(req)}
106 {% end %}
107 {% end %}
108
109=== modified file 'ivle/webapp/admin/templates/project.html'
110--- ivle/webapp/admin/templates/project.html 2010-07-21 04:21:50 +0000
111+++ ivle/webapp/admin/templates/project.html 2010-07-22 01:56:43 +0000
112@@ -33,6 +33,7 @@
113 Bash script for exporting submitted projects
114 </a>
115 </p>
116+ <p class="late_submission">* Late submissions (number of days late)</p>
117 <div py:if="project.latest_submissions.count() == 0">
118 There are no submissions.
119 </div>
120@@ -48,13 +49,13 @@
121 </thead>
122 <tbody>
123 <py:for each="submission in project.latest_submissions">
124- <tr>
125+ <tr py:attrs="{'class': 'late_submission'} if submission.late else {}">
126 <py:choose test="submission.assessed.principal is submission.submitter">
127 <td py:when="True">-</td>
128 <td py:otherwise=""><span title="${submission.assessed.principal.display_name}">${submission.assessed.principal.short_name}</span></td>
129 </py:choose>
130 <td><span title="${submission.submitter.display_name}">${submission.submitter.short_name}</span></td>
131- <td>${submission.date_submitted.strftime("%Y-%m-%d %H:%M:%S")}</td>
132+ <td>${submission.date_submitted.strftime("%Y-%m-%d %H:%M:%S")}<py:if test="submission.late">* (${submission.days_late})</py:if></td>
133 <td>${submission.get_svn_export_command(req)}</td>
134 </tr>
135 </py:for>
136
137=== modified file 'ivle/webapp/coremedia/ivle.css'
138--- ivle/webapp/coremedia/ivle.css 2010-03-05 06:30:38 +0000
139+++ ivle/webapp/coremedia/ivle.css 2010-07-22 01:56:43 +0000
140@@ -366,8 +366,11 @@
141 margin-bottom: 0.3em;
142 }
143
144-.project.closed {
145- opacity: 0.6;
146+/* For project view (late_submission entries in the submission list), must
147+ * apply to the td (not the tr) and be !important to override the pretty_table
148+ * styling of the td text colour. */
149+.project.closed, .late_submission, tr.late_submission td {
150+ color: darkred !important;
151 }
152
153 .form_error {
154
155=== modified file 'ivle/webapp/submit/__init__.py'
156--- ivle/webapp/submit/__init__.py 2010-07-20 05:22:02 +0000
157+++ ivle/webapp/submit/__init__.py 2010-07-22 01:56:43 +0000
158@@ -85,6 +85,9 @@
159 except ValueError:
160 raise BadRequest('Project must be an integer.')
161
162+ # True, if the user has confirmed to submit late
163+ late = 'late' in data and data['late'] == "yes"
164+
165 project = req.store.find(Project, Project.id == projectid).one()
166
167 # This view's offering will be the sole offering for which the
168@@ -97,39 +100,46 @@
169
170 try:
171 ctx['submission'] = project.submit(self.context,
172- unicode(self.path), revision, req.user)
173- except (database.DeadlinePassed, database.SubmissionError), e:
174+ unicode(self.path), revision, req.user,
175+ late=late)
176+ except database.DeadlinePassed:
177+ # Show late submission page
178+ self.template = 'submit-late.html'
179+ ctx['project'] = project
180+ except database.SubmissionError, e:
181 raise BadRequest(str(e) + ".")
182-
183- # The Subversion configuration needs to be updated, to grant
184- # tutors and lecturers access to this submission. We have to
185- # commit early so usrmgt-server can see the new submission.
186- req.store.commit()
187-
188- # Instruct usrmgt-server to rebuild the SVN group authz file.
189- msg = {'rebuild_svn_group_config': {}}
190- usrmgt = ivle.chat.chat(req.config['usrmgt']['host'],
191- req.config['usrmgt']['port'],
192- msg,
193- req.config['usrmgt']['magic'],
194- )
195-
196- if usrmgt.get('response') in (None, 'failure'):
197- raise Exception("Failure creating repository: " + str(usrmgt))
198-
199- # Instruct usrmgt-server to rebuild the SVN user authz file.
200- msg = {'rebuild_svn_config': {}}
201- usrmgt = ivle.chat.chat(req.config['usrmgt']['host'],
202- req.config['usrmgt']['port'],
203- msg,
204- req.config['usrmgt']['magic'],
205- )
206-
207- if usrmgt.get('response') in (None, 'failure'):
208- raise Exception("Failure creating repository: " + str(usrmgt))
209-
210- self.template = 'submitted.html'
211- ctx['project'] = project
212+ else:
213+ # The Subversion configuration needs to be updated, to grant
214+ # tutors and lecturers access to this submission. We have to
215+ # commit early so usrmgt-server can see the new submission.
216+ req.store.commit()
217+
218+ # Instruct usrmgt-server to rebuild the SVN group authz file.
219+ msg = {'rebuild_svn_group_config': {}}
220+ usrmgt = ivle.chat.chat(req.config['usrmgt']['host'],
221+ req.config['usrmgt']['port'],
222+ msg,
223+ req.config['usrmgt']['magic'],
224+ )
225+
226+ if usrmgt.get('response') in (None, 'failure'):
227+ raise Exception("Failure creating repository: "
228+ + str(usrmgt))
229+
230+ # Instruct usrmgt-server to rebuild the SVN user authz file.
231+ msg = {'rebuild_svn_config': {}}
232+ usrmgt = ivle.chat.chat(req.config['usrmgt']['host'],
233+ req.config['usrmgt']['port'],
234+ msg,
235+ req.config['usrmgt']['magic'],
236+ )
237+
238+ if usrmgt.get('response') in (None, 'failure'):
239+ raise Exception("Failure creating repository: "
240+ + str(usrmgt))
241+
242+ self.template = 'submitted.html'
243+ ctx['project'] = project
244
245 ctx['req'] = req
246 ctx['principal'] = self.context
247
248=== added file 'ivle/webapp/submit/submit-late.html'
249--- ivle/webapp/submit/submit-late.html 1970-01-01 00:00:00 +0000
250+++ ivle/webapp/submit/submit-late.html 2010-07-22 01:56:43 +0000
251@@ -0,0 +1,27 @@
252+<html xmlns="http://www.w3.org/1999/xhtml"
253+ xmlns:py="http://genshi.edgewall.org/">
254+ <head>
255+ <title>Submit project - late</title>
256+ </head>
257+ <body>
258+ <h1>Submit project - late</h1>
259+ <div id="ivle_padding">
260+ <form action="" method="post">
261+ <input type="hidden" name="project" value="${project.id}" />
262+ <input type="hidden" name="late" value="yes" />
263+ <p class="late_submission"><strong>This submission has not yet been
264+ completed.</strong></p>
265+ <p>You are about to submit ${project.name} for ${offering.subject.name}.</p>
266+ <p>The project deadline has already passed. If you choose to continue,
267+ <span class="late_submission"><strong>your submission will be
268+ considered late</strong></span>. This may incur a late penalty, at the
269+ discretion of the subject coordinator, even if you have already
270+ submitted on time.</p>
271+ <p>You may resubmit this project again at any time, but a new submission
272+ will overwrite any made earlier, and further submissions may incur an
273+ increased penalty.</p>
274+ <input type="submit" value="Submit Late" />
275+ </form>
276+ </div>
277+ </body>
278+</html>
279
280=== modified file 'ivle/webapp/submit/submit.html'
281--- ivle/webapp/submit/submit.html 2010-02-12 10:58:21 +0000
282+++ ivle/webapp/submit/submit.html 2010-07-22 01:56:43 +0000
283@@ -27,10 +27,9 @@
284 <form action="" method="post">
285 <table>
286 <tr py:for="project in principal.get_projects(offering=offering)"
287- py:with="attrs = {'disabled': 'disabled'} if project.has_deadline_passed(req.user) else {}"
288 py:attrs="{'class': 'project closed'} if project.has_deadline_passed(req.user) else {'class': 'project'}">
289 <td style="vertical-align: top">
290- <input type="radio" name="project" id="project_${project.id}" value="${project.id}" py:attrs="attrs" />
291+ <input type="radio" name="project" id="project_${project.id}" value="${project.id}" />
292 </td>
293 <td>
294 <label for="project_${project.id}">
295@@ -60,12 +59,15 @@
296 </py:if>
297 <br />
298 ${project.synopsis}
299+ <py:if test="project.has_deadline_passed(req.user)"><br />
300+ <em>Note: The deadline has passed. You may still submit late, but a penalty may be incurred.</em>
301+ </py:if>
302 </label>
303 </td>
304 </tr>
305 </table>
306 <p>Ensure that you have committed all changes - only changes in the repository will be submitted.</p>
307- <p>You may resubmit a project again at any time until its deadline, but a new submission will overwrite any made earlier.</p>
308+ <p>You may resubmit a project again at any time, but a new submission will overwrite any made earlier, and submissions after the deadline may incur a penalty.</p>
309 <p><input type="submit" value="Submit Project" />
310 <a class="helpaction" href="/+help/Submitting%20a%20project">Help submitting a project</a>
311 </p>
312
313=== modified file 'ivle/webapp/submit/submitted.html'
314--- ivle/webapp/submit/submitted.html 2010-02-11 09:24:34 +0000
315+++ ivle/webapp/submit/submitted.html 2010-07-22 01:56:43 +0000
316@@ -7,8 +7,9 @@
317 <h1>Project submitted</h1>
318 <div id="ivle_padding">
319 <p>You successfully submitted ${project.name} for ${offering.subject.name}.</p>
320- <p>You may resubmit this project again at any time until the deadline,
321- but a new submission will overwrite any made earlier.
322+ <p>You may resubmit this project again at any time, but a new submission
323+ will overwrite any made earlier, and submissions after the deadline may
324+ incur a penalty.
325 It is important to verify each submission after you make it.</p>
326 <p><a class="verifyaction"
327 href="${submission.get_verify_url(req.user)}">Verify this submission</a></p>

Subscribers

People subscribed via source and target branches