README.md 8.74 KB
Newer Older
1
[![coverage report](https://gitlab.kwant-project.org/zesje/zesje/badges/master/coverage.svg)](https://gitlab.kwant-project.org/zesje/zesje/commits/master)
Ruben Young On's avatar
Ruben Young On committed
2

3 4 5 6
# Welcome to Zesje

Zesje is an online grading system for written exams.

7 8 9 10
## Running Zesje

### Running Zesje using Docker
Running Zesje using Docker is the easiest method to run Zesje
11 12
yourself with minimal technical knowledge required. For this approach
we assume that you already have [Docker](https://www.docker.com/)
13
installed, cloned the Zesje repository and entered its directory.
14

15 16 17 18 19
First create a volume to store the data:

    docker volume create zesje

Then build the Docker image using the following below. Anytime you
20 21
update Zesje by pulling the repository you have to run this command again.

22
    docker build -f auto.Dockerfile . -t zesje:auto
23 24 25

Finally, you can run the container to start Zesje using:

26
    docker run -p 8881:80 --volume zesje:/app/data-dev -it zesje:auto
27

28
Zesje should be available at http://127.0.0.1:8881. If you get
29 30
the error `502 - Bad Gateway` it means that Zesje is still starting.

31 32 33
## Development

### Setting up a development environment
34 35
*Zesje currently doesn't support native Windows, but WSL works.*

36 37 38
We recommend using the Conda tool for managing your development
environment. If you already have Anaconda or Miniconda installed,
you may skip this step.
39

40 41 42 43
Install Miniconda by following the instructions on this page:

https://conda.io/miniconda.html

44 45
Make sure you cloned this repository and enter its directory. Then
create a Conda environment that will automatically install all
46
of zesje's Python dependencies:
47

48
    conda env create  # Creates an environment from environment.yml
49 50 51 52 53 54 55 56 57

Then, *activate* the conda environment:

    conda activate zesje-dev

You should see `(zesje-dev)` inserted into your shell prompt.
This tells you that the environment is activated.

Install all of the Javascript dependencies:
58

59
    yarn install
60

61 62 63 64
Unfortunately there is also another dependency that must be installed
manually for now (we are working to bring this dependency into the
Conda ecosystem). You can install this dependency in the following way
on different platforms:
65

Hugo Kerstens's avatar
Hugo Kerstens committed
66 67 68
| OS                            | Command                   |
|-------------------------------|---------------------------|
| macOS                         | `brew install libdmtx`    |
69
| Debian, Ubuntu                | `apt install libdmtx-dev` |
Hugo Kerstens's avatar
Hugo Kerstens committed
70 71 72
| Arch                          | `pacman -S libdmtx`       |
| Fedora                        | `dnf install libdmtx`     |
| openSUSE                      | `zypper install libdmtx0` |
Adrià Labay's avatar
Adrià Labay committed
73 74 75 76 77


#### Setting up MySQL server

If this is the first time that you will run Zesje with MySQL in
Adrià Labay's avatar
Adrià Labay committed
78
development, then run the following command from the Zesje
Adrià Labay's avatar
Adrià Labay committed
79 80
repository directory:

Hugo Kerstens's avatar
Hugo Kerstens committed
81
    yarn dev:mysql-init
Adrià Labay's avatar
Adrià Labay committed
82

Adrià Labay's avatar
Adrià Labay committed
83 84
That's all it needs to create the MySQL files in the data directory,
migrate the database to the last schema and move all your previous data.
Adrià Labay's avatar
Adrià Labay committed
85

86

Jamy Mahabier's avatar
Jamy Mahabier committed
87
### Running a development server
88
Activate your zesje development environment and run
Jamy Mahabier's avatar
Jamy Mahabier committed
89 90 91 92 93 94 95

    yarn dev

to start the development server, which you can access on http://127.0.0.1:8881.
It will automatically reload whenever you change any source files in `client/`
or `zesje/`.

96 97 98 99 100 101 102 103 104 105
### Generate sample data

The script `example_data.py` can be used to create a sample exam that mimics the appearance and behavior of a typical grading process in Zesje. The prototype exam consist on 3 open answer questions per page and 1 multiple choice question per page (excluding the first one). The script partially solves those questions and assigns random feedback to the answered questions while the not answered questions are processed as blank.

The script is called from the command line with the following parameters:
 - `-d, --delete`  If specified, removes any existing data and creates a new empty database. Otherwise, new exams are added without deleting previous data.
 - `--exams (int)` the number of exams to add, default is 1.
 - `--pages (int)` the number of pages per exam, default is 3.
 - `--students (int)` the number of students per exam, default is 30
 - `--graders (int)` the number of graders to add, default is 4.
106 107 108 109 110
 - `--solve (float)` between 0 and 100, indicates the percentage of questions to answer (including MCQ), default is 90%.
 - `--grade (float)` between 0 and 100, indicate the percentage of solved questions to grade (that is, excluding blank answers), default is 60%.
 - `--skip-processing` if specified, fakes the pdf processing to reduce time. As a drawback, blanks will not be detected.
 - `--multiple-copies (float)` between 0 and 100, indicates how much of the students submit multiple copies, default is 5%

111 112 113

The actual processing of the exam takes a while, specially when the number of students is large.

Jamy Mahabier's avatar
Jamy Mahabier committed
114 115
### Running the tests

Thomas Roos's avatar
Thomas Roos committed
116 117 118
You can run the tests by running

    yarn test
119

120 121
#### Viewing test coverage

122
As a test coverage tool for Python tests, `pytest-cov` is used.
123

Ruben Young On's avatar
Ruben Young On committed
124 125
To view test coverage, run

126
    yarn test:py:cov
Ruben Young On's avatar
Ruben Young On committed
127

128 129
A coverage report is now generated in the terminal, as an XML file, and in HTML format.
The HTML file shows an overview of untested code in red.
Thomas Roos's avatar
Thomas Roos committed
130

Ruben Young On's avatar
Ruben Young On committed
131
##### Viewing coverage in Visual Studio Code
RABijl's avatar
RABijl committed
132 133 134 135 136

There is a plugin called Coverage Gutter that will highlight which lines of code are covered.
Simply install Coverage Gutter, after which a watch button appears in the colored box at the bottom of your IDE.
When you click watch, green and red lines appear next to the line numbers indicating if the code is covered.

137
Coverage Gutter uses the XML which is produced by `yarn test:py:cov`, called `cov.xml`. This file should be located in the main folder.
138

Ruben Young On's avatar
Ruben Young On committed
139
##### Viewing coverage in PyCharm
140
To view test coverage in PyCharm, run `yarn test:py:cov` to generate the coverage report XML file `cov.xml` if it is not present already.
Ruben Young On's avatar
Ruben Young On committed
141 142 143 144 145

Next, open up PyCharm and in the top bar go to **Run -> Show Code Coverage Data** (Ctrl + Alt + F6).

Press **+** and add the file `cov.xml` that is in the main project directory.
A code coverage report should now appear in the side bar on the right.
RABijl's avatar
RABijl committed
146

147 148 149 150 151 152 153
#### Policy errors

If you encounter PolicyErrors related to ImageMagick in any of the previous steps, please
try the instructions listed
[here](https://alexvanderbist.com/posts/2018/fixing-imagick-error-unauthorized) as
a first resort.

154 155
### Database modifications

156
Zesje uses Flask-Migrate and Alembic for database versioning and migration. Flask-Migrate is an extension that handles SQLAlchemy database migrations for Flask applications using Alembic.
157 158 159

To change something in the database schema, simply add this change to `zesje/database.py`. After that run the following command to prepare a new migration:

160
    yarn dev:prepare-migration
161 162 163

This uses Flask-Migrate to make a new migration script in `migrations/versions` which needs to be reviewed and edited. Please suffix the name of this file with something distinctive and add a short description at the top of the file. To apply the database migration run:

164
    yarn dev:mysql-migrate # (for the development database)
165
    yarn migrate # (for the production database, MySQL must be running)
166

Thomas Roos's avatar
Thomas Roos committed
167 168
### Building and running the production version

Jamy Mahabier's avatar
Jamy Mahabier committed
169 170 171
### Code style

#### Python
172
Adhere to [PEP8](https://www.python.org/dev/peps/pep-0008/), but use a column width of 120 characters (instead of 79).
173

Jamy Mahabier's avatar
Jamy Mahabier committed
174 175 176 177 178 179
If you followed the instructions above, the linter `flake8` is installed in your virtual environment. If you use Visual Studio Code, install the [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) extension and add the following lines to your workspace settings:

    "python.linting.pylintEnabled": false,
    "python.linting.flake8Enabled": true,
    "[python]": {
        "editor.rulers": [120]
180
    },
Jamy Mahabier's avatar
Jamy Mahabier committed
181 182 183 184 185 186

If you use Atom, install the [linter-flake8](https://atom.io/packages/linter-flake8) plugin and add the following lines to your config:

    ".source.python":
      "editor":
        "preferredLineLength": 120
187

188 189 190 191 192 193 194
#### Javascript
Adhere to [StandardJS](https://standardjs.com/).

If you use Visual Studio Code, install the [vscode-standardjs](https://marketplace.visualstudio.com/items?itemName=chenxsan.vscode-standardjs) plugin.

If you use Atom, install the [linter-js-standard-engine](https://atom.io/packages/linter-js-standard-engine) plugin.

195 196 197
### Adding dependencies

#### Server-side
198 199
If you start using a new Python library, be sure to add it to `environment.yml`.
The packages can be installed and updated in your environment by `conda` using
Thomas Roos's avatar
Thomas Roos committed
200

201
    conda env update
Thomas Roos's avatar
Thomas Roos committed
202 203 204 205 206

#### Client-side
Yarn keeps track of all the client-side dependancies in `package.json` when you install new packages with `yarn add [packageName]`. Yarn will install and update your packages if your run

    yarn install
Thomas Roos's avatar
Thomas Roos committed
207 208

## License
209
Zesje is licensed under AGPLv3, which can be found in `LICENSE`. An summary of this license with it's permissions, conditions and limitations can be found [here](https://choosealicense.com/licenses/agpl-3.0/).