Newer
Older
# Grady - will correct you!
The intention of this tool is to simplify the exam correcting process at the
University of Goettingen. It is deployed as a web application consisting
of a Django-Rest backend and a Vue.js frontend.
[](https://gitlab.gwdg.de/j.michal/grady/commits/master) [](https://gitlab.gwdg.de/j.michal/grady/commits/master)
## Overview
Grady has three basic functions for the three types of users
* Reviewers can
* edit feedback that has been provided by tutors
* mark feedback as final if it should not be modified (only final feedback is
shown to students)
* delete feedback (submission will be reassigned)
* Tutors can
* request a submission that they have to correct and submit feedback for it
* delete their own feedback
* review feedback of other tutors
* they do not see which student submitted the solution
* Students can
* review their final feedback and score in the post exam review
An overview over the database can be found in the docs folder.
## Contributing

Jan Maximilian Michal
committed
Feature proposals are welcome! If you experienced any bugs or otherwise
unexpected behavior please submit an issue using the issue templates.
It is of course possible to contribute but currently there is no standardized

Jan Maximilian Michal
committed
way since the project is in a very early stage and fairly small. If you feel the
need to help us out anyway, please contact us via our university email
addresses.
## Development
### Dependencies
Make sure the following packages and tools are installed:
- Python 3.6
- [Docker](https://www.docker.com/) or a local installation of [Postgres](https://www.postgresql.org/)
- `npm` or `yarn` (you can use `npm` to install `yarn`)
- `make`
These are required to set up the project. All other application dependencies are
listed in the `requirements.txt` and the `package.json` files. These will be
installed automatically during the installation process.
### Installing
To set up a new development instance perform the following steps:
1. Create a virtual environment with a Python3.6 interpreter and
activate it. It works like this:
make .venv
source .venv/bin/activate
Just type `deactivate` the get out.
2. Set the environment variable `DJANGO_DEV` to `True` like this:
export DJANGO_DEV=True
3. Install backend dependencies with:
make install
4. Set up a Postgres 9.5 database. If you have docker installed the
easiest way is to just run it in a docker container, like this:

Jan Maximilian Michal
committed
docker run -d --rm --name postgres -p 5432:5432 postgres:9.5
Alternatively, take a look at the Makefile targets that should make your
And apply database migrations once the database is up:
python manage.py migrate
5. Create a superuser if necessary:
python manage.py createsuperuser
More users can be added in the admin interface. You should be able
to reach it via <http://localhost:8000/admin>.

Jan Maximilian Michal
committed
7. Everything is set. You can start the development server with:
make run
8. Congratulations! Your backend should now be up an running. To setup the frontend
see the README in the `frontend` folder.
### Testing
> "Code without tests is broken by design." -- (Jacob Kaplan-Moss, Django core developer)
Well, currently this repository lacks tests, thats true. But that will change as
this work until now is merely a prototype that will be developed further. However,
the few existing tests can be seen as examples and can be found in the `tests.py`
file of each app (currently only `core`). You can run those tests with
python manage.py test core
or if you want a coverage report as well you can run:

Jan Maximilian Michal
committed
make coverage
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
## Production
In order to run the app in production, a server with
[Docker](https://www.docker.com/) is needed. To make routing to the
respective instances easier, we recommend running [traefik](https://traefik.io/)
as a reverse proxy on the server. For easier configuration of the containers
we recommend using `docker-compose`. The following guide will assume both these
dependencies are available.
### Setting up a new instance
Simply copy the following `docker-compose.yml` onto your production server:
```yaml
version: "3"
services:
postgres:
image: postgres:9.6
labels:
traefik.enable: "false"
networks:
- internal
volumes:
- ./database:/var/lib/postgresql/data
grady:
image: docker.gitlab.gwdg.de/j.michal/grady:master
restart: always
entrypoint:
- ./deploy.sh
volumes:
- ./secret:/code/secret
environment:
GRADY_INSTANCE: ${INSTANCE}
SCRIPT_NAME: ${URLPATH}
networks:
- internal
- proxy
labels:
traefik.backend: ${INSTANCE}
traefik.enable: "true"
traefik.frontend.rule: Host:${GRADY_HOST};PathPrefix:${URLPATH}
traefik.docker.network: proxy
traefik.port: "8000"
depends_on:
- postgres
networks:
proxy:
external: true
internal:
external: false
```
and set the `INSTANCE`, `URLPATH`, `GRADY_HOST` variables either directly in the
compose file or within an `.env` file in the same directory as the `docker-compose.yml`
(it will be automatically loaded by `docker-compose`).
Login to gwdg gitlab docker registry by entering:
```commandline
docker login docker.gitlab.gwdg.de
```
Running
```commandline
docker-compose pull
docker-compose up -d
```
will download the latest postgres and grady images and run them in the background.
### Importing exam data
#### Exam data structure
In order to import the exam data it must be in a specific format.
You need the following:
1. A .json file file containing the output of the converted ILIAS export which is
generated by [hektor](https://gitlab.gwdg.de/j.michal/hektor)
2. A .csv file where the columns are: id, name, score, (file suffix). No
suffix defaults to .c
Supported suffixes: .c , .java , .hs , .s or .asm (for mips)
Important: The name values must be the same as the ones that are contained in
the export file file from 1.
Example:
```commandline
$ cat submission_types.csv
a01, Alpha Team, 10, .c
a02, Beta Distribution, 10, .java
a03, Gamma Ray, 20
```
3. A path to a directory with sample solutions named
4. A path to a directory containing HTML files with an accurate
description of the task. File name pattern has to be: <id>.html (same id as in 2.)
```commandline
$ tree -L 2
.
├── code-lsg
│ ├── a01.c
│ ├── a02.java
│ └── a03.hs
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
└── html
├── a01.html
├── a02.html
└── a03.html
```
5. (Optional) a .csv file containing module information. This step is purely
optional -- Grady works just fine without these information. If you want to
distinguish students within one instance or give information about the
grading type you should provide this info.
CSV file format: module_reference, total_score, pass_score, pass_only
Example:
```commandline
$ cat mpdules.csv
B.Inf.1801, 90, 45, yes
B.Mat.31415, 50, 10, no
```
6. (Optional) a plain text file containing one username per line. A new tutor
user account will be created with the corresponding username and a randomly
generated password. The passwords are written to a `.importer_passwords` file.
Note: Rather than during the import, tutors can register their own accounts
on the web login page. A reviewer can then activate their accounts via the
tutor overview.
7. A plain text file containing one username per line. A new **reviewer** account
will be created with the corresponding username and a randomly
generated password. The passwords are written to a `.importer_passwords` file.
This step should not be skipped because a reviewer account is necessary in order
to activate the tutor accounts.
#### Importing exam data
In order to import the exam data it has to be copied into the container
and the importer script has to be started. This process is still quite manual
and will likely change in the future.
Copy the prepared exam data as outlined above to the production server
(e.g. via scp). Then copy the data into the running grady container:
```commandline
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ce0d61416f83 docker.gitlab.gwdg.de/j.michal/grady:master "./deploy.sh" 6 weeks ago Up 6 weeks grady_1
$ docker cp exam-data/ ce0d61416f83:/
```
This will copy the folder exam-data into the container with the id ce0d61416f83
under the root directory.
Open an interactive shell session in the running container:
```commandline
$ docker exec -it ce0d61416f83 /bin/sh
```
Change to the `/exam-data/` folder and run the importer script:
```commandline
$ python /code/manage.py importer
```
The importer script will now interactively guide you through the import process.
Note: The step `[2] do_preprocess_submissions` is in part specific to
c programming course exam data. The EmptyTest can be used for every kind of
submission, the other tests not. Submissions that are empty will be labeled as
such and receive a score of 0 during step `[3] do_load_submissions`.
Generated user account passwords will be saved under .import_passwords