Merge lp:~ivle-dev/ivle/late-submit into lp:ivle
- late-submit
- Merge into trunk
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David Coles | Approve | ||
William Grant | Approve | ||
Review via email:
|
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.
- 1821. By Matt Giuca
-
Merge from trunk.
- 1822. By Matt Giuca
-
doc/man/tour: Updated the tour page to discuss late submissions.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
David Coles (dcoles) wrote : | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
David Coles (dcoles) wrote : | # |
Do we want to highlight late submissions more than just a '*'? Put those lines in red perhaps?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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?
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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.
- 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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
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.
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.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Matt Giuca (mgiuca) wrote : | # |
Cheers :) But I merged this like 5 hours ago...
Preview Diff
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> |
"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.