Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Martin Mareš
Postal Owl
Commits
b5053f4f
Commit
b5053f4f
authored
May 21, 2021
by
Martin Mareš
Browse files
Export of points in CSV and JSON for teachers
parent
2093834f
Changes
3
Hide whitespace changes
Inline
Side-by-side
owl.py
View file @
b5053f4f
...
...
@@ -28,6 +28,8 @@ from collections import defaultdict
import
urllib.parse
from
html
import
escape
from
markupsafe
import
Markup
import
csv
import
io
### Flask app object ###
...
...
@@ -895,6 +897,97 @@ def serve_file(name):
return
"No such file"
,
HTTPStatus
.
NOT_FOUND
### Exports ###
@
app
.
route
(
'/teacher/c/<cident>/results.json'
)
def
results_json
(
cident
):
err
=
course_init
(
cident
)
or
must_be_teacher
()
if
err
:
return
err
return
export_points
(
'json'
)
@
app
.
route
(
'/teacher/c/<cident>/results.csv'
)
def
results_csv
(
cident
):
err
=
course_init
(
cident
)
or
must_be_teacher
()
if
err
:
return
err
return
export_points
(
'csv'
)
def
export_points
(
format
):
db_query
(
"""
SELECT u.uid, u.ukco, u.full_name
FROM owl_users u
JOIN owl_enroll e USING(uid)
WHERE e.cid = %s
AND e.is_teacher = false
ORDER BY uid
"""
,
(
g
.
course
.
cid
,))
students
=
db
.
fetchall
()
db_query
(
"""
SELECT *
FROM owl_topics
WHERE cid=%s
AND type IN ('A', 'T')
ORDER BY rank, tid
"""
,
(
g
.
course
.
cid
,))
topics
=
db
.
fetchall
()
db_query
(
"""
SELECT t.ident AS tident, p.target_uid, p.points
FROM owl_topics t
JOIN owl_posts p USING(tid)
WHERE t.cid = %s
AND p.points IS NOT NULL
ORDER BY p.created
"""
,
(
g
.
course
.
cid
,))
awards
=
db
.
fetchall
()
points
=
{
s
.
uid
:
{}
for
s
in
students
}
for
a
in
awards
:
if
a
.
target_uid
==
-
1
:
for
uid
in
points
.
keys
():
points
[
uid
][
a
.
tident
]
=
float
(
a
.
points
)
elif
a
.
target_uid
in
points
:
points
[
a
.
target_uid
][
a
.
tident
]
=
float
(
a
.
points
)
if
format
==
"json"
:
out
=
[]
for
s
in
students
:
out
.
append
({
"uid"
:
s
.
uid
,
"ukco"
:
s
.
ukco
,
"name"
:
s
.
full_name
,
"tasks"
:
points
[
s
.
uid
],
"points"
:
sum
(
points
[
s
.
uid
].
values
()),
})
enc
=
JSONEncoder
(
ensure_ascii
=
False
,
sort_keys
=
True
,
indent
=
4
)
resp
=
make_response
(
enc
.
encode
(
out
))
resp
.
headers
.
add
(
'Content-type'
,
'application/json'
)
return
resp
elif
format
==
"csv"
:
out
=
io
.
StringIO
()
writer
=
csv
.
writer
(
out
,
delimiter
=
','
,
quoting
=
csv
.
QUOTE_MINIMAL
)
writer
.
writerow
([
'uid'
,
'ukco'
,
'name'
,
'points'
]
+
[
t
.
ident
for
t
in
topics
])
for
s
in
students
:
writer
.
writerow
([
s
.
uid
,
s
.
ukco
,
s
.
full_name
,
sum
(
points
[
s
.
uid
].
values
()),
]
+
[
points
[
s
.
uid
].
get
(
t
.
ident
,
""
)
for
t
in
topics
])
resp
=
make_response
(
out
.
getvalue
())
resp
.
headers
.
add
(
'Content-type'
,
'text/csv; charset=utf-8'
)
return
resp
else
:
raise
NotImplementedError
()
### User settings ###
...
...
@@ -1365,47 +1458,7 @@ def api_points():
if
not
api_auth
():
return
"Unauthorized
\n
"
,
HTTPStatus
.
UNAUTHORIZED
db_query
(
"""
SELECT u.uid, u.ukco, u.full_name
FROM owl_users u
JOIN owl_enroll e USING(uid)
WHERE e.cid = %s
AND e.is_teacher = false
"""
,
(
g
.
course
.
cid
,))
students
=
db
.
fetchall
()
db_query
(
"""
SELECT t.ident AS tident, p.target_uid, p.points
FROM owl_topics t
JOIN owl_posts p USING(tid)
WHERE t.cid = %s
AND p.points IS NOT NULL
ORDER BY p.created
"""
,
(
g
.
course
.
cid
,))
awards
=
db
.
fetchall
()
points
=
{
s
.
uid
:
{}
for
s
in
students
}
for
a
in
awards
:
if
a
.
target_uid
==
-
1
:
for
uid
in
points
.
keys
():
points
[
uid
][
a
.
tident
]
=
float
(
a
.
points
)
elif
a
.
target_uid
in
points
:
points
[
a
.
target_uid
][
a
.
tident
]
=
float
(
a
.
points
)
out
=
[]
for
s
in
students
:
out
.
append
({
"uid"
:
s
.
uid
,
"ukco"
:
s
.
ukco
,
"name"
:
s
.
full_name
,
"tasks"
:
points
[
s
.
uid
],
"points"
:
sum
(
points
[
s
.
uid
].
values
()),
})
enc
=
JSONEncoder
(
ensure_ascii
=
False
,
sort_keys
=
True
,
indent
=
4
)
resp
=
make_response
(
enc
.
encode
(
out
))
resp
.
headers
.
add
(
'Content-type'
,
'application/json'
)
return
resp
return
export_points
(
'json'
)
### Administrative commands ###
...
...
templates/main.html
View file @
b5053f4f
...
...
@@ -28,6 +28,7 @@
<h2>
News
</h2>
<table
class=
news
>
<tr><td>
2021-05-21
<td>
Teachers can now download results in CSV or JSON.
<tr><td>
2021-04-20
<td>
Added a Reply button for quoting of posts.
<tr><td>
2021-03-13
<td>
Added syntax highlighting for C, C++, Python, Haskell, and Prolog.
Use
<code>
```python
</code>
in Markdown to start a code block. Ask for more languages
...
...
templates/teacher.html
View file @
b5053f4f
...
...
@@ -73,6 +73,10 @@
<td
class=
pts
>
{{ totals[c.cid][s.uid] }}
{% endfor %}
</table>
<p>
Download as
<a
href=
'{{ url_for('
results_json
',
cident=
c.ident)
}}'
>
JSON
</a>
,
<a
href=
'{{ url_for('
results_csv
',
cident=
c.ident)
}}'
>
CSV
</a>
.
{% endfor %}
{% endblock %}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment